forked from lijiext/lammps
Added initial untested ADIOS 2.x code with cmake building problems
This commit is contained in:
parent
12bec9cbad
commit
8db88b1c02
|
@ -2,7 +2,22 @@
|
|||
# CMake build system
|
||||
# This file is part of LAMMPS
|
||||
# Created by Christoph Junghans and Richard Berger
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
if(PKG_USER-ADIOS)
|
||||
message(STATUS "Force newer standards because using ADIOS")
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
# Force C++11 and C99
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
# Use meta-compile features if available, otherwise use specific language
|
||||
# features
|
||||
# if(NOT (CMAKE_VERSION VERSION_LESS 3.9))
|
||||
# set(ADIOS2_CXX11_FEATURES cxx_std_11)
|
||||
# else()
|
||||
# set(ADIOS2_CXX11_FEATURES cxx_auto_type cxx_nullptr)
|
||||
# endif()
|
||||
else()
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
endif()
|
||||
|
||||
project(lammps CXX)
|
||||
set(SOVERSION 0)
|
||||
|
@ -178,7 +193,7 @@ set(DEFAULT_PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS DIPOLE GRANULAR
|
|||
USER-MEAMC USER-MGPT USER-MISC USER-MOFFF USER-MOLFILE USER-NETCDF
|
||||
USER-PHONON USER-PLUMED USER-PTM USER-QTB USER-REAXC USER-SCAFACOS
|
||||
USER-SDPD USER-SMD USER-SMTBQ USER-SPH USER-TALLY USER-UEF USER-VTK
|
||||
USER-QUIP USER-QMMM USER-YAFF)
|
||||
USER-QUIP USER-QMMM USER-YAFF USER-ADIOS)
|
||||
set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL GPU)
|
||||
set(OTHER_PACKAGES CORESHELL QEQ)
|
||||
foreach(PKG ${DEFAULT_PACKAGES})
|
||||
|
@ -613,6 +628,7 @@ if(PKG_USER-NETCDF)
|
|||
add_definitions(-DLMP_HAS_NETCDF -DNC_64BIT_DATA=0x0020)
|
||||
endif()
|
||||
|
||||
|
||||
if(PKG_USER-SMD)
|
||||
option(DOWNLOAD_EIGEN3 "Download Eigen3 instead of using an already installed one)" OFF)
|
||||
if(DOWNLOAD_EIGEN3)
|
||||
|
@ -1354,6 +1370,34 @@ if(BUILD_EXE)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
#if(PKG_USER-ADIOS)
|
||||
# cmake_minimum_required(VERSION 3.6)
|
||||
# enable_language(C)
|
||||
#
|
||||
# find_package(ADIOS2 REQUIRED)
|
||||
## find_package(MPI REQUIRED)
|
||||
# include_directories(${ADIOS2_INCLUDE_DIRS})
|
||||
## include_directories(/opt/adios2/include)
|
||||
## list(APPEND LAMMPS_LINK_LIBS ${ADIOS2_LIBRARIES})
|
||||
# list(APPEND LAMMPS_LINK_LIBS ${MPI_C_LIBRARIES})
|
||||
# if(BUILD_LIB)
|
||||
## target_link_libraries(lammps adios2::adios2 MPI::MPI_C)
|
||||
## #target_include_directories(lammps PRIVATE ${ADIOS_INCLUDE_DIRS})
|
||||
# elseif(BUILD_EXE)
|
||||
## target_link_libraries(lmp adios2::adios2 MPI::MPI_C)
|
||||
# endif()
|
||||
#endif(PKG_USER-ADIOS)
|
||||
|
||||
if(PKG_USER-ADIOS)
|
||||
enable_language(C)
|
||||
find_package(ADIOS2 REQUIRED)
|
||||
if(BUILD_LIB)
|
||||
target_link_libraries(lammps adios2::adios2)
|
||||
elseif(BUILD_EXE)
|
||||
target_link_libraries(lmp adios2::adios2)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
###############################################################################
|
||||
# Build documentation
|
||||
###############################################################################
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
# -D LAMMPS_SIZES=value # smallbig (default) or bigbig or smallsmall
|
||||
|
||||
export HDF5_ROOT=/opt/hdf5-serial
|
||||
export ADIOS2_DIR=/opt/adios2
|
||||
|
||||
cmake -D CMAKE_INSTALL_PREFIX=/opt/lammps \
|
||||
-D CMAKE_BUILD_TYPE=Debug \
|
||||
-D BUILD_MPI=yes \
|
||||
-D LAMMPS_MACHINE=adiosvm \
|
||||
-D BUILD_EXE=yes \
|
||||
-D BUILD_LIB=no \
|
||||
-D BUILD_SHARED_LIBS=no \
|
||||
-D BUILD_DOC=no \
|
||||
-D LAMMPS_SIZES=smallbig \
|
||||
-D PKG_USER-H5MD=yes \
|
||||
-D PKG_USER-ADIOS=yes \
|
||||
../cmake
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
# Install/unInstall package files in LAMMPS
|
||||
# mode = 0/1/2 for uninstall/install/update
|
||||
|
||||
mode=$1
|
||||
|
||||
# arg1 = file, arg2 = file it depends on
|
||||
|
||||
action () {
|
||||
if (test $mode = 0) then
|
||||
rm -f ../$1
|
||||
elif (! cmp -s $1 ../$1) then
|
||||
if (test -z "$2" || test -e ../$2) then
|
||||
cp $1 ..
|
||||
if (test $mode = 2) then
|
||||
echo " updating src/$1"
|
||||
fi
|
||||
fi
|
||||
elif (test -n "$2") then
|
||||
if (test ! -e ../$2) then
|
||||
rm -f ../$1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
for file in *.cpp *.h; do
|
||||
action $file
|
||||
done
|
||||
|
||||
# edit 2 Makefile.package files to include/exclude package info
|
||||
|
||||
if (test $1 = 1) then
|
||||
|
||||
# if (test -z "$ADIOS_DIR") then
|
||||
# if command -v adios_config; then
|
||||
# ADIOS_DIR=`adios_config -d`
|
||||
# else
|
||||
# echo "ERROR: ADIOS_DIR environment variable needs to point to ADIOS" \
|
||||
# " installation directory or adios_config should be in PATH"
|
||||
# fi
|
||||
# fi
|
||||
# ADIOS_INC=-I${ADIOS_DIR}/include
|
||||
# ADIOS_LIB=`${ADIOS_DIR}/bin/adios_config -l`
|
||||
#
|
||||
# echo "adios_SYSINC=${ADIOS_INC}
|
||||
#adios_SYSLIB=${ADIOS_LIB}
|
||||
#adios_SYSPATH=${ADIOS_DIR}
|
||||
#" > ../Makefile.adios
|
||||
|
||||
|
||||
if (test -e ../Makefile.package) then
|
||||
sed -i -e 's/[^ \t]*adios[^ \t]* //g' ../Makefile.package
|
||||
sed -i -e 's/-DLMP_ADIOS //g' ../Makefile.package
|
||||
sed -i -e '/^adios_SYS.*$/d' ../Makefile.package
|
||||
# sed -i -e '4 i \
|
||||
#adios_SYSINC='"${ADIOS_INC}"'
|
||||
#' ../Makefile.package
|
||||
# sed -i -e '5 i \
|
||||
#adios_SYSLIB='"${ADIOS_LIB}"'
|
||||
#' ../Makefile.package
|
||||
# sed -i -e '6 i \
|
||||
#adios_SYSPATH='"${ADIOS_DIR}"'
|
||||
#' ../Makefile.package
|
||||
sed -i -e 's|^PKG_INC =[ \t]*|&-DLMP_ADIOS |' ../Makefile.package
|
||||
sed -i -e 's|^PKG_SYSINC =[ \t]*|&$(adios_SYSINC) |' ../Makefile.package
|
||||
sed -i -e 's|^PKG_SYSLIB =[ \t]*|&$(adios_SYSLIB) |' ../Makefile.package
|
||||
sed -i -e 's|^PKG_SYSPATH =[ \t]*|&$(adios_SYSPATH) |' ../Makefile.package
|
||||
fi
|
||||
|
||||
if (test -e ../Makefile.package.settings) then
|
||||
sed -i -e '/^include.*adios.*$/d' ../Makefile.package.settings
|
||||
# multiline form needed for BSD sed on Macs
|
||||
sed -i -e '4 i \
|
||||
include ..\/..\/lib\/adios\/Makefile.lammps
|
||||
' ../Makefile.package.settings
|
||||
fi
|
||||
|
||||
elif (test $1 = 0) then
|
||||
|
||||
if (test -e ../Makefile.package) then
|
||||
sed -i -e 's/[^ \t]*adios[^ \t]* //g' ../Makefile.package
|
||||
sed -i -e 's/-DLMP_ADIOS //g' ../Makefile.package
|
||||
sed -i -e '/^adios_SYS.*$/d' ../Makefile.package
|
||||
fi
|
||||
|
||||
if (test -e ../Makefile.package.settings) then
|
||||
sed -i -e '/^include.*adios.*$/d' ../Makefile.package.settings
|
||||
fi
|
||||
|
||||
fi
|
|
@ -0,0 +1,16 @@
|
|||
This package provides the adios dump and restart styles.
|
||||
|
||||
See the doc page for the "dump adios" and "restart adios" commands.
|
||||
These styles require having ADIOS 2.x itself installed on your system.
|
||||
|
||||
Configure LAMMPS with CMake
|
||||
a. set the environment variable
|
||||
ADIOS2_DIR
|
||||
to the ADIOS 2.x installation path
|
||||
b. use the cmake option
|
||||
-D PKG_USER-ADIOS=yes
|
||||
|
||||
The person who created this package is Norbert Podhorszki (Oak Ridge National Laboratory);
|
||||
If you need help, please submit a ticket at the OLCF ticket user support mentioning his name in the ticket.
|
||||
https://www.olcf.ornl.gov/support/submit-ticket
|
||||
|
|
@ -0,0 +1,314 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing author: Norbert Podhorszki (ORNL)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include <string.h>
|
||||
#include "dump_atom_adios.h"
|
||||
#include "domain.h"
|
||||
#include "atom.h"
|
||||
#include "update.h"
|
||||
#include "group.h"
|
||||
#include "memory.h"
|
||||
#include "universe.h"
|
||||
#include "error.h"
|
||||
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
#define MAX_TEXT_HEADER_SIZE 4096
|
||||
#define DUMP_BUF_CHUNK_SIZE 16384
|
||||
#define DUMP_BUF_INCREMENT_SIZE 4096
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
DumpAtomADIOS::DumpAtomADIOS(LAMMPS *lmp, int narg, char **arg) :
|
||||
DumpAtom(lmp, narg, arg)
|
||||
{
|
||||
ad = new adios2::ADIOS("adios2_config.xml", world, adios2::DebugON);
|
||||
groupSize = 0;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
DumpAtomADIOS::~DumpAtomADIOS()
|
||||
{
|
||||
if (fh)
|
||||
{
|
||||
fh.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void DumpAtomADIOS::openfile()
|
||||
{
|
||||
if (multifile) {
|
||||
// if one file per timestep, replace '*' with current timestep
|
||||
char *filestar = strdup(filename);
|
||||
char *filecurrent = new char[strlen(filestar) + 16];
|
||||
char *ptr = strchr(filestar,'*');
|
||||
*ptr = '\0';
|
||||
if (padflag == 0)
|
||||
sprintf(filecurrent,"%s" BIGINT_FORMAT "%s",
|
||||
filestar,update->ntimestep,ptr+1);
|
||||
else {
|
||||
char bif[8],pad[16];
|
||||
strcpy(bif,BIGINT_FORMAT);
|
||||
sprintf(pad,"%%s%%0%d%s%%s",padflag,&bif[1]);
|
||||
sprintf(filecurrent,pad,filestar,update->ntimestep,ptr+1);
|
||||
}
|
||||
fh = io.Open(filecurrent, adios2::Mode::Write, world);
|
||||
if (!fh) {
|
||||
char str[128];
|
||||
sprintf(str,"Cannot open dump file %s",filecurrent);
|
||||
error->one(FLERR,str);
|
||||
}
|
||||
free(filestar);
|
||||
delete [] filecurrent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!singlefile_opened)
|
||||
{
|
||||
fh = io.Open(filename, adios2::Mode::Write, world);
|
||||
if (!fh) {
|
||||
char str[128];
|
||||
sprintf(str,"Cannot open dump file %s",filename);
|
||||
error->one(FLERR,str);
|
||||
}
|
||||
singlefile_opened = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void DumpAtomADIOS::write()
|
||||
{
|
||||
if (domain->triclinic == 0) {
|
||||
boxxlo = domain->boxlo[0];
|
||||
boxxhi = domain->boxhi[0];
|
||||
boxylo = domain->boxlo[1];
|
||||
boxyhi = domain->boxhi[1];
|
||||
boxzlo = domain->boxlo[2];
|
||||
boxzhi = domain->boxhi[2];
|
||||
} else {
|
||||
boxxlo = domain->boxlo_bound[0];
|
||||
boxxhi = domain->boxhi_bound[0];
|
||||
boxylo = domain->boxlo_bound[1];
|
||||
boxyhi = domain->boxhi_bound[1];
|
||||
boxzlo = domain->boxlo_bound[2];
|
||||
boxzhi = domain->boxhi_bound[2];
|
||||
boxxy = domain->xy;
|
||||
boxxz = domain->xz;
|
||||
boxyz = domain->yz;
|
||||
}
|
||||
|
||||
// nme = # of dump lines this proc contributes to dump
|
||||
|
||||
nme = count();
|
||||
|
||||
// ntotal = total # of atoms in snapshot
|
||||
// atomOffset = sum of # of atoms up to this proc (exclusive prefix sum)
|
||||
|
||||
bigint bnme = nme;
|
||||
MPI_Allreduce(&bnme,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
|
||||
bigint atomOffset; // sum of all atoms on processes 0..me-1
|
||||
MPI_Scan (&bnme, &atomOffset, 1, MPI_LMP_BIGINT, MPI_SUM, world);
|
||||
atomOffset -= nme; // exclusive prefix sum needed
|
||||
|
||||
// Now we know the global size and the local subset size and offset
|
||||
// of the atoms table
|
||||
size_t nAtomsGlobal = static_cast<size_t>(ntotal);
|
||||
size_t startRow = static_cast<size_t>(atomOffset);
|
||||
size_t nAtomsLocal = static_cast<size_t>(nme);
|
||||
size_t nColumns = static_cast<size_t>(size_one);
|
||||
varAtoms.SetShape({nAtomsGlobal,nColumns});
|
||||
varAtoms.SetSelection({{startRow, 0}, {nAtomsLocal,nColumns}});
|
||||
|
||||
// insure buf is sized for packing
|
||||
// adios does not limit per-process data size so nme*size_one is not constrained to int
|
||||
// if sorting on IDs also request ID list from pack()
|
||||
// sort buf as needed
|
||||
|
||||
if (nme > maxbuf) {
|
||||
maxbuf = nme;
|
||||
memory->destroy(buf);
|
||||
memory->create(buf,(maxbuf*size_one),"dump:buf");
|
||||
}
|
||||
if (sort_flag && sortcol == 0 && nme > maxids) {
|
||||
maxids = nme;
|
||||
memory->destroy(ids);
|
||||
memory->create(ids,maxids,"dump:ids");
|
||||
}
|
||||
|
||||
if (sort_flag && sortcol == 0) pack(ids);
|
||||
else pack(NULL);
|
||||
if (sort_flag) sort();
|
||||
|
||||
// Calculate data size written by this process
|
||||
groupSize = nme * size_one * sizeof(double); // size of atoms data on this process
|
||||
groupSize += 3*sizeof(uint64_t) + 1*sizeof(int); // scalars written by each process
|
||||
if (me == 0) {
|
||||
groupSize += 1*sizeof(uint64_t) + 1*sizeof(int) + 6*sizeof(double); // scalars
|
||||
if (domain->triclinic) {
|
||||
groupSize += 3*sizeof(double); // boxxy, boxxz, boxyz
|
||||
}
|
||||
}
|
||||
|
||||
openfile();
|
||||
fh.BeginStep();
|
||||
// write info on data as scalars (by me==0)
|
||||
if (me == 0) {
|
||||
fh.Put<uint64_t>("ntimestep", update->ntimestep);
|
||||
fh.Put<int>("nprocs", nprocs);
|
||||
|
||||
fh.Put<double>("boxxlo", boxxlo);
|
||||
fh.Put<double>("boxxhi", boxxhi);
|
||||
fh.Put<double>("boxylo", boxylo);
|
||||
fh.Put<double>("boxyhi", boxyhi);
|
||||
fh.Put<double>("boxzlo", boxzlo);
|
||||
fh.Put<double>("boxzhi", boxzhi);
|
||||
|
||||
if (domain->triclinic) {
|
||||
fh.Put<double>("boxxy", boxxy);
|
||||
fh.Put<double>("boxxz", boxxz);
|
||||
fh.Put<double>("boxyz", boxyz);
|
||||
}
|
||||
}
|
||||
// Everyone needs to write scalar variables that are used as dimensions and offsets of arrays
|
||||
fh.Put<uint64_t>("natoms", ntotal);
|
||||
fh.Put<int>("ncolumns", size_one);
|
||||
fh.Put<uint64_t>("nme", bnme);
|
||||
fh.Put<uint64_t>("offset", atomOffset);
|
||||
// now write the atoms
|
||||
fh.Put<double>("atoms", buf);
|
||||
fh.EndStep();// I/O will happen now...
|
||||
|
||||
if (multifile)
|
||||
{
|
||||
fh.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void DumpAtomADIOS::init_style()
|
||||
{
|
||||
if (image_flag == 0) size_one = 5;
|
||||
else size_one = 8;
|
||||
|
||||
// setup boundary string
|
||||
|
||||
domain->boundary_string(boundstr);
|
||||
|
||||
// remove % from filename since ADIOS always writes a global file with data/metadata
|
||||
int len = strlen(filename);
|
||||
char *ptr = strchr(filename,'%');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
char *s = new char[len-1];
|
||||
sprintf(s,"%s%s",filename,ptr+1);
|
||||
strncpy(filename,s,len);
|
||||
}
|
||||
|
||||
// setup column string
|
||||
|
||||
if (scale_flag == 0 && image_flag == 0)
|
||||
columns = (char *) "id type x y z";
|
||||
else if (scale_flag == 0 && image_flag == 1)
|
||||
columns = (char *) "id type x y z ix iy iz";
|
||||
else if (scale_flag == 1 && image_flag == 0)
|
||||
columns = (char *) "id type xs ys zs";
|
||||
else if (scale_flag == 1 && image_flag == 1)
|
||||
columns = (char *) "id type xs ys zs ix iy iz";
|
||||
|
||||
// setup function ptrs
|
||||
|
||||
if (scale_flag == 1 && image_flag == 0 && domain->triclinic == 0)
|
||||
pack_choice = &DumpAtomADIOS::pack_scale_noimage;
|
||||
else if (scale_flag == 1 && image_flag == 1 && domain->triclinic == 0)
|
||||
pack_choice = &DumpAtomADIOS::pack_scale_image;
|
||||
else if (scale_flag == 1 && image_flag == 0 && domain->triclinic == 1)
|
||||
pack_choice = &DumpAtomADIOS::pack_scale_noimage_triclinic;
|
||||
else if (scale_flag == 1 && image_flag == 1 && domain->triclinic == 1)
|
||||
pack_choice = &DumpAtomADIOS::pack_scale_image_triclinic;
|
||||
else if (scale_flag == 0 && image_flag == 0)
|
||||
pack_choice = &DumpAtomADIOS::pack_noscale_noimage;
|
||||
else if (scale_flag == 0 && image_flag == 1)
|
||||
pack_choice = &DumpAtomADIOS::pack_noscale_image;
|
||||
|
||||
/* Define the group of variables for the atom style here since it's a fixed set */
|
||||
adios2::IO io = ad->DeclareIO(ioName);
|
||||
if (!io.InConfigFile())
|
||||
{
|
||||
// if not defined by user, we can change the default settings
|
||||
// BPFile is the default writer
|
||||
io.SetEngine("BPFile");
|
||||
int num_aggregators = multiproc;
|
||||
if (num_aggregators == 0)
|
||||
num_aggregators = 1;
|
||||
char nstreams[128];
|
||||
sprintf (nstreams, "%d", num_aggregators);
|
||||
io.SetParameters({{"substreams", nstreams}});
|
||||
if (me==0 && screen) fprintf(screen, "ADIOS method for %s is n-to-m (aggregation with %s writers)\n", filename, nstreams);
|
||||
}
|
||||
|
||||
|
||||
io.DefineVariable<uint64_t>("ntimestep");
|
||||
io.DefineVariable<uint64_t>("natoms");
|
||||
|
||||
io.DefineVariable<int>("nprocs");
|
||||
io.DefineVariable<int>("ncolumns");
|
||||
|
||||
io.DefineVariable<double>("boxxlo");
|
||||
io.DefineVariable<double>("boxxhi");
|
||||
io.DefineVariable<double>("boxylo");
|
||||
io.DefineVariable<double>("boxyhi");
|
||||
io.DefineVariable<double>("boxzlo");
|
||||
io.DefineVariable<double>("boxzhi");
|
||||
|
||||
io.DefineVariable<double>("boxxy");
|
||||
io.DefineVariable<double>("boxxz");
|
||||
io.DefineVariable<double>("boxyz");
|
||||
|
||||
io.DefineAttribute<int>("triclinic", domain->triclinic);
|
||||
io.DefineAttribute<int>("scaled", scale_flag);
|
||||
io.DefineAttribute<int>("image", image_flag);
|
||||
|
||||
int *boundaryptr = reinterpret_cast<int*>(domain->boundary);
|
||||
io.DefineAttribute<int>("boundary", boundaryptr, 6);
|
||||
|
||||
io.DefineAttribute<std::string>("columns", columns);
|
||||
io.DefineAttribute<std::string>("boundarystr", boundstr);
|
||||
io.DefineAttribute<std::string>("LAMMPS/dump_style", "atom");
|
||||
io.DefineAttribute<std::string>("LAMMPS/version", universe->version);
|
||||
io.DefineAttribute<std::string>("LAMMPS/num_ver", universe->num_ver);
|
||||
|
||||
io.DefineVariable<uint64_t>("nme", {adios2::LocalValueDim}); // local dimension variable
|
||||
io.DefineVariable<uint64_t>("offset", {adios2::LocalValueDim}); // local dimension variable
|
||||
|
||||
// atom table size is not known at the moment
|
||||
// it will be correctly defined at the moment of write
|
||||
size_t UnknownSizeYet = 1;
|
||||
size_t nColumns = static_cast<size_t>(size_one);
|
||||
varAtoms = io.DefineVariable<double>("atoms",
|
||||
{UnknownSizeYet,nColumns},
|
||||
{UnknownSizeYet, 0},
|
||||
{UnknownSizeYet,nColumns});
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef DUMP_CLASS
|
||||
|
||||
DumpStyle(atom/adios,DumpAtomADIOS)
|
||||
|
||||
#else
|
||||
|
||||
#ifndef LMP_DUMP_ATOM_ADIOS_H
|
||||
#define LMP_DUMP_ATOM_ADIOS_H
|
||||
|
||||
#include "dump_atom.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "adios2.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class DumpAtomADIOS : public DumpAtom {
|
||||
|
||||
public:
|
||||
DumpAtomADIOS(class LAMMPS *, int, char **);
|
||||
virtual ~DumpAtomADIOS();
|
||||
|
||||
protected:
|
||||
|
||||
const std::string ioName="atom"; // name of adios group, referrable in adios2_config.xml
|
||||
adios2::ADIOS *ad = nullptr; // adios object
|
||||
adios2::IO io; // adios group of variables and attributes in this dump
|
||||
adios2::Engine fh; // adios file/stream handle object
|
||||
adios2::Variable<double> varAtoms; // one ADIOS output variable we need to change
|
||||
uint64_t groupSize; // pre-calculate # of bytes written per processor in a step before writing anything
|
||||
uint64_t groupTotalSize; // ADIOS buffer size returned by adios_group_size(), valid only if size is > default 16MB ADIOS buffer
|
||||
std::string filecurrent; // name of file for this round (with % and * replaced)
|
||||
|
||||
virtual void openfile();
|
||||
virtual void write();
|
||||
virtual void init_style();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ERROR/WARNING messages:
|
||||
|
||||
E: Cannot open dump file %s
|
||||
|
||||
The output file for the dump command cannot be opened. Check that the
|
||||
path and name are correct.
|
||||
|
||||
E: Too much per-proc info for dump
|
||||
|
||||
Number of local atoms times number of columns must fit in a 32-bit
|
||||
integer for dump.
|
||||
|
||||
*/
|
|
@ -0,0 +1,354 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing author: Paul Coffman (IBM)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "dump_custom_adios.h"
|
||||
#include "atom.h"
|
||||
#include "force.h"
|
||||
#include "domain.h"
|
||||
#include "region.h"
|
||||
#include "group.h"
|
||||
#include "input.h"
|
||||
#include "variable.h"
|
||||
#include "update.h"
|
||||
#include "modify.h"
|
||||
#include "compute.h"
|
||||
#include "fix.h"
|
||||
#include "universe.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
#define MAX_TEXT_HEADER_SIZE 4096
|
||||
#define DUMP_BUF_CHUNK_SIZE 16384
|
||||
#define DUMP_BUF_INCREMENT_SIZE 4096
|
||||
|
||||
enum{ID,MOL,TYPE,ELEMENT,MASS,
|
||||
X,Y,Z,XS,YS,ZS,XSTRI,YSTRI,ZSTRI,XU,YU,ZU,XUTRI,YUTRI,ZUTRI,
|
||||
XSU,YSU,ZSU,XSUTRI,YSUTRI,ZSUTRI,
|
||||
IX,IY,IZ,
|
||||
VX,VY,VZ,FX,FY,FZ,
|
||||
Q,MUX,MUY,MUZ,MU,RADIUS,DIAMETER,
|
||||
OMEGAX,OMEGAY,OMEGAZ,ANGMOMX,ANGMOMY,ANGMOMZ,
|
||||
TQX,TQY,TQZ,SPIN,ERADIUS,ERVEL,ERFORCE,
|
||||
COMPUTE,FIX,VARIABLE};
|
||||
enum{LT,LE,GT,GE,EQ,NEQ};
|
||||
enum{INT,DOUBLE,STRING,BIGINT}; // same as in DumpCustom
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
DumpCustomADIOS::DumpCustomADIOS(LAMMPS *lmp, int narg, char **arg) :
|
||||
DumpCustom(lmp, narg, arg)
|
||||
{
|
||||
ad = new adios2::ADIOS("adios2_config.xml", world, adios2::DebugON);
|
||||
groupsize = 0;
|
||||
//if (screen) fprintf(screen, "DumpCustomADIOS constructor: nvariable=%d id_variable=%p, variables=%p, nfield=%d, earg=%p\n", nvariable, id_variable, variable, nfield, earg);
|
||||
columnNames.reserve(nfield);
|
||||
for (int i = 0; i < nfield; ++i) {
|
||||
columnNames[i]=std::string(earg[i]);
|
||||
//if (screen) fprintf(screen, "earg[%d] = '%s'\n", i, earg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
DumpCustomADIOS::~DumpCustomADIOS()
|
||||
{
|
||||
columnNames.clear();
|
||||
if (fh)
|
||||
{
|
||||
fh.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void DumpCustomADIOS::openfile()
|
||||
{
|
||||
if (multifile) {
|
||||
// if one file per timestep, replace '*' with current timestep
|
||||
char *filestar = strdup(filename);
|
||||
char *filecurrent = new char[strlen(filestar) + 16];
|
||||
char *ptr = strchr(filestar,'*');
|
||||
*ptr = '\0';
|
||||
if (padflag == 0)
|
||||
sprintf(filecurrent,"%s" BIGINT_FORMAT "%s",
|
||||
filestar,update->ntimestep,ptr+1);
|
||||
else {
|
||||
char bif[8],pad[16];
|
||||
strcpy(bif,BIGINT_FORMAT);
|
||||
sprintf(pad,"%%s%%0%d%s%%s",padflag,&bif[1]);
|
||||
sprintf(filecurrent,pad,filestar,update->ntimestep,ptr+1);
|
||||
}
|
||||
fh = io.Open(filecurrent, adios2::Mode::Write, world);
|
||||
if (!fh) {
|
||||
char str[128];
|
||||
sprintf(str,"Cannot open dump file %s",filecurrent);
|
||||
error->one(FLERR,str);
|
||||
}
|
||||
free(filestar);
|
||||
delete [] filecurrent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!singlefile_opened)
|
||||
{
|
||||
fh = io.Open(filename, adios2::Mode::Write, world);
|
||||
if (!fh) {
|
||||
char str[128];
|
||||
sprintf(str,"Cannot open dump file %s",filename);
|
||||
error->one(FLERR,str);
|
||||
}
|
||||
singlefile_opened = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void DumpCustomADIOS::write()
|
||||
{
|
||||
if (domain->triclinic == 0) {
|
||||
boxxlo = domain->boxlo[0];
|
||||
boxxhi = domain->boxhi[0];
|
||||
boxylo = domain->boxlo[1];
|
||||
boxyhi = domain->boxhi[1];
|
||||
boxzlo = domain->boxlo[2];
|
||||
boxzhi = domain->boxhi[2];
|
||||
} else {
|
||||
boxxlo = domain->boxlo_bound[0];
|
||||
boxxhi = domain->boxhi_bound[0];
|
||||
boxylo = domain->boxlo_bound[1];
|
||||
boxyhi = domain->boxhi_bound[1];
|
||||
boxzlo = domain->boxlo_bound[2];
|
||||
boxzhi = domain->boxhi_bound[2];
|
||||
boxxy = domain->xy;
|
||||
boxxz = domain->xz;
|
||||
boxyz = domain->yz;
|
||||
}
|
||||
|
||||
// nme = # of dump lines this proc contributes to dump
|
||||
|
||||
nme = count();
|
||||
|
||||
// ntotal = total # of atoms in snapshot
|
||||
// atomOffset = sum of # of atoms up to this proc (exclusive prefix sum)
|
||||
|
||||
bigint bnme = nme;
|
||||
MPI_Allreduce(&bnme,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
|
||||
bigint atomOffset; // sum of all atoms on processes 0..me-1
|
||||
MPI_Scan (&bnme, &atomOffset, 1, MPI_LMP_BIGINT, MPI_SUM, world);
|
||||
atomOffset -= nme; // exclusive prefix sum needed
|
||||
|
||||
// Now we know the global size and the local subset size and offset
|
||||
// of the atoms table
|
||||
size_t nAtomsGlobal = static_cast<size_t>(ntotal);
|
||||
size_t startRow = static_cast<size_t>(atomOffset);
|
||||
size_t nAtomsLocal = static_cast<size_t>(nme);
|
||||
size_t nColumns = static_cast<size_t>(size_one);
|
||||
varAtoms.SetShape({nAtomsGlobal,nColumns});
|
||||
varAtoms.SetSelection({{startRow, 0}, {nAtomsLocal,nColumns}});
|
||||
|
||||
// insure filewriter proc can receive everyone's info
|
||||
// limit nmax*size_one to int since used as arg in MPI_Rsend() below
|
||||
// pack my data into buf
|
||||
// if sorting on IDs also request ID list from pack()
|
||||
// sort buf as needed
|
||||
|
||||
if (nme > maxbuf) {
|
||||
if ((bigint) nme * size_one > MAXSMALLINT)
|
||||
error->all(FLERR,"Too much per-proc info for dump");
|
||||
maxbuf = nme;
|
||||
memory->destroy(buf);
|
||||
memory->create(buf,(maxbuf*size_one),"dump:buf");
|
||||
}
|
||||
if (sort_flag && sortcol == 0 && nme > maxids) {
|
||||
maxids = nme;
|
||||
memory->destroy(ids);
|
||||
memory->create(ids,maxids,"dump:ids");
|
||||
}
|
||||
|
||||
if (sort_flag && sortcol == 0) pack(ids);
|
||||
else pack(NULL);
|
||||
if (sort_flag) sort();
|
||||
|
||||
// Calculate data size written by this process
|
||||
groupsize = nme * size_one * sizeof(double); // size of atoms data on this process
|
||||
groupsize += 3*sizeof(uint64_t) + 1*sizeof(int); // scalars written by each process
|
||||
if (me == 0) {
|
||||
groupsize += 1*sizeof(uint64_t) + 1*sizeof(int) + 6*sizeof(double); // scalars
|
||||
if (domain->triclinic) {
|
||||
groupsize += 3*sizeof(double); // boxxy, boxxz, boxyz
|
||||
}
|
||||
}
|
||||
|
||||
openfile();
|
||||
fh.BeginStep();
|
||||
// write info on data as scalars (by me==0)
|
||||
if (me == 0) {
|
||||
fh.Put<uint64_t>("ntimestep", update->ntimestep);
|
||||
fh.Put<int>("nprocs", nprocs);
|
||||
|
||||
fh.Put<double>("boxxlo", boxxlo);
|
||||
fh.Put<double>("boxxhi", boxxhi);
|
||||
fh.Put<double>("boxylo", boxylo);
|
||||
fh.Put<double>("boxyhi", boxyhi);
|
||||
fh.Put<double>("boxzlo", boxzlo);
|
||||
fh.Put<double>("boxzhi", boxzhi);
|
||||
|
||||
if (domain->triclinic) {
|
||||
fh.Put<double>("boxxy", boxxy);
|
||||
fh.Put<double>("boxxz", boxxz);
|
||||
fh.Put<double>("boxyz", boxyz);
|
||||
}
|
||||
}
|
||||
// Everyone needs to write scalar variables that are used as dimensions and offsets of arrays
|
||||
fh.Put<uint64_t>("natoms", ntotal);
|
||||
fh.Put<int>("ncolumns", size_one);
|
||||
fh.Put<uint64_t>("nme", bnme);
|
||||
fh.Put<uint64_t>("offset", atomOffset);
|
||||
// now write the atoms
|
||||
fh.Put<double>("atoms", buf);
|
||||
fh.EndStep();// I/O will happen now...
|
||||
|
||||
if (multifile)
|
||||
{
|
||||
fh.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void DumpCustomADIOS::init_style()
|
||||
{
|
||||
|
||||
// setup boundary string
|
||||
|
||||
domain->boundary_string(boundstr);
|
||||
|
||||
// remove % from filename since ADIOS always writes a global file with data/metadata
|
||||
int len = strlen(filename);
|
||||
char *ptr = strchr(filename,'%');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
char *s = new char[len-1];
|
||||
sprintf(s,"%s%s",filename,ptr+1);
|
||||
strncpy(filename,s,len);
|
||||
}
|
||||
|
||||
/* The next four loops are copied from dump_custom_mpiio, but nothing is done with them.
|
||||
* It is unclear why we need them here.
|
||||
* For metadata, variable[] will be written out as an ADIOS attribute if nvariable>0
|
||||
*/
|
||||
// find current ptr for each compute,fix,variable
|
||||
// check that fix frequency is acceptable
|
||||
int icompute;
|
||||
for (int i = 0; i < ncompute; i++) {
|
||||
icompute = modify->find_compute(id_compute[i]);
|
||||
if (icompute < 0) error->all(FLERR,"Could not find dump custom compute ID");
|
||||
compute[i] = modify->compute[icompute];
|
||||
}
|
||||
|
||||
int ifix;
|
||||
for (int i = 0; i < nfix; i++) {
|
||||
ifix = modify->find_fix(id_fix[i]);
|
||||
if (ifix < 0) error->all(FLERR,"Could not find dump custom fix ID");
|
||||
fix[i] = modify->fix[ifix];
|
||||
if (nevery % modify->fix[ifix]->peratom_freq)
|
||||
error->all(FLERR,"Dump custom and fix not computed at compatible times");
|
||||
}
|
||||
|
||||
int ivariable;
|
||||
for (int i = 0; i < nvariable; i++) {
|
||||
ivariable = input->variable->find(id_variable[i]);
|
||||
if (ivariable < 0)
|
||||
error->all(FLERR,"Could not find dump custom variable name");
|
||||
variable[i] = ivariable;
|
||||
}
|
||||
|
||||
// set index and check validity of region
|
||||
if (iregion >= 0) {
|
||||
iregion = domain->find_region(idregion);
|
||||
if (iregion == -1)
|
||||
error->all(FLERR,"Region ID for dump custom does not exist");
|
||||
}
|
||||
|
||||
/* Define the group of variables for the atom style here since it's a fixed set */
|
||||
adios2::IO io = ad->DeclareIO(ioName);
|
||||
if (!io.InConfigFile())
|
||||
{
|
||||
// if not defined by user, we can change the default settings
|
||||
// BPFile is the default writer
|
||||
io.SetEngine("BPFile");
|
||||
int num_aggregators = multiproc;
|
||||
if (num_aggregators == 0)
|
||||
num_aggregators = 1;
|
||||
char nstreams[128];
|
||||
sprintf (nstreams, "%d", num_aggregators);
|
||||
io.SetParameters({{"substreams", nstreams}});
|
||||
if (me==0 && screen) fprintf(screen, "ADIOS method for %s is n-to-m (aggregation with %s writers)\n", filename, nstreams);
|
||||
}
|
||||
|
||||
|
||||
io.DefineVariable<uint64_t>("ntimestep");
|
||||
io.DefineVariable<uint64_t>("natoms");
|
||||
|
||||
io.DefineVariable<int>("nprocs");
|
||||
io.DefineVariable<int>("ncolumns");
|
||||
|
||||
io.DefineVariable<double>("boxxlo");
|
||||
io.DefineVariable<double>("boxxhi");
|
||||
io.DefineVariable<double>("boxylo");
|
||||
io.DefineVariable<double>("boxyhi");
|
||||
io.DefineVariable<double>("boxzlo");
|
||||
io.DefineVariable<double>("boxzhi");
|
||||
|
||||
io.DefineVariable<double>("boxxy");
|
||||
io.DefineVariable<double>("boxxz");
|
||||
io.DefineVariable<double>("boxyz");
|
||||
|
||||
io.DefineAttribute<int>("triclinic", domain->triclinic);
|
||||
|
||||
int *boundaryptr = reinterpret_cast<int*>(domain->boundary);
|
||||
io.DefineAttribute<int>("boundary", boundaryptr, 6);
|
||||
|
||||
size_t nColumns = static_cast<size_t>(size_one);
|
||||
io.DefineAttribute<std::string>("columns", columnNames.data(), nColumns);
|
||||
io.DefineAttribute<std::string>("columnstr", columns);
|
||||
io.DefineAttribute<std::string>("boundarystr", boundstr);
|
||||
io.DefineAttribute<std::string>("LAMMPS/dump_style", "atom");
|
||||
io.DefineAttribute<std::string>("LAMMPS/version", universe->version);
|
||||
io.DefineAttribute<std::string>("LAMMPS/num_ver", universe->num_ver);
|
||||
|
||||
io.DefineVariable<uint64_t>("nme", {adios2::LocalValueDim}); // local dimension variable
|
||||
io.DefineVariable<uint64_t>("offset", {adios2::LocalValueDim}); // local dimension variable
|
||||
|
||||
// atom table size is not known at the moment
|
||||
// it will be correctly defined at the moment of write
|
||||
size_t UnknownSizeYet = 1;
|
||||
varAtoms = io.DefineVariable<double>("atoms",
|
||||
{UnknownSizeYet,nColumns},
|
||||
{UnknownSizeYet, 0},
|
||||
{UnknownSizeYet,nColumns});
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/* -*- c++ -*- ----------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef DUMP_CLASS
|
||||
|
||||
DumpStyle(custom/adios,DumpCustomADIOS)
|
||||
|
||||
#else
|
||||
|
||||
#ifndef LMP_DUMP_CUSTOM_ADIOS_H
|
||||
#define LMP_DUMP_CUSTOM_ADIOS_H
|
||||
|
||||
#include "dump_custom.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "adios2.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class DumpCustomADIOS : public DumpCustom {
|
||||
public:
|
||||
DumpCustomADIOS(class LAMMPS *, int, char **);
|
||||
virtual ~DumpCustomADIOS();
|
||||
|
||||
protected:
|
||||
|
||||
const std::string ioName="custom"; // name of adios group, referrable in adios2_config.xml
|
||||
adios2::ADIOS *ad = nullptr; // adios object
|
||||
adios2::IO io; // adios group of variables and attributes in this dump
|
||||
adios2::Engine fh; // adios file/stream handle object
|
||||
adios2::Variable<double> varAtoms; // one ADIOS output variable we need to change
|
||||
uint64_t groupsize; // pre-calculate # of bytes written per processor in a step before writing anything
|
||||
std::vector<std::string>columnNames; // list of column names for the atom table (individual list of 'columns' string)
|
||||
|
||||
virtual void openfile();
|
||||
virtual void write();
|
||||
virtual void init_style();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ERROR/WARNING messages:
|
||||
|
||||
E: Cannot open dump file %s
|
||||
|
||||
The output file for the dump command cannot be opened. Check that the
|
||||
path and name are correct.
|
||||
|
||||
E: Too much per-proc info for dump
|
||||
|
||||
Number of local atoms times number of columns must fit in a 32-bit
|
||||
integer for dump.
|
||||
|
||||
E: Dump_modify format string is too short
|
||||
|
||||
There are more fields to be dumped in a line of output than your
|
||||
format string specifies.
|
||||
|
||||
E: Could not find dump custom compute ID
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Could not find dump custom fix ID
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Dump custom and fix not computed at compatible times
|
||||
|
||||
The fix must produce per-atom quantities on timesteps that dump custom
|
||||
needs them.
|
||||
|
||||
E: Could not find dump custom variable name
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
E: Region ID for dump custom does not exist
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
*/
|
Loading…
Reference in New Issue