Skip to content

Commit

Permalink
Merge pull request #179 from f-schmitt-zih/topic-adios
Browse files Browse the repository at this point in the history
ADIOS output support
  • Loading branch information
psychocoderHPC committed Feb 7, 2014
2 parents 387ee2c + b0e8b6d commit 7d0e1cb
Show file tree
Hide file tree
Showing 20 changed files with 1,879 additions and 89 deletions.
1 change: 1 addition & 0 deletions src/libPMacc/include/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,6 @@ enum AreaType
};

#define __delete(var) if((var)) { delete (var); var=NULL; }
#define __deleteArray(var) if((var)) { delete[] (var); var=NULL; }

} //namespace PMacc
42 changes: 41 additions & 1 deletion src/picongpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright 2013 Axel Huebl, Benjamin Schneider, Felix Schmitt, Heiko Burau, Rene Widera
# Copyright 2013-2014 Axel Huebl, Benjamin Schneider, Felix Schmitt, Heiko Burau, Rene Widera
#
# This file is part of PIConGPU.
#
Expand Down Expand Up @@ -231,6 +231,46 @@ if(PIC_ENABLE_INSITU_VOLVIS)
endif(PIC_ENABLE_INSITU_VOLVIS)


################################################################################
# ADIOS
################################################################################

# find adios installation
find_path(PIC_ADIOS_ROOT_DIR
NAMES include/adios.h lib/libadios.so
PATHS ENV ADIOS_ROOT
DOC "ADIOS ROOT location. (only used if ADIOS is enabled)"
)

if(PIC_ADIOS_ROOT_DIR)
message(STATUS "Found ADIOS: "${PIC_ADIOS_ROOT_DIR})
include_directories(SYSTEM ${PIC_ADIOS_ROOT_DIR}/include)
link_directories(${PIC_ADIOS_ROOT_DIR}/lib)
set(LIBS ${LIBS} adios)

# find mxml installation
find_path(PIC_MXML_ROOT_DIR
NAMES include/mxml.h lib/libmxml.so
PATHS ENV MXML_ROOT
DOC "MXML ROOT location. (only used if ADIOS is enabled)"
)

if(PIC_MXML_ROOT_DIR)
message(STATUS "Found MXML: "${PIC_MXML_ROOT_DIR})
include_directories(SYSTEM ${PIC_MXML_ROOT_DIR}/include)
link_directories(${PIC_MXML_ROOT_DIR}/lib)
set(LIBS ${LIBS} mxml)

add_definitions(-DENABLE_ADIOS=1)
elseif(PIC_MXML_ROOT_DIR)
message(STATUS "Could NOT find MXML (ADIOS will be disabled)")
endif(PIC_MXML_ROOT_DIR)

elseif(PIC_ADIOS_ROOT_DIR)
message(STATUS "Could NOT find ADIOS")
endif(PIC_ADIOS_ROOT_DIR)


################################################################################
# Warnings
################################################################################
Expand Down
6 changes: 3 additions & 3 deletions src/picongpu/include/initialization/InitialiserController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ class InitialiserController : public IInitModule

#if (ENABLE_HDF5==1)
// check for HDF5 restart capability
typedef typename boost::mpl::find<Hdf5OutputFields, FieldE>::type itFindFieldE;
typedef typename boost::mpl::find<Hdf5OutputFields, FieldB>::type itFindFieldB;
typedef typename boost::mpl::end< Hdf5OutputFields>::type itEnd;
typedef typename boost::mpl::find<FileOutputFields, FieldE>::type itFindFieldE;
typedef typename boost::mpl::find<FileOutputFields, FieldB>::type itFindFieldB;
typedef typename boost::mpl::end< FileOutputFields>::type itEnd;
const bool restartImpossible = (boost::is_same<itFindFieldE, itEnd>::value)
|| (boost::is_same<itFindFieldB, itEnd>::value);
if( restartImpossible )
Expand Down
9 changes: 9 additions & 0 deletions src/picongpu/include/plugins/PluginController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
#include "plugins/makroParticleCounter/PerSuperCell.hpp"
#endif

#if (ENABLE_ADIOS == 1)
#include "plugins/adios/ADIOSWriter.hpp"
#endif

namespace picongpu
{

Expand Down Expand Up @@ -149,6 +153,11 @@ class PluginController : public IPluginModule
#if (ENABLE_HDF5 == 1)
modules.push_back(new hdf5::HDF5Writer());
#endif

#if (ENABLE_ADIOS == 1)
modules.push_back(new adios::ADIOSWriter());
#endif

modules.push_back(new EnergyFields("EnergyFields", "energy_fields"));
modules.push_back(new SumCurrents());
modules.push_back(new LineSliceFields());
Expand Down
167 changes: 167 additions & 0 deletions src/picongpu/include/plugins/adios/ADIOSCountParticles.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/**
* Copyright 2014 Felix Schmitt
*
* This file is part of PIConGPU.
*
* PIConGPU is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PIConGPU is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PIConGPU.
* If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <mpi.h>

#include "types.h"
#include "simulation_types.hpp"
#include "plugins/adios/ADIOSWriter.def"

#include "plugins/IPluginModule.hpp"
#include <boost/mpl/vector.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/find.hpp>
#include "compileTime/conversion/MakeSeq.hpp"

#include "RefWrapper.hpp"
#include <boost/type_traits.hpp>

#include "plugins/output/WriteSpeciesCommon.hpp"
#include "plugins/kernel/CopySpecies.kernel"
#include "mappings/kernel/AreaMapping.hpp"

#include "traits/PICToAdios.hpp"
#include "plugins/adios/writer/ParticleAttributeSize.hpp"
#include "compileTime/conversion/RemoveFromSeq.hpp"

namespace picongpu
{

namespace adios
{
using namespace PMacc;

namespace bmpl = boost::mpl;

/** Count number of particles for a species
*
* @tparam T_Species type of species
*
*/
template< typename T_Species >
struct ADIOSCountParticles
{
public:

typedef T_Species ThisSpecies;
typedef typename ThisSpecies::FrameType FrameType;
typedef typename FrameType::ValueTypeSeq ParticleAttributeList;
typedef typename FrameType::MethodsList ParticleMethodsList;

/* delete multiMask and localCellIdx in adios particle*/
typedef bmpl::vector<multiMask,localCellIdx> TypesToDelete;
typedef typename RemoveFromSeq<ParticleAttributeList, TypesToDelete>::type ParticleCleanedAttributeList;

/* add globalCellIdx for adios particle*/
typedef typename MakeSeq<
ParticleCleanedAttributeList,
globalCellIdx<globalCellIdx_pic>
>::type ParticleNewAttributeList;

typedef Frame<OperatorCreateVectorBox, ParticleNewAttributeList, ParticleMethodsList> AdiosFrameType;

HINLINE void operator()(RefWrapper<ThreadParams*> params,
const std::string subGroup,
const DomainInformation domInfo)
{
DataConnector &dc = DataConnector::getInstance();
GridController<simDim>& gc = GridController<simDim>::getInstance();
uint64_t mpiSize = gc.getGlobalSize();
uint64_t mpiRank = gc.getGlobalRank();

/* load particle without copy particle data to host */
ThisSpecies* speciesTmp = &(dc.getData<ThisSpecies >(ThisSpecies::FrameType::CommunicationTag, true));

/* count total number of particles on the device */
uint64_cu totalNumParticles = 0;
totalNumParticles = PMacc::CountParticles::countOnDevice < CORE + BORDER > (
*speciesTmp,
*(params.get()->cellDescription),
domInfo.localDomainOffset,
domInfo.domainSize);

/* MPI_Allgather to compute global size and my offset */
uint64_t myNumParticles = totalNumParticles;
uint64_t allNumParticles[mpiSize];
uint64_t globalNumParticles = 0;
uint64_t myParticleOffset = 0;

MPI_CHECK(MPI_Allgather(
&myNumParticles, 1, MPI_UNSIGNED_LONG_LONG,
allNumParticles, 1, MPI_UNSIGNED_LONG_LONG,
gc.getCommunicator().getMPIComm()));

for (uint64_t i = 0; i < mpiSize; ++i)
{
globalNumParticles += allNumParticles[i];
if (i < mpiRank)
myParticleOffset += allNumParticles[i];
}

if (myNumParticles > 0)
{
/* iterate over all attributes of this species */
ForEach<typename AdiosFrameType::ValueTypeSeq, adios::ParticleAttributeSize<void> > attributeSize;
attributeSize(params, (FrameType::getName() + std::string("/") + subGroup).c_str(),
myNumParticles, globalNumParticles, myParticleOffset);
}

/* define adios var for species index/info table */
{
const size_t localTableSize = 5;
traits::PICToAdios<uint64_t> adiosIndexType;

std::stringstream indexVarSizeStr;
indexVarSizeStr << localTableSize;

std::stringstream indexVarGlobalSizeStr;
indexVarGlobalSizeStr << localTableSize * gc.getGlobalSize();

std::stringstream indexVarOffsetStr;
indexVarOffsetStr << localTableSize * gc.getGlobalRank();

int64_t adiosSpeciesIndexVar = adios_define_var(
params.get()->adiosGroupHandle,
(params.get()->adiosBasePath + std::string(ADIOS_PATH_PARTICLES) +
FrameType::getName() + std::string("/") + subGroup +
std::string("particles_info")).c_str(),
NULL,
adiosIndexType.type,
indexVarSizeStr.str().c_str(),
indexVarGlobalSizeStr.str().c_str(),
indexVarOffsetStr.str().c_str());

params.get()->adiosSpeciesIndexVarIds.push_back(adiosSpeciesIndexVar);

params.get()->adiosGroupSize += sizeof(uint64_t) * localTableSize * gc.getGlobalSize();
}
}
};


} //namspace adios

} //namespace picongpu
132 changes: 132 additions & 0 deletions src/picongpu/include/plugins/adios/ADIOSWriter.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* Copyright 2014 Felix Schmitt
*
* This file is part of PIConGPU.
*
* PIConGPU is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PIConGPU is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PIConGPU.
* If not, see <http://www.gnu.org/licenses/>.
*/



#pragma once

#include <adios.h>
#include <list>

#include "types.h"
#include "simulation_types.hpp"
#include "particles/frame_types.hpp"
#include "simulationControl/MovingWindow.hpp"

namespace picongpu
{

namespace adios
{
using namespace PMacc;

namespace bmpl = boost::mpl;

namespace po = boost::program_options;

#define ADIOS_INVALID_HANDLE -1
#define ADIOS_SUCCESS err_no_error
#define ADIOS_GROUP_NAME "data"

#define ADIOS_PATH_ROOT "/data/"
#define ADIOS_PATH_FIELDS "fields/"
#define ADIOS_PATH_PARTICLES "particles/"

#define ADIOS_SIZE_LOCAL "size_"
#define ADIOS_SIZE_GLOBAL "totalSize_"
#define ADIOS_OFFSET_GLOBAL "offset_"

#define ADIOS_CMD(_cmd) \
{ \
int _err_code = _cmd; \
if (_err_code != ADIOS_SUCCESS) \
log<picLog::INPUT_OUTPUT > ("ADIOS: error at cmd '%1%': '%2%'") % \
#_cmd % _err_code; \
}

#define ADIOS_CMD_EXPECT_NONZERO(_cmd) \
{ \
int _err_code = _cmd; \
if (_err_code == 0) \
log<picLog::INPUT_OUTPUT > ("ADIOS: error at cmd '%1%': '%2%'") % \
#_cmd % _err_code; \
}

struct ThreadParams
{
uint32_t currentStep;
std::string fullFilename;

MPI_Comm adiosComm; /* MPI communicator for adios lib */
bool adiosBufferInitialized; /* set if ADIOS buffer has been allocated */
int64_t adiosFileHandle; /* ADIOS file handle */
int64_t adiosGroupHandle; /* ADIOS group handle */
uint64_t adiosGroupSize; /* size of ADIOS group in bytes */
std::string adiosBasePath; /* base path for the current step */

int64_t adiosSizeVarIds[simDim]; /* var IDs for ADIOS_SIZE_LOCAL_x/y/z */
int64_t adiosTotalSizeVarIds[simDim]; /* var IDs for ADIOS_SIZE_GLOBAL_x/y/z */
int64_t adiosOffsetVarIds[simDim]; /* var IDs for ADIOS_OFFSET_GLOBAL_x/y/z */

std::list<int64_t> adiosFieldVarIds; /* var IDs for fields in order of appearance */
std::list<int64_t> adiosParticleAttrVarIds; /* var IDs for particle attributes in order of appearance */
std::list<int64_t> adiosSpeciesIndexVarIds; /* var IDs for species index tables in order of appearance */

GridLayout<simDim> gridLayout;
DataSpace<simDim> gridPosition;
MappingDesc *cellDescription;

float *fieldBfr; /* temp. buffer for fields */

VirtualWindow window;
};

struct DomainInformation
{
/* Offset from simulation origin to moving window */
DataSpace<simDim> globalDomainOffset;
/* Total size of current simulation area (i.e. moving window size) */
DataSpace<simDim> globalDomainSize;

/* Offset from simulation origin to this GPU */
DataSpace<simDim> domainOffset;
/* Size of this GPU */
DataSpace<simDim> domainSize;

/* Offset of simulation area (i.e. moving window) from start of this GPU.
* >= 0 for top GPUs, 0 otherwise */
DataSpace<simDim> localDomainOffset;

};

/**
* Writes simulation data to adios files.
* Implements the ISimulationIO interface.
*
* @param ElectronsBuffer class description for electrons
* @param IonsBuffer class description for ions
* @param simDim dimension of the simulation (2-3)
*/

class ADIOSWriter;

} //namespace adios
} //namespace picongpu

Loading

0 comments on commit 7d0e1cb

Please sign in to comment.