Skip to content

Commit

Permalink
Implement NC4_Serial
Browse files Browse the repository at this point in the history
This class uses rank 0 to write NetCDF-4 files.
  • Loading branch information
ckhroulev committed Aug 20, 2020
1 parent db75ed4 commit 32b0f99
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/util/CMakeLists.txt
Expand Up @@ -31,6 +31,7 @@ set(PISMUTIL_SRC
io/LocalInterpCtx.cc
io/File.cc
io/NC_Serial.cc
io/NC4_Serial.cc
io/NC4File.cc
io/NCFile.cc
io/io_helpers.cc
Expand Down
62 changes: 55 additions & 7 deletions src/util/io/NC4_Serial.cc
@@ -1,4 +1,4 @@
// Copyright (C) 2012, 2013, 2014, 2015, 2019 PISM Authors
// Copyright (C) 2012, 2013, 2014, 2015, 2019, 2020 PISM Authors
//
// This file is part of PISM.
//
Expand All @@ -16,7 +16,7 @@
// along with PISM; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#include "PISMNC4_Serial.hh"
#include "NC4_Serial.hh"

// The following is a stupid kludge necessary to make NetCDF 4.x work in
// serial mode in an MPI program:
Expand All @@ -25,18 +25,66 @@
#endif
#include <netcdf.h>

#include "pism/util/error_handling.hh"

namespace pism {
namespace io {

int NC4_Serial::open_impl(const std::string &fname, IO_Mode mode) {
int open_mode = mode == PISM_READONLY ? NC_NOWRITE : NC_WRITE;
//! \brief Prints an error message; for debugging.
static void check(const ErrorLocation &where, int return_code) {
if (return_code != NC_NOERR) {
throw RuntimeError(where, nc_strerror(return_code));
}
}

NC4_Serial::NC4_Serial(MPI_Comm c)
: NC_Serial(c), m_compression_level(0) {
// empty
}

NC4_Serial::~NC4_Serial() {
// empty
}

void NC4_Serial::create_impl(const std::string &fname) {
int stat = NC_NOERR;

if (m_rank == 0) {
stat = nc_create(fname.c_str(), NC_CLOBBER | NC_NETCDF4, &m_file_id);
}

MPI_Barrier(m_com);
MPI_Bcast(&m_file_id, 1, MPI_INT, 0, m_com);
MPI_Bcast(&stat, 1, MPI_INT, 0, m_com);

int stat = nc_open(fname.c_str(), open_mode, &m_file_id);
check(PISM_ERROR_LOCATION, stat);
}

int NC4_Serial::create_impl(const std::string &fname) {
int stat = nc_create(fname.c_str(), NC_NETCDF4, &m_file_id);
void NC4_Serial::set_compression_level_impl(int level) const {
m_compression_level = level;
}

void NC4_Serial::def_var_impl(const std::string &name,
IO_Type nctype,
const std::vector<std::string> &dims) const {

// use the parent class to define the variable
NC_Serial::def_var_impl(name, nctype, dims);

int stat = NC_NOERR;

// set compression level (except for scalars and time-series)
if (m_compression_level > 0 and dims.size() > 1) {
if (m_rank == 0) {
int varid = get_varid(name);

stat = nc_def_var_deflate(m_file_id, varid, 0, 1, m_compression_level);
}
}

MPI_Barrier(m_com);
MPI_Bcast(&stat, 1, MPI_INT, 0, m_com);

check(PISM_ERROR_LOCATION, stat);
}

Expand Down
21 changes: 12 additions & 9 deletions src/util/io/NC4_Serial.hh
@@ -1,4 +1,4 @@
// Copyright (C) 2012, 2013, 2014, 2015, 2019 PISM Authors
// Copyright (C) 2012, 2013, 2014, 2015, 2019, 2020 PISM Authors
//
// This file is part of PISM.
//
Expand All @@ -19,24 +19,27 @@
#ifndef _NC4_Serial_H_
#define _NC4_Serial_H_

#include "PISMNC4File.hh"
#include "NC_Serial.hh"

namespace pism {
namespace io {

class NC4_Serial : public NC4File
class NC4_Serial : public NC_Serial
{
public:
NC4_Serial(MPI_Comm c, unsigned int compression_level)
: NC4File(c, compression_level) {}
virtual ~NC4_Serial() {}
NC4_Serial(MPI_Comm c);
virtual ~NC4_Serial();

protected:
// open/create/close
void open_impl(const std::string &filename, IO_Mode mode);
void set_compression_level_impl(int level) const;

void create_impl(const std::string &filename);
};

void def_var_impl(const std::string &name, IO_Type nctype,
const std::vector<std::string> &dims) const;

mutable int m_compression_level;
};

} // end of namespace io
} // end of namespace pism
Expand Down
14 changes: 8 additions & 6 deletions src/util/io/NC_Serial.hh
Expand Up @@ -37,7 +37,7 @@ protected:
// open/create/close
void open_impl(const std::string &filename, IO_Mode mode);

void create_impl(const std::string &filename);
virtual void create_impl(const std::string &filename);

void sync_impl() const;

Expand All @@ -58,7 +58,7 @@ protected:
void inq_unlimdim_impl(std::string &result) const;

// var
void def_var_impl(const std::string &name, IO_Type nctype, const std::vector<std::string> &dims) const;
virtual void def_var_impl(const std::string &name, IO_Type nctype, const std::vector<std::string> &dims) const;

void get_vara_double_impl(const std::string &variable_name,
const std::vector<unsigned int> &start,
Expand Down Expand Up @@ -86,7 +86,7 @@ protected:

void inq_varname_impl(unsigned int j, std::string &result) const;

void set_compression_level_impl(int level) const;
virtual void set_compression_level_impl(int level) const;

// att
void get_att_double_impl(const std::string &variable_name, const std::string &att_name, std::vector<double> &result) const;
Expand All @@ -105,16 +105,18 @@ protected:
void set_fill_impl(int fillmode, int &old_modep) const;

void del_att_impl(const std::string &variable_name, const std::string &att_name) const;
private:

int m_rank;

int get_varid(const std::string &variable_name) const;

private:

void get_var_double(const std::string &variable_name,
const std::vector<unsigned int> &start,
const std::vector<unsigned int> &count,
const std::vector<unsigned int> &imap, double *ip,
bool transposed) const;

int get_varid(const std::string &variable_name) const;
};

} // end of namespace io
Expand Down

0 comments on commit 32b0f99

Please sign in to comment.