Skip to content

Commit

Permalink
EAMxx: automatically change var dtype inside io interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
bartgol committed May 6, 2024
1 parent bcdc820 commit 29dd63b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 44 deletions.
17 changes: 0 additions & 17 deletions components/eamxx/src/control/intensive_observation_period.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,6 @@ initialize_iop_file(const util::TimeStamp& run_t0,
else if (scorpio::has_var(iop_file, "nbdate")) bdate_name = "nbdate";
else EKAT_ERROR_MSG("Error! No valid name for bdate in "+iop_file+".\n");

// Just in case bdate_name is stored with a type that is not "int" (e.g., it's int64)
scorpio::change_var_dtype(iop_file,bdate_name,"int");
scorpio::read_var(iop_file, bdate_name, &bdate);

int yr=bdate/10000;
Expand All @@ -255,8 +253,6 @@ initialize_iop_file(const util::TimeStamp& run_t0,

const auto ntimes = scorpio::get_dimlen(iop_file, time_dimname);
m_time_info.iop_file_times_in_sec = view_1d_host<int>("iop_file_times", ntimes);
// Just in case "tsec" is stored with a different data type
scorpio::change_var_dtype(iop_file,"tsec","int");
scorpio::read_var(iop_file,"tsec",m_time_info.iop_file_times_in_sec.data());

// From now on, when we read vars, "time" must be treated as unlimited, to avoid issues
Expand All @@ -271,9 +267,6 @@ initialize_iop_file(const util::TimeStamp& run_t0,
EKAT_REQUIRE_MSG(nlats==1 and nlons==1, "Error! IOP data file requires a single lat/lon pair.\n");
Real iop_file_lat, iop_file_lon;

// Just in case "lat/lon" are stored with a different data type (e.g., float instead of double)
scorpio::change_var_dtype(iop_file,"lat","real");
scorpio::change_var_dtype(iop_file,"lon","real");
scorpio::read_var(iop_file,"lat",&iop_file_lat);
scorpio::read_var(iop_file,"lon",&iop_file_lon);

Expand All @@ -300,8 +293,6 @@ initialize_iop_file(const util::TimeStamp& run_t0,
iop_file_pressure.get_header().get_alloc_properties().request_allocation(Pack::n);
iop_file_pressure.allocate_view();
auto data = iop_file_pressure.get_view<Real*, Host>().data();
// Just in case "lev" is stored with a different data type (e.g., float instead of double)
scorpio::change_var_dtype(iop_file,"lev","real");
scorpio::read_var(iop_file,"lev",data);

// Convert to pressure to millibar (file gives pressure in Pa)
Expand Down Expand Up @@ -550,8 +541,6 @@ read_iop_file_data (const util::TimeStamp& current_ts)
// Load surface pressure (Ps) from iop file
auto ps_data = surface_pressure.get_view<Real, Host>().data();

// Just in case "Ps" is stored with a different data type (e.g., float instead of double)
scorpio::change_var_dtype(iop_file,"Ps","real");
scorpio::read_var(iop_file,"Ps",ps_data,iop_file_time_idx);
surface_pressure.sync_to_dev();

Expand Down Expand Up @@ -639,8 +628,6 @@ read_iop_file_data (const util::TimeStamp& current_ts)
if (field.rank()==0) {
// For scalar data, read iop file variable directly into field data
auto data = field.get_view<Real, Host>().data();
// Just in case the var is stored with a different data type (e.g., float instead of double)
scorpio::change_var_dtype(iop_file,file_varname,"real");
scorpio::read_var(iop_file,file_varname,data,iop_file_time_idx);
field.sync_to_dev();
} else if (field.rank()==1) {
Expand All @@ -658,8 +645,6 @@ read_iop_file_data (const util::TimeStamp& current_ts)

// Read data from iop file.
std::vector<Real> data(file_levs);
// Just in case the var is stored with a different data type (e.g., float instead of double)
scorpio::change_var_dtype(iop_file,file_varname,"real");
scorpio::read_var(iop_file,file_varname,data.data(),iop_file_time_idx);

// Copy first adjusted_file_levs-1 values to field
Expand All @@ -670,8 +655,6 @@ read_iop_file_data (const util::TimeStamp& current_ts)
const auto has_srf = m_iop_field_surface_varnames.count(fname)>0;
if (has_srf) {
const auto srf_varname = m_iop_field_surface_varnames[fname];
// Just in case the var is stored with a different data type (e.g., float instead of double)
scorpio::change_var_dtype(iop_file,srf_varname,"real");
scorpio::read_var(iop_file,srf_varname,&iop_file_v_h(adjusted_file_levs-1),iop_file_time_idx);
} else {
// No surface value exists, compute surface value
Expand Down
47 changes: 20 additions & 27 deletions components/eamxx/src/share/io/scream_scorpio_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,11 +1012,12 @@ void define_var (const std::string& filename, const std::string& varname,
define_var(filename,varname,"",dimensions,dtype,dtype,time_dependent);
}

void change_var_dtype (const std::string& filename, const std::string& varname,
const std::string& dtype)
// This overload is not exposed externally. Also, filename is only
// used to print it in case there are errors
void change_var_dtype (PIOVar& var,
const std::string& dtype,
const std::string& filename)
{
auto& var = impl::get_var(filename,varname,"scorpio::change_var_dtype");

if (refine_dtype(dtype)==refine_dtype(var.dtype)) {
// The type is not changing, nothing to do
return;
Expand All @@ -1030,6 +1031,14 @@ void change_var_dtype (const std::string& filename, const std::string& varname,
}
}

void change_var_dtype (const std::string& filename,
const std::string& varname,
const std::string& dtype)
{
auto& var = impl::get_var(filename,varname,"scorpio::change_var_dtype");
change_var_dtype(var,dtype,filename);
}

bool has_var (const std::string& filename, const std::string& varname)
{
// If file wasn't open, open it on the fly. See comment in PeekFile class above.
Expand Down Expand Up @@ -1142,6 +1151,9 @@ void read_var (const std::string &filename, const std::string &varname, T* buf,
const auto& f = impl::get_file(filename,"scorpio::read_var");
auto& var = impl::get_var(filename,varname,"scorpio::read_var");

// If the input pointer type already matches var.dtype, this is a no-op
change_var_dtype(var,get_dtype<T>(),filename);

int err;
int frame = -1;
if (var.time_dep) {
Expand Down Expand Up @@ -1169,18 +1181,6 @@ void read_var (const std::string &filename, const std::string &varname, T* buf,
" - first dim len: " + std::to_string(var.dims[0]->length) + "\n");
}

// The user may be using a different data type than the one that is in the file
// If that's the case, they should call `change_var_dtype` *before* trying to read it
if (get_dtype<T>()!=var.dtype) {
EKAT_ERROR_MSG (
"Error! You're attempting to read a variable with the wrong data type.\n"
"If you want to use a different data type, call change_var_dtype *before* attempting a read.\n"
" - filename : " + filename + "\n"
" - varname : " + varname + "\n"
" - var dtype: " + var.dtype + "\n"
" - ptr dtype: " + get_dtype<T>() + "\n");
}

std::string pioc_func;
if (var.decomp) {
// A decomposed variable, requires read_darray
Expand Down Expand Up @@ -1245,6 +1245,10 @@ void write_var (const std::string &filename, const std::string &varname, const T

const auto& f = impl::get_file(filename,"scorpio::write_var");
auto& var = impl::get_var(filename,varname,"scorpio::write_var");

// If the input pointer type already matches var.dtype, this is a no-op
change_var_dtype(var,get_dtype<T>(),filename);

int err;

if (var.time_dep) {
Expand All @@ -1259,17 +1263,6 @@ void write_var (const std::string &filename, const std::string &varname, const T
check_scorpio_noerr (err,f.name,"variable",varname,"write_var","setframe");
}

// The user may be using a different data type than the one that is in the file
if (get_dtype<T>()!=var.dtype) {
EKAT_ERROR_MSG (
"Error! You're attempting to write a variable with the wrong data type.\n"
"If you want to use a different data type, call change_var_dtype *before* attempting a write.\n"
" - filename : " + filename + "\n"
" - varname : " + varname + "\n"
" - var dtype: " + var.dtype + "\n"
" - ptr dtype: " + get_dtype<T>() + "\n");
}

std::string pioc_func;
if (var.decomp) {
// A decomposed variable, requires write_darray
Expand Down
6 changes: 6 additions & 0 deletions components/eamxx/src/share/io/scream_scorpio_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ void define_var (const std::string& filename, const std::string& varname,

// This is useful when reading data sets. E.g., if the pio file is storing
// a var as float, but we need to read it as double, we need to call this.
// NOTE: read_var/write_var automatically change the dtype if the input
// pointer type does not match the var dtype. However, changing dtype
// forces a rebuild of the var decomp (if any). Hence, if you know
// the var WILL be read/written as decomposed, you should call this method
// BEFORE calling set_dim_decomp, so that the decomp is built directly
// with the correct data type (PIO decomps depend on var dtype).
void change_var_dtype (const std::string& filename,
const std::string& varname,
const std::string& dtype);
Expand Down

0 comments on commit 29dd63b

Please sign in to comment.