Commit 8db88b1c authored by Norbert Podhorszki's avatar Norbert Podhorszki
Browse files

Added initial untested ADIOS 2.x code with cmake building problems

parent 12bec9cb
Loading
Loading
Loading
Loading
+46 −2
Original line number Diff line number Diff line
@@ -2,7 +2,22 @@
# CMake build system
# This file is part of LAMMPS
# Created by Christoph Junghans and Richard Berger
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
###############################################################################

runconf

0 → 100644
+22 −0
Original line number Diff line number Diff line

# -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



+89 −0
Original line number Diff line number Diff line
# 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

src/USER-ADIOS/README

0 → 100644
+16 −0
Original line number Diff line number Diff line
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
+314 −0
Original line number Diff line number Diff line
/* ----------------------------------------------------------------------
   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});
}
Loading