BUG: Proper handling of bigint data. Corrects behavior when compiled with LAMMPS_BIGBIG.

This commit is contained in:
Lars Pastewka
2017-11-26 22:35:56 +01:00
parent e755a8339d
commit a111cf640a
4 changed files with 179 additions and 59 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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;