From a111cf640a02e548f51ea702780e51e87b50a6e3 Mon Sep 17 00:00:00 2001 From: Lars Pastewka <lars.pastewka@imtek.uni-freiburg.de> Date: Sun, 26 Nov 2017 22:35:56 +0100 Subject: [PATCH] BUG: Proper handling of bigint data. Corrects behavior when compiled with LAMMPS_BIGBIG. --- src/USER-NETCDF/dump_netcdf.cpp | 122 +++++++++++++++++++------- src/USER-NETCDF/dump_netcdf.h | 2 +- src/USER-NETCDF/dump_netcdf_mpiio.cpp | 112 +++++++++++++++++------ src/USER-NETCDF/dump_netcdf_mpiio.h | 2 +- 4 files changed, 179 insertions(+), 59 deletions(-) diff --git a/src/USER-NETCDF/dump_netcdf.cpp b/src/USER-NETCDF/dump_netcdf.cpp index 988a9db6c3..a88d74434b 100644 --- a/src/USER-NETCDF/dump_netcdf.cpp +++ b/src/USER-NETCDF/dump_netcdf.cpp @@ -43,7 +43,8 @@ using namespace LAMMPS_NS; using namespace MathConst; -enum{INT,FLOAT,BIGINT}; // same as in thermo.cpp +enum{THERMO_INT,THERMO_FLOAT,THERMO_BIGINT}; // same as in thermo.cpp +enum{DUMP_INT,DUMP_DOUBLE,DUMP_STRING,DUMP_BIGINT}; // same as in DumpCFG const char NC_FRAME_STR[] = "frame"; const char NC_SPATIAL_STR[] = "spatial"; @@ -121,10 +122,6 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : ndims = 3; strcpy(mangled, "velocities"); } - // extensions to the AMBER specification - else if (!strcmp(mangled, "type")) { - strcpy(mangled, "atom_types"); - } else if (!strcmp(mangled, "xs") || !strcmp(mangled, "ys") || !strcmp(mangled, "zs")) { idim = mangled[0] - 'x'; @@ -409,10 +406,11 @@ void DumpNetCDF::openfile() nc_type xtype; // Type mangling - if (vtype[perat[i].field[0]] == INT) { + if (vtype[perat[i].field[0]] == DUMP_INT) { xtype = NC_INT; - } - else { + } else if (vtype[perat[i].field[0]] == DUMP_BIGINT) { + xtype = NC_INT64; + } else { if (double_precision) xtype = NC_DOUBLE; else @@ -476,15 +474,15 @@ void DumpNetCDF::openfile() if (thermo) { Thermo *th = output->thermo; for (int i = 0; i < th->nfield; i++) { - if (th->vtype[i] == FLOAT) { + if (th->vtype[i] == THERMO_FLOAT) { NCERRX( nc_def_var(ncid, th->keyword[i], NC_DOUBLE, 1, dims, &thermovar[i]), th->keyword[i] ); } - else if (th->vtype[i] == INT) { + else if (th->vtype[i] == THERMO_INT) { NCERRX( nc_def_var(ncid, th->keyword[i], NC_INT, 1, dims, &thermovar[i]), th->keyword[i] ); } - else if (th->vtype[i] == BIGINT) { + else if (th->vtype[i] == THERMO_BIGINT) { #if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG) NCERRX( nc_def_var(ncid, th->keyword[i], NC_INT64, 1, dims, &thermovar[i]), th->keyword[i] ); @@ -645,6 +643,52 @@ int nc_put_var1_bigint<long long>(int ncid, int varid, const size_t index[], return nc_put_var1_longlong(ncid, varid, index, tp); } +template <typename T> +int nc_put_vara_bigint(int ncid, int varid, const size_t start[], + const size_t count[], const T* tp) +{ + return nc_put_vara_int(ncid, varid, start, count, tp); +} + +template <> +int nc_put_vara_bigint<long>(int ncid, int varid, const size_t start[], + const size_t count[], const long* tp) +{ + return nc_put_vara_long(ncid, varid, start, count, tp); +} + +template <> +int nc_put_vara_bigint<long long>(int ncid, int varid, const size_t start[], + const size_t count[], const long long* tp) +{ + return nc_put_vara_longlong(ncid, varid, start, count, tp); +} + +template <typename T> +int nc_put_vars_bigint(int ncid, int varid, const size_t start[], + const size_t count[], const ptrdiff_t stride[], + const T* tp) +{ + return nc_put_vars_int(ncid, varid, start, count, stride, tp); +} + +template <> +int nc_put_vars_bigint<long>(int ncid, int varid, const size_t start[], + const size_t count[], const ptrdiff_t stride[], + const long* tp) +{ + return nc_put_vars_long(ncid, varid, start, count, stride, tp); +} + +template <> +int nc_put_vars_bigint<long long>(int ncid, int varid, const size_t start[], + const size_t count[], + const ptrdiff_t stride[], + const long long* tp) +{ + return nc_put_vars_longlong(ncid, varid, start, count, stride, tp); +} + void DumpNetCDF::write() { // open file @@ -666,16 +710,16 @@ void DumpNetCDF::write() for (int i = 0; i < th->nfield; i++) { th->call_vfunc(i); if (filewriter) { - if (th->vtype[i] == FLOAT) { + if (th->vtype[i] == THERMO_FLOAT) { NCERRX( nc_put_var1_double(ncid, thermovar[i], start, &th->dvalue), th->keyword[i] ); } - else if (th->vtype[i] == INT) { + else if (th->vtype[i] == THERMO_INT) { NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &th->ivalue), th->keyword[i] ); } - else if (th->vtype[i] == BIGINT) { + else if (th->vtype[i] == THERMO_BIGINT) { NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue), th->keyword[i] ); } @@ -776,16 +820,16 @@ void DumpNetCDF::write_data(int n, double *mybuf) if (!int_buffer) { n_buffer = n; - int_buffer = (int *) - memory->smalloc(n*sizeof(int),"dump::int_buffer"); + int_buffer = (bigint *) + memory->smalloc(n*sizeof(bigint),"dump::int_buffer"); double_buffer = (double *) memory->smalloc(n*sizeof(double),"dump::double_buffer"); } if (n > n_buffer) { n_buffer = n; - int_buffer = (int *) - memory->srealloc(int_buffer, n*sizeof(int),"dump::int_buffer"); + int_buffer = (bigint *) + memory->srealloc(int_buffer, n*sizeof(bigint),"dump::int_buffer"); double_buffer = (double *) memory->srealloc(double_buffer, n*sizeof(double),"dump::double_buffer"); } @@ -805,7 +849,7 @@ void DumpNetCDF::write_data(int n, double *mybuf) for (int i = 0; i < n_perat; i++) { int iaux = perat[i].field[0]; - if (vtype[iaux] == INT) { + if (vtype[iaux] == DUMP_INT || vtype[iaux] == DUMP_BIGINT) { // integers if (perat[i].dims > 1) { @@ -813,41 +857,55 @@ void DumpNetCDF::write_data(int n, double *mybuf) iaux = perat[i].field[idim]; if (iaux >= 0) { - for (int j = 0; j < n; j++, iaux+=size_one) { - int_buffer[j] = mybuf[iaux]; + if (vtype[iaux] == DUMP_INT) { + for (int j = 0; j < n; j++, iaux+=size_one) { + int_buffer[j] = static_cast<int>(mybuf[iaux]); + } + } + else { // DUMP_BIGINT + for (int j = 0; j < n; j++, iaux+=size_one) { + int_buffer[j] = static_cast<bigint>(mybuf[iaux]); + } } start[2] = idim; if (perat[i].constant) { if (perat[i].ndumped < ntotalgr) { - NCERR( nc_put_vars_int(ncid, perat[i].var, - start+1, count+1, stride+1, - int_buffer) ); + NCERR( nc_put_vars_bigint(ncid, perat[i].var, + start+1, count+1, stride+1, + int_buffer) ); perat[i].ndumped += n; } } else - NCERR( nc_put_vars_int(ncid, perat[i].var, start, count, stride, - int_buffer) ); + NCERR( nc_put_vars_bigint(ncid, perat[i].var, start, count, stride, + int_buffer) ); } } } else { - for (int j = 0; j < n; j++, iaux+=size_one) { - int_buffer[j] = mybuf[iaux]; + if (vtype[iaux] == DUMP_INT) { + for (int j = 0; j < n; j++, iaux+=size_one) { + int_buffer[j] = static_cast<int>(mybuf[iaux]); + } + } + else { // DUMP_BIGINT + for (int j = 0; j < n; j++, iaux+=size_one) { + int_buffer[j] = static_cast<bigint>(mybuf[iaux]); + } } if (perat[i].constant) { if (perat[i].ndumped < ntotalgr) { - NCERR( nc_put_vara_int(ncid, perat[i].var, start+1, count+1, - int_buffer) ); + NCERR( nc_put_vara_bigint(ncid, perat[i].var, start+1, count+1, + int_buffer) ); perat[i].ndumped += n; } } else - NCERR( nc_put_vara_int(ncid, perat[i].var, start, count, - int_buffer) ); + NCERR( nc_put_vara_bigint(ncid, perat[i].var, start, count, + int_buffer) ); } } else { diff --git a/src/USER-NETCDF/dump_netcdf.h b/src/USER-NETCDF/dump_netcdf.h index 25d64efade..f97fd58409 100644 --- a/src/USER-NETCDF/dump_netcdf.h +++ b/src/USER-NETCDF/dump_netcdf.h @@ -66,7 +66,7 @@ class DumpNetCDF : public DumpCustom { bool thermo; // write thermo output to netcdf file bigint n_buffer; // size of buffer - int *int_buffer; // buffer for passing data to netcdf + bigint *int_buffer; // buffer for passing data to netcdf double *double_buffer; // buffer for passing data to netcdf int ncid; diff --git a/src/USER-NETCDF/dump_netcdf_mpiio.cpp b/src/USER-NETCDF/dump_netcdf_mpiio.cpp index 168e46a6b7..5e5be1c7aa 100644 --- a/src/USER-NETCDF/dump_netcdf_mpiio.cpp +++ b/src/USER-NETCDF/dump_netcdf_mpiio.cpp @@ -43,7 +43,8 @@ using namespace LAMMPS_NS; using namespace MathConst; -enum{INT,FLOAT,BIGINT}; // same as in thermo.cpp +enum{THERMO_INT,THERMO_FLOAT,THERMO_BIGINT}; // same as in thermo.cpp +enum{DUMP_INT,DUMP_DOUBLE,DUMP_STRING,DUMP_BIGINT}; // same as in DumpCFG const char NC_FRAME_STR[] = "frame"; const char NC_SPATIAL_STR[] = "spatial"; @@ -404,10 +405,11 @@ void DumpNetCDFMPIIO::openfile() nc_type xtype; // Type mangling - if (vtype[perat[i].field[0]] == INT) { + if (vtype[perat[i].field[0]] == DUMP_INT) { xtype = NC_INT; - } - else { + } else if (vtype[perat[i].field[0]] == DUMP_BIGINT) { + xtype = NC_INT64; + } else { if (double_precision) xtype = NC_DOUBLE; else @@ -443,15 +445,15 @@ void DumpNetCDFMPIIO::openfile() if (thermo) { Thermo *th = output->thermo; for (int i = 0; i < th->nfield; i++) { - if (th->vtype[i] == FLOAT) { + if (th->vtype[i] == THERMO_FLOAT) { NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_DOUBLE, 1, dims, &thermovar[i]), th->keyword[i] ); } - else if (th->vtype[i] == INT) { + else if (th->vtype[i] == THERMO_INT) { NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_INT, 1, dims, &thermovar[i]), th->keyword[i] ); } - else if (th->vtype[i] == BIGINT) { + else if (th->vtype[i] == THERMO_BIGINT) { #if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG) NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_INT64, 1, dims, &thermovar[i]), th->keyword[i] ); @@ -602,25 +604,77 @@ void DumpNetCDFMPIIO::closefile() template <typename T> int ncmpi_put_var1_bigint(int ncid, int varid, const MPI_Offset index[], - const T* tp) + const T* tp) { return ncmpi_put_var1_int(ncid, varid, index, tp); } template <> int ncmpi_put_var1_bigint<long>(int ncid, int varid, const MPI_Offset index[], - const long* tp) + const long* tp) { return ncmpi_put_var1_long(ncid, varid, index, tp); } template <> -int ncmpi_put_var1_bigint<long long>(int ncid, int varid, const MPI_Offset index[], - const long long* tp) +int ncmpi_put_var1_bigint<long long>(int ncid, int varid, + const MPI_Offset index[], + const long long* tp) { return ncmpi_put_var1_longlong(ncid, varid, index, tp); } +template <typename T> +int ncmpi_put_vara_bigint_all(int ncid, int varid, const MPI_Offset start[], + const MPI_Offset count[], const T* tp) +{ + return ncmpi_put_vara_int_all(ncid, varid, start, count, tp); +} + +template <> +int ncmpi_put_vara_bigint_all<long>(int ncid, int varid, + const MPI_Offset start[], + const MPI_Offset count[], const long* tp) +{ + return ncmpi_put_vara_long_all(ncid, varid, start, count, tp); +} + +template <> +int ncmpi_put_vara_bigint_all<long long>(int ncid, int varid, + const MPI_Offset start[], + const MPI_Offset count[], + const long long* tp) +{ + return ncmpi_put_vara_longlong_all(ncid, varid, start, count, tp); +} + +template <typename T> +int ncmpi_put_vars_bigint_all(int ncid, int varid, const MPI_Offset start[], + const MPI_Offset count[], + const MPI_Offset stride[], const T* tp) +{ + return ncmpi_put_vars_int_all(ncid, varid, start, count, stride, tp); +} + +template <> +int ncmpi_put_vars_bigint_all<long>(int ncid, int varid, + const MPI_Offset start[], + const MPI_Offset count[], + const MPI_Offset stride[], const long* tp) +{ + return ncmpi_put_vars_long_all(ncid, varid, start, count, stride, tp); +} + +template <> +int ncmpi_put_vars_bigint_all<long long>(int ncid, int varid, + const MPI_Offset start[], + const MPI_Offset count[], + const MPI_Offset stride[], + const long long* tp) +{ + return ncmpi_put_vars_longlong_all(ncid, varid, start, count, stride, tp); +} + void DumpNetCDFMPIIO::write() { // open file @@ -644,16 +698,16 @@ void DumpNetCDFMPIIO::write() for (int i = 0; i < th->nfield; i++) { th->call_vfunc(i); if (filewriter) { - if (th->vtype[i] == FLOAT) { + if (th->vtype[i] == THERMO_FLOAT) { NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start, &th->dvalue), th->keyword[i] ); } - else if (th->vtype[i] == INT) { + else if (th->vtype[i] == THERMO_INT) { NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &th->ivalue), th->keyword[i] ); } - else if (th->vtype[i] == BIGINT) { + else if (th->vtype[i] == THERMO_BIGINT) { NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue), th->keyword[i] ); } @@ -782,16 +836,16 @@ void DumpNetCDFMPIIO::write_data(int n, double *mybuf) if (!int_buffer) { n_buffer = std::max(1, n); - int_buffer = (int *) - memory->smalloc(n_buffer*sizeof(int),"dump::int_buffer"); + int_buffer = (bigint *) + memory->smalloc(n_buffer*sizeof(bigint),"dump::int_buffer"); double_buffer = (double *) memory->smalloc(n_buffer*sizeof(double),"dump::double_buffer"); } if (n > n_buffer) { n_buffer = std::max(1, n); - int_buffer = (int *) - memory->srealloc(int_buffer, n_buffer*sizeof(int),"dump::int_buffer"); + int_buffer = (bigint *) + memory->srealloc(int_buffer, n_buffer*sizeof(bigint),"dump::int_buffer"); double_buffer = (double *) memory->srealloc(double_buffer, n_buffer*sizeof(double), "dump::double_buffer"); @@ -824,7 +878,7 @@ void DumpNetCDFMPIIO::write_data(int n, double *mybuf) error->one(FLERR,errmsg); } - if (vtype[iaux] == INT) { + if (vtype[iaux] == DUMP_INT || vtype[iaux] == DUMP_BIGINT) { // integers if (perat[i].dims > 1) { @@ -839,13 +893,21 @@ void DumpNetCDFMPIIO::write_data(int n, double *mybuf) error->one(FLERR,errmsg); } - for (int j = 0; j < n; j++, iaux+=size_one) { - int_buffer[j] = mybuf[iaux]; + if (vtype[iaux] == DUMP_INT) { + for (int j = 0; j < n; j++, iaux+=size_one) { + int_buffer[j] = static_cast<int>(mybuf[iaux]); + } + } + else { // DUMP_BIGINT + for (int j = 0; j < n; j++, iaux+=size_one) { + int_buffer[j] = static_cast<bigint>(mybuf[iaux]); + } } start[2] = idim; - NCERRX( ncmpi_put_vars_int_all(ncid, perat[i].var, start, count, - stride, int_buffer), perat[i].name ); + NCERRX( ncmpi_put_vars_bigint_all(ncid, perat[i].var, start, count, + stride, int_buffer), + perat[i].name ); } } } @@ -854,8 +916,8 @@ void DumpNetCDFMPIIO::write_data(int n, double *mybuf) int_buffer[j] = mybuf[iaux]; } - NCERRX( ncmpi_put_vara_int_all(ncid, perat[i].var, start, count, - int_buffer), perat[i].name ); + NCERRX( ncmpi_put_vara_bigint_all(ncid, perat[i].var, start, count, + int_buffer), perat[i].name ); } } else { diff --git a/src/USER-NETCDF/dump_netcdf_mpiio.h b/src/USER-NETCDF/dump_netcdf_mpiio.h index 3ca52449a5..330fa46c04 100644 --- a/src/USER-NETCDF/dump_netcdf_mpiio.h +++ b/src/USER-NETCDF/dump_netcdf_mpiio.h @@ -65,7 +65,7 @@ class DumpNetCDFMPIIO : public DumpCustom { bool thermo; // write thermo output to netcdf file bigint n_buffer; // size of buffer - int *int_buffer; // buffer for passing data to netcdf + bigint *int_buffer; // buffer for passing data to netcdf double *double_buffer; // buffer for passing data to netcdf int ncid; -- GitLab