Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • nektar/nektar
  • dmoxey/nektar
  • meshing/nektar
  • gm2511/nektar
  • mvymaza1/nektar
  • ssherw/nektar
  • hongfu2233/nektar
  • lackhove/nektar
  • zbhui/nektar
  • hectordo/nektar
  • kayarre/nektar
  • li12242/nektar
  • Russ/nektar
  • MMFSolver/nektar
  • JDocampo/nektar
  • jkr/nektar
  • Xulia/nektar
  • dperry/nektar
  • dav/nektar
  • bing/nektar
  • mt4313/nektar
  • Dappur/nektar
  • castigli/nektar
  • ARSanderson/nektar
  • tz722/nektar
  • tim48/nektar
  • hl2323/nektar-phys-deriv
  • fei/nektar
  • Leileiji/nektar
  • tsb121/nektar-fyp-thilak
  • victorballester7/nektar
  • mb321/nektar-cu-blas-mika
32 results
Show changes
Commits on Source (1)
Showing
with 2948 additions and 637 deletions
......@@ -202,6 +202,7 @@ ENDIF ()
INCLUDE (ThirdPartyTinyxml)
INCLUDE (ThirdPartyMetis)
INCLUDE (ThirdPartyHDF5)
INCLUDE (ThirdPartySIONLIB)
INCLUDE (ThirdPartyScotch)
INCLUDE (ThirdPartyZlib)
INCLUDE (ThirdPartyBoost)
......
# Module that checks whether SIONLIB is available.
#
# Variables used by this module which you may want to set:
# SIONLIB_ROOTDIR Path list to search for SIONLIB
# SIONLIB_SUFFIX suffix to the library name , e.g. gcc or something
# SIONLIB_INCDIR directory with SIONLIB headers inside
# SIONLIB_LIBDIR directory with SIONLIB libraries inside
#
# Sets the following variables
#
# SIONLIB_INCLUDE_DIR Path to the SIONLIB include dir
# SIONLIB_MPI_LIBRARY
# SIONLIB_GEN_LIBRARY
# SIONLIB_SER_LIBRARY
# SIONLIB_COM_LIBRARY
# SIONLIB_COMLOCKNONE_LIBRARY
# SIONLIB_LIBRARY_DIR
# SIONLIB_FOUND True if SIONLIB was found and usable
# HAVE_SIONLIB True if SIONLIB was found and usable
# SIONLIB_LIBRARIES Names of the SIONLIB libraries
#
set(SIONLIB_ROOTDIR $ENV{SIONLIB_DIR} CACHE PATH "Path list to search for SIONLIB" FORCE)
set(SIONLIB_SUFFIX "_lib64" CACHE STRING "suffix to the library name , e.g. gcc or something")
set(SIONLIB_INCDIR $ENV{SIONLIB_INC} CACHE PATH "directory with SIONLIB headers inside" FORCE)
set(SIONLIB_LIBDIR $ENV{SIONLIB_LIB} CACHE PATH "directory with SIONLIB libraries inside" FORCE)
MESSAGE(STATUS "SIONLIB_ROOTDIR=${SIONLIB_ROOTDIR}")
MESSAGE(STATUS "SIONLIB_INCDIR=${SIONLIB_INCDIR}")
MESSAGE(STATUS "SIONLIB_LIBDIR=${SIONLIB_LIBDIR}")
mark_as_advanced(SIONLIB_ROOTDIR SIONLIB_SUFFIX SIONLIB_INCDIR SIONLIB_LIBDIR)
#look for header files at positions given by the user
find_path(SIONLIB_INCLUDE_DIR
NAMES "sion.h"
PATHS ${SIONLIB_INCDIR}
PATH_SUFFIXES "include"
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
)
MESSAGE(STATUS "SIONLIB_INCLUDE_DIR=${SIONLIB_INCLUDE_DIR}")
# check header usability
include(CMakePushCheckState)
cmake_push_check_state()
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} ${MPI_COMPILE_FLAGS}")
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${MPI_INCLUDE_PATH} ${SIONLIB_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${MPI_LIBRARIES})
check_include_files(sion.h SIONLIB_HEADER_USABLE)
find_library(SIONLIB_MPI_LIBRARY
NAMES "sionmpi_64"
PATHS ${SIONLIB_LIBDIR}
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
MESSAGE(STATUS "SIONLIB_MPI_LIBRARY=${SIONLIB_MPI_LIBRARY}")
find_library(SIONLIB_GEN_LIBRARY
NAMES "siongen_64"
PATHS ${SIONLIB_LIBDIR}
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
MESSAGE(STATUS "SIONLIB_GEN_LIBRARY=${SIONLIB_GEN_LIBRARY}")
find_library(SIONLIB_SER_LIBRARY
NAMES "sionser_64"
PATHS ${SIONLIB_LIBDIR}
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
MESSAGE(STATUS "SIONLIB_SER_LIBRARY=${SIONLIB_SER_LIBRARY}")
find_library(SIONLIB_COM_LIBRARY
NAMES "sioncom_64"
PATHS ${SIONLIB_LIBDIR}
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
MESSAGE(STATUS "SIONLIB_COM_LIBRARY=${SIONLIB_COM_LIBRARY}")
find_library(SIONLIB_COMLOCKNONE_LIBRARY
NAMES "sioncom_64_lock_none"
PATHS ${SIONLIB_LIBDIR}
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
MESSAGE(STATUS "SIONLIB_COMLOCKNONE_LIBRARY=${SIONLIB_COMLOCKNONE_LIBRARY}")
cmake_pop_check_state()
# behave like a CMake module is supposed to behave
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
"SIONlib"
DEFAULT_MSG
SIONLIB_INCLUDE_DIR
SIONLIB_MPI_LIBRARY
SIONLIB_GEN_LIBRARY
SIONLIB_SER_LIBRARY
SIONLIB_COM_LIBRARY
SIONLIB_COMLOCKNONE_LIBRARY
)
mark_as_advanced(SIONLIB_INCLUDE_DIR SIONLIB_MPI_LIBRARY SIONLIB_GEN_LIBRARY SIONLIB_SER_LIBRARY SIONLIB_COM_LIBRARY SIONLIB_COMLOCKNONE_LIBRARY)
# if both headers and library are found, store results
if(SIONLIB_FOUND)
set(SIONLIB_LIBRARY_DIR ${SIONLIB_LIBDIR})
set(SIONLIB_LIBRARIES ${SIONLIB_MPI_LIBRARY} ${SIONLIB_GEN_LIBRARY} ${SIONLIB_SER_LIBRARY} ${SIONLIB_COM_LIBRARY} ${SIONLIB_COMLOCKNONE_LIBRARY})
# log result
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining location of SIONLIB succeded:\n"
"Include directory: ${SIONLIB_INCLUDE_DIR}\n"
"Library directory: ${SIONLIB_LIBRARY_DIR}\n\n")
set(SIONLIB_COMPILE_FLAGS "-I${SIONLIB_INCLUDE_DIR} -D_SION_XT -DSION_MPI"
CACHE STRING "Compile Flags used by Nektar++ when compiling with SIONLIB libraries")
set(SIONLIB_LIBRARIES ${SIONLIB_LIBRARIES}
CACHE STRING "Libraries used by Nektar++ when linking with SIONLIB libraries")
else(SIONLIB_FOUND)
# log errornous result
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determing location of SIONLIB failed:\n"
"Include directory: ${SIONLIB_INCLUDE_DIR}\n"
"Library directory: ${SIONLIB_LIBRARY_DIR}\n\n")
endif(SIONLIB_FOUND)
MESSAGE(STATUS "SIONLIB_LIBRARIES=${SIONLIB_LIBRARIES}")
#set HAVE_SIONLIB for config.h
set(HAVE_SIONLIB ${SIONLIB_FOUND})
#add all sionlib related flags to ALL_PKG_FLAGS, this must happen regardless of a target using add_sionlib_flags
if(SIONLIB_FOUND)
set_property(GLOBAL APPEND PROPERTY ALL_PKG_FLAGS "${SIONLIB_COMPILE_FLAGS}")
foreach(dir "${SIONLIB_INCLUDE_DIR}")
set_property(GLOBAL APPEND PROPERTY ALL_PKG_FLAGS "-I${dir}")
endforeach()
endif()
\ No newline at end of file
......@@ -8,8 +8,10 @@
#If the user has not set BOOST_ROOT, look in a couple common places first.
MESSAGE(STATUS "Searching for Boost:")
SET(MIN_VER "1.56.0")
SET(NEEDED_BOOST_LIBS thread iostreams filesystem system program_options regex)
SET(MIN_VER "1.60.0")
SET(NEEDED_BOOST_LIBS thread iostreams date_time filesystem system
program_options regex)
SET(Boost_DEBUG 0)
SET(Boost_NO_BOOST_CMAKE ON)
IF( BOOST_ROOT )
SET(Boost_NO_SYSTEM_PATHS ON)
......@@ -164,7 +166,13 @@ IF (THIRDPARTY_BUILD_BOOST)
STRING(TOUPPER ${BOOSTLIB} BOOSTLIB_UPPER)
THIRDPARTY_LIBRARY(Boost_${BOOSTLIB_UPPER}_LIBRARY
SHARED boost_${BOOSTLIB} DESCRIPTION "Boost ${BOOSTLIB} library")
THIRDPARTY_LIBRARY(Boost_${BOOSTLIB_UPPER}_LIBRARY_DEBUG
SHARED boost_${BOOSTLIB} DESCRIPTION "Boost ${BOOSTLIB} library, debug")
THIRDPARTY_LIBRARY(Boost_${BOOSTLIB_UPPER}_LIBRARY_RELEASE
SHARED boost_${BOOSTLIB} DESCRIPTION "Boost ${BOOSTLIB} library, release")
MARK_AS_ADVANCED(Boost_${BOOSTLIB_UPPER}_LIBRARY)
MARK_AS_ADVANCED(Boost_${BOOSTLIB_UPPER}_LIBRARY_DEBUG)
MARK_AS_ADVANCED(Boost_${BOOSTLIB_UPPER}_LIBRARY_RELEASE)
LIST(APPEND Boost_LIBRARIES ${Boost_${BOOSTLIB_UPPER}_LIBRARY})
ENDFOREACH()
......
########################################################################
#
# ThirdParty configuration for Nektar++
#
# SIONlib
#
########################################################################
OPTION(NEKTAR_USE_SIONLIB
"Enable SIONlib I/O support." ON)
IF (NEKTAR_USE_SIONLIB)
INCLUDE (CheckIncludeFiles)
IF (NOT NEKTAR_USE_MPI)
MESSAGE(FATAL_ERROR "SIONlib requires Nektar++ to be configured with NEKTAR_USE_MPI for MPI support.")
ENDIF()
# Try to find SIONlib package.
FIND_PACKAGE(SIONLIB)
IF (NOT SIONLIB_FOUND)
MESSAGE(FATAL_ERROR "SIONlib not detected.")
ENDIF()
SET(BUILD_SIONLIB OFF)
SET(SIONLIB_CONFIG_INCLUDE_DIR ${SIONLIB_INCLUDE_DIR})
MARK_AS_ADVANCED(SIONLIB_LIBRARIES)
MARK_AS_ADVANCED(SIONLIB_INCLUDE_DIR)
INCLUDE_DIRECTORIES(SYSTEM ${SIONLIB_INCLUDE_DIR})
ENDIF()
......@@ -10,7 +10,7 @@
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and laimitations under
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
......@@ -29,37 +29,56 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Measure the performance of FieldIO XML and HDF5 classes.
// Description: Measure the performance of FieldIO XML, HDF5 and SIONlib classes.
//
////////////////////////////////////////////////////////////////////////////////
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <boost/bimap.hpp>
#include <LibUtilities/BasicUtils/H5.h>
#include <LibUtilities/BasicUtils/SIONlib.h>
#include <LibUtilities/BasicUtils/FieldIO.h>
#include <LibUtilities/BasicUtils/FieldIOXml.h>
#include <LibUtilities/BasicUtils/FieldIOHdf5.h>
#include <LibUtilities/BasicUtils/FieldIOSIONlib.h>
#include <LibUtilities/BasicUtils/FileSystem.h>
#include <LibUtilities/Communication/CommMpi.h>
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <unordered_set>
#include <string>
#include <LibUtilities/BasicUtils/SessionReader.h>
// Below, we'd like to use an unordered set for its faster lookup performance
// However this is only available if C++11 is.
//
#if __cplusplus >= 201103L
#include <unordered_set>
typedef std::unordered_set<int> IntSet;
#else
#include <set>
typedef std::set<int> IntSet;
#endif
using namespace Nektar;
using namespace LibUtilities;
namespace po = boost::program_options;
namespace po = boost::program_options;
namespace berrc = boost::system::errc;
typedef std::vector<FieldDefinitionsSharedPtr> DefVec;
typedef std::vector<std::vector<NekDouble> > DatVec;
/// Struct that contains experimental setup.
typedef boost::shared_ptr<FieldIOXml> FieldIOXmlSharedPtr;
typedef boost::shared_ptr<FieldIOHdf5> FieldIOHdf5SharedPtr;
typedef boost::shared_ptr<FieldIOSIONlib> FieldIOSIONlibSharedPtr;
struct Experiment
{
/// Test read (false) or write (true)
bool write;
/// Test the HDF5 (true) or XML (false) reader/writer.
/// Test the HDF5 (true) or XML/SIONlib (false) reader/writer.
bool hdf;
/// Test the SIONlib (true) or XML/HDF5 (false) reader/writer.
bool sionlib;
/// If true, print additional debugging information.
bool verbose;
/// Number of writes to perform.
......@@ -72,25 +91,38 @@ struct Experiment
CommSharedPtr comm;
};
typedef std::vector<NekDouble> Results;
IOSettingsSharedPtr sionlib_settings(new IOSettings);
typedef std::vector<double> Results;
const double MB = 1000000.0;
const int AORTIC_ARCH = 0;
const int RACING_CAR = 1;
std::string SIONlib_GetIOBlocksPerChunk(int nprocs, int testid);
Results TestRead(Experiment &exp);
Results TestWrite(Experiment &exp);
void PrintResults(Experiment &exp, Results &results);
int main(int argc, char *argv[])
{
Experiment exp;
exp.write = false;
exp.hdf = false;
exp.sionlib = false;
exp.verbose = false;
exp.n = 3;
exp.comm = GetCommFactory().CreateInstance("ParallelMPI", argc, argv);
sionlib_settings->insert( IOSettings::value_type("IOBlockSize", "65536") );
sionlib_settings->insert( IOSettings::value_type("IOBlocksPerChunk", SIONlib_GetIOBlocksPerChunk(exp.comm->GetSize(), AORTIC_ARCH)) );
sionlib_settings->insert( IOSettings::value_type("IOReadMode", "br,collective,collsize=-1") );
sionlib_settings->insert( IOSettings::value_type("IOWriteMode", "bw,collective,collectivemerge,collsize=-1") );
po::options_description desc("Available options");
desc.add_options()("help,h", "Produce this help message.")(
"mode,m", po::value<char>(),
"Choose r[ead] (default), x[ml write] or h[df5 write]")(
"Choose r[ead] (default), x[ml write] or h[df5 write] or s[sionlib write]")(
"number,n", po::value<unsigned>(),
"Number of iterations to perform, default 3")("verbose,v",
"Enable verbose mode.");
......@@ -157,15 +189,22 @@ int main(int argc, char *argv[])
switch (mode)
{
case 'r':
exp.write = false;
exp.write = false;
break;
case 'x':
exp.write = true;
exp.hdf = false;
exp.write = true;
exp.hdf = false;
exp.sionlib = false;
break;
case 'h':
exp.write = true;
exp.hdf = true;
exp.write = true;
exp.hdf = true;
exp.sionlib = false;
break;
case 's':
exp.write = true;
exp.hdf = false;
exp.sionlib = true;
break;
default:
std::cout << "Unrecognised mode: " << mode << std::endl;
......@@ -194,10 +233,62 @@ int main(int argc, char *argv[])
res = TestRead(exp);
}
PrintResults(exp, res);
exp.comm->Finalise();
}
/**
* @brief Return the number of file system blocks per SIONlib chunk.
*
* This result depends on the number of processes and on the size of the checkpoint
* file associated with the test case.
*
* @param nprocs The number of MPI processes.
* @param testid The test case --- this determines the size of the checkpoint file.
*
* @return string.
*/
std::string SIONlib_GetIOBlocksPerChunk(int nprocs, int testid)
{
std::string bpc = "1.0";
if (AORTIC_ARCH == testid)
{
switch (nprocs)
{
case 48:
bpc = "8.0";
break;
case 96:
bpc = "4.0";
break;
case 192:
bpc = "2.0";
break;
}
}
else if (RACING_CAR == testid)
{
switch (nprocs)
{
case 768:
bpc = "110.0";
break;
case 1536:
bpc = "55.0";
break;
case 3072:
bpc = "29.0";
break;
case 6144:
bpc = "16.0";
break;
}
}
return bpc;
}
/**
* @brief Read elemental IDs from XML field file format for this rank.
*
......@@ -274,91 +365,13 @@ Array<OneD, int> ReadIDsForThisRank(Experiment &exp, FieldIOSharedPtr fio)
}
/**
* @brief Construct data for this rank based on element IDs and input data.
*
* Extract from @p inFieldDefs and @p inFieldData those elements which are in @p
* ElementIDs and return them in the parameters @p outFieldDefs and @p
* outFieldData.
* @brief Get the IDs of the elements managed by this rank.
*
* @param inFieldDefs Field definitions of input file
* @param inFieldData Input field data corresponding to the definitions
* @param ElementIDs Element IDs for this rank
* @param outFieldDefs Output field definitions containing this rank's data
* @param outFieldData Output field data corresponding to the definitions
*/
void FilterDataForThisRank(const DefVec &inFieldDefs,
const DatVec &inFieldData,
Array<OneD, int> ElementIDs,
DefVec &outFieldDefs,
DatVec &outFieldData)
{
// Create a set with all the IDs
IntSet IDs(ElementIDs.begin(), ElementIDs.end());
// Clear the output vectors
outFieldDefs.clear();
outFieldData.clear();
// Loop through all the loaded elements and copy over if in the requested
// set
DefVec::const_iterator inDefIt = inFieldDefs.begin();
DatVec::const_iterator inDatIt = inFieldData.begin();
for (; inDefIt != inFieldDefs.end(); ++inDefIt, ++inDatIt)
{
FieldDefinitionsSharedPtr inDef = *inDefIt;
// Use list to avoid endless reallocation.
std::list<unsigned int> elOut;
std::list<NekDouble> datOut;
unsigned dat_per_el = inDatIt->size() / inDef->m_elementIDs.size();
std::vector<unsigned int>::const_iterator elIt =
inDef->m_elementIDs.begin();
std::vector<NekDouble>::const_iterator datIt = inDatIt->begin();
for (; elIt != inDef->m_elementIDs.end(); ++elIt, datIt += dat_per_el)
{
if (IDs.find(*elIt) != IDs.end())
{
// Copy across element id
elOut.push_back(*elIt);
// and data
datOut.insert(datOut.end(), datIt, datIt + dat_per_el);
}
}
if (elOut.size())
{
// create the outFieldDefs
FieldDefinitionsSharedPtr defOut =
FieldDefinitionsSharedPtr(new FieldDefinitions(
inDef->m_shapeType,
std::vector<unsigned int>(elOut.begin(), elOut.end()),
inDef->m_basis, inDef->m_uniOrder, inDef->m_numModes,
inDef->m_fields, inDef->m_numHomogeneousDir,
inDef->m_homogeneousLengths, inDef->m_homoStrips,
inDef->m_homogeneousSIDs, inDef->m_homogeneousZIDs,
inDef->m_homogeneousYIDs, inDef->m_points,
inDef->m_pointsDef, inDef->m_numPoints,
inDef->m_numPointsDef));
// Add to return
outFieldDefs.push_back(defOut);
// create the out data vector from our list
outFieldData.push_back(
std::vector<NekDouble>(datOut.begin(), datOut.end()));
}
}
}
/**
* @brief Read all data in those files that this rank wants (and any other data
* in them too).
* @param exp Experimental setup.
*
* @param Exp Experiment to be run
* @param outFieldDefs Output field definitions
* @param outFieldData Output data corresponding to the definitions
* @return IDs of the elements managed by this rank.
*/
void ReadWholeFilesForThisRank(Experiment &exp,
DefVec &outFieldDefs,
DatVec &outFieldData)
Array<OneD, int> ReadIDsForThisRank(Experiment& exp)
{
std::string ft = FieldIO::GetFileType(exp.dataSource, exp.comm);
FieldIOSharedPtr fio =
......@@ -366,43 +379,16 @@ void ReadWholeFilesForThisRank(Experiment &exp,
if (fs::is_directory(exp.dataSource))
{
Array<OneD, int> ElementIDs = ReadIDsForThisRank(exp, fio);
FieldMetaDataMap fieldmetadatamap;
// Load all the data from files that contain any of the IDs we want.
fio->Import(exp.dataSource, outFieldDefs, outFieldData,
fieldmetadatamap, ElementIDs);
return ReadIDsForThisRank(exp, fio);
}
else
else if (exp.hdf)
{
fio->Import(exp.dataSource, outFieldDefs, outFieldData);
// ensure auto_selective
Array<OneD, int> ElementIDs;
return ElementIDs;
}
}
/**
* @brief Read only the data that this rank wants.
*
* @param exp Experiment setup details
* @param outFieldDefs Resulting output field definitions for this rank.
* @param outFieldData Output field data for this rank.
*/
void ReadDecomposed(Experiment &exp, DefVec &outFieldDefs, DatVec &outFieldData)
{
std::string ft = FieldIO::GetFileType(exp.dataSource, exp.comm);
FieldIOSharedPtr fio =
GetFieldIOFactory().CreateInstance(ft, exp.comm, true);
Array<OneD, int> ElementIDs = ReadIDsForThisRank(exp, fio);
DefVec fileFieldDefs;
DatVec fileFieldData;
FieldMetaDataMap fieldmetadatamap;
// Load all the data from files that contain any of the IDs we want.
fio->Import(exp.dataSource, fileFieldDefs, fileFieldData, fieldmetadatamap,
ElementIDs);
// Filter it
FilterDataForThisRank(fileFieldDefs, fileFieldData, ElementIDs,
outFieldDefs, outFieldData);
return NullInt1DArray;
}
/**
......@@ -417,45 +403,60 @@ void ReadDecomposed(Experiment &exp, DefVec &outFieldDefs, DatVec &outFieldData)
*/
Results TestRead(Experiment &exp)
{
const std::string ft = FieldIO::GetFileType(exp.dataSource, exp.comm);
if (exp.verbose)
{
std::cout << "Beginning read experiment with " << exp.n << " loops."
<< std::endl;
std::cout << "Beginning read experiment..."
<< exp.n << " iterations." << std::endl;
std::cout << "Determining file type... ";
std::cout << ft << std::endl;
}
const std::string ft = FieldIO::GetFileType(exp.dataSource, exp.comm);
if (exp.verbose)
if (0 == ft.compare("Hdf5"))
{
exp.hdf = true;
}
else if (0 == ft.compare("SIONlib"))
{
std::cout << ft << endl;
exp.sionlib = true;
}
std::vector<FieldDefinitionsSharedPtr> fielddefs;
std::vector < std::vector<NekDouble> > fielddata;
FieldMetaDataMap fieldmetadatamap;
FieldIOSharedPtr fio = GetFieldIOFactory().CreateInstance(
ft, exp.comm, true);
if (exp.sionlib)
{
fio->InitFromBenchmarker(sionlib_settings);
}
Array<OneD, int> ElementIDs = ReadIDsForThisRank(exp);
Results res(exp.n, 0.0);
for (unsigned i = 0; i < exp.n; ++i)
{
if (exp.verbose)
{
std::cout << "Test " << i << " of " << exp.n;
std::cout << "Test " << i+1 << " of " << exp.n;
}
double t0 = MPI_Wtime();
unsigned long nRead = fio->Import(exp.dataSource,
fielddefs, fielddata,
fieldmetadatamap, ElementIDs);
double t1 = MPI_Wtime() - t0;
std::vector<FieldDefinitionsSharedPtr> fielddefs;
std::vector<std::vector<NekDouble> > fielddata;
// Synchronise
exp.comm->Block();
NekDouble t0 = MPI_Wtime();
ReadWholeFilesForThisRank(exp, fielddefs, fielddata);
NekDouble t1 = MPI_Wtime();
t1 -= t0;
exp.comm->AllReduce(nRead, LibUtilities::ReduceSum);
if (exp.verbose)
{
std::cout << ": t = " << t1 << " s" << std::endl;
std::cout << ": read " << nRead/MB << " MB in "
<< t1 << " s." << std::endl;
}
res[i] = t1;
res[i] = (nRead/MB) / t1;
}
return res;
}
......@@ -472,112 +473,76 @@ Results TestRead(Experiment &exp)
*/
Results TestWrite(Experiment &exp)
{
const std::string ft = FieldIO::GetFileType(exp.dataSource, exp.comm);
if (exp.verbose)
std::cout << "Reading in input: " << exp.dataSource << std::endl;
std::vector<FieldDefinitionsSharedPtr> fielddefs;
std::vector<std::vector<NekDouble> > fielddata;
ReadDecomposed(exp, fielddefs, fielddata);
std::string outtype;
if (exp.hdf)
{
outtype = "Hdf5";
}
else
{
outtype = "Xml";
std::cout << "Beginning write experiment..."
<< exp.n << " iterations." << std::endl;
std::cout << "Determining file type... ";
std::cout << ft << std::endl;
}
std::vector<FieldDefinitionsSharedPtr> fielddefs;
std::vector < std::vector<NekDouble> > fielddata;
FieldMetaDataMap fieldmetadatamap;
FieldIOSharedPtr fio = GetFieldIOFactory().CreateInstance(
ft, exp.comm, true);
if (exp.verbose)
if (exp.sionlib)
{
std::cout << "Beginning write (" << outtype << ") experiment with "
<< exp.n << " loops." << std::endl;
std::cout << "Writing to temp file: " << exp.dataDest << std::endl;
fio->InitFromBenchmarker(sionlib_settings);
}
Array<OneD, int> ElementIDs = ReadIDsForThisRank(exp);
fio->Import(exp.dataSource, fielddefs, fielddata,
fieldmetadatamap, ElementIDs);
exp.comm->Block();
Results res(exp.n, 0);
fs::path specPath(exp.dataDest);
for (unsigned i = 0; i < exp.n; ++i)
{
if (exp.verbose)
{
std::cout << "Test " << i << " of " << exp.n << std::endl;
std::cout << "Test " << i+1 << " of " << exp.n;
}
double t0 = MPI_Wtime();
unsigned long nWritten = fio->Write(exp.dataDest, fielddefs, fielddata);
double t1 = MPI_Wtime() - t0;
// Synchronise - have to do this before removing any old data in case
// any ranks haven't closed their file yet.
exp.comm->Block();
// Remove any existing files
fs::path specPath(exp.dataDest);
try
exp.comm->AllReduce(nWritten, LibUtilities::ReduceSum);
if (exp.verbose)
{
fs::remove_all(specPath);
std::cout << ": written " << nWritten/MB << " MB in "
<< t1 << " s." << std::endl;
}
catch (fs::filesystem_error &e)
res[i] = (nWritten/MB) / t1;
/*
if (exp.comm->GetRank() == 0)
{
ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
"Filesystem error: " + string(e.what()));
try
{
// remove any files that have just been written
// as part of test
fs::remove_all(specPath);
}
catch (fs::filesystem_error& e)
{
ASSERTL0(
e.code().value()
== berrc::no_such_file_or_directory,
"Filesystem error: " + string(e.what()));
}
}
// Synchronise to make sure we're all at the same point.
*/
exp.comm->Block();
NekDouble t0 = MPI_Wtime();
FieldIOSharedPtr fio =
GetFieldIOFactory().CreateInstance(outtype, exp.comm, true);
fio->Write(exp.dataDest, fielddefs, fielddata);
NekDouble t1 = MPI_Wtime();
t1 -= t0;
if (exp.verbose)
{
std::cout << ": t = " << t1 << " s" << std::endl;
}
res[i] = t1;
}
return res;
}
/**
* @brief Print out the results of the timing.
*
* Given an experimental setup @p exp and timing in @p results, this routine
* prints the mean time per read/write.
*
* @param exp Experimental setup.
* @param results Results of timing for @p exp
*/
void PrintResults(Experiment &exp, Results &results)
{
NekDouble sum = 0.0;
NekDouble sumSq = 0.0;
for (Results::const_iterator it = results.begin(); it != results.end();
++it)
{
NekDouble x = *it;
sum += x;
sumSq += x * x;
}
NekDouble mean = sum / exp.n;
// NekDouble var = sumSq / exp.n - mean*mean;
// NekDouble std = std::sqrt(var);
if (exp.comm->GetSize() > 1)
{
// Use all version since reduce to specified rank isn't wrapped.
exp.comm->AllReduce(mean, ReduceSum);
mean /= exp.comm->GetSize();
}
if (exp.comm->GetRank() == 0)
{
std::cout << "Mean: " << mean << std::endl;
// std::cout << "Std: " << std << std::endl;
}
}
......@@ -41,6 +41,7 @@
namespace Nektar
{
typedef unsigned char NekByte;
typedef double NekDouble;
typedef std::int32_t NekInt;
......
......@@ -77,7 +77,8 @@ FieldIOFactory &GetFieldIOFactory()
/// Enumerator for auto-detection of FieldIO types.
enum FieldIOType {
eXML,
eHDF5
eHDF5,
eSIONLIB
};
......@@ -97,7 +98,7 @@ const std::string FieldIO::GetFileType(const std::string &filename,
CommSharedPtr comm)
{
FieldIOType ioType = eXML;
int size = comm->GetSize();
int size = comm->GetSize();
bool root = comm->TreatAsRankZero();
if (size == 1 || root)
......@@ -119,22 +120,44 @@ const std::string FieldIO::GetFileType(const std::string &filename,
// Read first 8 bytes. If they correspond with magic bytes below it's an
// HDF5 file. XML is potentially a nightmare with all the different
// encodings so we'll just assume it's OK if it's not HDF.
const unsigned char magic[8] = {
const unsigned char hdf5_magic[8] = {
0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a};
const unsigned char sionlib_magic[8] = {
0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00};
std::ifstream datafile(datafilename.c_str(), ios_base::binary);
ASSERTL0(datafile.good(), "Unable to open file: " + filename);
ioType = eHDF5;
bool is_hdf5 = true;
bool is_sionlib = true;
for (unsigned i = 0; i < 8 && datafile.good(); ++i)
{
unsigned char byte = datafile.get();
if (byte != magic[i])
if (is_hdf5 && byte != hdf5_magic[i])
{
is_hdf5 = false;
}
if (is_sionlib && byte != sionlib_magic[i])
{
is_sionlib = false;
}
if (!is_hdf5 && !is_sionlib)
{
ioType = eXML;
break;
}
}
ioType = eXML;
if (is_hdf5)
{
ioType = eHDF5;
}
else if (is_sionlib)
{
ioType = eSIONLIB;
}
}
if (size > 1)
......@@ -153,6 +176,10 @@ const std::string FieldIO::GetFileType(const std::string &filename,
{
iofmt = "Hdf5";
}
else if (ioType == eSIONLIB)
{
iofmt = "SIONlib";
}
else
{
// Error
......@@ -187,10 +214,14 @@ FieldIOSharedPtr FieldIO::CreateDefault(
iofmt = session->GetCmdLineArgument<std::string>("io-format");
}
return GetFieldIOFactory().CreateInstance(
FieldIOSharedPtr fieldio = GetFieldIOFactory().CreateInstance(
iofmt,
session->GetComm(),
session->GetSharedFilesystem());
fieldio->Init(session);
return fieldio;
}
/**
......@@ -210,10 +241,15 @@ FieldIOSharedPtr FieldIO::CreateForFile(
{
const std::string iofmt =
FieldIO::GetFileType(filename, session->GetComm());
return GetFieldIOFactory().CreateInstance(
FieldIOSharedPtr fieldio = GetFieldIOFactory().CreateInstance(
iofmt,
session->GetComm(),
session->GetSharedFilesystem());
fieldio->Init(session);
return fieldio;
}
/**
......@@ -226,12 +262,13 @@ FieldIOSharedPtr FieldIO::CreateForFile(
* @param fielddata Binary field data that stores the output corresponding
* to @p fielddefs.
* @param fieldinfomap Associated field metadata map.
* @return The number of bytes written.
*/
void Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap,
const bool backup)
uint64_t Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap,
const bool backup)
{
#ifdef NEKTAR_USE_MPI
int size;
......@@ -253,7 +290,7 @@ void Write(const std::string &outFile,
#endif
CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
FieldIOSharedPtr f = GetFieldIOFactory().CreateInstance("Xml", c, false);
f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
return f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
}
/**
......@@ -270,8 +307,9 @@ void Write(const std::string &outFile,
* @param ElementIDs Element IDs that lie on this processor, which can be
* optionally supplied to avoid reading the entire file on
* each processor.
* @return The number of bytes read.
*/
LIB_UTILITIES_EXPORT void Import(
LIB_UTILITIES_EXPORT uint64_t Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
......@@ -299,7 +337,7 @@ LIB_UTILITIES_EXPORT void Import(
CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
const std::string iofmt = FieldIO::GetFileType(infilename, c);
FieldIOSharedPtr f = GetFieldIOFactory().CreateInstance(iofmt, c, false);
f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
return f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
}
/**
......@@ -393,7 +431,7 @@ std::string FieldIO::SetUpOutput(const std::string outname, bool perRank, bool b
ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
int nprocs = m_comm->GetSize();
bool root = m_comm->TreatAsRankZero();
bool root = m_comm->TreatAsRankZero();
// Path to output: will be directory if parallel, normal file if
// serial.
......@@ -501,7 +539,7 @@ std::string FieldIO::SetUpOutput(const std::string outname, bool perRank, bool b
if (root)
{
cout << "Writing: " << specPath;
//cout << "Writing: " << specPath << std::endl;
}
// serial processing just add ending.
......
......@@ -53,6 +53,9 @@ namespace LibUtilities
typedef std::map<std::string, std::string> FieldMetaDataMap;
static FieldMetaDataMap NullFieldMetaDataMap;
typedef std::map<std::string, std::string> IOSettings;
typedef std::shared_ptr<IOSettings> IOSettingsSharedPtr;
/**
* @brief Base class for writing hierarchical data (XML or HDF5).
*/
......@@ -179,13 +182,14 @@ struct FieldDefinitions
typedef std::shared_ptr<FieldDefinitions> FieldDefinitionsSharedPtr;
LIB_UTILITIES_EXPORT void Write(
LIB_UTILITIES_EXPORT uint64_t Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const bool backup = false);
LIB_UTILITIES_EXPORT void Import(
LIB_UTILITIES_EXPORT uint64_t Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata = NullVectorNekDoubleVector,
......@@ -230,14 +234,20 @@ public:
{
}
LIB_UTILITIES_EXPORT inline void Write(
LIB_UTILITIES_EXPORT inline void Init(
const LibUtilities::SessionReaderSharedPtr session);
LIB_UTILITIES_EXPORT inline void InitFromBenchmarker(
const LibUtilities::IOSettingsSharedPtr iosettings);
LIB_UTILITIES_EXPORT inline uint64_t Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const bool backup = false);
LIB_UTILITIES_EXPORT inline void Import(
LIB_UTILITIES_EXPORT inline uint64_t Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata =
......@@ -249,6 +259,12 @@ public:
const std::string &filename,
FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT void ImportMultiFldFileIDs(
const std::string &inFile,
std::vector<std::string> &fileNames,
std::vector<std::vector<unsigned int> > &elementList,
FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT static const std::string GetFileType(
const std::string &filename, CommSharedPtr comm);
LIB_UTILITIES_EXPORT virtual const std::string &GetClassName() const = 0;
......@@ -282,8 +298,16 @@ protected:
LIB_UTILITIES_EXPORT std::string SetUpOutput(
const std::string outname, bool perRank, bool backup = false);
/// @copydoc FieldIO::Init
LIB_UTILITIES_EXPORT virtual void v_Init(
const LibUtilities::SessionReaderSharedPtr session) {};
/// @copydoc FieldIO::InitFromBenchmarker
LIB_UTILITIES_EXPORT virtual void v_InitFromBenchmarker(
const LibUtilities::IOSettingsSharedPtr iosettings) {};
/// @copydoc FieldIO::Write
LIB_UTILITIES_EXPORT virtual void v_Write(
LIB_UTILITIES_EXPORT virtual uint64_t v_Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
......@@ -291,7 +315,7 @@ protected:
const bool backup = false) = 0;
/// @copydoc FieldIO::Import
LIB_UTILITIES_EXPORT virtual void v_Import(
LIB_UTILITIES_EXPORT virtual uint64_t v_Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> >
......@@ -302,10 +326,37 @@ protected:
/// @copydoc FieldIO::ImportFieldMetaData
LIB_UTILITIES_EXPORT virtual DataSourceSharedPtr v_ImportFieldMetaData(
const std::string &filename, FieldMetaDataMap &fieldmetadatamap) = 0;
LIB_UTILITIES_EXPORT virtual void v_ImportMultiFldFileIDs(
const std::string &inFile,
std::vector<std::string> &fileNames,
std::vector<std::vector<unsigned int> > &elementList,
FieldMetaDataMap &fieldmetadatamap) {};
};
typedef std::shared_ptr<FieldIO> FieldIOSharedPtr;
/**
* @brief Allow the FieldIO class an opportunity for further initialisation.
*
* @param pointer to session configuration
*/
inline void FieldIO::Init(const LibUtilities::SessionReaderSharedPtr session)
{
return v_Init(session);
}
/**
* @brief Allow the FieldIO class an opportunity for further initialisation
* from outside a usual Nektar++ session, e.g., a benchmarker.
*
* @param pointer to stl map containing extra io settings
*/
inline void FieldIO::InitFromBenchmarker(const LibUtilities::IOSettingsSharedPtr iosettings)
{
return v_InitFromBenchmarker(iosettings);
}
/**
* @brief Write out the field information to the file @p outFile.
*
......@@ -314,14 +365,15 @@ typedef std::shared_ptr<FieldIO> FieldIOSharedPtr;
* @param fielddata Binary field data that stores the output corresponding
* to @p fielddefs.
* @param fieldinfomap Associated field metadata map.
* @return The number of bytes written.
*/
inline void FieldIO::Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap,
const bool backup)
inline uint64_t FieldIO::Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap,
const bool backup)
{
v_Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
return v_Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
}
/**
......@@ -336,14 +388,15 @@ inline void FieldIO::Write(const std::string &outFile,
* @param ElementIDs Element IDs that lie on this processor, which can be
* optionally supplied to avoid reading the entire file on
* each processor.
* @return The number of bytes read.
*/
inline void FieldIO::Import(const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
FieldMetaDataMap &fieldinfo,
const Array<OneD, int> &ElementIDs)
inline uint64_t FieldIO::Import(const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
FieldMetaDataMap &fieldinfo,
const Array<OneD, int> &ElementIDs)
{
v_Import(infilename, fielddefs, fielddata, fieldinfo, ElementIDs);
return v_Import(infilename, fielddefs, fielddata, fieldinfo, ElementIDs);
}
/**
......@@ -359,6 +412,24 @@ inline DataSourceSharedPtr FieldIO::ImportFieldMetaData(
return v_ImportFieldMetaData(filename, fieldmetadatamap);
}
/**
* @brief Read file containing element ID to partition mapping.
*
* @param inFile Input multi-field file name.
* @param fileNames List of partition filenames.
* @param elementList Vector of element IDs that lie on each process.
* @param fieldmetadatamap Field metadata map that is read from @p inFile.
*/
inline void FieldIO::ImportMultiFldFileIDs(
const std::string &inFile,
std::vector<std::string> &fileNames,
std::vector<std::vector<unsigned int> > &elementList,
FieldMetaDataMap &fieldmetadatamap)
{
v_ImportMultiFldFileIDs(inFile, fileNames, elementList, fieldmetadatamap);
}
}
}
#endif
......@@ -227,55 +227,55 @@ public:
private:
struct OffsetHelper {
OffsetHelper() : data(0), order(0), homy(0), homz(0), homs(0) {}
OffsetHelper() : ids(0), data(0), order(0), homy(0), homz(0), homs(0) {}
OffsetHelper(const OffsetHelper &in) :
data(in.data), order(in.order), homy(in.homy), homz(in.homz),
homs(in.homs)
ids(in.ids), data(in.data), order(in.order),
homy(in.homy), homz(in.homz), homs(in.homs)
{
}
uint64_t data, order, homy, homz, homs;
uint64_t ids, data, order, homy, homz, homs;
};
LIB_UTILITIES_EXPORT virtual void v_Write(
LIB_UTILITIES_EXPORT virtual uint64_t v_Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const bool backup = false);
LIB_UTILITIES_EXPORT virtual void v_Import(
const std::string &infilename,
template <class T>
LIB_UTILITIES_EXPORT uint64_t WriteFieldDataInd(std::size_t nFields,
H5::DataSpaceSharedPtr &fspace, H5::DataSetSharedPtr &dset,
uint64_t data_i, std::vector<std::vector<T> > &data);
template <class T>
LIB_UTILITIES_EXPORT uint64_t WriteFieldData(std::size_t nMinFields, std::size_t nFields,
H5::DataSpaceSharedPtr &fspace, H5::DataSetSharedPtr &dset,
uint64_t data_i, std::vector<std::vector<T> > &data);
LIB_UTILITIES_EXPORT virtual uint64_t v_Import(const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata =
NullVectorNekDoubleVector,
std::vector<std::vector<NekDouble> > &fielddata = NullVectorNekDoubleVector,
FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const Array<OneD, int> &ElementIDs = NullInt1DArray);
template <class T>
LIB_UTILITIES_EXPORT uint64_t ImportFieldDataInd(H5::GroupSharedPtr root,
std::string dsetName, std::string dataTag, uint64_t nDataItems,
uint64_t offset, std::vector<T> &data);
LIB_UTILITIES_EXPORT uint64_t ImportFieldDef(H5::GroupSharedPtr root,
std::string group,
FieldDefinitionsSharedPtr def);
LIB_UTILITIES_EXPORT virtual DataSourceSharedPtr v_ImportFieldMetaData(
const std::string &filename, FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT void ImportHDF5FieldMetaData(
DataSourceSharedPtr dataSource, FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT void ImportFieldDef(
H5::PListSharedPtr readPL,
H5::GroupSharedPtr root,
std::vector<uint64_t> &decomps,
uint64_t decomp,
OffsetHelper offset,
std::string group,
FieldDefinitionsSharedPtr def);
LIB_UTILITIES_EXPORT void ImportFieldData(
H5::PListSharedPtr readPL,
H5::DataSetSharedPtr data_dset,
H5::DataSpaceSharedPtr data_fspace,
uint64_t data_i,
std::vector<uint64_t> &decomps,
uint64_t decomp,
const FieldDefinitionsSharedPtr fielddef,
std::vector<NekDouble> &fielddata);
};
}
}
......
This diff is collapsed.
///////////////////////////////////////////////////////////////////////////////
//
// File FieldIOSIONlib.h
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Field IO to/from SIONlib files.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_FIELDIOSIONLIB_H
#define NEKTAR_LIB_UTILITIES_BASIC_UTILS_FIELDIOSIONLIB_H
#include <LibUtilities/BasicUtils/SessionReader.h>
#include <LibUtilities/BasicUtils/FieldIO.h>
#include <LibUtilities/BasicUtils/FileSystem.h>
namespace Nektar
{
namespace LibUtilities
{
/**
* @class Class encapsulating simple SIONlib data source.
*/
class SIONlibDataSource : public DataSource
{
public:
/// Constructor based on filename.
SIONlibDataSource(const std::string &fn)
{
}
std::string Get()
{
return fn;
}
const std::string Get() const
{
return fn;
}
/// Static constructor for this data source.
static DataSourceSharedPtr create(const std::string &fn)
{
return DataSourceSharedPtr(new SIONlibDataSource(fn));
}
private:
/// SION document.
std::string fn;
};
typedef std::shared_ptr<SIONlibDataSource> SIONlibDataSourceSharedPtr;
class FieldIOSIONlib : public FieldIO
{
public:
static const unsigned int FORMAT_VERSION;
/// Creates an instance of this class
LIB_UTILITIES_EXPORT static FieldIOSharedPtr create(
LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
{
return MemoryManager<FieldIOSIONlib>::AllocateSharedPtr(pComm,
sharedFilesystem);
}
/// Name of class
LIB_UTILITIES_EXPORT static std::string className;
LIB_UTILITIES_EXPORT FieldIOSIONlib(
LibUtilities::CommSharedPtr pComm,
bool sharedFilesystem);
LIB_UTILITIES_EXPORT virtual ~FieldIOSIONlib()
{
}
/// Get class name
inline virtual const std::string &GetClassName() const
{
return className;
}
private:
static const std::string ATTRNAME_FIELDS;
static const std::string ATTRNAME_BASIS;
static const std::string ATTRNAME_SHAPE;
static const std::string ATTRNAME_HOMOLENS;
static const std::string ATTRNAME_NUMMODES;
static const std::string ATTRNAME_POINTSTYPE;
static const std::string ATTRNAME_NUMPOINTS;
static const std::string ATTRVALUE_MIXORDER;
static const std::string ATTRVALUE_UNIORDER;
static sion_int32 block_size;
static sion_int64 chunk_size;
static std::string read_mode;
static std::string write_mode;
SIONlib::SIONFile *OpenFileForWriting(const std::string &outFilename);
LIB_UTILITIES_EXPORT virtual void v_Init(
const LibUtilities::SessionReaderSharedPtr session);
LIB_UTILITIES_EXPORT virtual void v_InitFromBenchmarker(
const LibUtilities::IOSettingsSharedPtr iosettings);
void WriteRawDataToBinaryVector(std::vector<NekByte> &v, const NekByte* dptr, const size_t dsize);
void WriteStringToBinaryVector(std::vector<NekByte> &v, const std::string &s);
template<class T>
void WriteDatumToBinaryVector(std::vector<NekByte> &v, const T d);
template<class T>
void WriteDataToBinaryVector(std::vector<NekByte> &v, const std::vector<T> &d);
LIB_UTILITIES_EXPORT virtual unsigned long v_Write(
const std::string &outFileSuffix,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const bool backup = false);
SIONlib::SIONFile *OpenFileForReading(const std::string &inFilename);
unsigned long DirectImport(SIONlib::SIONFile &f,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
FieldMetaDataMap &fieldinfomap,
const Array<OneD, int> &ElementiDs);
LIB_UTILITIES_EXPORT virtual unsigned long v_Import(const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata = NullVectorNekDoubleVector,
FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const Array<OneD, int> &ElementiDs = NullInt1DArray);
LIB_UTILITIES_EXPORT virtual DataSourceSharedPtr v_ImportFieldMetaData(
const std::string &filename, FieldMetaDataMap &fieldmetadatamap);
};
}
}
#endif
......@@ -84,22 +84,25 @@ FieldIOXml::FieldIOXml(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
* @param fielddefs Input field definitions.
* @param fielddata Input field data.
* @param fieldmetadatamap Field metadata.
* @return The number of bytes written.
*/
void FieldIOXml::v_Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldmetadatamap,
const bool backup)
uint64_t FieldIOXml::v_Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldmetadatamap,
const bool backup)
{
uint64_t nWritten = 0;
double tm0 = 0.0, tm1 = 0.0;
if (m_comm->TreatAsRankZero())
{
tm0 = m_comm->Wtime();
}
// Check everything seems sensible
ASSERTL1(fielddefs.size() == fielddata.size(),
"Length of fielddefs and fielddata incompatible");
"Length of fielddefs and fielddata incompatible.");
for (int f = 0; f < fielddefs.size(); ++f)
{
ASSERTL1(fielddata[f].size() > 0,
......@@ -152,6 +155,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
}
fieldsString = fieldsStringStream.str();
}
nWritten += fieldsString.size();
elemTag->SetAttribute("FIELDS", fieldsString);
// Write SHAPE
......@@ -175,6 +179,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
shapeString = shapeStringStream.str();
}
nWritten += shapeString.size();
elemTag->SetAttribute("SHAPE", shapeString);
// Write BASIS
......@@ -195,6 +200,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
}
basisString = basisStringStream.str();
}
nWritten += basisString.size();
elemTag->SetAttribute("BASIS", basisString);
// Write homogeneuous length details
......@@ -214,6 +220,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
}
homoLenString = homoLenStringStream.str();
}
nWritten += homoLenString.size();
elemTag->SetAttribute("HOMOGENEOUSLENGTHS", homoLenString);
}
......@@ -239,6 +246,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
}
homoYIDsString = homoYIDsStringStream.str();
}
nWritten += homoYIDsString.size();
elemTag->SetAttribute("HOMOGENEOUSYIDS", homoYIDsString);
}
......@@ -261,6 +269,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
}
homoZIDsString = homoZIDsStringStream.str();
}
nWritten += homoZIDsString.size();
elemTag->SetAttribute("HOMOGENEOUSZIDS", homoZIDsString);
}
......@@ -283,6 +292,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
}
homoSIDsString = homoSIDsStringStream.str();
}
nWritten += homoSIDsString.size();
elemTag->SetAttribute("HOMOGENEOUSSIDS", homoSIDsString);
}
}
......@@ -328,6 +338,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
numModesString = numModesStringStream.str();
}
nWritten += numModesString.size();
elemTag->SetAttribute("NUMMODESPERDIR", numModesString);
// Write ID
......@@ -338,20 +349,26 @@ void FieldIOXml::v_Write(const std::string &outFile,
std::stringstream idStringStream;
idString = ParseUtils::GenerateSeqString(fielddefs[f]->m_elementIDs);
}
nWritten += idString.size();
elemTag->SetAttribute("ID", idString);
std::string compressedString = LibUtilities::CompressData::GetCompressString();
nWritten += compressedString.size();
elemTag->SetAttribute("COMPRESSED",
LibUtilities::CompressData::GetCompressString());
compressedString);
// Add this information for future compatibility
// issues, for exmaple in case we end up using a 128
// bit machine.
elemTag->SetAttribute("BITSIZE",
LibUtilities::CompressData::GetBitSizeStr());
std::string bitSizeString = LibUtilities::CompressData::GetBitSizeStr();
nWritten += bitSizeString.size();
elemTag->SetAttribute("BITSIZE" ,bitSizeString);
std::string base64string;
ASSERTL0(Z_OK == CompressData::ZlibEncodeToBase64Str(fielddata[f],
base64string),
"Failed to compress field data.");
nWritten += base64string.size();
elemTag->LinkEndChild(new TiXmlText(base64string));
}
doc.SaveFile(filename);
......@@ -359,11 +376,13 @@ void FieldIOXml::v_Write(const std::string &outFile,
m_comm->Block();
// all data has been written
if (m_comm->TreatAsRankZero())
{
tm1 = m_comm->Wtime();
cout << " (" << tm1 - tm0 << "s, XML)" << endl;
}
//if (m_comm->TreatAsRankZero())
//{
// tm1 = m_comm->Wtime();
// cout << " (" << tm1 - tm0 << "s, XML)" << endl;
//}
return nWritten;
}
/**
......@@ -389,7 +408,7 @@ void FieldIOXml::WriteMultiFldFileIDs(
doc.LinkEndChild(decl);
ASSERTL0(fileNames.size() == elementList.size(),
"Outfile names and list of elements ids does not match");
"Outfile names and list of elements ids does not match.");
TiXmlElement *root = new TiXmlElement("NEKTAR");
doc.LinkEndChild(root);
......@@ -426,7 +445,7 @@ void FieldIOXml::WriteMultiFldFileIDs(
* @param elementList Vector of element IDs that lie on each process.
* @param fieldmetadatamap Field metadata map that is read from @p inFile.
*/
void FieldIOXml::ImportMultiFldFileIDs(
void FieldIOXml::v_ImportMultiFldFileIDs(
const std::string &inFile,
std::vector<std::string> &fileNames,
std::vector<std::vector<unsigned int> > &elementList,
......@@ -480,7 +499,7 @@ void FieldIOXml::ImportMultiFldFileIDs(
std::string elementIDsStr(elementIDs);
std::vector<unsigned int> idvec;
ParseUtils::GenerateSeqVector(elementIDsStr, idvec);
ParseUtils::GenerateSeqVector(elementIDsStr.c_str(), idvec);
elementList.push_back(idvec);
......@@ -499,13 +518,16 @@ void FieldIOXml::ImportMultiFldFileIDs(
* this rank. The resulting field definitions will only
* contain data for the element IDs specified in this
* array.
* @return The number of bytes read.
*/
void FieldIOXml::v_Import(const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
FieldMetaDataMap &fieldinfomap,
const Array<OneD, int> &ElementIDs)
uint64_t FieldIOXml::v_Import(const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
FieldMetaDataMap &fieldinfomap,
const Array<OneD, int> &ElementIDs)
{
uint64_t nRead = 0;
std::string infile = infilename;
fs::path pinfilename(infilename);
......@@ -535,10 +557,10 @@ void FieldIOXml::v_Import(const std::string &infilename,
fullpath = pinfilename / pfilename;
string fname = PortablePath(fullpath);
DataSourceSharedPtr dataSource = XmlDataSource::create(fname);
ImportFieldDefs(dataSource, fielddefs, false);
nRead += ImportFieldDefs(dataSource, fielddefs, false);
if (fielddata != NullVectorNekDoubleVector)
{
ImportFieldData(dataSource, fielddefs, fielddata);
nRead += ImportFieldData(dataSource, fielddefs, fielddata);
}
}
}
......@@ -576,10 +598,10 @@ void FieldIOXml::v_Import(const std::string &infilename,
fullpath = pinfilename / pfilename;
string fname = PortablePath(fullpath);
DataSourceSharedPtr dataSource = XmlDataSource::create(fname);
ImportFieldDefs(dataSource, fielddefs, false);
nRead += ImportFieldDefs(dataSource, fielddefs, false);
if (fielddata != NullVectorNekDoubleVector)
{
ImportFieldData(dataSource, fielddefs, fielddata);
nRead += ImportFieldData(dataSource, fielddefs, fielddata);
}
}
}
......@@ -588,12 +610,15 @@ void FieldIOXml::v_Import(const std::string &infilename,
{
// serial format case
DataSourceSharedPtr doc = ImportFieldMetaData(infilename, fieldinfomap);
ImportFieldDefs(doc, fielddefs, false);
nRead += ImportFieldDefs(doc, fielddefs, false);
if (fielddata != NullVectorNekDoubleVector)
{
ImportFieldData(doc, fielddefs, fielddata);
nRead += ImportFieldData(doc, fielddefs, fielddata);
}
}
m_comm->Block();
return nRead;
}
/**
......@@ -765,12 +790,14 @@ void FieldIOXml::SetUpFieldMetaData(
* @param fielddefs Output vector that will contain read field definitions.
* @param expChild Determines if the field definitions are defined by
* `<EXPANSIONS>` or in `<NEKTAR>`.
* @return The number of bytes read.
*/
void FieldIOXml::ImportFieldDefs(
uint64_t FieldIOXml::ImportFieldDefs(
DataSourceSharedPtr dataSource,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
bool expChild)
{
uint64_t nRead = 0;
XmlDataSourceSharedPtr xml =
std::static_pointer_cast<XmlDataSource>(dataSource);
TiXmlElement *master =
......@@ -884,6 +911,8 @@ void FieldIOXml::ImportFieldDefs(
ASSERTL1(false, errstr.c_str());
}
nRead += attr->ValueStr().size();
// Get the next attribute.
attr = attr->Next();
}
......@@ -1091,6 +1120,8 @@ void FieldIOXml::ImportFieldDefs(
}
loopXml = loopXml->NextSiblingElement(strLoop);
}
return nRead;
}
/**
......@@ -1099,12 +1130,15 @@ void FieldIOXml::ImportFieldDefs(
* @param dataSource Target XML file
* @param fielddefs Field definitions for file
* @param fielddata On return, contains field data for each field.
* @return The number of bytes read.
*/
void FieldIOXml::ImportFieldData(
uint64_t FieldIOXml::ImportFieldData(
DataSourceSharedPtr dataSource,
const std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata)
{
uint64_t nRead = 0;
int cntdumps = 0;
XmlDataSourceSharedPtr xml =
std::static_pointer_cast<XmlDataSource>(dataSource);
......@@ -1150,6 +1184,8 @@ void FieldIOXml::ImportFieldData(
" but got " + string(CompressStr));
}
nRead += elementStr.size();
ASSERTL0(Z_OK == CompressData::ZlibDecodeFromBase64Str(
elementStr, elementFieldData),
"Failed to decompress field data.");
......@@ -1159,14 +1195,17 @@ void FieldIOXml::ImportFieldData(
ASSERTL0(
fielddata[cntdumps].size() ==
datasize * fielddefs[cntdumps]->m_fields.size(),
"Input data is not the same length as header infoarmation");
"Input data is not the same length as header information");
cntdumps++;
element = element->NextSiblingElement("ELEMENTS");
}
master = master->NextSiblingElement("NEKTAR");
}
return nRead;
}
}
}
......@@ -220,13 +220,13 @@ public:
LIB_UTILITIES_EXPORT virtual ~FieldIOXml()
{
}
LIB_UTILITIES_EXPORT void ImportFieldDefs(
LIB_UTILITIES_EXPORT uint64_t ImportFieldDefs(
DataSourceSharedPtr dataSource,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
bool expChild);
LIB_UTILITIES_EXPORT void ImportFieldData(
LIB_UTILITIES_EXPORT uint64_t ImportFieldData(
DataSourceSharedPtr dataSource,
const std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata);
......@@ -240,21 +240,21 @@ public:
LIB_UTILITIES_EXPORT void SetUpFieldMetaData(
const std::string &outname,
const std::vector<FieldDefinitionsSharedPtr> &fielddefs,
const FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT void ImportMultiFldFileIDs(
const std::string &inFile,
std::vector<std::string> &fileNames,
std::vector<std::vector<unsigned int> > &elementList,
FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT void v_Import(
const FieldMetaDataMap &fieldmetadatamap);
LIB_UTILITIES_EXPORT virtual uint64_t v_Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata =
NullVectorNekDoubleVector,
FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const Array<OneD, int> &ElementIDs = NullInt1DArray);
const Array<OneD, int> &ElementiDs = NullInt1DArray);
LIB_UTILITIES_EXPORT virtual void v_ImportMultiFldFileIDs(
const std::string &inFile,
std::vector<std::string> &fileNames,
std::vector<std::vector<unsigned int> > &elementList,
FieldMetaDataMap &fieldmetadatamap);
/// Returns the class name.
inline virtual const std::string &GetClassName() const
......@@ -262,8 +262,8 @@ public:
return className;
}
private:
LIB_UTILITIES_EXPORT virtual void v_Write(
private:
LIB_UTILITIES_EXPORT virtual uint64_t v_Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
......
......@@ -465,6 +465,12 @@ void DataSpace::SelectRange(const hsize_t start, const hsize_t count)
(m_Id, H5S_SELECT_SET, &start, NULL, &count, NULL));
}
void DataSpace::SelectRange(const H5S_seloper_t op, const hsize_t start, const hsize_t count)
{
H5_CALL(H5Sselect_hyperslab,
(m_Id, op, &start, NULL, &count, NULL));
}
hsize_t DataSpace::GetSize()
{
return H5Sget_simple_extent_npoints(m_Id);
......
......@@ -326,6 +326,7 @@ public:
void Close();
void SelectRange(const hsize_t start, const hsize_t count);
void SelectRange(const H5S_seloper_t op, const hsize_t start, const hsize_t count);
hsize_t GetSize();
std::vector<hsize_t> GetDims();
......
////////////////////////////////////////////////////////////////////////////////
//
// File: SIONlib.cpp
//
// For more information, please see: http://www.nektar.info/
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Minimal SIONlib wrapper
//
////////////////////////////////////////////////////////////////////////////////
#include <LibUtilities/BasicUtils/SIONlib.h>
namespace Nektar
{
namespace LibUtilities
{
namespace SIONlib
{
const unsigned int SION_Base::LUSTRE_STRIPE_BASE_SIZE = 65536;
// Common functions
char *SION_Base::getSionFileName() const
{
return _sion_file_name;
}
void SION_Base::setDebug(bool debug)
{
_debug = debug;
}
void SION_Base::setMode(std::string mode)
{
_mode = mode;
}
std::string SION_Base::getMode() const
{
return _mode;
}
bool SION_Base::isModeCollective() const
{
return _is_mode_collective;
}
bool SION_Base::isModeCollectiveMerge() const
{
return _is_mode_collectivemerge;
}
void SION_Base::setNumberOfFiles(int num_files)
{
_num_files = num_files;
}
int SION_Base::getNumberOfFiles() const
{
return _num_files;
}
void SION_Base::setNumberOfTasks(int num_tasks)
{
_num_tasks = num_tasks;
}
int SION_Base::getNumberOfTasks() const
{
return _num_tasks;
}
void SION_Base::setRank(int rank)
{
_rank = rank;
}
int SION_Base::getRank() const
{
return _rank;
}
void SION_Base::setChunkSize(sion_int64 chunk_size)
{
_chunk_size = chunk_size;
}
sion_int64 SION_Base::getChunkSize() const
{
return _chunk_size;
}
void SION_Base::setChunkSizes(sion_int64 *chunk_sizes)
{
_chunk_sizes = chunk_sizes;
}
sion_int64 *SION_Base::getChunkSizes() const
{
return _chunk_sizes;
}
void SION_Base::setGlobalRanks(int *global_ranks)
{
_global_ranks = global_ranks;
}
int *SION_Base::getGlobalRanks() const
{
return _global_ranks;
}
void SION_Base::setFileSystemBlockSize(sion_int32 fs_blk_size)
{
_fs_blk_size = fs_blk_size;
}
sion_int32 SION_Base::getFileSystemBlockSize() const
{
return _fs_blk_size;
}
int SION_Base::getNumberOfSuccessfulReadElements() const
{
return _number_of_elements_sucessfully_read;
}
int SION_Base::getReturnCode() const
{
return _return_code;
}
int SION_Base::getSid() const
{
return _sid;
}
/* get information (with sion datatypes) */
int SION_Base::getFileEndianness() const
{
return sion_get_file_endianness(_sid);
}
sion_int64 SION_Base::getBytesWritten() const
{
return sion_get_bytes_written(_sid);
}
sion_int64 SION_Base::getBytesRead() const
{
return sion_get_bytes_read(_sid);
}
sion_int64 SION_Base::getBytesAvailInBlock() const
{
return sion_bytes_avail_in_block(_sid);
}
sion_int64 SION_Base::getBytesAvailInChunk() const
{
return sion_bytes_avail_in_chunk(_sid);
}
sion_int64 SION_Base::getPosition() const
{
return sion_get_position(_sid);
}
void SION_Base::seek()
{
_return_code = sion_seek(_sid,
SION_CURRENT_RANK, SION_CURRENT_BLK, SION_CURRENT_POS);
}
SIONFile::SIONFile(std::string sion_file_name, std::string mode,
int num_files, sion_int64 chunk_size, sion_int32 block_size,
int global_rank, MPI_Comm gComm, MPI_Comm lComm)
{
size_t ncharacter = sion_file_name.length()+1;
const char *tmp_sion_file_name = sion_file_name.c_str();
_sion_file_name = new char[ncharacter];
strncpy(_sion_file_name, tmp_sion_file_name, ncharacter);
_debug = false;
_mode = mode;
_is_mode_collective = false;
_is_mode_collectivemerge = false;
std::istringstream mode_stream(mode);
std::string mode_comp;
while (getline(mode_stream, mode_comp, ','))
{
if (!_is_mode_collective) _is_mode_collective = (0 == mode_comp.compare("collective"));
if (!_is_mode_collectivemerge) _is_mode_collectivemerge = (0 == mode_comp.compare("collectivemerge"));
}
_num_files = num_files;
_global_rank = global_rank;
_g_comm = gComm;
_l_comm = lComm;
const sion_int32 base_size = LUSTRE_STRIPE_BASE_SIZE;
if (block_size > 0)
{
sion_int32 base_cnt = block_size / base_size;
if (0 == base_cnt)
{
// block_size can never be smaller than base_size
block_size = base_size;
}
else
{
if (0 != block_size % base_size)
{
// block_size must be a multiple of base_size
base_cnt += 1;
block_size = base_size*base_cnt;
}
if (base_cnt > 1 && 0 != base_cnt % 2)
{
// if block_size > base_size then
// block_size must be an even multiple of base_size
base_cnt += 1;
block_size = base_size*base_cnt;
// this ensures that Lustre file stripe size can be
// set equal to the SIONlib file system block size
}
}
_fs_blk_size = block_size;
}
else
{
block_size = base_size;
_fs_blk_size = -1;
}
if (chunk_size > 0)
{
if (block_size > chunk_size)
{
// set chunk_size such that block_size is a multiple of chunk_size
if (0 != block_size % chunk_size)
{
sion_int32 chunk_cnt = block_size / chunk_size + 1;
chunk_size = block_size / chunk_cnt;
}
}
else if (chunk_size > block_size)
{
// force chunk_size to be a multiple of block_size
if (0 != chunk_size % block_size)
{
sion_int32 block_cnt = chunk_size / block_size + 1;
chunk_size = block_size*block_cnt;
}
}
}
else
{
chunk_size = base_size;
}
_chunk_size = chunk_size;
_file_ptr = NULL;
_new_sion_file_name = new char[255];
}
SIONFile::~SIONFile()
{
delete [] _sion_file_name;
_sion_file_name = NULL;
delete [] _new_sion_file_name;
_new_sion_file_name = NULL;
}
void SIONFile::setLocalCommunicator(MPI_Comm lComm)
{
_l_comm = lComm;
}
MPI_Comm SIONFile::getLocalCommunicator() const
{
return _l_comm;
}
void SIONFile::setGlobalCommunicator(MPI_Comm gComm)
{
_g_comm = gComm;
}
MPI_Comm SIONFile::getGlobalCommunicator() const
{
return _g_comm;
}
void SIONFile::setGlobalRank(int global_rank)
{
_global_rank = global_rank;
}
int SIONFile::getGlobalRank() const
{
return _global_rank;
}
char *SIONFile::getNewSionFileName() const
{
return _new_sion_file_name;
}
void SIONFile::open()
{
_sid = sion_paropen_mpi(_sion_file_name, _mode.c_str(), &_num_files,
_g_comm, &_l_comm, &_chunk_size, &_fs_blk_size,
&_global_rank, NULL, &_new_sion_file_name);
_return_code = _sid;
}
void SIONFile::close()
{
_return_code = sion_parclose_mpi(_sid);
}
void SIONFile::ensureFreeSpace(long numbytes)
{
_return_code = sion_ensure_free_space(_sid, numbytes);
}
void SIONFile::endOfFile()
{
_return_code = sion_feof(_sid);
}
template<class T>
void SIONFile::write(const T rhs)
{
if (_is_mode_collective)
{
_return_code = sion_coll_fwrite(&rhs, sizeof(rhs), 1, _sid);
}
else
{
_return_code = sion_fwrite(&rhs, sizeof(rhs), 1, _sid);
}
}
SIONFile &operator<<(SIONFile &sf, const LibUtilities::BasisType &rhs)
{
sf.write(rhs);
return sf;
}
SIONFile &operator<<(SIONFile &sf, const unsigned int &rhs)
{
sf.write(rhs);
return sf;
}
SIONFile &operator<<(SIONFile &sf, const size_t &rhs)
{
sf.write(rhs);
return sf;
}
SIONFile &operator<<(SIONFile &sf, const double &rhs)
{
sf.write(rhs);
return sf;
}
void SIONFile::write_string(const std::string &rhs)
{
size_t rhs_size = rhs.size();
if (_is_mode_collective)
{
_return_code = sion_coll_fwrite(&rhs_size, sizeof(rhs_size), 1, _sid);
_return_code = sion_coll_fwrite(rhs.c_str(), sizeof(char), rhs_size, _sid);
}
else
{
_return_code = sion_fwrite(&rhs_size, sizeof(rhs_size), 1, _sid);
_return_code = sion_fwrite(rhs.c_str(), sizeof(char), rhs_size, _sid);
}
}
SIONFile &operator<<(SIONFile &sf, const std::string &rhs)
{
sf.write_string(rhs);
return sf;
}
template<class T>
void SIONFile::write_vector(const std::vector<T> &rhs)
{
size_t rhs_size = rhs.size();
if (_is_mode_collective)
{
_return_code = sion_coll_fwrite(&rhs_size, sizeof(rhs_size), 1, _sid);
_return_code = sion_coll_fwrite(rhs.data(), sizeof(T), rhs_size, _sid);
}
else
{
_return_code = sion_fwrite(&rhs_size, sizeof(rhs_size), 1, _sid);
_return_code = sion_fwrite(rhs.data(), sizeof(T), rhs_size, _sid);
}
}
SIONFile &operator<<(SIONFile &sf, const std::vector<LibUtilities::BasisType> &rhs)
{
sf.write_vector(rhs);
return sf;
}
SIONFile &operator<<(SIONFile &sf, const std::vector<unsigned int> &rhs)
{
sf.write_vector(rhs);
return sf;
}
SIONFile &operator<<(SIONFile &sf, const std::vector<double> &rhs)
{
sf.write_vector(rhs);
return sf;
}
SIONFile &operator<<(SIONFile &sf, const std::vector<unsigned char> &rhs)
{
sf.write_vector(rhs);
return sf;
}
template<class T>
void SIONFile::read(T *rhs)
{
if (NULL != rhs)
{
if (_is_mode_collective)
{
_return_code = sion_coll_fread(rhs, sizeof(T), 1, _sid);
}
else
{
_return_code = sion_fread(rhs, sizeof(T), 1, _sid);
}
}
}
SIONFile &operator>>(SIONFile &sf, LibUtilities::BasisType &rhs)
{
sf.read(&rhs);
return sf;
}
SIONFile &operator>>(SIONFile &sf, unsigned int &rhs)
{
sf.read(&rhs);
return sf;
}
SIONFile &operator>>(SIONFile &sf, size_t &rhs)
{
sf.read(&rhs);
return sf;
}
SIONFile &operator>>(SIONFile &sf, double &rhs)
{
sf.read(&rhs);
return sf;
}
void SIONFile::read_string(std::string &rhs)
{
size_t rhs_size = 0;
if (_is_mode_collective)
{
_return_code = sion_coll_fread(&rhs_size, sizeof(rhs_size), 1, _sid);
}
else
{
_return_code = sion_fread(&rhs_size, sizeof(rhs_size), 1, _sid);
}
if (1 == _return_code && rhs_size > 0)
{
char *rhs_buf = new char[rhs_size];
if (NULL != rhs_buf)
{
if (_is_mode_collective)
{
_return_code = sion_coll_fread(rhs_buf, sizeof(char), rhs_size, _sid);
}
else
{
_return_code = sion_fread(rhs_buf, sizeof(char), rhs_size, _sid);
}
if (rhs_size == _return_code)
{
rhs.resize(rhs_size);
rhs.assign(rhs_buf, rhs_size);
}
delete [] rhs_buf;
}
}
}
SIONFile &operator>>(SIONFile &sf, std::string &rhs)
{
sf.read_string(rhs);
return sf;
}
template<class T>
void SIONFile::read_vector(std::vector<T> &rhs)
{
size_t rhs_size = 0;
if (_is_mode_collective)
{
_return_code = sion_coll_fread(&rhs_size, sizeof(rhs_size), 1, _sid);
}
else
{
_return_code = sion_fread(&rhs_size, sizeof(rhs_size), 1, _sid);
}
if (1 == _return_code && rhs_size > 0)
{
T *rhs_buf = new T[rhs_size];
if (NULL != rhs_buf)
{
if (_is_mode_collective)
{
_return_code = sion_coll_fread(rhs_buf, sizeof(T), rhs_size, _sid);
}
else
{
_return_code = sion_fread(rhs_buf, sizeof(T), rhs_size, _sid);
}
if (rhs_size == _return_code)
{
rhs.resize(rhs_size);
rhs.assign(rhs_buf, rhs_buf+rhs_size);
}
delete [] rhs_buf;
}
}
}
SIONFile &operator>>(SIONFile &sf, std::vector<LibUtilities::BasisType> &rhs)
{
sf.read_vector(rhs);
return sf;
}
SIONFile &operator>>(SIONFile &sf, std::vector<unsigned int> &rhs)
{
sf.read_vector(rhs);
return sf;
}
SIONFile &operator>>(SIONFile &sf, std::vector<double> &rhs)
{
sf.read_vector(rhs);
return sf;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// File SIONlib.h
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Simple OO wrapper around SIONlib
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_SIONLIB_H
#define NEKTAR_LIB_UTILITIES_BASIC_UTILS_SIONLIB_H
#include "mpi.h"
#include "sion.h"
#include <exception>
#include <string>
#include <string.h>
#include <vector>
#include <sstream>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <LibUtilities/Foundations/BasisType.h>
namespace Nektar
{
namespace LibUtilities
{
namespace SIONlib
{
class SION_Base
{
public:
static const unsigned int LUSTRE_STRIPE_BASE_SIZE;
SION_Base() : _sid(-9999) {}
~SION_Base() {}
// Common functions
char *getSionFileName() const;
void setDebug(bool debug);
void setMode(std::string mode);
std::string getMode() const;
bool isModeCollective() const;
bool isModeCollectiveMerge() const;
void setNumberOfFiles(int num_files);
int getNumberOfFiles() const;
void setNumberOfTasks(int num_tasks);
int getNumberOfTasks() const;
void setRank(int rank);
int getRank() const;
void setChunkSize(sion_int64 chunk_size);
sion_int64 getChunkSize() const;
void setChunkSizes(sion_int64 *chunk_sizes);
sion_int64 *getChunkSizes() const;
void setGlobalRanks(int *global_ranks);
int *getGlobalRanks() const;
void setFileSystemBlockSize(sion_int32 fs_blk_size);
sion_int32 getFileSystemBlockSize() const;
int getNumberOfSuccessfulReadElements() const;
int getSid() const;
int getReturnCode() const;
void seek();
/* get information (with sion datatypes) */
int getFileEndianness() const;
sion_int64 getBytesWritten() const;
sion_int64 getBytesRead() const;
sion_int64 getBytesAvailInBlock() const;
sion_int64 getBytesAvailInChunk() const;
sion_int64 getPosition() const;
protected:
// Common attributes
char *_sion_file_name;
std::string _mode;
bool _is_mode_collective;
bool _is_mode_collectivemerge;
int _num_files;
int _num_tasks;
int _rank;
sion_int64 *_chunk_sizes;
sion_int64 _chunk_size;
sion_int32 _fs_blk_size;
int *_global_ranks;
FILE *_file_ptr;
int _number_of_elements_sucessfully_read;
int _return_code;
int _sid;
bool _debug;
// get information (with sion datatypes)
int _file_endianness;
sion_int64 _bytes_written;
sion_int64 _bytes_read;
sion_int64 _bytes_avail_in_block;
sion_int64 _bytes_avail_in_chunk;
sion_int64 _position;
};
class SIONFile : public SION_Base
{
public:
SIONFile();
SIONFile(std::string sion_file_name, std::string mode = "bw",
int num_files = 1, sion_int64 chunk_size=LUSTRE_STRIPE_BASE_SIZE, sion_int32 block_size=-1,
int global_rank = 0, MPI_Comm gComm=MPI_COMM_WORLD, MPI_Comm lComm=MPI_COMM_WORLD);
virtual ~SIONFile();
char *getNewSionFileName() const;
void setLocalCommunicator(MPI_Comm lComm);
MPI_Comm getLocalCommunicator() const;
void setGlobalCommunicator(MPI_Comm gComm);
MPI_Comm getGlobalCommunicator() const;
void setGlobalRank(int global_rank);
int getGlobalRank() const;
void open();
void close();
void ensureFreeSpace(long numbytes);
void endOfFile();
template<class T>
void write(const T rhs);
friend SIONFile &operator<<(SIONFile &sf, const LibUtilities::BasisType &rhs);
friend SIONFile &operator<<(SIONFile &sf, const unsigned int &rhs);
friend SIONFile &operator<<(SIONFile &sf, const size_t &rhs);
friend SIONFile &operator<<(SIONFile &sf, const double &rhs);
void write_string(const std::string &rhs);
friend SIONFile &operator<<(SIONFile &sf, const std::string &rhs);
template<class T>
void write_vector(const std::vector<T> &rhs);
friend SIONFile &operator<<(SIONFile &sf, const std::vector<LibUtilities::BasisType> &rhs);
friend SIONFile &operator<<(SIONFile &sf, const std::vector<unsigned int> &rhs);
friend SIONFile &operator<<(SIONFile &sf, const std::vector<double> &rhs);
friend SIONFile &operator<<(SIONFile &sf, const std::vector<unsigned char> &rhs);
template<class T>
void read(T *rhs);
friend SIONFile &operator>>(SIONFile &sf, LibUtilities::BasisType &rhs);
friend SIONFile &operator>>(SIONFile &sf, unsigned int &rhs);
friend SIONFile &operator>>(SIONFile &sf, size_t &rhs);
friend SIONFile &operator>>(SIONFile &sf, double &rhs);
void read_string(std::string &rhs);
friend SIONFile &operator>>(SIONFile &sf, std::string &rhs);
template<class T>
void read_vector(std::vector<T> &rhs);
friend SIONFile &operator>>(SIONFile &sf, std::vector<LibUtilities::BasisType> &rhs);
friend SIONFile &operator>>(SIONFile &sf, std::vector<unsigned int> &rhs);
friend SIONFile &operator>>(SIONFile &sf, std::vector<double> &rhs);
private:
char *_new_sion_file_name;
MPI_Comm _g_comm;
MPI_Comm _l_comm;
int _global_rank;
};
}
}
}
#endif
......@@ -64,6 +64,15 @@ IF( NEKTAR_USE_HDF5 )
./BasicUtils/FieldIOHdf5.cpp)
ENDIF( NEKTAR_USE_HDF5 )
# SIONlib
IF( NEKTAR_USE_SIONLIB )
SET(BasicUtilsHeaders ${BasicUtilsHeaders}
./BasicUtils/SIONlib.h
./BasicUtils/FieldIOSIONlib.h)
SET(BasicUtilsSources ${BasicUtilsSources}
./BasicUtils/SIONlib.cpp
./BasicUtils/FieldIOSIONlib.cpp)
ENDIF( NEKTAR_USE_SIONLIB )
SET(CommunicationHeaders
./Communication/Comm.h
......@@ -424,6 +433,13 @@ IF( NEKTAR_USE_HDF5 )
ADD_DEPENDENCIES(LibUtilities hdf5-1.8.16)
ENDIF( NEKTAR_USE_HDF5 )
# SIONlib
IF( NEKTAR_USE_SIONLIB )
SET_SOURCE_FILES_PROPERTIES(./BasicUtils/FieldIOSIONlib.cpp
PROPERTY COMPILE_FLAGS "${SIONLIB_COMPILE_FLAGS}")
TARGET_LINK_LIBRARIES(LibUtilities LINK_PRIVATE ${SIONLIB_LIBRARIES})
ENDIF( NEKTAR_USE_SIONLIB )
INSTALL(DIRECTORY ./
DESTINATION ${NEKTAR_INCLUDE_DIR}/LibUtilities
COMPONENT dev
......