diff --git a/Makefile b/Makefile index 27f123ee3ab70e90b313adec7b966e2ed8a41ea9..86b405b8d6fb215b39fc4d13322042cc9cf72a7a 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ HFiles:=$(shell find ./include -type f -name "*.h") CPPFiles:=$(shell find ./src -type f -name "*.cpp") INC:=-I./include VPATH = ./src ./src/core ./src/functions \ - ./src/engine ./src/engine/writer ./src/engine/dataman ./src/engine/vis \ + ./src/engine ./src/engine/writer ./src/engine/dataman \ ./src/capsule ./src/transform ./src/transport ./src/format #SEPARATE EXTERNAL LIBRARIES HANDLING in Makefile.libs diff --git a/buildTest.sh b/buildDataman.sh similarity index 77% rename from buildTest.sh rename to buildDataman.sh index d4a20878fc5fb73e7214badee2c590abe966a710..bf57df38dfcc1d75ffd96305a4714d761cdbc2cb 100755 --- a/buildTest.sh +++ b/buildDataman.sh @@ -1,7 +1,7 @@ #!/bin/bash -# buildTest.sh for vis engine build and run test +# buildTest.sh for Dataman example # Created on: Feb 9, 2017 # Author: wfg @@ -14,21 +14,21 @@ echo echo echo "#################################################################" -echo "Building vis example" +echo "Building Dataman example" echo "#################################################################" -make -C ./examples/hello/vis +make -C ./examples/hello/dataman echo echo echo "#################################################################" -echo "Running vis nompi example" +echo "Running helloDataman_nompi.exe example" echo "#################################################################" -./examples/hello/vis/helloVis_nompi +./examples/hello/dataman/helloDataMan_nompi.exe echo echo echo "#################################################################" echo "To run mpi version with 4 mpi processes: " -echo "mpirun -n 4 ./examples/hello/vis/helloVis_mpi" +echo "mpirun -n 4 ./examples/hello/dataman/helloDataman.exe" echo "END" echo "################################################################" diff --git a/examples/groupless/basic/Makefile b/examples/groupless/basic/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1fc69407c352f75f74bee1bcdc588ea00463cb4e --- /dev/null +++ b/examples/groupless/basic/Makefile @@ -0,0 +1,26 @@ +# Makefile for testing purposes, will build writer_mpi (make or make mpi) or writer_nompi (make nompi) +# Created on: Feb 13, 2017 +# Author: pnorbert + +#COMPILERS +CC=g++ +MPICC=mpic++ + +#ADIOS LOCATION +ADIOS_DIR=../../.. +ADIOS_INCLUDE=-I$(ADIOS_DIR)/include +ADIOS_LIB=$(ADIOS_DIR)/lib/libadios.a +ADIOS_NOMPI_LIB=$(ADIOS_DIR)/lib/libadios_nompi.a + +#FLAGS +CFLAGS=-Wall -Wpedantic -Woverloaded-virtual -std=c++11 -O0 -g +LDFLAGS= + +all: writer reader + +writer reader: $(ADIOS_LIB) $(ADIOS_HFiles) + $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $@.cpp -o $@ $(ADIOS_LIB) $(LDFLAGS) -lpthread \ + +clean: + rm -f writer reader + diff --git a/examples/groupless/basic/reader.cpp b/examples/groupless/basic/reader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ccbde89114b6344c6fad9a17809e347834ca501e --- /dev/null +++ b/examples/groupless/basic/reader.cpp @@ -0,0 +1,180 @@ +/* + * reader.cpp + * + * Created on: Feb 13, 2017 + * Author: pnorbert + */ + +#include <vector> +#include <iostream> + +#include <mpi.h> +#include "ADIOS_CPP.h" + + +int main( int argc, char* argv [] ) +{ + int rank, nproc; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + MPI_Comm_size( MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); + + //Application variable + std::vector<double> NiceArray; + std::vector<float> RaggedArray; + unsigned int Nx; + int Nparts; + int Nwriters; + + try + { + //Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method& bpReaderSettings = adios.GetMethod( "input" ); + if( bpReaderSettings.undeclared() ) + { + // if not defined by user, we can change the default settings + bpReaderSettings.SetEngine( "BP" ); // BP is the default engine + } + + //Create engine smart pointer due to polymorphism, + // Default behavior + // auto bpReader = adios.Open( "myNumbers.bp", "r" ); + // this would just open with a default transport, which is "BP" + auto bpReader = adios.Open( "myNumbers.bp", "r", bpReaderSettings ); + + // All the above is same as default use: + //auto bpReader = adios.Open( "myNumbers.bp", "r"); + + if( bpReader == nullptr ) + throw std::ios_base::failure( "ERROR: failed to open ADIOS bpReader\n" ); + + + /* Variable names are available as a vector of strings */ + std::cout << "List of variables in file: " << bpReader->VariableNames << "\n"; + + /* NX */ + bpReader->Read<unsigned int>( "NX", Nx ); // read a Global scalar which has a single value in a step + + /* nproc */ + bpReader->Read<int>( "nproc", Nwriters ); // also a global scalar + + + /* Nparts */ + // Nparts local scalar is presented as a 1D array of Nwriters elements. + // We need to read a specific value the same way as reading from any 1D array. + // Make a single-value selection to describe our rank's position in the + // 1D array of Nwriters values. + if( rank < Nwriters ) + { + std::shared_ptr<adios::Variable> varNparts = bpReader.InquiryVariable("Nparts"); + std::unique_ptr<adios::Selection> selNparts = adios.SelectionBoundingBox( {1}, {rank} ); + varNparts->SetSelection( selNparts ); + bpReader->Read<int>( varNparts, Nparts ); + } + // or we could just read the whole array by every process + std::vector<int> partsV( Nwriters ); + bpReader->Read<int>( "Nparts", partsV.data() ); // read with string name, no selection => read whole array + + std::vector<int> partsV; + bpReader->Read<int>( "Nparts", partsV); // read with string name, no selection => read whole array + (Nwriters == partsV.size()) + + /* Nice */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable> varNice = bpReader.InquiryVariable("Nice"); + + if( varNice == nullptr ) + throw std::ios_base::failure( "ERROR: failed to find variable 'myDoubles' in input file\n" ); + + // ? how do we know about the type? std::string varNice->m_Type + uint64_t gdim = varNice->m_GlobalDimensions[0]; // ?member var or member func? + uint64_t ldim = gdim / nproc; + uint64_t offs = rank * ldim; + if( rank == nproc-1 ) + { + ldim = gdim - (ldim * gdim); + } + + NiceArray.reserve(ldim); + + // Make a 1D selection to describe the local dimensions of the variable we READ and + // its offsets in the global spaces + std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( {ldim}, {offs} ); // local dims and offsets; both as list + varNice->SetSelection( bbsel ); + bpReader->Read<double>( varNice, NiceArray.data() ); + + + + /* Ragged */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void> > varRagged = bpReader.InquiryVariable("Ragged"); + if( varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) + { + throw std::ios_base::failure( "Unexpected condition: Ragged array's fast dimension " + "is supposed to be VARYING_DIMENSION\n" ); + } + // We have here varRagged->sum_nblocks, nsteps, nblocks[], global + if( rank < varRagged->nblocks[0] ) // same as rank < Nwriters in this example + { + // get per-writer size information + varRagged->InquiryBlocks(); + // now we have the dimensions per block + + unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[1]; + RaggedArray.resize( ldim ); + + std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock( rank ); + varRagged->SetSelection( wbsel ); + bpReader->Read<float>( varRagged, RaggedArray.data() ); + + // We can use bounding box selection as well + std::unique_ptr<adios::Selection> rbbsel = adios.SelectionBoundingBox( {1,ldim}, {rank,0} ); + varRagged->SetSelection( rbbsel ); + bpReader->Read<float>( varRagged, RaggedArray.data() ); + } + + /* Extra help to process Ragged */ + int maxRaggedDim = varRagged->GetMaxGlobalDimensions(1); // contains the largest + std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(1); // contains all individual sizes in that dimension + + + // Close file/stream + bpReader->Close(); + } + catch( std::invalid_argument& e ) + { + if( rank == 0 ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::ios_base::failure& e ) + { + if( rank == 0 ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::exception& e ) + { + if( rank == 0 ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + + MPI_Finalize( ); + + return 0; + +} + + + diff --git a/examples/groupless/basic/writer.cpp b/examples/groupless/basic/writer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc36069850ce7b47997b3f3873edd2057d3db33e --- /dev/null +++ b/examples/groupless/basic/writer.cpp @@ -0,0 +1,145 @@ +/* + * writer.cpp + * + * Created on: Feb 13, 2017 + * Author: pnorbert + */ + +#include <vector> +#include <iostream> + +#include <mpi.h> +#include "ADIOS_CPP.h" + +namespace adios { + typedef enum { + VARYING_DIMENSION = -1, + LOCAL_VALUE = 0, + GLOBAL_VALUE = 1 + }; +} + +int main( int argc, char* argv [] ) +{ + int rank, nproc; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &rank); + MPI_Comm_size( MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); + + //Application variable + const unsigned int Nx = 10; + const int Nparts = rand()%6 + 5; // random size per process, 5..10 each + + std::vector<double> NiceArray( Nx ); + for( int i=0; i < Nx; i++ ) + { + NiceArray[i] = rank*Nx + (double)i; + } + + std::vector<float> RaggedArray( Nparts ); + for( int i=0; i < Nparts; i++ ) + { + RaggedArray[i] = rank*Nx + (float)i; + } + + + try + { + //Define group and variables with transforms, variables don't have functions, only group can access variables + adios::Variable<unsigned int>& varNX = adios.DefineVariable<unsigned int>( "NX" ); // global single-value across processes + adios::Variable<int>& varNproc = adios.DefineVariable<int>( "nproc", adios::GLOBAL_VALUE ); // same def for global value + adios::Variable<int>& varNparts = adios.DefineVariable<int>( "Nparts", adios::LOCAL_VALUE ); // a single-value different on every process + adios::Variable<double>& varNice = adios.DefineVariable<double>( "Nice", {nproc*Nx} ); // 1D global array + adios::Variable<float>& varRagged = adios.DefineVariable<float>( "Ragged", {nproc,adios::VARYING_DIMENSION} ); // ragged array + + //add transform to variable in group...not executed (just testing API) + adios::Transform bzip2 = adios::transform::BZIP2( ); + varNice->AddTransform( bzip2, 1 ); + + //Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method& bpWriterSettings = adios.GetMethod( "output" ); + if( bpWriterSettings.undeclared() ) + { + // if not defined by user, we can change the default settings + bpWriterSettings.SetEngine( "BP" ); // BP is the default engine + bpWriterSettings.AddTransport( "File", "lucky=yes" ); // ISO-POSIX file is the default transport + // Passing parameters to the transport + bpWriterSettings.SetParameters("have_metadata_file","yes" ); // Passing parameters to the engine + bpWriterSettings.SetParameters( "Aggregation", (nproc+1)/2 ); // number of aggregators + } + + //Open returns a smart pointer to Engine containing the Derived class Writer + // "w" means we overwrite any existing file on disk, but AdvanceStep will append steps later. + auto bpWriter = adios.Open( "myNumbers.bp", "w", bpWriterSettings ); + + if( bpWriter == nullptr ) + throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" ); + + if( rank == 0 ) + { + // Writing a global scalar from only one process + bpWriter->Write<unsigned int>( varNX, Nx ); + } + // Writing a local scalar on every process. Will be shown at reading as a 1D array + bpWriter->Write<int>( varNparts, Nparts ); + + // Writing a global scalar on every process is useless. Information will be thrown away + // and only rank 0's data will be in the output + bpWriter->Write<int>( varNproc, nproc ); + + // Make a 1D selection to describe the local dimensions of the variable we write and + // its offsets in the global spaces + adios::Selection& sel = adios.SelectionBoundingBox( {Nx}, {rank*Nx} ); // local dims and offsets; both as list + varNice.SetSelection( sel ); + bpWriter->Write<double>( varNice, NiceArray.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived + + adios::Selection& lsel = adios.SelectionBoundingBox( {1,Nparts}, {rank,0} ); + varRagged.SetSelection( sel ); + bpWriter->Write<float>( varRagged, RaggedArray.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived + + // Indicate we are done for this step + // N-to-M Aggregation, disk I/O will be performed during this call, unless + // time aggregation postpones all of that to some later step + bpWriter->Advance( ); + bpWriter->AdvanceAsync( callback_func_to_notify_me ); + + // Called once: indicate that we are done with this output for the run + bpWriter->Close( ); + } + catch( std::invalid_argument& e ) + { + if( rank == 0 ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::ios_base::failure& e ) + { + if( rank == 0 ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::exception& e ) + { + if( rank == 0 ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + + MPI_Finalize( ); + + return 0; + +} + + + diff --git a/examples/groupless/multistep/Makefile b/examples/groupless/multistep/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1498091ae7097fdb382fd07a35bcd46d996700ef --- /dev/null +++ b/examples/groupless/multistep/Makefile @@ -0,0 +1,26 @@ +# Makefile for testing purposes, will build writer_mpi (make or make mpi) or writer_nompi (make nompi) +# Created on: Feb 13, 2017 +# Author: pnorbert + +#COMPILERS +CC=g++ +MPICC=mpic++ + +#ADIOS LOCATION +ADIOS_DIR=../../.. +ADIOS_INCLUDE=-I$(ADIOS_DIR)/include +ADIOS_LIB=$(ADIOS_DIR)/lib/libadios.a +ADIOS_NOMPI_LIB=$(ADIOS_DIR)/lib/libadios_nompi.a + +#FLAGS +CFLAGS=-Wall -Wpedantic -Woverloaded-virtual -std=c++11 -O0 -g +LDFLAGS= + +all: writer_multistep reader_allsteps reader_stepping + +writer_multistep reader_allsteps reader_stepping: $(ADIOS_LIB) $(ADIOS_HFiles) + $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $@.cpp -o $@ $(ADIOS_LIB) $(LDFLAGS) -lpthread \ + +clean: + rm -f writer_multistep reader_allsteps reader_stepping + diff --git a/examples/groupless/multistep/reader_allsteps.cpp b/examples/groupless/multistep/reader_allsteps.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46415c1bba62028d7773b0a54f8c28a3d7d562c2 --- /dev/null +++ b/examples/groupless/multistep/reader_allsteps.cpp @@ -0,0 +1,198 @@ +/* + * reader.cpp + * + * Created on: Feb 13, 2017 + * Author: pnorbert + */ + +#include <vector> +#include <iostream> + +#include <mpi.h> +#include "ADIOS_CPP.h" + + +int main( int argc, char* argv [] ) +{ + int rank, nproc; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + MPI_Comm_size( MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); + + //Application variable + std::vector<double> NiceArray; + std::vector<float> RaggedArray; + + int Nparts; + int Nwriters; + int Nsteps; + + try + { + //Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method& bpReaderSettings = adios.GetMethod( "input" ); + if( bpReaderSettings.undeclared() ) + { + // if not defined by user, we can change the default settings + bpReaderSettings.SetEngine( "BP" ); // BP is the default engine + // By default we see all steps available in a file, so the next line is not needed + bpReaderSettings.SetParameters ("Stepping", false); + } + + //Create engine smart pointer due to polymorphism, + // Default behavior + // auto bpReader = adios.Open( "myNumbers.bp", "r" ); + // this would just open with a default transport, which is "BP" + auto bpReader = adios.Open( "myNumbers.bp", "r", bpReaderSettings ); + + // All the above is same as default use: + //auto bpReader = adios.Open( "myNumbers.bp", "r"); + + if( bpReader == nullptr ) + throw std::ios_base::failure( "ERROR: failed to open ADIOS bpReader\n" ); + + + /* Note: there is no global number of steps. Each variable has its own number of steps */ + + /* NX */ + /* There is a single value for each step. We can read all into a 1D array with a step selection. + * We can also just conveniently get the first with a simple read statement. + * Steps are not automatically presented as an array dimension and read does not read it as array. + */ + unsigned int Nx; + bpReader->Read<unsigned int>( "NX", &Nx ); // read a Global scalar which has a single value in a step + + std::shared_ptr<adios::Variable<void> > varNx = bpReader.InquiryVariable("Nx"); + std::vector<int> Nxs( varNx->nsteps() ); // number of steps available + // make a StepSelection to select multiple steps. Args: From, #of consecutive steps + std::unique_ptr<adios::StepSelection> stepsNx = adios.StepSelection( 0, varNx->nsteps() ); + // ? How do we make a selection for an arbitrary list of steps ? + varNX.SetStepSelection( stepsNx ); + bpReader->Read<unsigned int>( varNx, Nxs.data() ); + + auto itmax = std::max_element(std::begin(Nxs), std::end(Nxs)); + auto itmin = std::min_element(std::begin(Nxs), std::end(Nxs)); + if (*itmin != *itmax) + { + throw std::ios_base::failure( "ERROR: NX is not the same at all steps!\n" ); + } + + + /* nproc */ + bpReader->Read<int>( "nproc", &Nwriters ); // also a global scalar + + + + /* Nparts */ + // Nparts local scalar is presented as a 1D array of Nwriters elements. + // We can read all steps into a 2D array of nproc * Nwriters + std::shared_ptr<adios::Variable<void> > varNparts = bpReader.InquiryVariable("Nparts"); + std::vector<int> partsV( Nproc*Nwriters ); + varNparts->SetStepSelection( + adios.StepSelection( 0, varNparts->nsteps() ) + ); + bpReader->Read<int>( varNparts, partsV.data() ); // missing spatial selection = whole array at each step + + + + + /* Nice */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void> > varNice = bpReader.InquiryVariable("Nice"); + + if( varNice == nullptr ) + throw std::ios_base::failure( "ERROR: failed to find variable 'myDoubles' in input file\n" ); + + // ? how do we know about the type? std::string varNice->m_Type + unsigned long long int gdim = varMyDoubles->m_GlobalDimensions[0]; // ?member var or member func? + unsigned long long int ldim = gdim / nproc; + unsigned long long int offs = rank * ldim; + if( rank == nproc-1 ) + { + ldim = gdim - (ldim * gdim); + } + + NiceArray.reserve(ldim); + + // Make a 1D selection to describe the local dimensions of the variable we READ and + // its offsets in the global spaces + std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( {ldim}, {offs} ); // local dims and offsets; both as list + bpReader->Read<double>( "Nice", bbsel, NiceArray.data() ); // Base class Engine own the Read<T> that will call overloaded Read from Derived + + + + /* Ragged */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void> > varRagged = bpReader.InquiryVariable("Ragged"); + if( varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) + { + throw std::ios_base::failure( "Unexpected condition: Ragged array's fast dimension " + "is supposed to be VARYING_DIMENSION\n" ); + } + // We have here varRagged->sum_nblocks, nsteps, nblocks[], global + if( rank < varRagged->nblocks[0] ) // same as rank < Nwriters in this example + { + // get per-writer size information + varRagged->InquiryBlocks(); + // now we have the dimensions per block + + unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[0]; + RaggedArray.resize( ldim ); + + std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock( rank ); + bpReader->Read<float>( "Ragged", wbsel, RaggedArray.data() ); + + // We can use bounding box selection as well + std::unique_ptr<adios::Selection> rbbsel = adios.SelectionBoundingBox( {1,ldim}, {rank,0} ); + bpReader->Read<float>( "Ragged", rbbsel, RaggedArray.data() ); + } + + /* Extra help to process Ragged */ + int maxRaggedDim = varRagged->GetMaxGlobalDimensions(1); // contains the largest + std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(1); // contains all individual sizes in that dimension + + + + + + // Close file/stream + bpReader->Close(); + + } + catch( std::invalid_argument& e ) + { + if( rank == 0 ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::ios_base::failure& e ) + { + if( rank == 0 ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::exception& e ) + { + if( rank == 0 ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + + MPI_Finalize( ); + + return 0; + +} + + + diff --git a/examples/groupless/multistep/reader_stepping.cpp b/examples/groupless/multistep/reader_stepping.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3bf7022e9e0c3b2ea136a6c7280ce956d57595e2 --- /dev/null +++ b/examples/groupless/multistep/reader_stepping.cpp @@ -0,0 +1,191 @@ +/* + * reader.cpp + * + * Created on: Feb 13, 2017 + * Author: pnorbert + */ + +#include <vector> +#include <iostream> + +#include <mpi.h> +#include "ADIOS_CPP.h" + + +int main( int argc, char* argv [] ) +{ + int rank, nproc; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + MPI_Comm_size( MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); + + //Application variable + std::vector<double> NiceArray; + std::vector<float> RaggedArray; + unsigned int Nx; + int Nparts; + int Nwriters; + int Nsteps; + + try + { + //Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method& bpReaderSettings = adios.GetMethod( "input" ); + if( bpReaderSettings.undeclared() ) + { + // if not defined by user, we can change the default settings + bpReaderSettings.SetEngine( "BP" ); // BP is the default engine + bpReaderSettings.SetParameters ("Stepping", true); // see only one step at a time + } + + //Create engine smart pointer due to polymorphism, + // Default behavior + // auto bpReader = adios.Open( "myNumbers.bp", "r" ); + // this would just open with a default transport, which is "BP" + try + { + auto bpReader = adios.Open( "myNumbers.bp", "r", bpReaderSettings ); + + while (true) + { + /* NX */ + bpReader->Read<unsigned int>( "NX", &Nx ); // read a Global scalar which has a single value in a step + + /* nproc */ + bpReader->Read<int>( "nproc", &Nwriters ); // also a global scalar + + + /* Nparts */ + // Nparts local scalar is presented as a 1D array of Nwriters elements. + // We can read all as a 1D array + std::vector<int> partsV( Nwriters ); + bpReader->Read<int>( "Nparts", &partsV ); // read with string name, no selection => read whole array + + + /* Nice */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void> > varNice = bpReader.InquiryVariable("Nice"); + + if( varNice == nullptr ) + throw std::ios_base::failure( "ERROR: failed to find variable 'myDoubles' in input file\n" ); + + // ? how do we know about the type? std::string varNice->m_Type + unsigned long long int gdim = varMyDoubles->m_GlobalDimensions[0]; // ?member var or member func? + unsigned long long int ldim = gdim / nproc; + unsigned long long int offs = rank * ldim; + if( rank == nproc-1 ) + { + ldim = gdim - (ldim * gdim); + } + + NiceArray.reserve(ldim); + + // Make a 1D selection to describe the local dimensions of the variable we READ and + // its offsets in the global spaces + std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( {ldim}, {offs} ); // local dims and offsets; both as list + varNice->SetSelection( bbsel ); + bpReader->Read<double>( varNice, NiceArray.data() ); + + + /* Ragged */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void> > varRagged = bpReader.InquiryVariable("Ragged"); + if( varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) + { + throw std::ios_base::failure( "Unexpected condition: Ragged array's fast dimension " + "is supposed to be VARYING_DIMENSION\n" ); + } + // We have here varRagged->sum_nblocks, nsteps, nblocks[], global + if( rank < varRagged->nblocks[0] ) // same as rank < Nwriters in this example + { + // get per-writer size information + varRagged->InquiryBlocks(); + // now we have the dimensions per block + + unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[0]; + RaggedArray.resize( ldim ); + + std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock( rank ); + varRagged->SetSelection( wbsel ); + bpReader->Read<float>( varRagged, RaggedArray.data() ); + + // We can use bounding box selection as well + std::unique_ptr<adios::Selection> rbbsel = adios.SelectionBoundingBox( {1,ldim}, {rank,0} ); + varRagged->SetSelection( rbbsel ); + bpReader->Read<float>( varRagged, RaggedArray.data() ); + } + + /* Extra help to process Ragged */ + int maxRaggedDim = varRagged->GetMaxGlobalDimensions(1); // contains the largest + std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(1); // contains all individual sizes in that dimension + + + + // promise to not read more from this step + bpReader->Release(); + + // want to move on to the next available step + //bpReader->Advance(adios::NextStep); + //bpReader->Advance(adios::LatestStep); + bpReader->Advance(); // default is adios::NextStep + + } + + // Close file/stream + bpReader->Close(); + + } + catch( adios::end_of_stream& e ) + { + if( rank == 0 ) + { + std::cout << "Reached end of stream, end processing loop.\n"; + } + // Close file/stream + bpReader->Close(); + } + catch( adios::file_not_found& e ) + { + if( rank == 0 ) + { + std::cout << "File/stream does not exist, quit.\n"; + } + } + } + catch( std::invalid_argument& e ) + { + if( rank == 0 ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::ios_base::failure& e ) + { + if( rank == 0 ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::exception& e ) + { + if( rank == 0 ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + + MPI_Finalize( ); + + return 0; + +} + + + diff --git a/examples/groupless/multistep/writer_multistep.cpp b/examples/groupless/multistep/writer_multistep.cpp new file mode 100644 index 0000000000000000000000000000000000000000..89eba61d40152d2f3cd088373fcab5472792506e --- /dev/null +++ b/examples/groupless/multistep/writer_multistep.cpp @@ -0,0 +1,150 @@ +/* + * writer.cpp + * + * Created on: Feb 13, 2017 + * Author: pnorbert + */ + +#include <vector> +#include <iostream> + +#include <mpi.h> +#include "ADIOS_CPP.h" + +namespace adios { + typedef enum { + VARYING_DIMENSION = -1, + LOCAL_VALUE = 0, + GLOBAL_VALUE = 1 + }; +} + +int main( int argc, char* argv [] ) +{ + int rank, nproc; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &rank); + MPI_Comm_size( MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + const int NSTEPS = 5; + + adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); + + //Application variable + const unsigned int Nx = 10; + int Nparts; // random size per process, 5..10 each + + std::vector<double> NiceArray( Nx ); + for( int i=0; i < Nx; i++ ) + { + NiceArray[i] = rank*Nx + (double)i; + } + + std::vector<float> RaggedArray; + + try + { + //Define group and variables with transforms, variables don't have functions, only group can access variables + adios::Variable<unsigned int>& varNX = adios.DefineVariable<unsigned int>( "NX" ); // global single-value across processes + adios::Variable<int>& varNproc = adios.DefineVariable<int>( "nproc", adios::GLOBAL_VALUE ); // same def for global value + adios::Variable<int>& varNparts = adios.DefineVariable<int>( "Nparts", adios::LOCAL_VALUE ); // a single-value different on every process + adios::Variable<double>& varNice = adios.DefineVariable<double>( "Nice", {nproc*Nx} ); // 1D global array + adios::Variable<float>& varRagged = adios.DefineVariable<float>( "Ragged", {nproc,adios::VARYING_DIMENSION} ); // ragged array + + //add transform to variable in group...not executed (just testing API) + adios::Transform bzip2 = adios::transform::BZIP2( ); + varNice->AddTransform( bzip2, 1 ); + + //Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method& bpWriterSettings = adios.GetMethod( "output" ); + if( bpWriterSettings.undeclared() ) + { + // if not defined by user, we can change the default settings + bpWriterSettings.SetEngine( "BP" ); // BP is the default engine + bpWriterSettings.AddTransport( "File", "lucky=yes" ); // ISO-POSIX file is the default transport + // Passing parameters to the transport + bpWriterSettings.SetParameters("have_metadata_file","yes" ); // Passing parameters to the engine + bpWriterSettings.SetParameters( "Aggregation", (nproc+1)/2 ); // number of aggregators + } + + //Open returns a smart pointer to Engine containing the Derived class Writer + // "w" means we overwrite any existing file on disk, but AdvanceStep will append steps later. + auto bpWriter = adios.Open( "myNumbers.bp", "w", bpWriterSettings ); + + if( bpWriter == nullptr ) + throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" ); + + for ( int step; step < NSTEPS; step++ ) + { + int Nparts = rand()%6 + 5; // random size per process, 5..10 each + RaggedArray.reserve(Nparts); + for( int i=0; i < Nparts; i++ ) + { + RaggedArray[i] = rank*Nx + (float)i; + } + + if( rank == 0 ) + { + // Writing a global scalar from only one process + bpWriter->Write<unsigned int>( varNX, &Nx ); + } + // Writing a local scalar on every process. Will be shown at reading as a 1D array + bpWriter->Write<int>( varNparts, &Nparts ); + + // Writing a global scalar on every process is useless. Information will be thrown away + // and only rank 0's data will be in the output + bpWriter->Write<int>( varNproc, &nproc ); + + // Make a 1D selection to describe the local dimensions of the variable we write and + // its offsets in the global spaces + adios::Selection& sel = adios.SelectionBoundingBox( {Nx}, {rank*Nx} ); // local dims and offsets; both as list + NiceArray.SetSelection( sel ); + bpWriter->Write<double>( varNice, NiceArray.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived + + adios::Selection& lsel = adios.SelectionBoundingBox( {1,Nparts}, {rank,0} ); + RaggedArray.SetSelection( sel ); + bpWriter->Write<float>( varRagged, RaggedArray.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived + + // Indicate we are done for this step + // N-to-M Aggregation, disk I/O will be performed during this call, unless + // time aggregation postpones all of that to some later step + bpWriter->Advance( ); + } + + // Called once: indicate that we are done with this output for the run + bpWriter->Close( ); + } + catch( std::invalid_argument& e ) + { + if( rank == 0 ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::ios_base::failure& e ) + { + if( rank == 0 ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::exception& e ) + { + if( rank == 0 ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + + MPI_Finalize( ); + + return 0; + +} + + + diff --git a/examples/hello/dataman/Makefile b/examples/hello/dataman/Makefile index 9ecfbc12f24b21580460c90522398550ada5970e..64efaa2a4a3c30103831febc991815633b58f634 100644 --- a/examples/hello/dataman/Makefile +++ b/examples/hello/dataman/Makefile @@ -3,11 +3,9 @@ # Author: wfg -BASE_NAME=helloDataMan_OOP - -TOOL_DIR=/usr/bin +BASE_NAME=helloDataMan -CC=g++ # Compiling with mpicc for now +CC=g++ # Compiling with defaults MPICC=mpic++ #ADIOS LOCATION @@ -24,11 +22,11 @@ CFLAGS=-Wall -O0 -g -Wpedantic -std=c++11 all: mpi nompi mpi: $(ADIOS_LIB) $(ADIOS_HFiles) - $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME)_mpi $(ADIOS_LIB) -lpthread + $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME).exe $(ADIOS_LIB) -lpthread nompi: $(ADIOS_NOMPI_LIB) $(NoMPI_HFiles) - $(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME).cpp -o $(BASE_NAME)_nompi $(ADIOS_NOMPI_LIB) -lpthread + $(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME)_nompi.cpp -o $(BASE_NAME)_nompi.exe $(ADIOS_NOMPI_LIB) -lpthread clean: - rm *_mpi; rm *_nompi + rm *.exe; diff --git a/examples/hello/dataman/dataman.xml b/examples/hello/dataman/dataman.xml deleted file mode 100644 index 71bfdb72b64dcfef5d6b17a21761fac0fcad78bc..0000000000000000000000000000000000000000 --- a/examples/hello/dataman/dataman.xml +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0"?> -<adios-config> - - <!-- Changes to ADIOS-1 XML - Accommodate for the following extensions and flexiblity: - - Multiple engines e.g. SIRIUS can have it's own - - Do not bind one transport to a group, i.e. we can reuse a group in multiple I/O - with different transports - - Do not bind one group to each output file, i.e., we can write variables from - different groups into a single file at the same step - --> - - <!-- Execution Engines: default-engine, sirius, dataman, hdf5 - --> - - - <adios-group name="solid"> - <var name="NX" type="integer"/> - <var name="size" type="integer"/> - <var name="rank" type="integer"/> - - <global-bounds dimensions="size,NX" offsets="rank,0"> - <var name="temperature" gwrite="solid.t" type="double" dimensions="1,NX"/> - <var name="pressure" gwrite="solid.p" type="std::vector<double>" dimensions="1,NX"/> - </global-bounds> - - <attribute name="temperature/description" - value="Global array written from 'size' processes over several timesteps" - type="string"/> - </adios-group> - - - <adios-group name="fluid"> - <var name="NX" type="integer"/> - <var name="size" type="integer"/> - <var name="rank" type="integer"/> - - <global-bounds dimensions="size,NX" offsets="rank,0"> - <var name="temperature" gwrite="fluid.t" type="double" dimensions="1,NX"/> - <var name="pressure" gwrite="fluid.p" type="std::vector<double>" dimensions="1,NX"/> - </global-bounds> - - <attribute name="temperature/description" - value="Global array written from 'size' processes over several timesteps" - type="string"/> - </adios-group> - - - <!-- Associate an engine with a group and parameterize it here - The manager will define the transport(s) used in an output - --> - <method name="dataMan2Fermi" group="fluid" engine="DataMan" real_time="yes"> - <transport="ZeroMQ" target="128.1.1.20">options to ZeroMQ transport</transport> - <transport="MDTM" target="128.1.1.1.10">options to MDTM transport</transport> - <!-- filenames overwrite the value provided in Open() call --> - </method> - - - - -</adios-config> - diff --git a/examples/hello/dataman/helloDataMan.cpp b/examples/hello/dataman/helloDataMan.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6c1f653e366e895ca770aa70f8729375b0549d4 --- /dev/null +++ b/examples/hello/dataman/helloDataMan.cpp @@ -0,0 +1,83 @@ +/* + * helloWriter.cpp + * + * Created on: Feb 16, 2017 + * Author: wfg + */ + + + +#include <vector> +#include <iostream> + + +#include <mpi.h> + + +#include "ADIOS_CPP.h" + + +int main( int argc, char* argv [] ) +{ + MPI_Init( &argc, &argv ); + int rank; + MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + const bool adiosDebug = true; + adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); + + //Application variable + std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const std::size_t Nx = myDoubles.size(); + + try + { + //Define variable and local size + auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} ); + + //Define method for engine creation, it is basically straight-forward parameters + adios::Method& datamanSettings = adios.DeclareMethod( "WAN", "DataMan" ); //default method type is Writer + datamanSettings.SetParameters( "peer-to-peer=yes", "optimize=yes", "compress=yes" ); + datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + //datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported, will throw an exception + + //Create engine smart pointer to DataMan Engine due to polymorphism, + //Open returns a smart pointer to Engine containing the Derived class DataMan + auto datamanWriter = adios.Open( "myDoubles.bp", "w", datamanSettings ); + + if( datamanWriter == nullptr ) + throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n" ); + + datamanWriter->Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived + datamanWriter->Close( ); + + } + catch( std::invalid_argument& e ) + { + if( rank == 0 ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::ios_base::failure& e ) + { + if( rank == 0 ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch( std::exception& e ) + { + if( rank == 0 ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + + MPI_Finalize( ); + + return 0; + +} diff --git a/examples/hello/dataman/helloDataMan_OOP.cpp b/examples/hello/dataman/helloDataMan_OOP.cpp deleted file mode 100644 index 90248225697844810cc97bcebeb443583a52aab9..0000000000000000000000000000000000000000 --- a/examples/hello/dataman/helloDataMan_OOP.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * helloADIOSNoXML_OOP.cpp - * - * Created on: Jan 9, 2017 - * Author: wfg - */ - -#include <vector> -#include <iostream> - -#ifdef HAVE_MPI - #include <mpi.h> -#else - #include "mpidummy.h" - using adios::MPI_Init; - using adios::MPI_Comm_rank; - using adios::MPI_Finalize; -#endif - - -#include "ADIOS_OOP.h" - - -int main( int argc, char* argv [] ) -{ - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variable - std::vector<double> myNumbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - int myNX = static_cast<int>( myNumbers.size() ); - - try - { - //Define group and variables - adios::Group& wanGroup = adios.DeclareGroup( "WAN_Group" ); - adios::Var ioNX = wanGroup.DefineVariable<int>( "myNX" ); - adios::Dims ioDim1D = wanGroup.SetDimensions( {ioNX} ); //can be extended to many dimensions {ioNx, ioNy} - adios::Var ioNumbers = wanGroup.DefineVariable<double>( "myNumbers", ioDim1D ); - - adios::Method& wanMethod = adios.DeclareMethod( "WAN_Method", "DataMan" ); //name and type - wanMethod.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" );//add as many as you want - wanMethod.SetDefaultGroup( wanGroup ); - - auto dataManWriter = adios.Open( "hello_dataman", "w", wanMethod ); //here pass the method to your engine - dataManWriter->Write<int>( ioDim1D, &myNX ); //a template Write is good to have - dataManWriter->Write<double>( ioNumbers, myNumbers.data() ); - dataManWriter->Close( ); - - } - catch( std::invalid_argument& e ) - { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - } - catch( std::ios_base::failure& e ) - { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - } - catch( std::exception& e ) - { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - } - - MPI_Finalize( ); - - return 0; - -} - - - diff --git a/examples/hello/dataman/helloDataMan_nompi.cpp b/examples/hello/dataman/helloDataMan_nompi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe7ebbafd5da3c5bc668535b5652c28df3ddcf71 --- /dev/null +++ b/examples/hello/dataman/helloDataMan_nompi.cpp @@ -0,0 +1,66 @@ +/* + * helloADIOSNoXML_OOP.cpp + * + * Created on: Jan 9, 2017 + * Author: wfg + */ + +#include <vector> +#include <iostream> + +#include "ADIOS_CPP.h" + + +int main( int argc, char* argv [] ) +{ + const bool adiosDebug = true; + adios::ADIOS adios( adiosDebug ); + + //Application variable + std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const std::size_t Nx = myDoubles.size(); + + try + { + //Define variable and local size + //Define variable and local size + auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} ); + + //Define method for engine creation, it is basically straight-forward parameters + adios::Method& datamanSettings = adios.DeclareMethod( "WAN", "DataMan" ); //default method type is Writer + datamanSettings.SetParameters( "peer-to-peer=yes", "optimize=yes", "compress=yes" ); + datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + //datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported , will throw an exception + + //Create engine smart pointer to DataMan Engine due to polymorphism, + //Open returns a smart pointer to Engine containing the Derived class DataMan + auto datamanWriter = adios.Open( "myDoubles.bp", "w", datamanSettings ); + + if( datamanWriter == nullptr ) + throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n" ); + + //datamanWriter->Write( "myDoubles", myDoubles.data() ); //you can write either by string or by object + datamanWriter->Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived + datamanWriter->Close( ); + } + catch( std::invalid_argument& e ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch( std::ios_base::failure& e ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch( std::exception& e ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + + return 0; +} + + + diff --git a/examples/hello/vis/Makefile b/examples/hello/vis/Makefile deleted file mode 100644 index f7767abd91902c0f51c32a8174394f67b87e4d5a..0000000000000000000000000000000000000000 --- a/examples/hello/vis/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# Makefile for testing purposes, will build helloWriter_OOP_mpi (make or make mpi) or helloWriter_OOP_nompi (make nompi) -# Created on: Oct 4, 2016 -# Author: wfg - -BASE_NAME=helloVis - -#COMPILERS -CC=g++ -MPICC=mpic++ - -#ADIOS LOCATION -ADIOS_DIR=../../.. -ADIOS_INCLUDE=-I$(ADIOS_DIR)/include -ADIOS_LIB=$(ADIOS_DIR)/lib/libadios.a -ADIOS_NOMPI_LIB=$(ADIOS_DIR)/lib/libadios_nompi.a - -#FLAGS -CFLAGS=-Wall -Wpedantic -Woverloaded-virtual -std=c++11 -O0 -g -LDFLAGS= - -all: mpi nompi - -mpi: $(BASE_NAME).cpp - @echo; - @echo Building mpi version $(BASE_NAME)_mpi; - $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME)_mpi $(ADIOS_LIB) $(LDFLAGS) -lpthread - -nompi: $(BASE_NAME).cpp - @echo; - @echo Building nompi version $(BASE_NAME)_nompi; - $(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME).cpp -o $(BASE_NAME)_nompi $(ADIOS_NOMPI_LIB) $(LDFLAGS) -lpthread - -clean: - rm *_mpi; rm *_nompi - \ No newline at end of file diff --git a/examples/hello/vis/helloVis.cpp b/examples/hello/vis/helloVis.cpp deleted file mode 100644 index bd5c67dadaf7a8fc11eb49f0b1e0e576dc9e0472..0000000000000000000000000000000000000000 --- a/examples/hello/vis/helloVis.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * helloADIOSNoXML_OOP.cpp - * - * Created on: Jan 9, 2017 - * Author: wfg - */ - -#include <vector> -#include <iostream> - -#ifdef HAVE_MPI - #include <mpi.h> -#else - #include "mpidummy.h" - using adios::MPI_Init; - using adios::MPI_Comm_rank; - using adios::MPI_Finalize; -#endif - - -#include "ADIOS_OOP.h" - - -int main( int argc, char* argv [] ) -{ - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variables from fluid and solid - const unsigned int fluidNx = 3; - const unsigned int fluidNy = 3; - const unsigned int fluidNz = 3; - std::vector<double> fluidTemperature = { 1, 2, 3, 4, 5, 6, 7, 8, 9, - 1, 2, 3, 4, 5, 6, 7, 8, 9, - 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - - const unsigned int solidNx = 5; - const unsigned int solidNy = 3; - const unsigned int solidNz = 3; - std::vector<double> solidTemperature = { 111, 112, 113, 121, 122, 123, 131, 132, 133, - 211, 212, 213, 221, 222, 223, 231, 232, 233, - 311, 312, 313, 321, 322, 323, 331, 332, 333, - 411, 412, 413, 421, 422, 423, 431, 432, 433, - 511, 512, 513, 521, 522, 523, 531, 532, 533 - }; - - try - { - //Define fluid group and variables - adios::Group& ioFluid = adios.DeclareGroup( "fluid" ); - adios::Var ioFluidNx = ioFluid.DefineVariable<unsigned int>( "fluidNx" ); - adios::Var ioFluidNy = ioFluid.DefineVariable<unsigned int>( "fluidNy" ); - adios::Var ioFluidNz = ioFluid.DefineVariable<unsigned int>( "fluidNz" ); - adios::Dims ioFluidDims = ioFluid.SetDimensions( { ioFluidNx, ioFluidNy, ioFluidNz } ); - adios::Var ioFluidTemperature = ioFluid.DefineVariable<double>( "fluidTemperature", ioFluidDims ); - - //add transform to variable in group...not executed (just testing API) - adios::Transform bzip2 = adios::transform::BZIP2( ); - ioFluid.AddTransform( ioFluidTemperature, bzip2 , 1 ); - - //adios::Transform merge = adios::transform::Merge( 1 ); //potential merge transform? 1 is a tag - //ioFluid.AddTransform( ioFluidTemperature, merge , 1 ); //potential merge transform? 1 is a tag - - //Define solid group and variables - adios::Group& ioSolid = adios.DeclareGroup( "solid" ); - adios::Var ioSolidNx = ioSolid.DefineVariable<unsigned int>( "solidNx" ); - adios::Var ioSolidNy = ioSolid.DefineVariable<unsigned int>( "solidNy" ); - adios::Var ioSolidNz = ioSolid.DefineVariable<unsigned int>( "solidNz" ); - adios::Dims ioSolidDims = ioSolid.SetDimensions( { ioSolidNx, ioSolidNy, ioSolidNz } ); - adios::Var ioSolidTemperature = ioSolid.DefineVariable<double>( "solidTemperature", ioSolidDims ); - - //adios::Transform merge = adios::transform::Merge( 1 ); //potential merge transform? 1 is a tag - //ioSolid.AddTransform( ioSolidTemperature, merge , 1 ); //potential merge transform? 1 is a tag - - - //Define method for engine creation - adios::Method& visSettings = adios.DeclareMethod( "SimpleTask", "Vis" ); - visSettings.AddTransport( "VisIt", "use_shared_memory=no", "hex_mesh=true", "vtk-m_cores=8" ); //as many as you want - visSettings.AddTransport( "POSIX", "have_metadata_file=yes" ); - - //Create engine, smart pointer due to polymorphism - //Open returns a smart pointer to Engine containing the Derived class Vis engine - auto visWriter = adios.Open( "visEngine.tmp", "w", visSettings ); - - visWriter->SetDefaultGroup( ioFluid ); //default group can change - visWriter->Write<unsigned int>( ioFluidNx, &fluidNx ); //group, variableName, *value - visWriter->Write<unsigned int>( ioFluidNy, &fluidNy ); - visWriter->Write<unsigned int>( ioFluidNz, &fluidNz ); - visWriter->Write<double>( ioFluidTemperature, fluidTemperature.data() ); - - visWriter->SetDefaultGroup( ioSolid ); //default group can change - visWriter->Write<unsigned int>( ioSolidNx, &solidNx ); //group, variableName, *value - visWriter->Write<unsigned int>( ioSolidNy, &solidNy ); - visWriter->Write<unsigned int>( ioSolidNz, &solidNz ); - visWriter->Write<double>( ioSolidTemperature, solidTemperature.data() ); - - visWriter->Close( ); - } - catch( std::invalid_argument& e ) - { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - } - catch( std::ios_base::failure& e ) - { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - } - catch( std::exception& e ) - { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - } - - MPI_Finalize( ); - - return 0; - -} - - - diff --git a/examples/hello/writer/Makefile b/examples/hello/writer/Makefile index 633a4445f629eddb64846e2b1c8c724485459e2c..30851e670e052a65824167c3d545ce7a272facaa 100644 --- a/examples/hello/writer/Makefile +++ b/examples/hello/writer/Makefile @@ -2,10 +2,10 @@ # Created on: Oct 4, 2016 # Author: wfg -BASE_NAME=helloWriter_OOP +BASE_NAME=helloWriter #COMPILERS -CC=g++ +CC=g++ MPICC=mpic++ #ADIOS LOCATION @@ -21,11 +21,11 @@ LDFLAGS= all: mpi nompi mpi: $(ADIOS_LIB) $(ADIOS_HFiles) - $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME)_mpi $(ADIOS_LIB) $(LDFLAGS) -lpthread + $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME).exe $(ADIOS_LIB) $(LDFLAGS) -lpthread nompi: $(ADIOS_NOMPI_LIB) $(NoMPI_HFiles) - $(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME).cpp -o $(BASE_NAME)_nompi $(ADIOS_NOMPI_LIB) $(LDFLAGS) -lpthread + $(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME)_nompi.cpp -o $(BASE_NAME)_nompi.exe $(ADIOS_NOMPI_LIB) $(LDFLAGS) -lpthread clean: - rm *_mpi; rm *_nompi + rm *.exe \ No newline at end of file diff --git a/examples/hello/writer/helloWriter_OOP.cpp b/examples/hello/writer/helloWriter.cpp similarity index 51% rename from examples/hello/writer/helloWriter_OOP.cpp rename to examples/hello/writer/helloWriter.cpp index af6cebb409fe06cc9354de0cb0e04ba67996d765..9667b3ae484d563344e62e75aced778aa644aa6b 100644 --- a/examples/hello/writer/helloWriter_OOP.cpp +++ b/examples/hello/writer/helloWriter.cpp @@ -1,24 +1,20 @@ /* - * helloADIOSNoXML_OOP.cpp + * helloWriter.cpp * - * Created on: Jan 9, 2017 + * Created on: Feb 16, 2017 * Author: wfg */ + + #include <vector> #include <iostream> -#ifdef HAVE_MPI - #include <mpi.h> -#else - #include "mpidummy.h" - using adios::MPI_Init; - using adios::MPI_Comm_rank; - using adios::MPI_Finalize; -#endif +#include <mpi.h> -#include "ADIOS_OOP.h" + +#include "ADIOS_CPP.h" int main( int argc, char* argv [] ) @@ -28,39 +24,28 @@ int main( int argc, char* argv [] ) MPI_Comm_rank( MPI_COMM_WORLD, &rank ); const bool adiosDebug = true; adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - //adios::ADIOS adios( "xmlFile.adios", MPI_COMM_WORLD, adiosDebug ); //Application variable std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - std::vector<float> myFloats = { 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 }; - const unsigned int Nx = 10; //static_cast<unsigned int>( myDoubles.size() ); + const std::size_t Nx = myDoubles.size(); try { - //Define group and variables with transforms, variables don't have functions, only group can access variables - adios::Group& ioGroup = adios.DeclareGroup( "ioGroup" ); - adios::Var ioNx = ioGroup.DefineVariable<unsigned int>( "Nx" ); - adios::Dims dimNx = ioGroup.SetDimensions( {ioNx} ); - adios::Var ioMyDoubles = ioGroup.DefineVariable<double>( "myDoubles", dimNx ); - - //add transform to variable in group...not executed (just testing API) - adios::Transform bzip2 = adios::transform::BZIP2( ); - ioGroup.AddTransform( ioMyDoubles, bzip2, 1 ); + //Define variable and local size + auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", adios::Dims{Nx} ); //Define method for engine creation, it is basically straight-forward parameters adios::Method& bpWriterSettings = adios.DeclareMethod( "SinglePOSIXFile" ); //default method type is Writer bpWriterSettings.AddTransport( "POSIX", "have_metadata_file=yes" ); - bpWriterSettings.SetDefaultGroup( ioGroup ); //Create engine smart pointer due to polymorphism, //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpWriter = adios.Open( "myNumbers.bp", "w", bpWriterSettings ); + auto bpWriter = adios.Open( "myDoubles.bp", "w", bpWriterSettings ); if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" ); + throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); - bpWriter->Write<unsigned int>( ioNx, &Nx ); - bpWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived + bpWriter->Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived bpWriter->Close( ); } catch( std::invalid_argument& e ) @@ -93,6 +78,3 @@ int main( int argc, char* argv [] ) return 0; } - - - diff --git a/examples/hello/writer/helloWriter_nompi.cpp b/examples/hello/writer/helloWriter_nompi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7438715cc89fba5393db5bb19683995e383536d7 --- /dev/null +++ b/examples/hello/writer/helloWriter_nompi.cpp @@ -0,0 +1,62 @@ +/* + * helloADIOSNoXML_OOP.cpp + * + * Created on: Jan 9, 2017 + * Author: wfg + */ + +#include <vector> +#include <iostream> + +#include "ADIOS_CPP.h" + + +int main( int argc, char* argv [] ) +{ + const bool adiosDebug = true; + adios::ADIOS adios( adiosDebug ); + + //Application variable + std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const std::size_t Nx = myDoubles.size(); + + try + { + //Define variable and local size + auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", adios::Dims{Nx} ); + + //Define method for engine creation, it is basically straight-forward parameters + adios::Method& bpWriterSettings = adios.DeclareMethod( "SinglePOSIXFile" ); //default method type is Writer + bpWriterSettings.AddTransport( "POSIX", "have_metadata_file=yes" ); + + //Create engine smart pointer due to polymorphism, + //Open returns a smart pointer to Engine containing the Derived class Writer + auto bpWriter = adios.Open( "myDoubles_nompi.bp", "w", bpWriterSettings ); + + if( bpWriter == nullptr ) + throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); + + bpWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived + bpWriter->Close( ); + } + catch( std::invalid_argument& e ) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch( std::ios_base::failure& e ) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch( std::exception& e ) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + + return 0; +} + + + diff --git a/examples/solidfluid/Makefile b/examples/solidfluid/Makefile index 00f97805631d729d763cc499c4326fd8f08df0d5..f4acbc65533602d220cafeae1af7c57ef486e3b3 100644 --- a/examples/solidfluid/Makefile +++ b/examples/solidfluid/Makefile @@ -4,12 +4,9 @@ BASE_NAME=solidfluid_write - -TOOL_DIR=/usr/bin -CC=$(TOOL_DIR)/g++ # Compiling with mpicc for now +CC=g++ # Compiling with mpicc for now MPICC:=mpic++ -AR=$(TOOL_DIR)/ar #ADIOS LOCATION ADIOS_DIR=../.. @@ -22,15 +19,15 @@ ADIOS_INCLUDE=-I$(ADIOS_DIR)/include #FLAGS CFLAGS=-Wall -O0 -g -Wpedantic -std=c++11 -all: mpi +all: mpi nompi mpi: $(ADIOS_LIB) $(ADIOS_HFiles) - $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME)_mpi $(ADIOS_LIB) + $(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME).exe $(ADIOS_LIB) -lpthread nompi: $(ADIOS_NOMPI_LIB) $(NoMPI_HFiles) - $(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME).cpp -o $(BASE_NAME)_nompi $(ADIOS_NOMPI_LIB) + $(CC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME)_nompi.cpp -o $(BASE_NAME)_nompi.exe $(ADIOS_NOMPI_LIB) -lpthread clean: - rm -f *_mpi *_nompi *.o + rm -f *.exe rm -rf *.dSYM diff --git a/examples/solidfluid/solidfluid_write.cpp b/examples/solidfluid/solidfluid_write.cpp index bb2f34f81a74da24088029d83daf1ed3a9835019..a5a2d260c62f4365005e4263b41edfc7d03f0da0 100644 --- a/examples/solidfluid/solidfluid_write.cpp +++ b/examples/solidfluid/solidfluid_write.cpp @@ -1,5 +1,5 @@ /* - * globalArrayXML.cpp + * solid fluid example * * Created on: Oct 31, 2016 * Author: pnorbert @@ -11,7 +11,9 @@ #include <string> #include <vector> -#include "ADIOS_OOP.h" +#include "ADIOS_CPP.h" + +using adiosFile = std::shared_ptr<adios::Engine>; struct MYDATA { @@ -26,23 +28,20 @@ MPI_Comm comm=MPI_COMM_WORLD; int rank, size; -void write_data (std::shared_ptr<adios::Engine> writer, struct MYDATA &data) +void write_data( adiosFile writer, struct MYDATA &data ) { writer->Write("NX", &data.NX); writer->Write("rank", &rank); writer->Write("size", &size); writer->Write("temperature", data.t); writer->Write("pressure", data.p.data()); - //writer->Flush(); + //writer->Flush(); AdvanceStep()??? } -void write_checkpoint (adios::ADIOS adios, struct MYDATA &solid, struct MYDATA &fluid) +void write_checkpoint( adiosFile ckptfile, const struct MYDATA &solid, const struct MYDATA &fluid ) { - try { - // Open an output for a Group - // a transport or an engine should be associated with the group - auto ckptfile = adios.Open("checkpoint.bp","w",comm,"checkpoint"); - + try + { ckptfile->Write ("solid/NX", &solid.NX); ckptfile->Write ("solid/rank", &rank); ckptfile->Write ("solid/size", &size); @@ -54,14 +53,14 @@ void write_checkpoint (adios::ADIOS adios, struct MYDATA &solid, struct MYDATA & ckptfile->Write ("fluid/size", &size); ckptfile->Write ("fluid/temperature", fluid.t); ckptfile->Write ("fluid/pressure", fluid.p.data()); + //ckptfile->AdvanceStep(); ?? - //ckptfile->Flush(); - ckptfile->Close(); // Should this do Write() if user misses or should we complain? } catch ( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking { if( rank == 0 ) { + std::cout << "ERROR: caught an exception from write_checkpoint\n"; std::cout << e.what() << "\n"; } } @@ -113,24 +112,29 @@ int main( int argc, char* argv [] ) MPI_Comm_size (comm, &size); solid.NX = N; - solid.t = new double(N); + solid.t = new double[N]; solid.p = std::vector<double>(N); fluid.NX = N; - fluid.t = new double(N); + fluid.t = new double[N]; fluid.p = std::vector<double>(N); try { // ADIOS manager object creation. MPI must be initialized - adios::ADIOS adios( "solidfluid.xml", comm, true ); + adios::ADIOS adios( comm, true ); + + adios::Method& fileSettings = adios.DeclareMethod( "Reusable" ); //default engine is BP writer + fileSettings.AddTransport( "POSIX", "have_metadata_file=no" ); // Open a file with a Method which has selected a group and a transport in the XML. // "a" will append to an already existing file, "w" would create a new file // Multiple writes to the same file work as append in this application run // FIXME: how do we support Update to same step? - auto solidfile = adios.Open("solid.bp", "a", comm, "solid"); + auto solidfile = adios.Open( "solid.bp", "w", comm, fileSettings ); + + // "solid" is a method but incidentally also a group // Constructor only creates an object and what is needed there but does not open a stream/file // It can be used to initialize a staging connection if not declared before @@ -143,30 +147,44 @@ int main( int argc, char* argv [] ) // "a" will append to an already existing file, "w" would create a new file // Multiple writes to the same file work as append in this application run // FIXME: how do we support Update to same step? - auto fluidfile = adios.Open("fluid.bp", "a", comm, "fluid"); + auto fluidfile = adios.Open("fluid.bp", "w", comm, fileSettings ); + + auto checkpointFile = adios.Open("checkpoint.bp", "w", comm, fileSettings ); //int ckptfile = adios.Open("checkpoint.bp", "checkpoint", "w", comm); // we do not open this here, but every time when needed in a function // Another output not associated with a single group, so that we can mix variables to it //adios:handle vizstream = adios.Open( "stream.bp", comm, "w", "STAGING", "options to staging method"); - auto vizstream = adios.Open("stream.bp", "w", comm, "groupless"); + auto vizstream = adios.Open("stream.bp", "w", comm, fileSettings ); // This creates an empty group inside, and we can write all kinds of variables to it //Get Monitor info std::ofstream logStream( "info_" + std::to_string(rank) + ".log" ); - adios.MonitorGroups( logStream ); + adios.MonitorVariables( logStream ); + + int checkPointSteps = 10; + for (int it = 1; it <= 100; it++) { compute (it, solid, fluid); - write_data(solidfile, solid); - write_data(fluidfile, fluid); + write_data( solidfile, solid ); + write_data( fluidfile, fluid ); + + if (it%checkPointSteps == 0) { + write_checkpoint( checkpointFile, solid, fluid ); - if (it%10 == 0) { - write_checkpoint (adios, solid, fluid); + MPI_Barrier( comm ); + if( rank == 0 ) + { + std::cout << "New checkpoint step, current = " << checkPointSteps << "\n"; + std::cin >> checkPointSteps; + MPI_Bcast( &checkPointSteps, 1, MPI_INT, 0, comm ); + } + MPI_Barrier( comm ); } write_viz(vizstream, solid, fluid); @@ -187,7 +205,7 @@ int main( int argc, char* argv [] ) { if( rank == 0 ) { - std::cout << "Error: " << e.what() << "\n"; + std::cout << "ERROR: " << e.what() << "\n"; } } diff --git a/examples/solidfluid/solidfluid_write_nompi.cpp b/examples/solidfluid/solidfluid_write_nompi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec450fd9a13337582f2c9e5f87c5394e0ec55b58 --- /dev/null +++ b/examples/solidfluid/solidfluid_write_nompi.cpp @@ -0,0 +1,217 @@ +/* + * solid fluid example + * + * Created on: Oct 31, 2016 + * Author: pnorbert + */ + +#include <stdexcept> +#include <iostream> +#include <fstream> +#include <string> +#include <vector> + +#include "ADIOS_CPP.h" + +using adiosFile = std::shared_ptr<adios::Engine>; + + +struct MYDATA { + int NX; + double *t; + std::vector<double> p; +}; + +const int N = 10; +struct MYDATA solid, fluid; +int rank = 0, size = 1; + + +void set_io_variables( adios::ADIOS& adios, const std::string process ) +{ + adios.DefineVariable<int>( process + "/NX" ); + adios.DefineVariable<int>( process + "/rank" ); + adios.DefineVariable<int>( process + "/size" ); + adios.DefineVariable<double>( process + "/temperature", adios::Dims{N} ); + adios.DefineVariable<double>( process + "/pressure", adios::Dims{N} ); +} + + +void write_data( adiosFile writer, const std::string process, struct MYDATA &data) +{ + writer->Write( process + "/NX", &data.NX); + writer->Write( process + "/rank", &rank); + writer->Write( process + "/size", &size); + writer->Write( process + "/temperature", data.t ); + writer->Write( process + "/pressure", data.p.data()); + //writer->Flush(); AdvanceStep()??? +} + + +void write_checkpoint( adiosFile ckptfile, const struct MYDATA &solid, const struct MYDATA &fluid ) +{ + try + { + ckptfile->Write ("solid/NX", &solid.NX); + ckptfile->Write ("solid/rank", &rank); + ckptfile->Write ("solid/size", &size); + ckptfile->Write ("solid/temperature", solid.t); + ckptfile->Write ("solid/pressure", &solid.p[0]); + + ckptfile->Write ("fluid/NX", &fluid.NX); + ckptfile->Write ("fluid/rank", &rank); + ckptfile->Write ("fluid/size", &size); + ckptfile->Write ("fluid/temperature", fluid.t); + ckptfile->Write ("fluid/pressure", fluid.p.data()); + //ckptfile->AdvanceStep(); ?? + + } + catch ( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + { + if( rank == 0 ) + { + std::cout << "ERROR: caught an exception from write_checkpoint\n"; + std::cout << e.what() << "\n"; + } + } +} + +void write_viz( adiosFile vizstream, struct MYDATA &solid, struct MYDATA &fluid ) +{ + // This stream is not associated with a group, so we must say for each write which group to use + // The output variable is re-defined inside as <groupname>/<varname>, unless given as third string argument + // An array variable's dimension definitions are also re-defined with dimensions <groupname>/<dimensionvar> + + //vizstream->Write ("solid", "NX", &solid.NX); + //vizstream->Write ("solid", "rank", &rank); + //vizstream->Write ("solid", "size", &size); + + // write solid group's temperature simply as temperature, risking overloading the 'temperature' variable when + // reading from a file + + //vizstream->Write ("solid", "temperature", "my/tempvarinfile", solid.t); + + //vizstream->Write ("fluid", "NX", &fluid.NX); + //vizstream->Write ("fluid", "rank", &rank); + //vizstream->Write ("fluid", "size", &size); + + //vizstream->Write ("fluid", "temperature", "temperature", fluid.t); + + //vizstream->Flush(); // flushes all data to disk; required operation + //vizstream.AdvanceStep(); +} + +void compute (int it, struct MYDATA &solid, struct MYDATA &fluid) +{ + for (int i = 0; i < solid.NX; i++) + { + solid.t[i] = it*100.0 + rank*solid.NX + i; + solid.p[i] = it*1000.0 + rank*solid.NX + i; + } + for (int i = 0; i < fluid.NX; i++) + { + fluid.t[i] = it*200.0 + rank*fluid.NX + i; + fluid.p[i] = it*2000.0 + rank*fluid.NX + i; + } +} + +int main( int argc, char* argv [] ) +{ + solid.NX = N; + solid.t = new double[N]; + solid.p = std::vector<double>(N); + + fluid.NX = N; + fluid.t = new double[N]; + fluid.p = std::vector<double>(N); + + try + { + // ADIOS manager object creation. MPI must be initialized + adios::ADIOS adios( true ); + set_io_variables( adios, "solid" ); + set_io_variables( adios, "fluid" ); + + adios::Method& fileSettings = adios.DeclareMethod( "Reusable" ); //default engine is BP writer + fileSettings.AddTransport( "POSIX", "have_metadata_file=no" ); + + // Open a file with a Method which has selected a group and a transport in the XML. + // "a" will append to an already existing file, "w" would create a new file + // Multiple writes to the same file work as append in this application run + // FIXME: how do we support Update to same step? + + auto solidfile = adios.Open( "solid.bp", "w", fileSettings ); + + + // "solid" is a method but incidentally also a group + // Constructor only creates an object and what is needed there but does not open a stream/file + // It can be used to initialize a staging connection if not declared before + // FIXME: which argument can be post-poned into Open() instead of constructor? + //solidfile.Open("solid.bp"); + + + // Open a file with a Method that has selected a group and an engine in the XML + // The transport method(s) are (must be) associated with the engines + // "a" will append to an already existing file, "w" would create a new file + // Multiple writes to the same file work as append in this application run + // FIXME: how do we support Update to same step? + auto fluidfile = adios.Open("fluid.bp", "w", fileSettings ); + + auto checkpointFile = adios.Open("checkpoint.bp", "w", fileSettings ); + + //int ckptfile = adios.Open("checkpoint.bp", "checkpoint", "w", comm); + // we do not open this here, but every time when needed in a function + + // Another output not associated with a single group, so that we can mix variables to it + //adios:handle vizstream = adios.Open( "stream.bp", comm, "w", "STAGING", "options to staging method"); + auto vizstream = adios.Open("stream.bp", "w", fileSettings ); + + // This creates an empty group inside, and we can write all kinds of variables to it + + //Get Monitor info + std::ofstream logStream( "info_nompi.log" ); + adios.MonitorVariables( logStream ); + + int checkPointSteps = 10; + + + for (int it = 1; it <= 100; it++) + { + compute (it, solid, fluid); + + write_data( solidfile, "solid", solid ); + write_data( fluidfile, "fluid", fluid ); + + if (it%checkPointSteps == 0) { + write_checkpoint( checkpointFile, solid, fluid ); + + { + std::cout << "New checkpoint step, current = " << checkPointSteps << "\n"; + std::cin >> checkPointSteps; + } + + } + + write_viz(vizstream, solid, fluid); + + std::cout << "Timestep " << it << " written\n"; + } + + solidfile->Close(); + fluidfile->Close(); + vizstream->Close(); + checkpointFile->Close(); + + // need barrier before we destroy the ADIOS object here automatically ...no! + std::cout << "Finalize adios\n"; + } + catch( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + { + std::cout << e.what() << "\n"; + } + + delete[] solid.t; + delete[] fluid.t; + + return 0; +} diff --git a/include/ADIOS.h b/include/ADIOS.h index 4df10d07c74171e5e5917c1dc32f7e5a13f07cb5..001334b700a30ddfb2ec300672faa5e5e72db962 100644 --- a/include/ADIOS.h +++ b/include/ADIOS.h @@ -23,14 +23,18 @@ #include "mpidummy.h" #endif -#include "core/Engine.h" -#include "core/Group.h" +#include "core/Transform.h" +#include "core/Variable.h" #include "core/Method.h" #include "core/Support.h" +#include "functions/adiosTemplates.h" namespace adios { + +class Engine; + /** * @brief Unique class interface between user application and ADIOS library */ @@ -40,7 +44,7 @@ class ADIOS public: // PUBLIC Constructors and Functions define the User Interface with ADIOS #ifdef HAVE_MPI - MPI_Comm m_MPIComm = NULL; ///< only used as reference to MPI communicator passed from parallel constructor, MPI_Comm is a pointer itself. Public as called from C + MPI_Comm m_MPIComm = MPI_COMM_NULL; ///< only used as reference to MPI communicator passed from parallel constructor, MPI_Comm is a pointer itself. Public as called from C #else MPI_Comm m_MPIComm = 0; ///< only used as reference to MPI communicator passed from parallel constructor, MPI_Comm is a pointer itself. Public as called from C #endif @@ -48,27 +52,43 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO int m_RankMPI = 0; ///< current MPI rank process int m_SizeMPI = 1; ///< current MPI processes size + std::string m_HostLanguage = "C++"; + + std::vector< Variable<char> > m_Char; ///< Key: variable name, Value: variable of type char + std::vector< Variable<unsigned char> > m_UChar; ///< Key: variable name, Value: variable of type unsigned char + std::vector< Variable<short> > m_Short; ///< Key: variable name, Value: variable of type short + std::vector< Variable<unsigned short> > m_UShort; ///< Key: variable name, Value: variable of type unsigned short + std::vector< Variable<int> > m_Int; ///< Key: variable name, Value: variable of type int + std::vector< Variable<unsigned int> > m_UInt; ///< Key: variable name, Value: variable of type unsigned int + std::vector< Variable<long int> > m_LInt; ///< Key: variable name, Value: variable of type long int + std::vector< Variable<unsigned long int> > m_ULInt; ///< Key: variable name, Value: variable of type unsigned long int + std::vector< Variable<long long int> > m_LLInt; ///< Key: variable name, Value: variable of type long long int + std::vector< Variable<unsigned long long int> > m_ULLInt; ///< Key: variable name, Value: variable of type unsigned long long int + std::vector< Variable<float> > m_Float; ///< Key: variable name, Value: variable of type float + std::vector< Variable<double> > m_Double; ///< Key: variable name, Value: variable of type double + std::vector< Variable<long double> > m_LDouble; ///< Key: variable name, Value: variable of type double + /** * @brief ADIOS empty constructor. Used for non XML config file API calls. */ - ADIOS( ); + ADIOS( const bool debugMode = false ); /** - * @brief Serial constructor for XML config file - * @param xmlConfigFile passed to m_XMLConfigFile + * @brief Serial constructor for config file + * @param configFileName passed to m_ConfigFile * @param debugMode true: on throws exceptions and do additional checks, false: off (faster, but unsafe) */ - ADIOS( const std::string xmlConfigFile, const bool debugMode = false ); + ADIOS( const std::string configFileName, const bool debugMode = false ); /** * @brief Parallel constructor for XML config file and MPI - * @param xmlConfigFile passed to m_XMLConfigFile + * @param configFileName passed to m_XMLConfigFile * @param mpiComm MPI communicator ...const to be discussed * @param debugMode true: on, false: off (faster, but unsafe) */ - ADIOS( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode = false ); + ADIOS( const std::string configFileName, const MPI_Comm mpiComm, const bool debugMode = false ); /** @@ -82,11 +102,23 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO ~ADIOS( ); ///< empty, using STL containers for memory management - /** - * Creates an empty group - * @param groupName - */ - Group& DeclareGroup( const std::string groupName ); + void InitMPI( ); ///< sets rank and size in m_rank and m_Size, respectively. + + + template<class T> inline + Variable<T>& DefineVariable( const std::string name, const Dims dimensions = Dims{1}, + const Dims globalDimensions = Dims( ), + const Dims globalOffsets = Dims() ) + { + //throw std::invalid_argument( "ERROR: type not supported for variable " + name + "\n" ); + } + + + template<class T> inline + Variable<T>& GetVariable( const std::string name ) + { + //throw std::invalid_argument( "ERROR: variable " + name + " and type don't match in call to GetVariable\n" ); + } /** @@ -147,38 +179,23 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode, const std::string methodName, const unsigned int cores = 1 ); - /** - * Close a particular stream and the corresponding transport - * @param streamName stream to be closed with all corresponding transports - * @param transportIndex identifier to a particular transport, if == -1 Closes all transports - */ - void Close( const unsigned int handler, const int transportIndex = -1 ); - - /** * @brief Dumps groups information to a file stream or standard output. * Note that either the user closes this fileStream or it's closed at the end. * @param logStream either std::cout standard output, or a std::ofstream file */ - void MonitorGroups( std::ostream& logStream ) const; + void MonitorVariables( std::ostream& logStream ); private: //no const to allow default empty and copy constructors - std::string m_XMLConfigFile; ///< XML File to be read containing configuration information - std::string m_HostLanguage = "C++"; ///< Supported languages: C, C++, Fortran, Python, etc. + std::string m_ConfigFile; ///< XML File to be read containing configuration information bool m_DebugMode = false; ///< if true will do more checks, exceptions, warnings, expect slower code - //GROUP - /** - * @brief List of groups defined from either ADIOS XML configuration file or the DeclareGroup function. - * <pre> - * Key: std::string unique group name - * Value: Group class - * </pre> - */ - std::map< std::string, Group > m_Groups; + //Variables + std::map< std::string, std::pair< std::string, unsigned int > > m_Variables; ///< Makes variable name unique, key: variable name, value: pair.first = type, pair.second = index in corresponding vector of Variable + std::vector< std::shared_ptr<Transform> > m_Transforms; ///< transforms associated with ADIOS run @@ -198,9 +215,16 @@ private: //no const to allow default empty and copy constructors * @param groupName unique name, passed for thrown exception only * @param hint adds information to thrown exception */ - void CheckGroup( std::map< std::string, Group >::const_iterator itGroup, - const std::string groupName, const std::string hint ) const; + void CheckVariableInput( const std::string name, const Dims& dimensions ) const; + /** + * Checks for variable name, if not found throws an invalid exception + * @param itVariable iterator pointing to the variable name in m_Variables + * @param name variable name + * @param hint message to be thrown for debugging purporses + */ + void CheckVariableName( std::map< std::string, std::pair< std::string, unsigned int > >::const_iterator itVariable, + const std::string name, const std::string hint ) const; /** * @brief Checks for method existence in m_Methods, if failed throws std::invalid_argument exception @@ -211,13 +235,215 @@ private: //no const to allow default empty and copy constructors void CheckMethod( std::map< std::string, Method >::const_iterator itMethod, const std::string methodName, const std::string hint ) const; + template< class T > + unsigned int GetVariableIndex( const std::string name ) + { + auto itVariable = m_Variables.find( name ); + CheckVariableName( itVariable, name, "in call to GetVariable<" + GetType<T>() + ">" ); + return itVariable->second.second; + } + }; +//template specializations of DefineVariable: +template<> inline +Variable<char>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_Char.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<char>(), m_Char.size()-1 ) ); + return m_Char.back(); +} -} //end namespace +template<> inline +Variable<unsigned char>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_UChar.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<unsigned char>(), m_UChar.size()-1 ) ); + return m_UChar.back(); +} + + +template<> inline +Variable<short>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_Short.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<unsigned char>(), m_Short.size()-1 ) ); + return m_Short.back(); +} + + +template<> inline +Variable<unsigned short>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_UShort.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<unsigned short>(), m_UShort.size()-1 ) ); + return m_UShort.back(); +} + + +template<> inline +Variable<int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_Int.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<int>(), m_Int.size()-1 ) ); + return m_Int.back(); +} + + +template<> inline +Variable<unsigned int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_UInt.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<unsigned int>(), m_UInt.size()-1 ) ); + return m_UInt.back(); +} +template<> inline +Variable<long int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_LInt.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<long int>(), m_LInt.size()-1 ) ); + return m_LInt.back(); +} + + +template<> inline +Variable<unsigned long int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_ULInt.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<unsigned long int>(), m_ULInt.size()-1 ) ); + return m_ULInt.back(); +} + + +template<> inline +Variable<long long int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_LLInt.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<long long int>(), m_LLInt.size()-1 ) ); + return m_LLInt.back(); +} + + +template<> inline +Variable<unsigned long long int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_ULLInt.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<unsigned long long int>(), m_ULLInt.size()-1 ) ); + return m_ULLInt.back(); +} + +template<> inline +Variable<float>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_Float.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<float>(), m_Float.size()-1 ) ); + return m_Float.back(); +} + + +template<> inline +Variable<double>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_Double.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<double>(), m_Double.size()-1 ) ); + return m_Double.back(); +} + + +template<> inline +Variable<long double>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets ) +{ + CheckVariableInput( name, dimensions ); + m_LDouble.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ); + m_Variables.emplace( name, std::make_pair( GetType<long double>(), m_LDouble.size()-1 ) ); + return m_LDouble.back(); +} + + +//Get template specialization +template<> inline +Variable<char>& ADIOS::GetVariable( const std::string name ) +{ return m_Char[ GetVariableIndex<char>(name) ]; } + +template<> inline +Variable<unsigned char>& ADIOS::GetVariable( const std::string name ) +{ return m_UChar[ GetVariableIndex<unsigned char>(name) ]; } + +template<> inline +Variable<short>& ADIOS::GetVariable( const std::string name ) +{ return m_Short[ GetVariableIndex<short>(name) ]; } + +template<> inline +Variable<unsigned short>& ADIOS::GetVariable( const std::string name ) +{ return m_UShort[ GetVariableIndex<unsigned short>(name) ]; } + +template<> inline +Variable<int>& ADIOS::GetVariable( const std::string name ) +{ return m_Int[ GetVariableIndex<int>(name) ]; } + +template<> inline +Variable<unsigned int>& ADIOS::GetVariable( const std::string name ) +{ return m_UInt[ GetVariableIndex<unsigned int>(name) ]; } + +template<> inline +Variable<long int>& ADIOS::GetVariable( const std::string name ) +{ return m_LInt[ GetVariableIndex<unsigned int>(name) ]; } + +template<> inline +Variable<unsigned long int>& ADIOS::GetVariable( const std::string name ) +{ return m_ULInt[ GetVariableIndex<unsigned long int>(name) ]; } + +template<> inline +Variable<long long int>& ADIOS::GetVariable( const std::string name ) +{ return m_LLInt[ GetVariableIndex<long long int>(name) ]; } + +template<> inline +Variable<unsigned long long int>& ADIOS::GetVariable( const std::string name ) +{ return m_ULLInt[ GetVariableIndex<unsigned long long int>(name) ]; } + +template<> inline +Variable<float>& ADIOS::GetVariable( const std::string name ) +{ return m_Float[ GetVariableIndex<float>(name) ]; } + +template<> inline +Variable<double>& ADIOS::GetVariable( const std::string name ) +{ return m_Double[ GetVariableIndex<double>(name) ]; } + +template<> inline +Variable<long double>& ADIOS::GetVariable( const std::string name ) +{ return m_LDouble[ GetVariableIndex<long double>(name) ]; } + + + +} //end namespace #endif /* ADIOS_H_ */ diff --git a/include/ADIOS_C.h b/include/ADIOS_C.h index efe9ed2865288befab52c5aef860ef42308ff75b..e9a20fe84b5cb29360ae7d6342941fcfbd0b5dae 100644 --- a/include/ADIOS_C.h +++ b/include/ADIOS_C.h @@ -19,7 +19,6 @@ typedef void ADIOS; -typedef void Group; typedef void Method; typedef void Engine; diff --git a/include/ADIOS_OOP.h b/include/ADIOS_CPP.h similarity index 65% rename from include/ADIOS_OOP.h rename to include/ADIOS_CPP.h index 0178a189f2c112843dbf9127220dad40bb3477ba..033de1873b91eecbaea946bc5e52b406a7ec4d6d 100644 --- a/include/ADIOS_OOP.h +++ b/include/ADIOS_CPP.h @@ -1,23 +1,23 @@ /* - * ADIOS_OOP.h + * ADIOS_CPP.h * * Created on: Jan 9, 2017 * Author: wfg */ -#ifndef ADIOS_OOP_H_ -#define ADIOS_OOP_H_ +#ifndef ADIOS_CPP_H_ +#define ADIOS_CPP_H_ #include "ADIOS.h" -#include "core/Group.h" #include "core/Method.h" #include "core/Engine.h" #include "engine/writer/Writer.h" +#include "engine/dataman/DataMan.h" #include "core/Transform.h" #include "transform/BZip2.h" -#endif /* ADIOS_OOP_H_ */ +#endif /* ADIOS_CPP_H_ */ diff --git a/include/capsule/Heap.h b/include/capsule/Heap.h index 739ec7ff857743b60fe7110feb0dd7c90529911e..5a1fa8d1966093e046b8b646eb6bd9c75cebaaef 100644 --- a/include/capsule/Heap.h +++ b/include/capsule/Heap.h @@ -8,6 +8,10 @@ #ifndef HEAP_H_ #define HEAP_H_ +/// \cond EXCLUDE_FROM_DOXYGEN +#include <vector> +/// \endcond + #include "core/Capsule.h" diff --git a/include/core/Capsule.h b/include/core/Capsule.h index d8c8bf459e7fc62c377edea93ea6f412b4dccfa3..e7b54b5558b021883bce7a89f7be03d840a9849a 100644 --- a/include/core/Capsule.h +++ b/include/core/Capsule.h @@ -8,7 +8,9 @@ #ifndef CAPSULE_H_ #define CAPSULE_H_ -#include "core/Variable.h" +/// \cond EXCLUDE_FROM_DOXYGEN +#include <string> +/// \endcond namespace adios @@ -37,10 +39,8 @@ public: * @param type derived class type * @param accessMode 'w':write, 'r':read, 'a':append * @param rankMPI current MPI rank - * @param cores if using threads */ - Capsule( const std::string type, const std::string accessMode, const int rankMPI, - const bool debugMode ); + Capsule( const std::string type, const std::string accessMode, const int rankMPI, const bool debugMode ); virtual ~Capsule( ); diff --git a/include/core/Engine.h b/include/core/Engine.h index 4543bf872ac27662712d83a7107c41669a19c103..2255cbf9db60cd5d4fe0b4b40cc2d7017e26c39f 100644 --- a/include/core/Engine.h +++ b/include/core/Engine.h @@ -23,8 +23,8 @@ #include "mpidummy.h" #endif +#include "ADIOS.h" #include "core/Method.h" -#include "core/Group.h" #include "core/Variable.h" #include "core/Transform.h" #include "core/Transport.h" @@ -43,7 +43,7 @@ class Engine public: #ifdef HAVE_MPI - MPI_Comm m_MPIComm = NULL; ///< only used as reference to MPI communicator passed from parallel constructor, MPI_Comm is a pointer itself. Public as called from C + MPI_Comm m_MPIComm = MPI_COMM_NULL; ///< only used as reference to MPI communicator passed from parallel constructor, MPI_Comm is a pointer itself. Public as called from C #else MPI_Comm m_MPIComm = 0; ///< only used as reference to MPI communicator passed from parallel constructor, MPI_Comm is a pointer itself. Public as called from C #endif @@ -52,76 +52,55 @@ public: const std::string m_Name; ///< name used for this engine const std::string m_AccessMode; ///< accessMode for buffers used by this engine const Method& m_Method; ///< associated method containing engine metadata - Group* m_Group = nullptr; ///< associated group to look for variable information int m_RankMPI = 0; ///< current MPI rank process int m_SizeMPI = 1; ///< current MPI processes size + const std::string m_HostLanguage = "C++"; + /** - * Unique constructor based on a method (engine metadata) - * @param engineType given by derived classes - * @param name engine name + * Unique constructor + * @param engineType + * @param name * @param accessMode * @param mpiComm * @param method + * @param debugMode + * @param cores + * @param endMessage */ - Engine( const std::string engineType, const std::string name, const std::string accessMode, - MPI_Comm mpiComm, const Method& method, const bool debugMode = false, const unsigned int cores = 1, - const std::string endMessage = "", const std::string hostLanguage = "C++" ); + Engine( ADIOS& adios, const std::string engineType, const std::string name, const std::string accessMode, + MPI_Comm mpiComm, const Method& method, const bool debugMode, const unsigned int cores, + const std::string endMessage ); virtual ~Engine( ); - void SetDefaultGroup( Group& group ); - /** * Write function that adds static checking on the variable to be passed by values * It then calls its corresponding derived class virtual function * This version uses m_Group to look for the variableName. - * @param variableName name of variable to the written - * @param values pointer passed from the application - */ - template< class T > - void Write( const Var variableName, const T* values ) - { - Write( variableName, values ); - } - - /** - * Write function that adds static checking on the variable to be passed by values. - * It then calls its corresponding derived class virtual function. - * This version accepts a group explicitly. - * @param group group object that contains the variable with variableName - * @param variableName name of variable to the written + * @param variable name of variable to the written * @param values pointer passed from the application */ template< class T > - void Write( Group& group, const Var variableName, const T* values ) + void Write( Variable<T>& variable, const T* values ) { - Write( group, variableName, values ); + Write( variable, values ); } - /** - * @brief Write functions can be overridden by derived classes. Base class behavior is to: - * 1) Write to Variable values (m_Values) in a group - * 2) Transform the data - * 3) Write to all capsules -> data and metadata - * @param group - * @param variableName - * @param values coming from user app - */ - virtual void Write( Group& group, const std::string variableName, const char* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const unsigned char* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const short* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const unsigned short* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const int* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const unsigned int* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const long int* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const unsigned long int* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const long long int* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const unsigned long long int* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const float* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const double* values ) = 0; - virtual void Write( Group& group, const std::string variableName, const long double* values ) = 0; + virtual void Write( Variable<char>& variable, const char* values ) = 0; + virtual void Write( Variable<unsigned char>& variable, const unsigned char* values ) = 0; + virtual void Write( Variable<short>& variable, const short* values ) = 0; + virtual void Write( Variable<unsigned short>& variable, const unsigned short* values ) = 0; + virtual void Write( Variable<int>& variable, const int* values ) = 0; + virtual void Write( Variable<unsigned int>& variable, const unsigned int* values ) = 0; + virtual void Write( Variable<long int>& variable, const long int* values ) = 0; + virtual void Write( Variable<unsigned long int>& variable, const unsigned long int* values ) = 0; + virtual void Write( Variable<long long int>& variable, const long long int* values ) = 0; + virtual void Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ) = 0; + virtual void Write( Variable<float>& variable, const float* values ) = 0; + virtual void Write( Variable<double>& variable, const double* values ) = 0; + virtual void Write( Variable<long double>& variable, const long double* values ) = 0; /** * @brief Write functions can be overridden by derived classes. Base class behavior is to: @@ -150,30 +129,18 @@ public: protected: - //std::vector< std::shared_ptr<Capsule> > m_Capsules; ///< managed Capsules might not be needed by certain engines + ADIOS& m_ADIOS; ///< reference to ADIOS object that creates this Engine at Open std::vector< std::shared_ptr<Transport> > m_Transports; ///< transports managed const bool m_DebugMode = false; ///< true: additional checks, false: by-pass checks unsigned int m_Cores = 1; const std::string m_EndMessage; ///< added to exceptions to improve debugging - const std::string m_HostLanguage = "C++"; ///< passed from ADIOS class to recognize language calling the ADIOS library - std::vector< std::pair<Group*, std::string> > m_WrittenVariables; + std::set<std::string> m_WrittenVariables; ///< contains the names of the variables that are being written virtual void Init( ); ///< Initialize m_Capsules and m_Transports, called from constructor virtual void InitCapsules( ); ///< Initialize transports from Method, called from Init in constructor. virtual void InitTransports( ); ///< Initialize transports from Method, called from Init in constructor. - /** - * Performs preliminary checks before writing a variable. Throws an exception if checks fail. - * Returns an index to variable type container in Group - * @param group variable group owner object - * @param variableName variable to be checked - * @param hint added information if exception is thrown - * @return index to variable in group type container - */ - unsigned int PreSetVariable( Group& group, const std::string variableName, - const std::string hint ); - /** * Used to verify parameters in m_Method containers * @param itParam iterator to a certain parameter @@ -186,8 +153,6 @@ protected: const std::string parameterName, const std::string hint ) const; - void CheckDefaultGroup( ) const; ///< checks if default group m_Group is nullptr, throws exception if trying to use - bool TransportNamesUniqueness( ) const; ///< checks if transport names are unique among the same types (file I/O) }; diff --git a/include/core/Group.h b/include/core/Group.h deleted file mode 100644 index 07dbcd3d56b1a9b00f2ec3b7e1bcd442cc5908af..0000000000000000000000000000000000000000 --- a/include/core/Group.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Group.h - * - * Created on: Oct 12, 2016 - * Author: wfg - */ - -#ifndef GROUP_H_ -#define GROUP_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <map> -#include <string> -#include <memory> //shared_pointer -#include <vector> -#include <ostream> -#include <set> -#include <initializer_list> //SetDimensions -/// \endcond - -#ifdef HAVE_MPI - #include <mpi.h> -#else - #include "mpidummy.h" -#endif - - -#include "core/Variable.h" -#include "core/Attribute.h" -#include "core/Transport.h" -#include "core/Transform.h" -#include "functions/adiosTemplates.h" - - -namespace adios -{ - -using Var = std::string; ///< used for returning variables from DefineVariable -using Dims = std::string; - -/** - * Class that defines each ADIOS Group composed of Variables, Attributes and GlobalBounds (if global variables exist) - */ -class Group -{ - friend class Engine; - -public: - - const std::string m_Name; - std::vector< std::pair< std::string, std::string > > m_GlobalBounds; ///< if a variable or an attribute is global it fills this container, from global-bounds in XML File, data in global space, pair.first = global dimensions, pair.second = global bounds - - std::vector< Variable<char> > m_Char; ///< Key: variable name, Value: variable of type char - std::vector< Variable<unsigned char> > m_UChar; ///< Key: variable name, Value: variable of type unsigned char - std::vector< Variable<short> > m_Short; ///< Key: variable name, Value: variable of type short - std::vector< Variable<unsigned short> > m_UShort; ///< Key: variable name, Value: variable of type unsigned short - std::vector< Variable<int> > m_Int; ///< Key: variable name, Value: variable of type int - std::vector< Variable<unsigned int> > m_UInt; ///< Key: variable name, Value: variable of type unsigned int - std::vector< Variable<long int> > m_LInt; ///< Key: variable name, Value: variable of type long int - std::vector< Variable<unsigned long int> > m_ULInt; ///< Key: variable name, Value: variable of type unsigned long int - std::vector< Variable<long long int> > m_LLInt; ///< Key: variable name, Value: variable of type long long int - std::vector< Variable<unsigned long long int> > m_ULLInt; ///< Key: variable name, Value: variable of type unsigned long long int - std::vector< Variable<float> > m_Float; ///< Key: variable name, Value: variable of type float - std::vector< Variable<double> > m_Double; ///< Key: variable name, Value: variable of type double - std::vector< Variable<long double> > m_LDouble; ///< Key: variable name, Value: variable of type double - - /** - * Empty constructor - */ - Group( ); - - /** - * Empty constructor - * @param debugMode true: additional checks throwing exceptions, false: skip checks - */ - Group( const std::string name, const bool debugMode = false ); - - /** - * @brief Constructor for XML config file - * @param hostLanguage reference from ADIOS class - * @param xmlGroup contains <adios-group (tag excluded)....</adios-group> single group definition from XML config file - * @param transforms passed from ADIOS.m_Transforms, single look up table for all transforms - * @param debugMode - */ - Group( const std::string name, const std::string& xmlGroup, std::vector< std::shared_ptr<Transform> >& transforms, const bool debugMode ); - - - ~Group( ); ///< Using STL containers, no deallocation - - - Dims SetDimensions( std::initializer_list<Var> variables ); ///< returns adios::Dims object from a list of existing adios::Var objects - - /** - * Define a new variable in the group object - * @param name variable name, must be unique in the group. If name exists it removes the current variable. In debug mode program will exit. - * @param type variable type, must be in SSupport::Datatypes[hostLanguage] in public/SSupport.h - * @param dimensionsCSV comma separated variable local dimensions (e.g. "Nx,Ny,Nz") - * @param globalDimensionsCSV comma separated variable global dimensions (e.g. "gNx,gNy,gNz"), if globalOffsetsCSV is also empty variable is local - * @param globalOffsetsCSV comma separated variable global dimensions (e.g. "gNx,gNy,gNz"), if globalOffsetsCSV is also empty variable is local - * @param transforms collection of Transform objects applied to this variable, sequence matters, default is empty - * @param parameters corresponding parameter used by a Transform object in transforms (index should match), default is empty - */ - Var DefineVariable( const std::string variableName, const std::string type, - const Dims dimensionsCSV = "1", - const Dims globalDimensionsCSV = "", const Dims globalOffsetsCSV = "", - const std::vector<Transform*> transforms = std::vector<Transform*>(), - const std::vector<int> parameters = std::vector<int>() ); - - - template< class T > - Var DefineVariable( const std::string variableName, - const Dims dimensionsCSV = "1", - const Dims globalDimensionsCSV = "", const Dims globalOffsetsCSV = "", - const std::vector<Transform*> transforms = std::vector<Transform*>(), - const std::vector<int> parameters = std::vector<int>() ) - { - return DefineVariable( variableName, GetType<T>(), dimensionsCSV, globalDimensionsCSV, globalOffsetsCSV, transforms, parameters ); - } - - /** - * Sets a variable transform contained in ADIOS Transforms (single container for all groups and variables) - * @param variableName variable to be assigned a transformation - * @param transform corresponding transform object, non-const as a pointer is created and pushed to a vector - * @param parameter optional parameter interpreted by the corresponding Transform, default = -1 - */ - void AddTransform( const Var variableName, Transform& transform, const int parameter = -1 ); - - /** - * Define a new attribute - * @param attributeName attribute name, must be unique. If name exists it removes the current variable. In debug mode program will exit. - * @param type attribute type string or numeric type - * @param value information about the attribute - */ - void DefineAttribute( const std::string attributeName, const std::string type, const std::string value ); - - /** - * @brief Dumps groups information to a file stream or standard output. - * Note that either the user closes this fileStream or it's closed at the end. - * @param logStream either std::cout standard output, or a std::ofstream file - */ - void Monitor( std::ostream& logStream ) const; - - /** - * Looks for variables defining a variable dimensions and return their actual values in a vector - * @param dimensionsCSV comma separated dimensions "Nx,Ny,Nz" - * @return actual vector values = { Nx, Ny, Nz } - */ - std::vector<unsigned long long int> GetDimensions( const Dims dimensionsCSV ) const; - -private: - - std::set<std::string> m_WrittenVariables; - - bool m_DebugMode = false; ///< if true will do more checks, exceptions, warnings, expect slower code, known at compile time - - std::map< std::string, std::pair< std::string, unsigned int > > m_Variables; ///< Makes variable name unique, key: variable name, value: pair.first = type, pair.second = index in corresponding vector of Variable - - /** - * @brief Contains all group attributes from SAttribute.h - * <pre> - * Key: std::string unique attribute name - * Value: SAttribute, plain-old-data struct - * </pre> - */ - std::map< std::string, Attribute > m_Attributes; - - /** - * Called from XML constructor - * @param xmlGroup contains <adios-group....</adios-group> single group definition from XML config file passing by reference as it could be big - */ - void ParseXMLGroup( const std::string& xmlGroup, std::vector< std::shared_ptr<Transform> >& transforms ); - - /** - * Used by SetVariable and SetAttribute to check if global bounds exist in m_GlobalBounds - * @param globalDimensionsCSV comma separated variables defining global dimensions (e.g. "Nx,NY,Nz") - * @param globalOffsetsCSV comma separated variables defining global offsets (e.g. "oNx,oNY,oNz") - * @return -1 if not global --> both inputs are empty, otherwise index in m_GlobalBounds if exist or create a new element in m_GlobalBounds; - */ - int SetGlobalBounds( const std::string globalDimensionsCSV, const std::string globalOffsetsCSV ) noexcept; - - /** - * Retrieves the value of a variable representing another's variable dimensions. Set with Write - * Must of integer type (from short to unsigned long long int) and positive. - * used by function GetDimensions - * @param variableName variable to be searched in m_SetVariables - * @return variable value - */ - unsigned long long int GetIntVariableValue( const std::string variableName ) const; - - /** - * Looks for variables assigned for dimensions in csv entry (local dimensions, global dimensions, or global offsets), and sets the bool flag IsDimension to true - * If m_DebugMode is true throws an exception if the variable is not found - * @param csv comma separated values string containing the dimension variables to look for - * @param hint message used if exceptions are thrown in debug mode to provide more context - */ - void SetDimensionVariablesFlag( const std::string csv, const std::string hint ); - -}; - - -} //end namespace - - -#endif /* GROUP_H_ */ diff --git a/include/core/Method.h b/include/core/Method.h index 0ead5672aa8460aee3726bdd84d996248e075892..1decbd7aac2511d23145e055d78393d4fbca8403 100644 --- a/include/core/Method.h +++ b/include/core/Method.h @@ -14,7 +14,6 @@ #include <map> /// \endcond -#include "core/Group.h" #include "functions/adiosFunctions.h" namespace adios @@ -32,7 +31,6 @@ public: const bool m_DebugMode = false; ///< true: on, throws exceptions and do additional checks, false: off, faster, but unsafe std::map<std::string, std::string> m_Parameters; ///< method parameters std::vector< std::map<std::string, std::string> > m_TransportParameters; ///< each is a separate Transport containing their own parameters - Group* m_Group = nullptr; ///< Set default group /** * Constructor @@ -40,14 +38,6 @@ public: */ Method( const std::string type, const bool debugMode = false ); - /** - * Constructor that accepts a group reference for access to a default group access - * @param type - * @param group - * @param debugMode - */ - Method( const std::string type, Group& group, const bool debugMode = false ); - ~Method( ); /** @@ -73,7 +63,6 @@ public: AddTransportParameters( type, parameters ); } - void SetDefaultGroup( Group& group ); private: diff --git a/include/core/Transform.h b/include/core/Transform.h index c78c7f18aa32f644fb5e3208431de4ea73d78be8..3c8a08451c82ec845dcbc72597713e0ed7422b82 100644 --- a/include/core/Transform.h +++ b/include/core/Transform.h @@ -26,7 +26,6 @@ class Transform public: - const std::string m_Method; /** diff --git a/include/core/Transport.h b/include/core/Transport.h index 781180699022a684d152f3a03c8ae04591e8370a..cb4d3ea08cc26bf5513a0c8932f160277f53e7a4 100644 --- a/include/core/Transport.h +++ b/include/core/Transport.h @@ -40,8 +40,8 @@ public: MPI_Comm m_MPIComm = 0; ///< only used as reference to MPI communicator passed from parallel constructor, MPI_Comm is a pointer itself. Public as called from C #endif - int m_MPIRank = 0; ///< current MPI rank process - int m_MPISize = 1; ///< current MPI processes size + int m_RankMPI = 0; ///< current MPI rank process + int m_SizeMPI = 1; ///< current MPI processes size /** * Base constructor that all derived classes pass diff --git a/include/core/Variable.h b/include/core/Variable.h index e226c62d81630ece598c3ed42e8b523cb5c47a28..24f54ef135a282efa27addc0239b777e1a3f67a9 100644 --- a/include/core/Variable.h +++ b/include/core/Variable.h @@ -11,33 +11,124 @@ /// \cond EXCLUDE_FROM_DOXYGEN #include <string> #include <vector> -#include <memory> +#include <map> +#include <ostream> //std::ostream in MonitorGroups /// \endcond #include "core/Transform.h" +#include "functions/adiosFunctions.h" +#include "functions/adiosTemplates.h" + namespace adios { + +using Dims = std::vector<size_t>; + +struct TransformData +{ + Transform& Operation; ///< pointer to transform object + std::map<std::string, std::string> Parameters; ///< transforms parameters + std::vector<std::size_t> Size; ///< vector that carries the sizes after a transformation is applied +}; + /** * @param Base (parent) class for template derived (child) class CVariable. Required to put CVariable objects in STL containers. */ template< class T > -struct Variable +class Variable { - std::string DimensionsCSV; ///< comma separated list for variables to search for local dimensions - const T* Values; ///< pointer to values passed from user in ADIOS Write, it might change in ADIOS Read - int GlobalBoundsIndex; ///< if global > 0, index corresponds to global-bounds in m_GlobalBounds in CGroup, if local then = -1 - std::vector< Transform* > Transforms; ///< associated transforms, sequence determines application order, e.g. first Transforms[0] then Transforms[1]. Pointer used as reference (no memory management). - std::vector< int > Parameters; ///< additional optional parameter understood by the corresponding Transform in Transforms vector +public: + + const std::string m_Name; ///< variable name + const std::string m_Type; ///< variable type + + Dims m_Dimensions; + std::string m_DimensionsCSV; ///< comma separated list for variables to search for local dimensions + + Dims m_GlobalDimensions; + std::string m_GlobalDimensionsCSV; ///< comma separated list for variables to search for global dimensions + + Dims m_GlobalOffsets; + std::string m_GlobalOffsetsCSV; ///< comma separated list for variables to search for global offsets + + const bool m_DebugMode = false; + + const T* m_AppValues = nullptr; ///< pointer to values passed from user in ADIOS Write, it might change in ADIOS Read + std::vector<T> m_Values; ///< Vector variable returned to user, might be used for zero-copy? + + bool m_IsScalar = false; + const bool m_IsDimension = false; + std::vector< TransformData > m_Transforms; ///< associated transforms, sequence determines application order, e.g. first Transforms[0] then Transforms[1]. Pointer used as reference (no memory management). + + Variable( const std::string name, const Dims dimensions, const Dims globalDimensions, const Dims globalOffsets, const bool debugMode ): + m_Name{ name }, + m_Type{ GetType<T>() }, + m_Dimensions{ dimensions }, + m_GlobalDimensions{ globalDimensions }, + m_GlobalOffsets{ globalOffsets }, + m_DebugMode{ debugMode } + { + if( m_Dimensions == Dims{1} ) + m_IsScalar = true; + } + + template< class ...Args> + void AddTransform( Transform& transform, Args... args ) + { + std::vector<std::string> parameters = { args... }; + m_Transforms.emplace_back( transform, BuildParametersMap( parameters, m_DebugMode ) ); //need to check + } + + + void Monitor( std::ostream& logInfo ) const noexcept + { + logInfo << "Variable: " << m_Name << "\n"; + logInfo << "Type: " << m_Type << "\n"; + logInfo << "Size: " << TotalSize() << " elements\n"; + logInfo << "Payload: " << PayLoadSize() << " bytes\n"; + + if( m_AppValues != nullptr ) + { + logInfo << "Values (first 10 or max_size): \n"; + std::size_t size = TotalSize(); + if( size > 10 ) + size = 10; + + for( std::size_t i = 0; i < size; ++i ) + { + logInfo << m_AppValues[i] << " "; + } + logInfo << " ..."; + } + + logInfo << "\n"; + } + + /** + * Returns the payload size in bytes + * @return TotalSize * sizeof(T) + */ + std::size_t PayLoadSize( ) const noexcept + { + return GetTotalSize( m_Dimensions ) * sizeof(T); + } + + /** + * Returns the total size + * @return number of elements + */ + std::size_t TotalSize( ) const noexcept + { + return GetTotalSize( m_Dimensions ); + } - bool IsDimension; ///< true: is used as a dimension in another variable (typically scalars), false: none }; } //end namespace - #endif /* VARIABLE_H_ */ diff --git a/include/engine/dataman/DataMan.h b/include/engine/dataman/DataMan.h index 94e1532f0cbe05fddd782bcfee22d7b51f420fa2..10d13a1201467145ec59bbc2c5fcc11f5fb1ca6c 100644 --- a/include/engine/dataman/DataMan.h +++ b/include/engine/dataman/DataMan.h @@ -8,6 +8,8 @@ #ifndef DATAMAN_H_ #define DATAMAN_H_ +#include <iostream> //must be removed +#include <unistd.h> //must be removed #include "core/Engine.h" #include "capsule/Heap.h" @@ -16,9 +18,6 @@ namespace adios { -namespace engine -{ - class DataMan : public Engine { @@ -34,25 +33,24 @@ public: * @param debugMode * @param hostLanguage */ - DataMan( const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const bool debugMode = false, const unsigned int cores = 1, - const std::string hostLanguage = "C++" ); + DataMan( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, + const Method& method, const bool debugMode = false, const unsigned int cores = 1 ); ~DataMan( ); - void Write( Group& group, const std::string variableName, const char* values ); - void Write( Group& group, const std::string variableName, const unsigned char* values ); - void Write( Group& group, const std::string variableName, const short* values ); - void Write( Group& group, const std::string variableName, const unsigned short* values ); - void Write( Group& group, const std::string variableName, const int* values ); - void Write( Group& group, const std::string variableName, const unsigned int* values ); - void Write( Group& group, const std::string variableName, const long int* values ); - void Write( Group& group, const std::string variableName, const unsigned long int* values ); - void Write( Group& group, const std::string variableName, const long long int* values ); - void Write( Group& group, const std::string variableName, const unsigned long long int* values ); - void Write( Group& group, const std::string variableName, const float* values ); - void Write( Group& group, const std::string variableName, const double* values ); - void Write( Group& group, const std::string variableName, const long double* values ); + void Write( Variable<char>& variable, const char* values ); + void Write( Variable<unsigned char>& variable, const unsigned char* values ); + void Write( Variable<short>& variable, const short* values ); + void Write( Variable<unsigned short>& variable, const unsigned short* values ); + void Write( Variable<int>& variable, const int* values ); + void Write( Variable<unsigned int>& variable, const unsigned int* values ); + void Write( Variable<long int>& variable, const long int* values ); + void Write( Variable<unsigned long int>& variable, const unsigned long int* values ); + void Write( Variable<long long int>& variable, const long long int* values ); + void Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ) ; + void Write( Variable<float>& variable, const float* values ); + void Write( Variable<double>& variable, const double* values ); + void Write( Variable<long double>& variable, const long double* values ); void Write( const std::string variableName, const char* values ); void Write( const std::string variableName, const unsigned char* values ); @@ -74,6 +72,7 @@ private: format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports void Init( ); ///< calls InitCapsules and InitTransports based on Method, called from constructor + void InitCapsules( ); void InitTransports( ); ///< from Transports /** @@ -84,10 +83,37 @@ private: */ std::string GetMdtmParameter( const std::string parameter, const std::map<std::string,std::string>& mdtmParameters ); + + template<class T> + void WriteVariable( Variable<T>& variable, const T* values ) + { + //here comes your magic at Writting now variable.m_UserValues has the data passed by the user + //set variable + variable.m_AppValues = values; + m_WrittenVariables.insert( variable.m_Name ); + + //This part will go away, this is just to monitor variables per rank + MPI_Barrier( m_MPIComm ); + + for( int i = 0; i < m_SizeMPI; ++i ) + { + if( i == m_RankMPI ) + { + std::cout << "Rank: " << m_RankMPI << "\n"; + variable.Monitor( std::cout ); + std::cout << std::endl; + } + else + { + sleep( 1 ); + } + } + MPI_Barrier( m_MPIComm ); + } + }; -} //end namespace engine } //end namespace adios diff --git a/include/engine/dataman/DataManTemplates.h b/include/engine/dataman/DataManTemplates.h deleted file mode 100644 index 2051dd5dfdc2fb5a785fac76bee52903e2ed193e..0000000000000000000000000000000000000000 --- a/include/engine/dataman/DataManTemplates.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * DataManTemplates.h - * - * Created on: Jan 18, 2017 - * Author: wfg - */ - -#ifndef DATAMANTEMPLATES_H_ -#define DATAMANTEMPLATES_H_ - -#include <vector> -#include <iostream> - - -#include "core/Group.h" -#include "core/Variable.h" -#include "capsule/Heap.h" -#include "core/Transport.h" -#include "format/BP1Writer.h" - - -namespace adios -{ - -/** - * - * @param group variable owner - * @param variableName string type - * @param variable - * @param buffer heap buffer to writer variables to for disk I/O - * @param transports - * @param bp1Writer - */ -template<class T> -void DataManWriteVariable( const Group& group, const Var variableName, Variable<T>& variable, - Heap& buffer, std::vector< std::shared_ptr<Transport> >& transports, - format::BP1Writer& bp1Writer ) - -{ - //here write your magic, this template replaces C MACROS - std::cout << "Hello from DataMan, writing variable " << variableName << " of typeid(T).name() = " << typeid(T).name() << "\n"; - if( variable.IsDimension ) - { - std::cout << "Which is a dimension variable\n"; - } -} - - - -} //end namespace - - - -#endif /* DATAMANTEMPLATES_H_ */ diff --git a/include/engine/vis/Vis.h b/include/engine/vis/Vis.h deleted file mode 100644 index ecdc2168883397980b5ae7c2931e9399a3b2955f..0000000000000000000000000000000000000000 --- a/include/engine/vis/Vis.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * DataMan.h - * - * Created on: Jan 10, 2017 - * Author: wfg - */ - -#ifndef VIS_H_ -#define VIS_H_ - - -#include "core/Engine.h" -#include "capsule/Heap.h" -#include "format/BP1Writer.h" - - -namespace adios -{ -namespace engine -{ - - -class Vis : public Engine -{ - -public: - - /** - * Constructor for single BP capsule engine, writes in BP format into a single heap capsule - * @param name unique name given to the engine - * @param accessMode "w" or "write", "r" or "read", "a" or "append" - * @param mpiComm communicator used for MPI operations - * @param method contains Engine metadata options provide by the user, Vis can make decisions based on these "knobs" - * @param debugMode true: handle exceptions, false: skip extra exceptions checks - * @param hostLanguage for Fortran users (due to array index), most of the time will be set with C++ - */ - Vis( const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const bool debugMode = false, const unsigned int cores = 1, - const std::string hostLanguage = "C++" ); - - ~Vis( ); - - void Write( Group& group, const std::string variableName, const char* values ); - void Write( Group& group, const std::string variableName, const unsigned char* values ); - void Write( Group& group, const std::string variableName, const short* values ); - void Write( Group& group, const std::string variableName, const unsigned short* values ); - void Write( Group& group, const std::string variableName, const int* values ); - void Write( Group& group, const std::string variableName, const unsigned int* values ); - void Write( Group& group, const std::string variableName, const long int* values ); - void Write( Group& group, const std::string variableName, const unsigned long int* values ); - void Write( Group& group, const std::string variableName, const long long int* values ); - void Write( Group& group, const std::string variableName, const unsigned long long int* values ); - void Write( Group& group, const std::string variableName, const float* values ); - void Write( Group& group, const std::string variableName, const double* values ); - void Write( Group& group, const std::string variableName, const long double* values ); - - void Write( const std::string variableName, const char* values ); - void Write( const std::string variableName, const unsigned char* values ); - void Write( const std::string variableName, const short* values ); - void Write( const std::string variableName, const unsigned short* values ); - void Write( const std::string variableName, const int* values ); - void Write( const std::string variableName, const unsigned int* values ); - void Write( const std::string variableName, const long int* values ); - void Write( const std::string variableName, const unsigned long int* values ); - void Write( const std::string variableName, const long long int* values ); - void Write( const std::string variableName, const unsigned long long int* values ); - void Write( const std::string variableName, const float* values ); - void Write( const std::string variableName, const double* values ); - void Write( const std::string variableName, const long double* values ); - - void Close( const int transportID = -1 ); - -private: - - std::vector< std::shared_ptr<Capsule> > m_Capsules; ///< it can be any derived class from Capsule: Heap, Shmem, RDMA ? - std::size_t m_MaxBufferSize; ///< maximum buffer size - float m_GrowthFactor = 1.5; ///< buffer growth factor if using a Heap capsule. New_size = f * Previous_size - - //optional if BP format is required - format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports - format::BP1MetadataSet m_MetadataSet; ///< metadata set accompanying the heap buffer data in bp format. Needed by m_BP1Writer - - void Init( ); ///< calls InitTransports based on Method and can extend other Init functions, called from constructor - void InitTransports( ); ///< from Transports - -}; - - -} //end namespace engine -} //end namespace adios - - - - - -#endif /* VIS_H_ */ diff --git a/include/engine/vis/VisTemplates.h b/include/engine/vis/VisTemplates.h deleted file mode 100644 index 0450bed88cc959e13cbdfb85b547e25883b6bee2..0000000000000000000000000000000000000000 --- a/include/engine/vis/VisTemplates.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * DataManTemplates.h - * - * Created on: Jan 18, 2017 - * Author: wfg - */ - -#ifndef VISTEMPLATES_H_ -#define VISTEMPLATES_H_ - -#include <vector> -#include <iostream> - - -#include "core/Group.h" -#include "core/Variable.h" -#include "capsule/Heap.h" -#include "core/Transport.h" -#include "format/BP1Writer.h" - - -namespace adios -{ - -template<class T> -void VisReadVariable( Transport& transport, const char* rawDataBuffer, const Var variableName ) -{ - //Here make decisions on what to do with a certain variable in a rawDataBuffer (BP Format?) -} - - -template<class T> -void VisReadVariables( Transport& transport, const char* rawDataBuffer, const std::vector<Var>& variableName ) -{ - //Here make decisions on what to do with many variables in a rawDataBuffer (BP Format?) -} - -template<class T> -void VisReadAllVariables( Transport& transport, const char* rawDataBuffer ) -{ - //Here make decisions on what to do with all variables in a rawDataBuffer (BP Format?) -} - - - -/** - * - * @param group variable owner - * @param variableName string type - * @param variable - * @param buffer heap buffer to writer variables to for disk I/O - * @param transports - * @param bp1Writer - */ -template<class T> -void VisWriteVariable( const Group& group, const Var variableName, Variable<T>& variable, - std::vector< std::shared_ptr<Capsule> >& capsules, - std::vector< std::shared_ptr<Transport> >& transports, - format::BP1Writer& bp1Writer, - const int rank ) - -{ - //here write your magic, this template replaces C MACROS in ADIOS 1.0 - std::cout << "Hello from Vis engine, writing variable " << variableName << " of typeid(T).name() = " << typeid(T).name() << "\n"; - if( variable.IsDimension ) - { - std::cout << "Which is a dimension variable\n"; - } - - auto localDimensions = group.GetDimensions( variable.DimensionsCSV ); - unsigned long long int totalDimensions = GetTotalSize( localDimensions ); - - std::cout << "Values: "; - for( unsigned int i = 0; i < totalDimensions; ++i ) - { - std::cout << variable.Values[i] << " "; - } - std::cout << "\nfrom RANK = " << rank << "\n\n"; - - - // This is just pseudo-code telling potential scenarios the engine can execute - //if( story = "simple task" ) - //{ - //Could be private functions -// RunSimpleTask( group, variableName, variable ); // e.g. Write to POSIX file -// - //} -// else if( story == "simple task + VisIt" ) -// { -// ///Could be private functions -// RunSimpleTask( group, variableName, variable ); // e.g. Write to POSIX file -// SendToVisIt( group, variableName, variable ); -// -// -// } -// else if( story == "Send to Service Flow Velocity and Potential" ) -// { - - -// if( m_IsPotentialWritten = true && m_IsVelocityWritten == true && m_IsSameGroup == true ) -// { -// SendToService( ); will send a buffer -// } -// else -// { -// if( variableName == "velocity" ) -// { -// -// WriteVariableToBuffer( group, variableName, variable, ... ); ///here -// m_WrittenVariables.push_back( std::make_pair( group, variableName ) ); // <Group*, variableName> keeps track of Written Variables -// m_IsVelocityWritten = true; -// } -// else if( variableName == "potential" ) -// { -// WriteVariableToBuffer( group, variableName, variable, ... ); ///here -// m_WrittenVariables.push_back( std::make_pair( group, variableName ) ); // <Group*, variableName> keeps track of Written Variables -// m_IsPotentialWritten = true; -// } -// } -// -// } -// -// -} - - -} //end namespace - - - -#endif /* VISTEMPLATES_H_ */ diff --git a/include/engine/writer/Writer.h b/include/engine/writer/Writer.h index ced2f65ef5232512ec66662a3f254b40fd0cd29e..8e9fc634b339a8f33c80b3f56a804408aaae94bb 100644 --- a/include/engine/writer/Writer.h +++ b/include/engine/writer/Writer.h @@ -1,5 +1,5 @@ /* - * SingleBP.h + * BPWriter.h * * Created on: Dec 16, 2016 * Author: wfg @@ -30,26 +30,24 @@ public: * @param method * @param debugMode */ - Writer( const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const bool debugMode = false, const unsigned int cores = 1, - const std::string hostLanguage = "C++" ); + Writer( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, + const Method& method, const bool debugMode = false, const unsigned int cores = 1 ); ~Writer( ); - - void Write( Group& group, const std::string variableName, const char* values ); - void Write( Group& group, const std::string variableName, const unsigned char* values ); - void Write( Group& group, const std::string variableName, const short* values ); - void Write( Group& group, const std::string variableName, const unsigned short* values ); - void Write( Group& group, const std::string variableName, const int* values ); - void Write( Group& group, const std::string variableName, const unsigned int* values ); - void Write( Group& group, const std::string variableName, const long int* values ); - void Write( Group& group, const std::string variableName, const unsigned long int* values ); - void Write( Group& group, const std::string variableName, const long long int* values ); - void Write( Group& group, const std::string variableName, const unsigned long long int* values ); - void Write( Group& group, const std::string variableName, const float* values ); - void Write( Group& group, const std::string variableName, const double* values ); - void Write( Group& group, const std::string variableName, const long double* values ); + void Write( Variable<char>& variable, const char* values ); + void Write( Variable<unsigned char>& variable, const unsigned char* values ); + void Write( Variable<short>& variable, const short* values ); + void Write( Variable<unsigned short>& variable, const unsigned short* values ); + void Write( Variable<int>& variable, const int* values ); + void Write( Variable<unsigned int>& variable, const unsigned int* values ); + void Write( Variable<long int>& variable, const long int* values ); + void Write( Variable<unsigned long int>& variable, const unsigned long int* values ); + void Write( Variable<long long int>& variable, const long long int* values ); + void Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ) ; + void Write( Variable<float>& variable, const float* values ); + void Write( Variable<double>& variable, const double* values ); + void Write( Variable<long double>& variable, const long double* values ); void Write( const std::string variableName, const char* values ); void Write( const std::string variableName, const unsigned char* values ); @@ -76,8 +74,13 @@ private: float m_GrowthFactor = 1.5; bool m_TransportFlush = false; ///< true: transport flush happened, buffer must be reset + void Init( ); void InitTransports( ); + void InitProcessGroup( ); + + + void WriteProcessGroupIndex( ); /** @@ -87,17 +90,20 @@ private: * @param variable */ template< class T > - void WriteVariable( const Group& group, const Var variableName, const Variable<T>& variable ) + void WriteVariable( Variable<T>& variable, const T* values ) { + //set variable + variable.m_AppValues = values; + m_WrittenVariables.insert( variable.m_Name ); //precalculate new metadata and payload sizes - const std::size_t indexSize = m_BP1Writer.GetVariableIndexSize( group, variableName, variable ); - const std::size_t payloadSize = GetTotalSize( group.GetDimensions( variable.DimensionsCSV ) ) * sizeof( T ); + const std::size_t indexSize = m_BP1Writer.GetVariableIndexSize( variable ); + const std::size_t payloadSize = variable.PayLoadSize(); //will change if compression is applied //Buffer reallocation, expensive part - m_TransportFlush = CheckBuffersAllocation( group, variableName, indexSize, payloadSize ); + m_TransportFlush = CheckBuffersAllocation( indexSize, payloadSize ); //WRITE INDEX to data buffer and metadata structure (in memory)// - m_BP1Writer.WriteVariableIndex( group, variableName, variable, m_Buffer, m_MetadataSet ); + m_BP1Writer.WriteVariableIndex( variable, m_Buffer, m_MetadataSet ); if( m_TransportFlush == true ) //in batches { @@ -110,8 +116,8 @@ private: } else //Write data to buffer { - //Values to Buffer -> Copy of data, Expensive part might want to use threads if large. Need a model to apply threading. - MemcpyThreads( m_Buffer.m_Data.data(), variable.Values, payloadSize, m_Cores ); + //EXPENSIVE part, might want to use threads if large. + MemcpyThreads( m_Buffer.m_Data.data(), variable.m_AppValues, payloadSize, m_Cores ); //update indices m_Buffer.m_DataPosition += payloadSize; m_Buffer.m_DataAbsolutePosition += payloadSize; @@ -120,13 +126,11 @@ private: /** * Check if heap buffers for data and metadata need reallocation or maximum sizes have been reached. - * @param group variable owner - * @param variableName name of the variable to be written * @param indexSize precalculated index size * @param payloadSize payload size from variable total size * @return true: transport must be flush and buffers reset, false: buffer is sufficient */ - bool CheckBuffersAllocation( const Group& group, const Var variableName, const std::size_t indexSize, const std::size_t payloadSize ); + bool CheckBuffersAllocation( const std::size_t indexSize, const std::size_t payloadSize ); }; diff --git a/include/format/BP1.h b/include/format/BP1.h index 02bcea1772c917145a85ed21a06156be1682d80f..b4139cd2f8e0804aa3fa91fbf8da43cb274a01d2 100644 --- a/include/format/BP1.h +++ b/include/format/BP1.h @@ -8,6 +8,9 @@ #ifndef BP1_H_ #define BP1_H_ + +#include <memory> //std::shared_ptr + #ifdef HAVE_MPI #include <mpi.h> #else @@ -16,7 +19,6 @@ #include "core/Transport.h" - namespace adios { namespace format @@ -27,6 +29,9 @@ namespace format */ struct BP1MetadataSet { + std::string TimeStepName; ///< time step name associated with this PG + std::uint32_t TimeStep = 0; ///< current time step, updated with advance step, if append it will be updated to last + std::uint64_t PGCount = 0; ///< number of process groups std::uint64_t PGLength = 0; ///< length in bytes of process groups std::size_t PGIndexPosition = 16; @@ -36,7 +41,6 @@ struct BP1MetadataSet std::uint64_t VarsLength = 0; ///< length in bytes of written Variables std::size_t VarsIndexPosition = 12; ///< initial position in bytes std::vector<char> VarsIndex = std::vector<char>( 102400 ); ///< metadata variable index, start with 1Kb - // std::map< std::string, std::pair<std::size_t,std::size_t> > VariablePositions; std::uint32_t AttributesCount = 0; ///< number of Attributes std::uint64_t AttributesLength = 0; ///< length in bytes of Attributes @@ -63,6 +67,48 @@ public: protected: + + /** + * method type for file I/O + */ + enum IO_METHOD { + METHOD_UNKNOWN = -2//!< ADIOS_METHOD_UNKNOWN + ,METHOD_NULL = -1 //!< ADIOS_METHOD_NULL + ,METHOD_MPI = 0 //!< METHOD_MPI + ,METHOD_DATATAP = 1 //OBSOLETE + ,METHOD_POSIX = 2 //!< METHOD_POSIX + ,METHOD_DATASPACES = 3 //!< METHOD_DATASPACES + ,METHOD_VTK = 4 //non-existent + ,METHOD_POSIX_ASCII = 5 //non-existent + ,METHOD_MPI_CIO = 6 //OBSOLETE + ,METHOD_PHDF5 = 7 //!< METHOD_PHDF5 + ,METHOD_PROVENANCE = 8 //OBSOLETE + ,METHOD_MPI_STRIPE = 9 //OBSOLETE + ,METHOD_MPI_LUSTRE = 10 //!< METHOD_MPI_LUSTRE + ,METHOD_MPI_STAGGER = 11 //OBSOLETE + ,METHOD_MPI_AGG = 12 //OBSOLETE + ,METHOD_ADAPTIVE = 13 //OBSOLETE + ,METHOD_POSIX1 = 14 //OBSOLETE + ,METHOD_NC4 = 15 //!< METHOD_NC4 + ,METHOD_MPI_AMR = 16 //!< METHOD_MPI_AMR + ,METHOD_MPI_AMR1 = 17 //OBSOLETE + ,METHOD_FLEXPATH = 18 //!< METHOD_FLEXPATH + ,METHOD_NSSI_STAGING = 19 //!< METHOD_NSSI_STAGING + ,METHOD_NSSI_FILTER = 20 //!< METHOD_NSSI_FILTER + ,METHOD_DIMES = 21 //!< METHOD_DIMES + ,METHOD_VAR_MERGE = 22 //!< METHOD_VAR_MERGE + ,METHOD_MPI_BGQ = 23 //!< METHOD_MPI_BGQ + ,METHOD_ICEE = 24 //!< METHOD_ICEE + ,METHOD_COUNT = 25 //!< METHOD_COUNT + ,METHOD_FSTREAM = 26 + ,METHOD_FILE = 27 + ,METHOD_ZMQ = 28 + ,METHOD_MDTM = 29 + + + }; + + /** * DataTypes mapping in BP Format */ @@ -122,9 +168,37 @@ protected: }; + /** + * Returns data type index from enum Datatypes + * @param variable input variable + * @return data type + */ + template< class T > inline std::int8_t GetDataType( ) const noexcept + { + return type_unknown; + } + + + std::vector<int> GetMethodIDs( const std::vector< std::shared_ptr<Transport> >& transports ) const noexcept; + }; +//Moving template BP1Writer::GetDataType template specializations outside of the class +template< > inline std::int8_t BP1::GetDataType<char>( ) const noexcept { return type_byte; } +template< > inline std::int8_t BP1::GetDataType<short>( ) const noexcept{ return type_short; } +template< > inline std::int8_t BP1::GetDataType<int>( ) const noexcept{ return type_integer; } +template< > inline std::int8_t BP1::GetDataType<long int>( ) const noexcept{ return type_long; } + +template< > inline std::int8_t BP1::GetDataType<unsigned char>( ) const noexcept { return type_unsigned_byte; } +template< > inline std::int8_t BP1::GetDataType<unsigned short>( ) const noexcept{ return type_unsigned_short; } +template< > inline std::int8_t BP1::GetDataType<unsigned int>( ) const noexcept{ return type_unsigned_integer; } +template< > inline std::int8_t BP1::GetDataType<unsigned long int>( ) const noexcept{ return type_unsigned_long; } + +template< > inline std::int8_t BP1::GetDataType<float>( ) const noexcept{ return type_real; } +template< > inline std::int8_t BP1::GetDataType<double>( ) const noexcept{ return type_double; } +template< > inline std::int8_t BP1::GetDataType<long double>( ) const noexcept{ return type_long_double; } + } //end namespace format diff --git a/include/format/BP1Writer.h b/include/format/BP1Writer.h index 425738d8a69aa74738040d3c3c4e6d626243926a..dd20dbc9695d4119e9dd3b566ca15243f8eccc88 100644 --- a/include/format/BP1Writer.h +++ b/include/format/BP1Writer.h @@ -18,7 +18,6 @@ #include "BP1.h" #include "core/Variable.h" -#include "core/Group.h" #include "core/Capsule.h" #include "capsule/Heap.h" #include "functions/adiosTemplates.h" @@ -40,35 +39,52 @@ public: unsigned int m_Cores = 1; ///< number of cores for thread operations in large array (min,max) unsigned int m_Verbosity = 0; ///< statistics verbosity, can change if redefined in Engine method. float m_GrowthFactor = 1.5; ///< memory growth factor, can change if redefined in Engine method. - unsigned int m_VariablesTotalCount = 0; /** - * Calculates the Process Index size in bytes according to the BP format - * @param name process group name - * @param timeStepName name of the corresponding time step - * @return size of process group index in bytes + * Calculates the Process Index size in bytes according to the BP format, including list of method with no parameters (for now) + * @param name + * @param timeStepName + * @param numberOfTransports + * @return size of pg index */ - std::size_t GetProcessIndexSize( const std::string name, const std::string timeStepName ); + std::size_t GetProcessGroupIndexSize( const std::string name, const std::string timeStepName, + const std::size_t numberOfTransports ) const noexcept; /** - * Writes a PGIndex, done at Open or aggregation + * Writes a process group index PGIndex and list of methods (from transports), done at Open or aggregation of new time step + * Version that operates on a single heap buffer and metadataset. * @param isFortran * @param name * @param processID * @param timeStepName * @param timeStep - * @param dataBuffers - * @param dataPositions - * @param dataAbsolutePositions - * @param metadataBuffers - * @param metadataPositions + * @param transports + * @param buffer + * @param metadataSet */ void WriteProcessGroupIndex( const bool isFortran, const std::string name, const unsigned int processID, const std::string timeStepName, const unsigned int timeStep, - std::vector<char*>& dataBuffers, std::vector<std::size_t>& dataPositions, - std::vector<std::size_t>& dataAbsolutePositions, - std::vector<char*>& metadataBuffers, - std::vector<std::size_t>& metadataPositions ); + const std::vector< std::shared_ptr<Transport> >& transports, + Heap& buffer, + BP1MetadataSet& metadataSet ) const noexcept; + /** + * Writes a process group index PGIndex and list of methods (from transports), done at Open or aggregation of new time step + * Version that operates on many capsules and metadatasets + * @param isFortran + * @param name + * @param processID + * @param timeStepName + * @param timeStep + * @param transports + * @param capsules + * @param metadataSets + */ + void WriteProcessGroupIndex( const bool isFortran, const std::string name, const unsigned int processID, + const std::string timeStepName, const unsigned int timeStep, + const std::vector< std::shared_ptr<Transport> >& transports, + std::vector< std::shared_ptr<Capsule> >& capsules, + std::vector<BP1MetadataSet>& metadataSets ) const noexcept; + /** * Returns the estimated variable index size @@ -79,16 +95,14 @@ public: * @return variable index size */ template< class T > - size_t GetVariableIndexSize( const Group& group, const std::string variableName, - const Variable<T> variable ) noexcept + size_t GetVariableIndexSize( const Variable<T>& variable ) const noexcept { //size_t indexSize = varEntryLength + memberID + lengthGroupName + groupName + lengthVariableName + lengthOfPath + path + datatype size_t indexSize = 23; //without characteristics - indexSize += group.m_Name.size(); - indexSize += variableName.size(); + indexSize += variable.m_Name.size(); // characteristics 3 and 4, check variable number of dimensions - const std::size_t dimensions = std::count( variable.DimensionsCSV.begin(), variable.DimensionsCSV.end(), ',' ) + 1; //number of commas in CSV + 1 + const std::size_t dimensions = variable.m_Dimensions.size(); //number of commas in CSV + 1 indexSize += 28 * dimensions; //28 bytes per dimension indexSize += 1; //id @@ -105,7 +119,7 @@ public: indexSize += sizeof(T); indexSize += 1; //id //must have an if here - indexSize += 2 + variableName.size(); + indexSize += 2 + variable.m_Name.size(); indexSize += 1; //id } @@ -130,8 +144,7 @@ public: * @param metadataSet */ template< class T > - void WriteVariableIndex( const Group& group, const Var variableName, const Variable<T>& variable, - Heap& buffer, BP1MetadataSet& metadataSet ) noexcept + void WriteVariableIndex( const Variable<T>& variable, Heap& buffer, BP1MetadataSet& metadataSet ) const noexcept { // adapt this part to local variables std::vector<char*> dataBuffers{ buffer.m_Data.data() }; @@ -142,8 +155,8 @@ public: std::vector<std::size_t> metadataPositions{ metadataSet.VarsIndexPosition }; std::vector<unsigned int> variablesCount{ metadataSet.VarsCount }; - WriteVariableCommon( group, variableName, variable, dataBuffers, dataPositions, dataAbsolutePositions, - metadataBuffers, metadataPositions, variablesCount ); + WriteVariableIndexCommon( variable, dataBuffers, dataPositions, dataAbsolutePositions, + metadataBuffers, metadataPositions, variablesCount ); //update positions and varsCount originally passed by value buffer.m_DataPosition = dataPositions[0]; @@ -162,9 +175,9 @@ public: * @param metadataSets */ template< class T > - void WriteVariableIndex( const Group& group, const Var variableName, const Variable<T>& variable, + void WriteVariableIndex( const Variable<T>& variable, std::vector< std::shared_ptr<Capsule> >& capsules, - std::vector<BP1MetadataSet>& metadataSets ) noexcept + std::vector<BP1MetadataSet>& metadataSets ) const noexcept { // adapt this part to local variables std::vector<char*> metadataBuffers, dataBuffers; @@ -185,8 +198,8 @@ public: dataAbsolutePositions.push_back( capsule->m_DataAbsolutePosition ); } - WriteVariableCommon( group, variableName, variable, dataBuffers, dataPositions, dataAbsolutePositions, - metadataBuffers, metadataPositions, variablesCount ); + WriteVariableIndexCommon( variable, dataBuffers, dataPositions, dataAbsolutePositions, + metadataBuffers, metadataPositions, variablesCount ); //update positions and varsCount originally passed by value const unsigned int buffersSize = static_cast<unsigned int>( capsules.size() ); @@ -200,18 +213,49 @@ public: } } - void Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ); + void Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ) const; private: + /** + * Common function that Writes a process group index PGIndex, done at Open or aggregation of new time step. + * Called from public WriteProcessGroupIndex functions. + * @param isFortran true: using Fortran, false: other language + * @param name process group, usually the rank (maybe communicator?) + * @param processID processID, usually the rank + * @param timeStepName + * @param timeStep + * @param dataBuffers + * @param dataPositions + * @param dataAbsolutePositions + * @param metadataBuffers + * @param metadataPositions + */ + void WriteProcessGroupIndexCommon( const bool isFortran, const std::string name, const unsigned int processID, + const std::string timeStepName, const unsigned int timeStep, + const std::vector<int>& methodIDs, + std::vector<char*>& dataBuffers, std::vector<std::size_t>& dataPositions, + std::vector<std::size_t>& dataAbsolutePositions, + std::vector<char*>& metadataBuffers, + std::vector<std::size_t>& metadataPositions ) const noexcept; + /** + * + * @param variable + * @param dataBuffers + * @param dataPositions + * @param dataAbsolutePositions + * @param metadataBuffers + * @param metadataPositions + * @param variablesCount + */ template<class T> - void WriteVariableCommon( const Group& group, const Var variableName, const Variable<T>& variable, - std::vector<char*>& dataBuffers, std::vector<size_t>& dataPositions, - std::vector<size_t>& dataAbsolutePositions, - std::vector<char*>& metadataBuffers, std::vector<size_t>& metadataPositions, - std::vector<unsigned int> variablesCount ) + void WriteVariableIndexCommon( const Variable<T>& variable, + std::vector<char*>& dataBuffers, std::vector<size_t>& dataPositions, + std::vector<size_t>& dataAbsolutePositions, + std::vector<char*>& metadataBuffers, std::vector<size_t>& metadataPositions, + std::vector<unsigned int> variablesCount ) const noexcept { //capture initial positions const std::vector<std::size_t> metadataLengthPositions( metadataPositions ); @@ -222,14 +266,13 @@ private: //memberID MemcpyToBuffers( metadataBuffers, metadataPositions, variablesCount, 4 ); - //group name, only in metadata - const std::uint16_t lengthGroupName = group.m_Name.length(); - WriteNameRecord( group.m_Name, lengthGroupName, metadataBuffers, metadataPositions ); + //skipping 2 bytes for length of group name which is zero, only in metadata + MovePositions( 2, metadataPositions ); //length of var, will come at the end from this offset //variable name to metadata and data - const std::uint16_t lengthVariableName = variableName.length(); - WriteNameRecord( variableName, lengthVariableName, metadataBuffers, metadataPositions ); - WriteNameRecord( variableName, lengthVariableName, dataBuffers, dataPositions ); + const std::uint16_t lengthVariableName = variable.m_Name.length(); + WriteNameRecord( variable.m_Name, lengthVariableName, metadataBuffers, metadataPositions ); + WriteNameRecord( variable.m_Name, lengthVariableName, dataBuffers, dataPositions ); //skip path (jump 2 bytes, already set to zero) MovePositions( 2, metadataPositions ); //length of var, will come at the end from this offset @@ -251,7 +294,7 @@ private: std::uint8_t characteristicsCounter = 0; //used for characteristics count, characteristics length will be calculated at the end //DIMENSIONS CHARACTERISTIC - const std::vector<unsigned long long int> localDimensions = group.GetDimensions( variable.DimensionsCSV ); + const std::vector<size_t>& localDimensions = variable.m_Dimensions; //write to metadata characteristic //characteristic: dimension @@ -263,13 +306,13 @@ private: MemcpyToBuffers( metadataBuffers, metadataPositions, &dimensionsLength, 2 ); //write in data if it's a dimension variable (scalar) y or n - const char dimensionYorN = ( variable.IsDimension ) ? 'y' : 'n'; + const char dimensionYorN = ( variable.m_IsDimension ) ? 'y' : 'n'; MemcpyToBuffers( dataBuffers, dataPositions, &dimensionYorN, 1 ); MemcpyToBuffers( dataBuffers, dataPositions, &dimensions, 1 ); const std::uint16_t dimensionsLengthInData = dimensions * 27; //27 is from 9 bytes for each: var y/n + local, var y/n + global dimension, var y/n + global offset MemcpyToBuffers( dataBuffers, dataPositions, &dimensionsLengthInData, 2 ); - if( variable.GlobalBoundsIndex == -1 ) //local variable + if( variable.m_GlobalDimensions.empty() ) //local variable { WriteDimensionRecord( metadataBuffers, metadataPositions, localDimensions, 16 ); WriteDimensionRecord( dataBuffers, dataPositions, localDimensions, 18, true ); //not using memberID for now @@ -287,8 +330,8 @@ private: } else //global variable { - const std::vector<unsigned long long int> globalDimensions = group.GetDimensions( group.m_GlobalBounds[variable.GlobalBoundsIndex].first ); - const std::vector<unsigned long long int> globalOffsets = group.GetDimensions( group.m_GlobalBounds[variable.GlobalBoundsIndex].second ); + const std::vector<std::size_t>& globalDimensions = variable.m_GlobalDimensions; + const std::vector<std::size_t>& globalOffsets = variable.m_GlobalOffsets; WriteDimensionRecord( metadataBuffers, metadataPositions, localDimensions, globalDimensions, globalOffsets ); WriteDimensionRecord( dataBuffers, dataPositions, localDimensions, globalDimensions, globalOffsets, true ); @@ -308,32 +351,32 @@ private: //VALUE for SCALAR or STAT min, max for ARRAY //Value for scalar - if( variable.DimensionsCSV == "1" ) //scalar //just doing string scalars for now (by name), needs to be modified when user passes value + if( variable.m_IsScalar ) //scalar //just doing string scalars for now (by name), needs to be modified when user passes value { characteristicID = characteristic_value; - const std::int16_t lengthOfName = variableName.length(); + const std::int16_t lengthOfName = variable.m_Name.length(); //metadata MemcpyToBuffers( metadataBuffers, metadataPositions, &characteristicID, 1 ); - WriteNameRecord( variableName, lengthOfName, metadataBuffers, metadataPositions ); + WriteNameRecord( variable.m_Name, lengthOfName, metadataBuffers, metadataPositions ); //data MemcpyToBuffers( dataBuffers, dataPositions, &characteristicID, 1 ); const std::int16_t lengthOfCharacteristic = 2 + lengthOfName; MemcpyToBuffers( dataBuffers, dataPositions, &lengthOfCharacteristic, 2 ); //added in data - WriteNameRecord( variableName, lengthOfName, dataBuffers, dataPositions ); + WriteNameRecord( variable.m_Name, lengthOfName, dataBuffers, dataPositions ); } else // Stat -> Min, Max for arrays, { if( m_Verbosity == 0 ) //default verbose { //Get min and max - const std::size_t valuesSize = GetTotalSize( localDimensions ); + const std::size_t valuesSize = variable.TotalSize(); T min, max; if( valuesSize >= 10000000 ) //ten million? this needs actual results //here we can make decisions for threads based on valuesSize - GetMinMax( variable.Values, valuesSize, min, max, m_Cores ); //here we can add cores from constructor + GetMinMax( variable.m_AppValues, valuesSize, min, max, m_Cores ); //here we can add cores from constructor else - GetMinMax( variable.Values, valuesSize, min, max ); + GetMinMax( variable.m_AppValues, valuesSize, min, max ); //set characteristic ids for min and max characteristicID = characteristic_stat; @@ -380,8 +423,6 @@ private: MemcpyToBuffers( metadataBuffers, metadataCharacteristicsCountPositions, &characteristicsCounter, 1 ); MemcpyToBuffers( metadataBuffers, metadataCharacteristicsCountPositions, metadataCharacteristicsLengths, 4 ); //vector to vector MovePositions( -5, metadataCharacteristicsCountPositions ); //back to original position - - ++m_VariablesTotalCount; } //end of function @@ -393,7 +434,7 @@ private: * @param positions to be moved */ void WriteNameRecord( const std::string name, const std::uint16_t length, - std::vector<char*>& buffers, std::vector<std::size_t>& positions ); + std::vector<char*>& buffers, std::vector<std::size_t>& positions ) const noexcept; /** * Write a dimension record for a global variable used by WriteVariableCommon @@ -405,10 +446,10 @@ private: * @param addType true: for data buffers, false: for metadata buffer and data characteristic */ void WriteDimensionRecord( std::vector<char*>& buffers, std::vector<std::size_t>& positions, - const std::vector<unsigned long long int>& localDimensions, - const std::vector<unsigned long long int>& globalDimensions, - const std::vector<unsigned long long int>& globalOffsets, - const bool addType = false ); + const std::vector<std::size_t>& localDimensions, + const std::vector<std::size_t>& globalDimensions, + const std::vector<std::size_t>& globalOffsets, + const bool addType = false ) const noexcept; /** * Write a dimension record for a local variable used by WriteVariableCommon @@ -419,9 +460,9 @@ private: * @param addType true: for data buffers, false: for metadata buffer and data characteristic */ void WriteDimensionRecord( std::vector<char*>& buffers, std::vector<std::size_t>& positions, - const std::vector<unsigned long long int>& localDimensions, + const std::vector<std::size_t>& localDimensions, const unsigned int skip, - const bool addType = false ); + const bool addType = false ) const noexcept; /** * @@ -434,7 +475,7 @@ private: template<class T> void WriteStatisticsRecord( const std::uint8_t& id, const T& value, std::vector<char*>& buffers, std::vector<std::size_t>& positions, - const bool addLength = false ) + const bool addLength = false ) const noexcept { const std::uint8_t characteristicID = characteristic_stat; MemcpyToBuffers( buffers, positions, &characteristicID, 1 ); @@ -449,36 +490,20 @@ private: MemcpyToBuffers( buffers, positions, &value, sizeof(T) ); } + /** - * Returns data type index from enum Datatypes - * @param variable input variable - * @return data type + * + * @param capsule + * @param transport */ - template< class T > inline std::int8_t GetDataType( ) noexcept { return type_unknown; } - - void CloseRankFile( Capsule& capsule, Transport& transport ); + void CloseRankFile( Capsule& capsule, Transport& transport ) const; - void SetMetadata( const BP1MetadataSet& metadataSet, Capsule& capsule ); ///< sets the metadata buffer in capsule with indices and minifooter - void SetMiniFooter( BP1MetadataSet& metadataSet ); ///< sets the minifooter + void SetMetadata( const BP1MetadataSet& metadataSet, Capsule& capsule ) const; ///< sets the metadata buffer in capsule with indices and minifooter + void SetMiniFooter( BP1MetadataSet& metadataSet ) const; ///< sets the minifooter }; -//Moving template BP1Writer::GetDataType template specializations outside of the class -template< > inline std::int8_t BP1Writer::GetDataType<char>( ) noexcept { return type_byte; } -template< > inline std::int8_t BP1Writer::GetDataType<short>( ) noexcept{ return type_short; } -template< > inline std::int8_t BP1Writer::GetDataType<int>( ) noexcept{ return type_integer; } -template< > inline std::int8_t BP1Writer::GetDataType<long int>( ) noexcept{ return type_long; } - -template< > inline std::int8_t BP1Writer::GetDataType<unsigned char>( ) noexcept { return type_unsigned_byte; } -template< > inline std::int8_t BP1Writer::GetDataType<unsigned short>( ) noexcept{ return type_unsigned_short; } -template< > inline std::int8_t BP1Writer::GetDataType<unsigned int>( ) noexcept{ return type_unsigned_integer; } -template< > inline std::int8_t BP1Writer::GetDataType<unsigned long int>( ) noexcept{ return type_unsigned_long; } - -template< > inline std::int8_t BP1Writer::GetDataType<float>( ) noexcept{ return type_real; } -template< > inline std::int8_t BP1Writer::GetDataType<double>( ) noexcept{ return type_double; } -template< > inline std::int8_t BP1Writer::GetDataType<long double>( ) noexcept{ return type_long_double; } - } //end namespace format diff --git a/include/functions/adiosFunctions.h b/include/functions/adiosFunctions.h index f43a7f3c9b44e027164234e3e4880acc5d3a6cd8..017816a66b0ddd3674aff3b2a00ada2cebfb1e65 100644 --- a/include/functions/adiosFunctions.h +++ b/include/functions/adiosFunctions.h @@ -13,6 +13,7 @@ #include <vector> #include <map> #include <cstring> //std::size_t +#include <memory> //std::shared_ptr /// \endcond #ifdef HAVE_MPI @@ -21,9 +22,7 @@ #include "mpidummy.h" #endif - -#include "core/Group.h" - +#include "core/Transform.h" namespace adios { @@ -84,9 +83,9 @@ void GetPairsFromTag( const std::string& fileContent, const std::string tag, * @param transforms return the modified transforms vector if there are variables with transformations * @param groups passed returns the map of groups defined in fileContent */ -void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, - std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, - std::map< std::string, Group >& groups ); +//void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, +// std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, +// std::map< std::string, Group >& groups ); /** @@ -98,9 +97,9 @@ void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, * @param transforms return the modified transforms vector if there are variables with transformations * @param groups passed returns the map of groups defined in fileContent */ -void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode, - std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, - std::map< std::string, Group >& groups ); +//void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode, +// std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, +// std::map< std::string, Group >& groups ); /** @@ -108,7 +107,7 @@ void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const boo * @param dimensions input containing size on each dimension {Nx, Ny, Nz} * @return product of all dimensions Nx * Ny * Nz */ -unsigned long long int GetTotalSize( const std::vector<unsigned long long int>& dimensions ); +std::size_t GetTotalSize( const std::vector<size_t>& dimensions ); /** diff --git a/include/functions/adiosTemplates.h b/include/functions/adiosTemplates.h index 9c97f221523fcb182b0f0d2231089de75d2eaea4..96d0969a128adb4baf291b752f57dbb229fb1391 100644 --- a/include/functions/adiosTemplates.h +++ b/include/functions/adiosTemplates.h @@ -12,6 +12,7 @@ #include <cstring> //std::memcpy #include <vector> #include <thread> +#include <set> /// \endcond @@ -33,6 +34,8 @@ template<> inline std::string GetType<int>() noexcept { return "int"; } template<> inline std::string GetType<unsigned int>() noexcept { return "unsigned int"; } template<> inline std::string GetType<long int>() noexcept { return "long int"; } template<> inline std::string GetType<unsigned long int>() noexcept { return "unsigned long int"; } +template<> inline std::string GetType<long long int>() noexcept { return "long long int"; } +template<> inline std::string GetType<unsigned long long int>() noexcept { return "unsigned long long int"; } template<> inline std::string GetType<float>() noexcept { return "float"; } template<> inline std::string GetType<double>() noexcept { return "double"; } template<> inline std::string GetType<long double>() noexcept { return "long double"; } @@ -100,9 +103,9 @@ void MemcpyThreads( T* destination, const U* source, std::size_t count, const un return; } - const unsigned long long int stride = count/cores; - const unsigned long long int remainder = count % cores; - const unsigned long long int last = stride + remainder; + const std::size_t stride = count/cores; + const std::size_t remainder = count % cores; + const std::size_t last = stride + remainder; std::vector<std::thread> memcpyThreads; memcpyThreads.reserve( cores ); diff --git a/src/ADIOS.cpp b/src/ADIOS.cpp index e522a976ce03e4772de2cac69ea034a97c6142bf..a5fd9a0f096c3cc7e50acb4c98e483c00ad2e478 100644 --- a/src/ADIOS.cpp +++ b/src/ADIOS.cpp @@ -18,36 +18,36 @@ //Engines #include "engine/writer/Writer.h" #include "engine/dataman/DataMan.h" -#include "engine/vis/Vis.h" +//#include "engine/vis/Vis.h" namespace adios { -ADIOS::ADIOS( ) +ADIOS::ADIOS( const bool debugMode ): + m_DebugMode{ debugMode } { - MPI_Comm_rank( m_MPIComm, &m_RankMPI ); - MPI_Comm_size( m_MPIComm, &m_SizeMPI ); + InitMPI( ); } -ADIOS::ADIOS( const std::string xmlConfigFile, const bool debugMode ): - m_XMLConfigFile{ xmlConfigFile }, +ADIOS::ADIOS( const std::string configFileName, const bool debugMode ): + m_ConfigFile{ configFileName }, m_DebugMode{ debugMode } { - InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage, m_Transforms, m_Groups ); + InitMPI( ); + // InitXML( m_ConfigFile, m_MPIComm, m_DebugMode, m_Transforms ); } ADIOS::ADIOS( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode ): m_MPIComm{ mpiComm }, - m_XMLConfigFile{ xmlConfigFile }, + m_ConfigFile{ xmlConfigFile }, m_DebugMode{ debugMode } { - MPI_Comm_rank( m_MPIComm, &m_RankMPI ); - MPI_Comm_size( m_MPIComm, &m_SizeMPI ); - InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage, m_Transforms, m_Groups ); + InitMPI( ); + //InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage, m_Transforms, m_Groups ); } @@ -55,8 +55,7 @@ ADIOS::ADIOS( const MPI_Comm mpiComm, const bool debugMode ): m_MPIComm{ mpiComm }, m_DebugMode{ debugMode } { - MPI_Comm_rank( m_MPIComm, &m_RankMPI ); - MPI_Comm_size( m_MPIComm, &m_SizeMPI ); + InitMPI( ); } @@ -64,16 +63,10 @@ ADIOS::~ADIOS( ) { } -Group& ADIOS::DeclareGroup( const std::string groupName ) +void ADIOS::InitMPI( ) { - if( m_DebugMode == true ) - { - if( m_Groups.count( groupName ) == 1 ) - throw std::invalid_argument( "ERROR: group " + groupName + " already exist, from call to DeclareGroup\n" ); - } - - m_Groups.emplace( groupName, Group( groupName, m_DebugMode ) ); - return m_Groups.at( groupName ); + MPI_Comm_rank( m_MPIComm, &m_RankMPI ); + MPI_Comm_size( m_MPIComm, &m_SizeMPI ); } @@ -103,7 +96,7 @@ std::shared_ptr<Engine> ADIOS::Open( const std::string name, const std::string a if( type == "Writer" || type == "writer" ) { - return std::make_shared<Writer>( name, accessMode, mpiComm, method, m_DebugMode, cores, m_HostLanguage ); + return std::make_shared<Writer>( *this, name, accessMode, mpiComm, method, m_DebugMode, cores ); } else if( type == "SIRIUS" || type == "sirius" || type == "Sirius" ) { @@ -112,11 +105,11 @@ std::shared_ptr<Engine> ADIOS::Open( const std::string name, const std::string a } else if( type == "DataMan" ) { - return std::make_shared<engine::DataMan>( name, accessMode, mpiComm, method, m_DebugMode, cores, m_HostLanguage ); + return std::make_shared<DataMan>( *this, name, accessMode, mpiComm, method, m_DebugMode, cores ); } else if( type == "Vis" ) { - return std::make_shared<engine::Vis>( name, accessMode, mpiComm, method, m_DebugMode, cores, m_HostLanguage ); + //return std::make_shared<Vis>( *this, name, accessMode, mpiComm, method, m_DebugMode, cores ); } else { @@ -156,22 +149,79 @@ std::shared_ptr<Engine> ADIOS::Open( const std::string name, const std::string a } -void ADIOS::MonitorGroups( std::ostream& logStream ) const +void ADIOS::MonitorVariables( std::ostream& logStream ) { - for( auto& groupPair : m_Groups ) + logStream << "\tVariable \t Type\n"; + + for( auto& variablePair : m_Variables ) { - logStream << "Group:..." << groupPair.first << "\n"; - groupPair.second.Monitor( logStream ); + const std::string name( variablePair.first ); + const std::string type( variablePair.second.first ); + + if( type == GetType<char>() ) + GetVariable<char>( name ).Monitor( logStream ); + + else if( type == GetType<unsigned char>() ) + GetVariable<unsigned char>( name ).Monitor( logStream ); + + else if( type == GetType<short>() ) + GetVariable<short>( name ).Monitor( logStream ); + + else if( type == GetType<unsigned short>() ) + GetVariable<unsigned short>( name ).Monitor( logStream ); + + else if( type == GetType<int>() ) + GetVariable<int>( name ).Monitor( logStream ); + + else if( type == GetType<unsigned int>() ) + GetVariable<unsigned int>( name ).Monitor( logStream ); + + else if( type == GetType<long int>() ) + GetVariable<long int>( name ).Monitor( logStream ); + + else if( type == GetType<unsigned long int>() ) + GetVariable<unsigned long int>( name ).Monitor( logStream ); + + else if( type == GetType<long long int>() ) + GetVariable<long long int>( name ).Monitor( logStream ); + + else if( type == GetType<unsigned long long int>() ) + GetVariable<unsigned long long int>( name ).Monitor( logStream ); + + else if( type == GetType<float>() ) + GetVariable<float>( name ).Monitor( logStream ); + + else if( type == GetType<double>() ) + GetVariable<double>( name ).Monitor( logStream ); + + else if( type == GetType<long double>() ) + GetVariable<long double>( name ).Monitor( logStream ); } } //PRIVATE FUNCTIONS BELOW -void ADIOS::CheckGroup( std::map< std::string, Group >::const_iterator itGroup, - const std::string groupName, const std::string hint ) const +void ADIOS::CheckVariableInput( const std::string name, const Dims& dimensions ) const { - if( itGroup == m_Groups.end() ) - throw std::invalid_argument( "ERROR: group " + groupName + " not found " + hint + "\n" ); + if( m_DebugMode == true ) + { + if( m_Variables.count( name ) == 1 ) + throw std::invalid_argument( "ERROR: variable " + name + " already exists, in call to DefineVariable\n" ); + + if( dimensions.empty() == true ) + throw std::invalid_argument( "ERROR: variable " + name + " dimensions can't be empty, in call to DefineVariable\n" ); + } +} + + +void ADIOS::CheckVariableName( std::map< std::string, std::pair< std::string, unsigned int > >::const_iterator itVariable, + const std::string name, const std::string hint ) const +{ + if( m_DebugMode == true ) + { + if( itVariable == m_Variables.end() ) + throw std::invalid_argument( "ERROR: variable " + name + " does not exist " + hint + "\n" ); + } } diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 3c63ac8e8e9190a9085e2e7ade98a92132807d87..8e3dcb4ac1a5fa124b3bfdc29d11a9830622468a 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -15,20 +15,18 @@ namespace adios { -Engine::Engine( const std::string engineType, const std::string name, const std::string accessMode, - const MPI_Comm mpiComm, const Method& method, - const bool debugMode, const unsigned int cores, const std::string endMessage, - const std::string hostLanguage ): +Engine::Engine( ADIOS& adios, const std::string engineType, const std::string name, const std::string accessMode, + const MPI_Comm mpiComm, const Method& method, const bool debugMode, const unsigned int cores, + const std::string endMessage ): m_MPIComm{ mpiComm }, m_EngineType{ engineType }, m_Name{ name }, m_AccessMode{ accessMode }, m_Method{ method }, - m_Group{ method.m_Group }, + m_ADIOS{ adios }, m_DebugMode{ debugMode }, m_Cores{ cores }, - m_EndMessage{ endMessage }, - m_HostLanguage{ hostLanguage } + m_EndMessage{ endMessage } { MPI_Comm_rank( m_MPIComm, &m_RankMPI ); MPI_Comm_size( m_MPIComm, &m_SizeMPI ); @@ -38,30 +36,8 @@ Engine::Engine( const std::string engineType, const std::string name, const std: Engine::~Engine( ) { } -void Engine::SetDefaultGroup( Group& group ) -{ - m_Group = &group; -} - //PROTECTED -unsigned int Engine::PreSetVariable( Group& group, const std::string variableName, - const std::string hint ) -{ - auto itVariable = group.m_Variables.find( variableName ); - - if( m_DebugMode == true ) - { - if( itVariable == group.m_Variables.end() ) - throw std::invalid_argument( "ERROR: variable " + variableName + " doesn't exist " + hint + ".\n" ); - } - - group.m_WrittenVariables.insert( variableName ); // group tracks its own written variables for dimensions - m_WrittenVariables.push_back( std::make_pair( &group, variableName ) ); - const unsigned int index = itVariable->second.second; - return index; -} - void Engine::Close( int transportIndex ) { @@ -97,17 +73,6 @@ void Engine::CheckParameter( const std::map<std::string, std::string>::const_ite } - -void Engine::CheckDefaultGroup( ) const -{ - if( m_DebugMode == true ) - { - if( m_Group == nullptr ) - throw std::invalid_argument( "ERROR: default group in engine " + m_Name + " is nullptr, check Method\n" ); - } -} - - bool Engine::TransportNamesUniqueness( ) const { auto lf_CheckTransportsType = [&]( const std::set<std::string>& specificType ) -> bool diff --git a/src/core/Group.cpp b/src/core/Group.cpp deleted file mode 100644 index 003e5aa66592f2ded980cb9572420ce9f22c3354..0000000000000000000000000000000000000000 --- a/src/core/Group.cpp +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Group.cpp - * - * Created on: Oct 12, 2016 - * Author: wfg - */ - -/// \cond EXCLUDED_FROM_DOXYGEN -#include <algorithm> // std::find -#include <sstream> // std::istringstream -/// \endcond - - -#include "core/Group.h" -#include "core/Support.h" -#include "functions/adiosFunctions.h" - - -namespace adios -{ - -Group::Group( ) -{ } - - -Group::Group( const std::string name, const bool debugMode ): - m_Name{ name }, - m_DebugMode{ debugMode } -{ } - - -Group::Group( const std::string name, const std::string& xmlGroup, std::vector< std::shared_ptr<Transform> >& transforms, - const bool debugMode ): - m_Name{ name }, - m_DebugMode{ debugMode } -{ - ParseXMLGroup( xmlGroup, transforms ); -} - - -Group::~Group( ) -{ } - - -Dims Group::SetDimensions( std::initializer_list<Var> variableList ) -{ - if( m_DebugMode == true ) - { - if( variableList.size() == 0 ) - throw std::invalid_argument( "ERROR: variableList is empty, in call to SetDimensions\n" ); - } - - Dims dimensionsCSV; - for( const auto variable : variableList ) - { - if( m_DebugMode == true ) - { - if( variable.find(",") != variable.npos ) - throw std::invalid_argument( "ERROR: variable can't contain a comma character, in call to SetDimensions\n" ); - } - dimensionsCSV += variable + ","; - } - dimensionsCSV.pop_back(); //remove last comma - return dimensionsCSV; -} - - -Var Group::DefineVariable( const std::string variableName, const std::string type, - const Dims dimensionsCSV, - const Dims globalDimensionsCSV, const Dims globalOffsetsCSV, - std::vector<Transform*> transforms, std::vector<int> parameters ) -{ - auto lf_CheckDimensionVariables = [&]( const std::string csv, const std::string dimensionType, const std::string variableName ) - { - if( csv.empty() == false && csv != "1" ) //skip scalars - SetDimensionVariablesFlag( csv, " in " + dimensionType + " of variable " + variableName ); - }; - - //BODY OF FUNCTION - if( m_DebugMode == true ) - { - if( m_Variables.count( variableName ) == 1 ) - throw std::invalid_argument( "ERROR: variable " + variableName + " already exists, in call to DefineVariable\n" ); - - if( dimensionsCSV.empty() == true ) - throw std::invalid_argument( "ERROR: variable " + variableName + " dimensions can't be empty, in call to DefineVariable\n" ); - } - - //Check for dimension variables - lf_CheckDimensionVariables( dimensionsCSV, "local dimensions", variableName ); - lf_CheckDimensionVariables( globalDimensionsCSV, "global dimensions", variableName ); - lf_CheckDimensionVariables( globalOffsetsCSV, "global offsets", variableName ); - - const int globalBoundsIndex = SetGlobalBounds( globalDimensionsCSV, globalOffsetsCSV ); - - if( IsTypeAlias<char>( type, Support::DatatypesAliases ) == true ) - { - m_Char.push_back( Variable<char>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_Char.size()-1 ); - } - else if( IsTypeAlias<unsigned char>( type, Support::DatatypesAliases ) == true ) - { - m_UChar.push_back( Variable<unsigned char>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_UChar.size()-1 ); - } - else if( IsTypeAlias<short>( type, Support::DatatypesAliases ) == true ) - { - m_Short.push_back( Variable<short>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_Short.size()-1 ); - } - else if( IsTypeAlias<unsigned short>( type, Support::DatatypesAliases ) == true ) - { - m_UShort.push_back( Variable<unsigned short>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_UShort.size()-1 ); - } - else if( IsTypeAlias<int>( type, Support::DatatypesAliases ) == true ) - { - m_Int.push_back( Variable<int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_Int.size()-1 ); - } - else if( IsTypeAlias<unsigned int>( type, Support::DatatypesAliases ) == true ) - { - m_UInt.push_back( Variable<unsigned int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_UInt.size()-1 ); - } - else if( IsTypeAlias<long int>( type, Support::DatatypesAliases ) == true ) - { - m_LInt.push_back( Variable<long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_LInt.size()-1 ); - } - else if( IsTypeAlias<unsigned long int>( type, Support::DatatypesAliases ) == true ) - { - m_ULInt.push_back( Variable<unsigned long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_ULInt.size()-1 ); - } - else if( IsTypeAlias<long long int>( type, Support::DatatypesAliases ) == true ) - { - m_LLInt.push_back( Variable<long long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_LLInt.size()-1 ); - } - else if( IsTypeAlias<unsigned long long int>( type, Support::DatatypesAliases ) == true ) - { - m_ULLInt.push_back( Variable<unsigned long long int>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_ULLInt.size()-1 ); - } - else if( IsTypeAlias<float>( type, Support::DatatypesAliases ) == true ) - { - m_Float.push_back( Variable<float>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_Float.size()-1 ); - } - else if( IsTypeAlias<double>( type, Support::DatatypesAliases ) == true ) - { - m_Double.push_back( Variable<double>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_Double.size()-1 ); - } - else if( IsTypeAlias<long double>( type, Support::DatatypesAliases ) == true ) - { - m_LDouble.push_back( Variable<long double>{ dimensionsCSV, nullptr, globalBoundsIndex, transforms, parameters, false } ); - m_Variables[variableName] = std::make_pair( type, m_LDouble.size()-1 ); - } - else - { - if( m_DebugMode == true ) - throw std::invalid_argument( "ERROR: type " + type + " not supported, in call to DefineVariable.\n" ); - } - return variableName; -} - - -void Group::AddTransform( const std::string variableName, Transform& transform, const int parameter ) -{ - auto itVariable = m_Variables.find( variableName ); - - if( m_DebugMode == true ) - { - if( itVariable == m_Variables.end() ) //variable doesn't exists - throw std::invalid_argument( "ERROR: variable " + variableName + " doesn't exist, in call to SetTransform.\n" ); - } - - const std::string type( itVariable->second.first ); - const unsigned int index = itVariable->second.second; - - if( IsTypeAlias<char>( type, Support::DatatypesAliases ) == true ) - { - m_Char[index].Transforms.push_back( &transform ); - m_Char[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<unsigned char>( type, Support::DatatypesAliases ) == true ) - { - m_UChar[index].Transforms.push_back( &transform ); - m_UChar[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<short>( type, Support::DatatypesAliases ) == true ) - { - m_Short[index].Transforms.push_back( &transform ); - m_Short[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<unsigned short>( type, Support::DatatypesAliases ) == true ) - { - m_UShort[index].Transforms.push_back( &transform ); - m_UShort[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<int>( type, Support::DatatypesAliases ) == true ) - { - m_Int[index].Transforms.push_back( &transform ); - m_Int[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<unsigned int>( type, Support::DatatypesAliases ) == true ) - { - m_UInt[index].Transforms.push_back( &transform ); - m_UInt[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<long int>( type, Support::DatatypesAliases ) == true ) - { - m_LInt[index].Transforms.push_back( &transform ); - m_LInt[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<unsigned long int>( type, Support::DatatypesAliases ) == true ) - { - m_ULInt[index].Transforms.push_back( &transform ); - m_ULInt[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<unsigned long long int>( type, Support::DatatypesAliases ) == true ) - { - m_ULLInt[index].Transforms.push_back( &transform ); - m_ULLInt[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<float>( type, Support::DatatypesAliases ) == true ) - { - m_Float[index].Transforms.push_back( &transform ); - m_Float[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<double>( type, Support::DatatypesAliases ) == true ) - { - m_Double[index].Transforms.push_back( &transform ); - m_Double[index].Parameters.push_back( parameter ); - } - else if( IsTypeAlias<long double>( type, Support::DatatypesAliases ) == true ) - { - m_LDouble[index].Transforms.push_back( &transform ); - m_LDouble[index].Parameters.push_back( parameter ); - } -} - - -void Group::DefineAttribute( const std::string attributeName, const std::string type, const std::string value ) -{ - auto lf_GetTypeID = []( const std::string type, const bool debugMode ) -> const char - { - char typeID = '\0'; - - if( type == "string" ) - typeID = '0'; - else if( type == "numeric" ) - typeID = '1'; - else - { - if( debugMode == true ) - throw std::invalid_argument( "ERROR: type " + type + " must be string or numeric, " - "in call to DefineAttribute\n" ); - } - - return typeID; - }; - - - if( m_DebugMode == true ) - { - if( m_Attributes.count( attributeName ) == 0 ) //attribute doesn't exists - m_Attributes.emplace( attributeName, Attribute{ lf_GetTypeID( type, m_DebugMode ), value } ); - else //name is found - throw std::invalid_argument( "ERROR: attribute " + attributeName + " exists, NOT setting a new variable\n" ); - } - else - { - m_Attributes.emplace( attributeName, Attribute{ lf_GetTypeID( type, m_DebugMode ), value } ); - } -} - - -unsigned long long int Group::GetIntVariableValue( const std::string variableName ) const -{ - if( m_DebugMode == true ) - { - if( m_WrittenVariables.count( variableName ) == 0 ) - throw std::invalid_argument( "ERROR: variable value for " + variableName + " was not set with Write function\n" ); - } - - const std::string type( m_Variables.at( variableName ).first ); - const unsigned int index = m_Variables.at( variableName ).second; - long long int value = -1; - - if( IsTypeAlias<short>( type, Support::DatatypesAliases ) == true ) - value = *( m_Short[index].Values ); - - else if( IsTypeAlias<unsigned short>( type, Support::DatatypesAliases ) == true ) - value = *( m_UShort[index].Values ); - - else if( IsTypeAlias<int>( type, Support::DatatypesAliases ) == true ) - value = *( m_Int[index].Values ); - - else if( IsTypeAlias<unsigned int>( type, Support::DatatypesAliases ) == true ) - value = *( m_UInt[index].Values ); - - else if( IsTypeAlias<long int>( type, Support::DatatypesAliases ) == true ) - value = *( m_LInt[index].Values ); - - else if( IsTypeAlias<unsigned long int>( type, Support::DatatypesAliases ) == true ) - value = *( m_ULInt[index].Values ); - - else if( IsTypeAlias<long long int>( type, Support::DatatypesAliases ) == true ) - value = *( m_LLInt[index].Values ); - - else if( IsTypeAlias<unsigned long long int>( type, Support::DatatypesAliases ) == true ) - value = *( m_ULLInt[index].Values ); - - else - { - if( m_DebugMode == true ) - throw std::invalid_argument( "ERROR: variable " + variableName + " must be of integer type : short, int or associated type (long int, unsigned long int, etc.)\n" ); - } - - if( m_DebugMode == true ) - { - if( value <= 0 ) - throw std::invalid_argument( "ERROR: variable " + variableName + " must be >= 0 to represent a dimension\n" ); - } - - return value; -} - - -std::vector<unsigned long long int> Group::GetDimensions( const std::string dimensionsCSV ) const -{ - if( dimensionsCSV == "1" ) //scalar - { - return std::vector<unsigned long long int>{ 1 }; - } - - std::vector<unsigned long long int> dimensions; - - if( dimensionsCSV.find(',') == dimensionsCSV.npos ) //check if 1D - { - const std::string dimension( dimensionsCSV ); - dimensions.push_back( GetIntVariableValue( dimension ) ); - return dimensions; - } - - std::istringstream dimensionsSS( dimensionsCSV ); - std::string dimension; - while( std::getline( dimensionsSS, dimension, ',' ) ) //need to test - { - dimensions.push_back( GetIntVariableValue( dimension ) ); - } - - return dimensions; -} - - -void Group::Monitor( std::ostream& logStream ) const -{ - logStream << "\tVariable \t Type\n"; - for( const auto& variablePair : m_Variables ) - { - logStream << "\t" << variablePair.first << " \t " << variablePair.second.first << "\n"; - } - logStream << "\n"; - - logStream << "\tAttribute \t Type \t Value \n"; - for( const auto& attributePair : m_Attributes ) - { - logStream << "\t" << attributePair.first << " \t " << attributePair.second.TypeID << " \t " << attributePair.second.Value << "\n"; - } - logStream << "\n"; -} - - -//PRIVATE FUNCTIONS BELOW -void Group::ParseXMLGroup( const std::string& xmlGroup, std::vector< std::shared_ptr<Transform> >& transforms ) -{ - std::string::size_type currentPosition( 0 ); - std::string globalDimensionsCSV; //used to set variables - std::string globalOffsetsCSV; //used to set variables - - while( currentPosition != std::string::npos ) - { - //Get tag - std::string tag; - GetSubString( "<", ">", xmlGroup, tag, currentPosition ); - if( tag == "</adios-group>" ) break; //end of current group - - if( tag == "</global-bounds>" ) - { - globalDimensionsCSV.clear(); //used for variables - globalOffsetsCSV.clear(); //used for variables - } - - if( m_DebugMode == true ) - { - if( tag.size() < 2 ) - throw std::invalid_argument( "ERROR: wrong tag " + tag + " when reading group \n" ); //check < or <=) - } - tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > - - //Get pairs from tag - std::vector< std::pair<const std::string, const std::string> > pairs; - GetPairsFromTag( xmlGroup, tag, pairs ); - - //Check based on tagName - const std::string tagName( tag.substr( 0, tag.find_first_of(" \t\n\r") ) ); - - if( tagName == "var" ) //assign a Group variable - { - std::string name, type, dimensionsCSV("1"); - std::vector<std::string> transformNames; - - for( auto& pair : pairs ) //loop through all pairs - { - if( pair.first == "name" ) name = pair.second; - else if( pair.first == "type" ) type = pair.second; - else if( pair.first == "dimensions" ) dimensionsCSV = pair.second; - else if( pair.first == "transform" ) transformNames.push_back( pair.second ); - } - - if( transformNames.empty() == true ) //no transforms - { - DefineVariable( name, type, dimensionsCSV, globalDimensionsCSV, globalOffsetsCSV ); - } - else - { - std::vector<short> transformIndices; - std::vector<short> parameters; - SetTransformsHelper( transformNames, transforms, m_DebugMode, transformIndices, parameters ); - - for( unsigned short t = 0; t < transformIndices.size(); ++t ) - { - AddTransform( name, *transforms[t], parameters[t] ); - } - } - } - else if( tagName == "attribute" ) - { - std::string name, value, type; - for( auto& pair : pairs ) //loop through all pairs - { - if( pair.first == "name" ) name = pair.second; - else if( pair.first == "value" ) value = pair.second; - else if( pair.first == "type" ) type = pair.second; - } - DefineAttribute( name, type, value ); - } - else if( tagName == "global-bounds" ) - { - for( auto& pair : pairs ) //loop through all pairs - { - if( pair.first == "dimensions" ) - globalDimensionsCSV = pair.second; - else if( pair.first == "offsets" ) - globalOffsetsCSV = pair.second; - } - - if( m_DebugMode == true ) - { - if( globalDimensionsCSV.empty() ) - throw std::invalid_argument( "ERROR: dimensions missing in global-bounds tag\n"); - - if( globalOffsetsCSV.empty() ) - throw std::invalid_argument( "ERROR: offsets missing in global-bounds tag\n"); - } - } - } //end while loop -} - - -int Group::SetGlobalBounds( const std::string globalDimensionsCSV, const std::string globalOffsetsCSV ) noexcept -{ - if( globalDimensionsCSV.empty() || globalOffsetsCSV.empty() ) - return -1; - - int globalBoundsIndex = -1; - const auto globalBounds = std::make_pair( globalDimensionsCSV, globalOffsetsCSV ); - auto itGlobalBounds = std::find( m_GlobalBounds.begin(), m_GlobalBounds.end(), globalBounds ); - - if( itGlobalBounds != m_GlobalBounds.end() ) - { - globalBoundsIndex = std::distance( m_GlobalBounds.begin(), itGlobalBounds ); - } - else - { - m_GlobalBounds.push_back( globalBounds ); - globalBoundsIndex = m_GlobalBounds.size(); - } - - return globalBoundsIndex; -} - - -void Group::SetDimensionVariablesFlag( const std::string csv, const std::string hint ) -{ - auto lf_SetVariableFlag = [&]( const std::string variableName, const std::string hint, const bool debugMode ) - { - auto itVariable = m_Variables.find( variableName ); - if( debugMode == true ) - { - if( itVariable == m_Variables.end() ) - throw std::invalid_argument( "ERROR: dimension variable " + variableName + " not previously defined\n" ); - } - - const std::string type( itVariable->second.first ); - const unsigned int index = itVariable->second.second; - - if( IsTypeAlias<short>( type, Support::DatatypesAliases ) == true ) - m_Short[index].IsDimension = true; - - else if( IsTypeAlias<unsigned short>( type, Support::DatatypesAliases ) == true ) - m_UShort[index].IsDimension = true; - - else if( IsTypeAlias<int>( type, Support::DatatypesAliases ) == true ) - m_Int[index].IsDimension = true; - - else if( IsTypeAlias<unsigned int>( type, Support::DatatypesAliases ) == true ) - m_UInt[index].IsDimension = true; - - else if( IsTypeAlias<long int>( type, Support::DatatypesAliases ) == true ) - m_LInt[index].IsDimension = true; - - else if( IsTypeAlias<unsigned long int>( type, Support::DatatypesAliases ) == true ) - m_ULInt[index].IsDimension = true; - - else if( IsTypeAlias<long long int>( type, Support::DatatypesAliases ) == true ) - m_LLInt[index].IsDimension = true; - - else if( IsTypeAlias<unsigned long long int>( type, Support::DatatypesAliases ) == true ) - m_ULLInt[index].IsDimension = true; - - else - { - if( m_DebugMode == true ) - throw std::invalid_argument( "ERROR: dimension variable " + variableName + - " must be of integer type : short, int or associated type (long int, unsigned long int, etc.)" + hint + "\n" ); - } - }; - - //BODY of function starts here - if( m_DebugMode == true ) - { - if( csv.empty() ) - throw std::invalid_argument( "ERROR: csv dimensions string is empty " + hint + "\n"); - } - - auto pos = csv.find(","); - - if( pos == csv.npos ) //one dimensional csv is a variable - { - lf_SetVariableFlag( csv, hint, m_DebugMode ); - } - else - { - std::istringstream csvSS( csv ); - std::string dimensionVariable; - while( std::getline( csvSS, dimensionVariable, ',' ) ) //need to test - { - lf_SetVariableFlag( dimensionVariable, " from call to DeclareVariable ", m_DebugMode ); - } - } -} - - - -} //end namespace diff --git a/src/core/Method.cpp b/src/core/Method.cpp index 2b304cc63796f053fe6541b0dda8d2b20ef0ca68..de56042a0bd39581de5bc22a0c0544380f1a0091 100644 --- a/src/core/Method.cpp +++ b/src/core/Method.cpp @@ -20,13 +20,6 @@ Method::Method( const std::string type, const bool debugMode ): { } -Method::Method( const std::string type, Group& group, const bool debugMode ): - m_Type{ type }, - m_DebugMode{ debugMode }, - m_Group{ &group } -{ } - - Method::~Method( ) { } @@ -53,13 +46,6 @@ void Method::AddTransportParameters( const std::string type, const std::vector<s } -void Method::SetDefaultGroup( Group& group ) -{ - m_Group = &group; -} - - - } //end namespace diff --git a/src/core/Transport.cpp b/src/core/Transport.cpp index a40be2576327fefa4230177df14974da294547d8..1b5cec2861f2bfe84a679828bad1136f9a0c48c4 100644 --- a/src/core/Transport.cpp +++ b/src/core/Transport.cpp @@ -11,14 +11,13 @@ namespace adios { - Transport::Transport( const std::string type, MPI_Comm mpiComm, const bool debugMode ): m_Type{ type }, m_MPIComm{ mpiComm }, m_DebugMode{ debugMode } { - MPI_Comm_rank( m_MPIComm, &m_MPIRank ); - MPI_Comm_size( m_MPIComm, &m_MPISize ); + MPI_Comm_rank( m_MPIComm, &m_RankMPI ); + MPI_Comm_size( m_MPIComm, &m_SizeMPI ); } @@ -38,6 +37,5 @@ void Transport::Close( ) { } - } //end namespace diff --git a/src/engine/dataman/DataMan.cpp b/src/engine/dataman/DataMan.cpp index 844d9039e2bc2c55181ca2c6f3d84db2faf228b4..96212d60a7bc64866d1e861db7486ef03b8f99dc 100644 --- a/src/engine/dataman/DataMan.cpp +++ b/src/engine/dataman/DataMan.cpp @@ -9,7 +9,6 @@ #include "engine/dataman/DataMan.h" -#include "engine/dataman/DataManTemplates.h" #include "core/Support.h" #include "functions/adiosFunctions.h" //CSVToVector @@ -25,14 +24,10 @@ namespace adios { -namespace engine -{ -DataMan::DataMan( const std::string streamName, const std::string accessMode, const MPI_Comm mpiComm, - const Method& method, const bool debugMode, const unsigned int cores, - const std::string hostLanguage ): - Engine( "DataMan", streamName, accessMode, mpiComm, method, debugMode, cores, - " DataMan constructor (or call to ADIOS Open).\n", hostLanguage ), +DataMan::DataMan( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, + const Method& method, const bool debugMode, const unsigned int cores ): + Engine( adios, "DataMan", name, accessMode, mpiComm, method, debugMode, cores, " Dataman constructor (or call to ADIOS Open).\n" ), m_Buffer( accessMode, m_RankMPI, m_DebugMode ) { Init( ); @@ -50,198 +45,88 @@ void DataMan::Init( ) } -void DataMan::Write( Group& group, const std::string variableName, const char* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write char*" ); - Variable<char>& variable = group.m_Char[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} +void DataMan::Write( Variable<char>& variable, const char* values ) +{ WriteVariable( variable, values ); } +void DataMan::Write( Variable<unsigned char>& variable, const unsigned char* values ) +{ WriteVariable( variable, values ); } -void DataMan::Write( Group& group, const std::string variableName, const unsigned char* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned char*" ); - Variable<unsigned char>& variable = group.m_UChar[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} +void DataMan::Write( Variable<short>& variable, const short* values ) +{ WriteVariable( variable, values ); } +void DataMan::Write( Variable<unsigned short>& variable, const unsigned short* values ) +{ WriteVariable( variable, values ); } -void DataMan::Write( Group& group, const std::string variableName, const short* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write short*" ); - Variable<short>& variable = group.m_Short[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} +void DataMan::Write( Variable<int>& variable, const int* values ) +{ WriteVariable( variable, values ); } +void DataMan::Write( Variable<unsigned int>& variable, const unsigned int* values ) +{ WriteVariable( variable, values ); } -void DataMan::Write( Group& group, const std::string variableName, const unsigned short* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned short*" ); - Variable<unsigned short>& variable = group.m_UShort[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} +void DataMan::Write( Variable<long int>& variable, const long int* values ) +{ WriteVariable( variable, values ); } +void DataMan::Write( Variable<unsigned long int>& variable, const unsigned long int* values ) +{ WriteVariable( variable, values ); } -void DataMan::Write( Group& group, const std::string variableName, const int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write int*" ); - Variable<int>& variable = group.m_Int[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} - - -void DataMan::Write( Group& group, const std::string variableName, const unsigned int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned int*" ); - Variable<unsigned int>& variable = group.m_UInt[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} +void DataMan::Write( Variable<long long int>& variable, const long long int* values ) +{ WriteVariable( variable, values ); } +void DataMan::Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ) +{ WriteVariable( variable, values ); } -void DataMan::Write( Group& group, const std::string variableName, const long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long int*" ); - Variable<long int>& variable = group.m_LInt[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} - - -void DataMan::Write( Group& group, const std::string variableName, const unsigned long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned long int*" ); - Variable<unsigned long int>& variable = group.m_ULInt[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} - - -void DataMan::Write( Group& group, const std::string variableName, const long long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long long int*" ); - Variable<long long int>& variable = group.m_LLInt[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} - - -void DataMan::Write( Group& group, const std::string variableName, const unsigned long long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned long long int*" ); - Variable<unsigned long long int>& variable = group.m_ULLInt[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} - - -void DataMan::Write( Group& group, const std::string variableName, const float* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write float*" ); - Variable<float>& variable = group.m_Float[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} - -void DataMan::Write( Group& group, const std::string variableName, const double* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write double*" ); - Variable<double>& variable = group.m_Double[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} +void DataMan::Write( Variable<float>& variable, const float* values ) +{ WriteVariable( variable, values ); } +void DataMan::Write( Variable<double>& variable, const double* values ) +{ WriteVariable( variable, values ); } -void DataMan::Write( Group& group, const std::string variableName, const long double* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long double*" ); - Variable<long double>& variable = group.m_LDouble[index]; //must be a reference - variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); -} +void DataMan::Write( Variable<long double>& variable, const long double* values ) +{ WriteVariable( variable, values ); } -//USING Preset Group void DataMan::Write( const std::string variableName, const char* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<char>( variableName ), values ); } void DataMan::Write( const std::string variableName, const unsigned char* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<unsigned char>( variableName ), values ); } void DataMan::Write( const std::string variableName, const short* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<short>( variableName ), values ); } void DataMan::Write( const std::string variableName, const unsigned short* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<unsigned short>( variableName ), values ); } void DataMan::Write( const std::string variableName, const int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<int>( variableName ), values ); } void DataMan::Write( const std::string variableName, const unsigned int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<unsigned int>( variableName ), values ); } void DataMan::Write( const std::string variableName, const long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<long int>( variableName ), values ); } void DataMan::Write( const std::string variableName, const unsigned long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<unsigned long int>( variableName ), values ); } void DataMan::Write( const std::string variableName, const long long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<long long int>( variableName ), values ); } void DataMan::Write( const std::string variableName, const unsigned long long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<unsigned long long int>( variableName ), values ); } void DataMan::Write( const std::string variableName, const float* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<float>( variableName ), values ); } void DataMan::Write( const std::string variableName, const double* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<double>( variableName ), values ); } void DataMan::Write( const std::string variableName, const long double* values ) +{ WriteVariable( m_ADIOS.GetVariable<long double>( variableName ), values ); } + + +void DataMan::InitCapsules( ) { - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); + //here init memory capsules } @@ -249,7 +134,6 @@ void DataMan::InitTransports( ) //maybe move this? { TransportNamesUniqueness( ); - for( const auto& parameters : m_Method.m_TransportParameters ) { auto itTransport = parameters.find( "transport" ); @@ -327,8 +211,6 @@ std::string DataMan::GetMdtmParameter( const std::string parameter, const std::m } - -} //end namespace engine } //end namespace adios diff --git a/src/engine/vis/Vis.cpp b/src/engine/vis/Vis.cpp deleted file mode 100644 index 93bb598d1e4185c8e237281538b49e3562ac45e9..0000000000000000000000000000000000000000 --- a/src/engine/vis/Vis.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Vis.cpp - * - * Created on: Jan 10, 2017 - * Author: wfg - */ - -#include <iostream> - - -#include "engine/vis/Vis.h" -#include "engine/vis/VisTemplates.h" -#include "core/Support.h" -#include "functions/adiosFunctions.h" //CSVToVector - -//supported capsules -#include "capsule/Heap.h" -#include "capsule/ShmSystemV.h" - -//supported transports -#include "transport/POSIX.h" -#include "transport/FStream.h" -#include "transport/File.h" - - -namespace adios -{ -namespace engine -{ - -Vis::Vis( const std::string streamName, const std::string accessMode, const MPI_Comm mpiComm, - const Method& method, const bool debugMode, const unsigned int cores, - const std::string hostLanguage ): - Engine( "Vis", streamName, accessMode, mpiComm, method, debugMode, cores, - " Vis constructor (or call to ADIOS Open).\n", hostLanguage ) -{ - Init( ); -} - - -Vis::~Vis( ) -{ } - - -void Vis::Init( ) -{ - InitTransports( ); -} - - -void Vis::Write( Group& group, const std::string variableName, const char* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write char*" ); - Variable<char>& variable = group.m_Char[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const unsigned char* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned char*" ); - Variable<unsigned char>& variable = group.m_UChar[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const short* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write short*" ); - Variable<short>& variable = group.m_Short[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const unsigned short* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned short*" ); - Variable<unsigned short>& variable = group.m_UShort[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write int*" ); - Variable<int>& variable = group.m_Int[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const unsigned int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned int*" ); - Variable<unsigned int>& variable = group.m_UInt[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long int*" ); - Variable<long int>& variable = group.m_LInt[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const unsigned long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned long int*" ); - Variable<unsigned long int>& variable = group.m_ULInt[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const long long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long long int*" ); - Variable<long long int>& variable = group.m_LLInt[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const unsigned long long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned long long int*" ); - Variable<unsigned long long int>& variable = group.m_ULLInt[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const float* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write float*" ); - Variable<float>& variable = group.m_Float[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - -void Vis::Write( Group& group, const std::string variableName, const double* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write double*" ); - Variable<double>& variable = group.m_Double[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - - -void Vis::Write( Group& group, const std::string variableName, const long double* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long double*" ); - Variable<long double>& variable = group.m_LDouble[index]; //must be a reference - variable.Values = values; - VisWriteVariable( group, variableName, variable, m_Capsules, m_Transports, m_BP1Writer, m_RankMPI ); -} - -//USING Preset Group -void Vis::Write( const std::string variableName, const char* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const unsigned char* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const short* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const unsigned short* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const unsigned int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const unsigned long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const long long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const unsigned long long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const float* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const double* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - -void Vis::Write( const std::string variableName, const long double* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - - -void Vis::InitTransports( ) //maybe move this? -{ - TransportNamesUniqueness( ); - - for( const auto& parameters : m_Method.m_TransportParameters ) - { - auto itTransport = parameters.find( "transport" ); - - if( itTransport->second == "POSIX" ) - { - m_Transports.push_back( std::make_shared<POSIX>( m_MPIComm, m_DebugMode ) ); - m_Transports.back()->Open( m_Name, m_AccessMode ); - } - else if( itTransport->second == "ShMem" ) - { - //m_Transports.push_back( std::make_shared<ShMemTransport>( m_MPIComm, m_DebugMode ) ); - } - else if( itTransport->second == "VisIt" ) - { - //m_Transports.push_back( std::make_shared<SomeStagingTransport>( m_MPIComm, m_DebugMode ) ); //not yet supported - // - } - else - { - if( m_DebugMode == true ) - throw std::invalid_argument( "ERROR: transport " + itTransport->second + " not supported, in " + - m_Name + m_EndMessage ); - } - } -} - - - -void Vis::Close( const int transportIndex ) -{ - //do some preliminary work here - // (e.g. process metadata ) - //flush the last piece of data or do more writes - - if( transportIndex == -1 ) // all transports - { - for( auto& transport : m_Transports ) - transport->Close( ); - } - else - { - if( m_DebugMode == true ) - { - if( transportIndex >= static_cast<int>( m_Transports.size() ) ) - throw std::invalid_argument( "ERROR: transportIndex " + std::to_string( transportIndex ) + " is out of range\n" ); - } - - m_Transports[ transportIndex ]->Close( ); - } - - std::cout << "I own many Capsules (buffers: heap, shared memory, RDMA ) and \n" - " many Transports ( POSIX, in-situ vis, staging, shared memory, RDMA )\n" - " and I can do whatever I need to do with them\n"; -} - - - -} //end namespace engine -} //end namespace adios - - - diff --git a/src/engine/writer/Writer.cpp b/src/engine/writer/Writer.cpp index f96d2b9c13287418f595243e83023cc0ffe5f5aa..7ddc5a5627a8f0be79859d6d73fe485a3a5d65ca 100644 --- a/src/engine/writer/Writer.cpp +++ b/src/engine/writer/Writer.cpp @@ -5,10 +5,7 @@ * Author: wfg */ -#include <iostream> - #include "engine/writer/Writer.h" -#include "core/Support.h" #include "functions/adiosFunctions.h" //GetTotalSize //supported capsules @@ -19,15 +16,15 @@ #include "transport/FStream.h" #include "transport/File.h" +#include "ADIOS.h" namespace adios { -Writer::Writer( const std::string streamName, const std::string accessMode, const MPI_Comm mpiComm, - const Method& method, const bool debugMode, const unsigned int cores, const std::string hostLanguage ): - Engine( "Writer", streamName, accessMode, mpiComm, method, debugMode, - cores, " Writer constructor (or call to ADIOS Open).\n", hostLanguage ), +Writer::Writer( ADIOS& adios, const std::string name, const std::string accessMode, const MPI_Comm mpiComm, + const Method& method, const bool debugMode, const unsigned int cores ): + Engine( adios, "Writer", name, accessMode, mpiComm, method, debugMode, cores, " Writer constructor (or call to ADIOS Open).\n" ), m_Buffer{ Heap( accessMode, m_RankMPI, m_DebugMode ) }, m_MaxBufferSize{ m_Buffer.m_Data.max_size() } { @@ -57,205 +54,91 @@ void Writer::Init( ) m_BP1Writer.m_Verbosity = std::stoi( itVerbosity->second ); InitTransports( ); -} - + InitProcessGroup( ); -void Writer::Write( Group& group, const std::string variableName, const char* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write char*" ); - Variable<char>& variable = group.m_Char[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); } -void Writer::Write( Group& group, const std::string variableName, const unsigned char* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned char*" ); - Variable<unsigned char>& variable = group.m_UChar[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} -void Writer::Write( Group& group, const std::string variableName, const short* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write short*" ); - Variable<short>& variable = group.m_Short[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} - -void Writer::Write( Group& group, const std::string variableName, const unsigned short* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned short*" ); - Variable<unsigned short>& variable = group.m_UShort[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<char>& variable, const char* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write int*" ); - Variable<int>& variable = group.m_Int[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<unsigned char>& variable, const unsigned char* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const unsigned int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned int*" ); - Variable<unsigned int>& variable = group.m_UInt[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<short>& variable, const short* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long int*" ); - Variable<long int>& variable = group.m_LInt[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<unsigned short>& variable, const unsigned short* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const unsigned long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned long int*" ); - Variable<unsigned long int>& variable = group.m_ULInt[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<int>& variable, const int* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const long long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long long int*" ); - Variable<long long int>& variable = group.m_LLInt[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<unsigned int>& variable, const unsigned int* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const unsigned long long int* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write unsigned long long int*" ); - Variable<unsigned long long int>& variable = group.m_ULLInt[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<long int>& variable, const long int* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const float* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write float*" ); - Variable<float>& variable = group.m_Float[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<unsigned long int>& variable, const unsigned long int* values ) +{ WriteVariable( variable, values ); } +void Writer::Write( Variable<long long int>& variable, const long long int* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const double* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write double*" ); - Variable<double>& variable = group.m_Double[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ) +{ WriteVariable( variable, values ); } +void Writer::Write( Variable<float>& variable, const float* values ) +{ WriteVariable( variable, values ); } -void Writer::Write( Group& group, const std::string variableName, const long double* values ) -{ - auto index = PreSetVariable( group, variableName, " from call to Write long double*" ); - Variable<long double>& variable = group.m_LDouble[index]; //must be a reference - variable.Values = values; - WriteVariable( group, variableName, variable ); -} +void Writer::Write( Variable<double>& variable, const double* values ) +{ WriteVariable( variable, values ); } +void Writer::Write( Variable<long double>& variable, const long double* values ) +{ WriteVariable( variable, values ); } +//String version void Writer::Write( const std::string variableName, const char* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<char>( variableName ), values ); } void Writer::Write( const std::string variableName, const unsigned char* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<unsigned char>( variableName ), values ); } void Writer::Write( const std::string variableName, const short* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<short>( variableName ), values ); } void Writer::Write( const std::string variableName, const unsigned short* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<unsigned short>( variableName ), values ); } void Writer::Write( const std::string variableName, const int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<int>( variableName ), values ); } void Writer::Write( const std::string variableName, const unsigned int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<unsigned int>( variableName ), values ); } void Writer::Write( const std::string variableName, const long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<long int>( variableName ), values ); } void Writer::Write( const std::string variableName, const unsigned long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<unsigned long int>( variableName ), values ); } void Writer::Write( const std::string variableName, const long long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<long long int>( variableName ), values ); } void Writer::Write( const std::string variableName, const unsigned long long int* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<unsigned long long int>( variableName ), values ); } void Writer::Write( const std::string variableName, const float* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<float>( variableName ), values ); } void Writer::Write( const std::string variableName, const double* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} - +{ WriteVariable( m_ADIOS.GetVariable<double>( variableName ), values ); } void Writer::Write( const std::string variableName, const long double* values ) -{ - CheckDefaultGroup( ); - Write( *m_Group, variableName, values ); -} +{ WriteVariable( m_ADIOS.GetVariable<long double>( variableName ), values ); } + + void Writer::Close( const int transportIndex ) @@ -285,9 +168,6 @@ void Writer::Close( const int transportIndex ) } - - - void Writer::InitTransports( ) { if( m_DebugMode == true ) @@ -335,9 +215,48 @@ void Writer::InitTransports( ) } +void Writer::InitProcessGroup( ) +{ + if( m_AccessMode == "a" ) + { + //Get last pg timestep and update timestep counter in format::BP1MetadataSet + } + WriteProcessGroupIndex( ); +} + + + +void Writer::WriteProcessGroupIndex( ) +{ + //pg = process group + const std::string pgName( std::to_string( m_RankMPI ) ); //using rank as name + const unsigned int timeStep = m_MetadataSet.TimeStep; + const std::string timeStepName( std::to_string( timeStep ) ); + const std::size_t pgIndexSize = m_BP1Writer.GetProcessGroupIndexSize( pgName, timeStepName, m_Transports.size() ); + + //metadata + GrowBuffer( pgIndexSize, m_GrowthFactor, m_MetadataSet.PGIndexPosition, m_MetadataSet.PGIndex ); + + //data? Need to be careful, maybe add some trailing tolerance in variable ???? + GrowBuffer( pgIndexSize, m_GrowthFactor, m_Buffer.m_DataPosition, m_Buffer.m_Data ); + +// const bool isFortran = ( m_HostLanguage == "Fortran" ) ? true : false; +// const unsigned int processID = static_cast<unsigned int> ( m_RankMPI ); + +// m_BP1Writer.WriteProcessGroupIndex( isFortran, name, processID, timeStepName, timeStep, m_Transports, +// m_Buffer.m_Data, m_Buffer.m_DataPosition, m_Buffer.m_DataAbsolutePosition, +// m_MetadataSet.PGIndex, m_MetadataSet.PGIndexPosition ); + +// const bool isFortran, const std::string name, const unsigned int processID, +// const std::string timeStepName, const unsigned int timeStep, +// std::vector<char*>& dataBuffers, std::vector<std::size_t>& dataPositions, +// std::vector<std::size_t>& dataAbsolutePositions, +// std::vector<char*>& metadataBuffers, +// std::vector<std::size_t>& metadataPositions + +} -bool Writer::CheckBuffersAllocation( const Group& group, const Var variableName, const std::size_t indexSize, - const std::size_t payloadSize ) +bool Writer::CheckBuffersAllocation( const std::size_t indexSize, const std::size_t payloadSize ) { //Check if data in buffer needs to be reallocated const std::size_t dataSize = payloadSize + indexSize + 10; //adding some bytes tolerance diff --git a/src/format/BP1.cpp b/src/format/BP1.cpp index 2ea0e054b3a1f69349467f93efadca90ff6fc2f7..2a29f11de2843e6d2226171edb11d2d07600674a 100644 --- a/src/format/BP1.cpp +++ b/src/format/BP1.cpp @@ -24,17 +24,16 @@ void BP1::OpenRankFiles( const std::string name, const std::string accessMode, T if( name.find(".bp") == name.size()-3 ) //need to test { baseName = name.substr( 0, name.size()-3 ); - directory = name + ".dir"; - CreateDirectory( name +".dir" ); + directory = name; } else { baseName = name; - directory = name + ".bp.dir"; - CreateDirectory( name +".bp.dir" ); + directory = name + ".bp"; } + CreateDirectory( directory ); - std::string fileName( directory + "/" + baseName + ".bp." + std::to_string( file.m_MPIRank ) ); + std::string fileName( directory + "/" + baseName + ".bp." + std::to_string( file.m_RankMPI ) ); if( file.m_MPIComm == MPI_COMM_SELF ) fileName = name; @@ -44,5 +43,32 @@ void BP1::OpenRankFiles( const std::string name, const std::string accessMode, T + +std::vector<int> BP1::GetMethodIDs( const std::vector< std::shared_ptr<Transport> >& transports ) const noexcept +{ + auto lf_GetMethodID = []( const std::string method ) -> int + { + int id = METHOD_UNKNOWN; + if( method == "NULL" ) id = METHOD_NULL; + else if( method == "POSIX" ) id = METHOD_POSIX; + else if( method == "FStream" ) id = METHOD_FSTREAM; + else if( method == "File" ) id = METHOD_FILE; + else if( method == "MPI" ) id = METHOD_MPI; + + return id; + }; + + std::vector<int> methodIDs; + methodIDs.reserve( transports.size() ); + + for( const auto transport : transports ) + { + methodIDs.push_back( lf_GetMethodID( transport->m_Type ) ); + } + + return methodIDs; +} + + } //end namespace format } //end namespace adios diff --git a/src/format/BP1Writer.cpp b/src/format/BP1Writer.cpp index eca2a094d375291c8384f324f9f0b0ad7e43146f..d5bbaf46bb66f8c8dfbdcb0536ad05bffcba914e 100644 --- a/src/format/BP1Writer.cpp +++ b/src/format/BP1Writer.cpp @@ -16,18 +16,98 @@ namespace format { -std::size_t BP1Writer::GetProcessIndexSize( const std::string name, const std::string timeStepName ) +std::size_t BP1Writer::GetProcessGroupIndexSize( const std::string name, const std::string timeStepName, + const size_t numberOfTransports ) const noexcept { - return name.length() + timeStepName.length() + 23; + //pgIndex + list of methods (transports) + return ( name.length() + timeStepName.length() + 23 ) + ( 3 + numberOfTransports ); //should be sufficient for data and metadata pgindices } +void BP1Writer::WriteProcessGroupIndex( const bool isFortran, const std::string name, const unsigned int processID, + const std::string timeStepName, const unsigned int timeStep, + const std::vector< std::shared_ptr<Transport> >& transports, + Heap& buffer, BP1MetadataSet& metadataSet ) const noexcept +{ + // adapt this part to local variables + std::vector<char*> dataBuffers{ buffer.m_Data.data() }; + std::vector<size_t> dataPositions{ buffer.m_DataPosition }; + std::vector<size_t> dataAbsolutePositions{ buffer.m_DataAbsolutePosition }; + + std::vector<char*> metadataBuffers{ metadataSet.PGIndex.data() }; + std::vector<std::size_t> metadataPositions{ metadataSet.PGIndexPosition }; + + const std::vector<int> methodIDs = GetMethodIDs( transports ); + + WriteProcessGroupIndexCommon( isFortran, name, processID, timeStepName, timeStep, methodIDs, + dataBuffers, dataPositions, dataAbsolutePositions, + metadataBuffers, metadataPositions ); + + buffer.m_DataPosition = dataPositions[0]; + buffer.m_DataAbsolutePosition = dataAbsolutePositions[0]; + metadataSet.PGIndexPosition = metadataPositions[0]; + +} void BP1Writer::WriteProcessGroupIndex( const bool isFortran, const std::string name, const unsigned int processID, const std::string timeStepName, const unsigned int timeStep, - std::vector<char*>& dataBuffers, std::vector<std::size_t>& dataPositions, - std::vector<std::size_t>& dataAbsolutePositions, - std::vector<char*>& metadataBuffers, - std::vector<std::size_t>& metadataPositions ) + const std::vector< std::shared_ptr<Transport> >& transports, + std::vector< std::shared_ptr<Capsule> >& capsules, + std::vector<BP1MetadataSet>& metadataSets ) const noexcept +{ + + // adapt this part to local variables + std::vector<char*> metadataBuffers, dataBuffers; + std::vector<std::size_t> metadataPositions, dataPositions, dataAbsolutePositions; + + for( auto& metadataSet : metadataSets ) + { + metadataBuffers.push_back( metadataSet.PGIndex.data() ); + metadataPositions.push_back( metadataSet.PGIndexPosition ); + } + + for( auto& capsule : capsules ) + { + dataBuffers.push_back( capsule->GetData( ) ); + dataPositions.push_back( capsule->m_DataPosition ); + dataAbsolutePositions.push_back( capsule->m_DataAbsolutePosition ); + } + + const std::vector<int> methodIDs = GetMethodIDs( transports ); + + WriteProcessGroupIndexCommon( isFortran, name, processID, timeStepName, timeStep, methodIDs, + dataBuffers, dataPositions, dataAbsolutePositions, + metadataBuffers, metadataPositions ); + + //update positions and varsCount originally passed by value + const unsigned int buffersSize = static_cast<unsigned int>( capsules.size() ); + for( unsigned int i = 0; i < buffersSize; ++i ) + { + metadataSets[i].PGIndexPosition = metadataPositions[i]; + + capsules[i]->m_DataPosition = dataPositions[i]; + capsules[i]->m_DataAbsolutePosition = dataAbsolutePositions[i]; + } +} + + + +void BP1Writer::Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ) const +{ + + + +} + + + + +void BP1Writer::WriteProcessGroupIndexCommon( const bool isFortran, const std::string name, const unsigned int processID, + const std::string timeStepName, const unsigned int timeStep, + const std::vector<int>& methodIDs, + std::vector<char*>& dataBuffers, std::vector<std::size_t>& dataPositions, + std::vector<std::size_t>& dataAbsolutePositions, + std::vector<char*>& metadataBuffers, + std::vector<std::size_t>& metadataPositions ) const noexcept { std::vector<std::size_t> metadataLengthPositions( metadataPositions ); //get length of pg position @@ -62,7 +142,6 @@ void BP1Writer::WriteProcessGroupIndex( const bool isFortran, const std::string //write offset to pg in data on metadata which is the current absolute position MemcpyToBuffers( metadataBuffers, metadataPositions, dataAbsolutePositions, 8 ); - //get pg index length std::vector<std::uint16_t> metadataIndexLengths( metadataPositions.size() ); for( unsigned int i = 0; i < metadataPositions.size(); ++i ) @@ -73,18 +152,9 @@ void BP1Writer::WriteProcessGroupIndex( const bool isFortran, const std::string MovePositions( -2, metadataLengthPositions ); //back to original position } - - -void BP1Writer::Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ) -{ - - - -} - //PRIVATE FUNCTIONS void BP1Writer::WriteNameRecord( const std::string name, const std::uint16_t length, - std::vector<char*>& buffers, std::vector<std::size_t>& positions ) + std::vector<char*>& buffers, std::vector<std::size_t>& positions ) const noexcept { MemcpyToBuffers( buffers, positions, &length, 2 ); MemcpyToBuffers( buffers, positions, name.c_str( ), length ); @@ -92,10 +162,10 @@ void BP1Writer::WriteNameRecord( const std::string name, const std::uint16_t len void BP1Writer::WriteDimensionRecord( std::vector<char*>& buffers, std::vector<std::size_t>& positions, - const std::vector<unsigned long long int>& localDimensions, - const std::vector<unsigned long long int>& globalDimensions, - const std::vector<unsigned long long int>& globalOffsets, - const bool addType ) + const std::vector<std::size_t>& localDimensions, + const std::vector<std::size_t>& globalDimensions, + const std::vector<std::size_t>& globalOffsets, + const bool addType ) const noexcept { if( addType == true ) { @@ -122,11 +192,10 @@ void BP1Writer::WriteDimensionRecord( std::vector<char*>& buffers, std::vector<s } void BP1Writer::WriteDimensionRecord( std::vector<char*>& buffers, std::vector<std::size_t>& positions, - const std::vector<unsigned long long int>& localDimensions, + const std::vector<std::size_t>& localDimensions, const unsigned int skip, - const bool addType ) + const bool addType ) const noexcept { - if( addType == true ) { constexpr char no = 'n'; //dimension format unsigned int value (not using memberID for now) @@ -148,7 +217,7 @@ void BP1Writer::WriteDimensionRecord( std::vector<char*>& buffers, std::vector<s } -void BP1Writer::CloseRankFile( Capsule& capsule, Transport& transport ) +void BP1Writer::CloseRankFile( Capsule& capsule, Transport& transport ) const { } @@ -156,7 +225,7 @@ void BP1Writer::CloseRankFile( Capsule& capsule, Transport& transport ) -void BP1Writer::SetMiniFooter( BP1MetadataSet& metadataSet ) +void BP1Writer::SetMiniFooter( BP1MetadataSet& metadataSet ) const { @@ -164,7 +233,7 @@ void BP1Writer::SetMiniFooter( BP1MetadataSet& metadataSet ) } -void BP1Writer::SetMetadata( const BP1MetadataSet& metadataSet, Capsule& capsule ) +void BP1Writer::SetMetadata( const BP1MetadataSet& metadataSet, Capsule& capsule ) const { //setup metadata to capsule metadata buffer diff --git a/src/functions/adiosFunctions.cpp b/src/functions/adiosFunctions.cpp index 8f468a92c58042c57cf6478bf09e3eaf06cee747..e0ec7ce420ff8a132bce14f589cb7336eb0d630a 100644 --- a/src/functions/adiosFunctions.cpp +++ b/src/functions/adiosFunctions.cpp @@ -189,181 +189,181 @@ void GetPairsFromTag( const std::string& fileContent, const std::string tag, } -void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, const bool debugMode, - std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, - std::map< std::string, Group >& groups ) +//void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, const bool debugMode, +// std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, +// std::map< std::string, Group >& groups ) +//{ +// //adios-config +// std::string currentContent; +// std::string::size_type currentPosition( 0 ); +// GetSubString( "<adios-config ", "</adios-config>", fileContent, currentContent, currentPosition ); +// +// //remove comment sections +// std::string::size_type startComment ( currentContent.find( "<!--" ) ); +// +// while( startComment != currentContent.npos ) +// { +// std::string::size_type endComment( currentContent.find( "-->") ); +// currentContent.erase( startComment, endComment-startComment+3 ); +// startComment = currentContent.find( "<!--" ); +// } +// +// //Tag <adios-config +// currentPosition = 0; +// +// std::string tag; //use for < > tags +// GetSubString( "<adios-config", ">", currentContent, tag, currentPosition ); +// tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > +// +// std::vector< std::pair<const std::string, const std::string> > pairs; // pairs in tag +// GetPairsFromTag( currentContent, tag, pairs ); +// +// for( auto& pair : pairs ) +// if( pair.first == "host-language" ) +// hostLanguage = pair.second; +// +// if( debugMode == true ) +// { +// if( Support::HostLanguages.count( hostLanguage ) == 0 ) +// throw std::invalid_argument("ERROR: host language " + hostLanguage + " not supported.\n" ); +// +// if( hostLanguage.empty() == true ) +// throw std::invalid_argument("ERROR: host language is empty.\n" ); +// } +// +// //adios-group +// currentPosition = 0; +// +// while( currentPosition != std::string::npos ) +// { +// std::string xmlGroup; +// GetSubString("<adios-group ", "</adios-group>", currentContent, xmlGroup, currentPosition ); //Get all group contents +// +// if( xmlGroup.empty() ) //no more groups to find +// break; +// +// //get group name +// std::string::size_type groupPosition( 0 ); +// GetSubString( "<adios-group ", ">", xmlGroup, tag, groupPosition ); +// if( debugMode == true ) +// { +// if( tag.size() < 2 ) +// throw std::invalid_argument( "ERROR: wrong tag " + tag + " in adios-group\n" ); //check < or <= +// } +// +// tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > +// GetPairsFromTag( xmlGroup, tag, pairs ); +// std::string groupName; +// +// for( auto& pair : pairs ) +// { +// if( pair.first == "name") +// groupName = pair.second; +// } +// +// if( debugMode == true ) +// { +// if( groupName.empty() ) +// throw std::invalid_argument( "ERROR: group name not found. \n" ); +// +// if( groups.count( groupName ) == 1 ) //group exists +// throw std::invalid_argument( "ERROR: group " + groupName + " defined twice.\n" ); +// } +// +// groups.emplace( groupName, Group( groupName, xmlGroup, transforms, debugMode ) ); +// +// currentContent.erase( currentContent.find( xmlGroup ), xmlGroup.size() ); +// currentPosition = 0; +// } +// +// //transport +// //lambda function to check priority and iteration casting to unsigned int +// auto lf_UIntCheck = []( const std::string method, const std::string fieldStr, const std::string fieldName, +// const bool debugMode, int& field ) +// { +// field = 0; +// if( fieldStr.empty() == false ) +// { +// field = std::stoi( fieldStr ); //throws invalid_argument +// +// if( debugMode == true ) +// { +// if( field < 0 ) +// throw std::invalid_argument("ERROR: " + fieldName + " in transport " + method + " can't be negative\n" ); +// } +// } +// }; +// +// //this section will have to change, doing nothing for now +// currentPosition = 0; +// while( currentPosition != std::string::npos ) +// { +// GetSubString( "<transport ", ">", currentContent, tag, currentPosition ); +// if( tag.empty() ) break; +// tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > +// pairs.clear(); +// GetPairsFromTag( currentContent, tag, pairs ); +// +// std::string groupName, method, priorityStr, iterationStr; +// for( auto& pair : pairs ) +// { +// if( pair.first == "group" ) groupName = pair.second; +// else if( pair.first == "method" ) method = pair.second; +// else if( pair.first == "priority" ) priorityStr = pair.second; +// else if( pair.first == "iteration" ) iterationStr = pair.second; +// } +// +// auto itGroup = groups.find( groupName ); +// if( debugMode == true ) +// { +// if( itGroup == groups.end() ) //not found +// throw std::invalid_argument( "ERROR: in transport " + method + " group " + groupName + " not found.\n" ); +// } +// +// int priority, iteration; +// lf_UIntCheck( method, priorityStr, "priority", debugMode, priority ); +// lf_UIntCheck( method, iterationStr, "iteration", debugMode, iteration ); +// //here do something with the capsule +// } +//} + + +//void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode, +// std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, +// std::map< std::string, Group >& groups ) +//{ +// int xmlFileContentSize; +// std::string xmlFileContent; +// +// int rank; +// MPI_Comm_rank( mpiComm, &rank ); +// +// if( rank == 0 ) //serial part +// { +// DumpFileToString( xmlConfigFile, xmlFileContent ); //in ADIOSFunctions.h dumps all XML Config File to xmlFileContent +// xmlFileContentSize = xmlFileContent.size( ) + 1; // add one for the null character +// +// MPI_Bcast( &xmlFileContentSize, 1, MPI_INT, 0, mpiComm ); //broadcast size for allocation +// MPI_Bcast( (char*)xmlFileContent.c_str(), xmlFileContentSize, MPI_CHAR, 0, mpiComm ); //broadcast contents +// } +// else +// { +// MPI_Bcast( &xmlFileContentSize, 1, MPI_INT, 0, mpiComm ); //receive size +// +// char* xmlFileContentMPI = new char[ xmlFileContentSize ]; //allocate xml C-char +// MPI_Bcast( xmlFileContentMPI, xmlFileContentSize, MPI_CHAR, 0, mpiComm ); //receive xml C-char +// xmlFileContent.assign( xmlFileContentMPI ); //copy to a string +// +// delete []( xmlFileContentMPI ); //delete char* needed for MPI, might add size is moving to C++14 for optimization, avoid memory leak +// } +// +// SetMembers( xmlFileContent, mpiComm, debugMode, hostLanguage, transforms, groups ); +//} + + +std::size_t GetTotalSize( const std::vector<std::size_t>& dimensions ) { - //adios-config - std::string currentContent; - std::string::size_type currentPosition( 0 ); - GetSubString( "<adios-config ", "</adios-config>", fileContent, currentContent, currentPosition ); - - //remove comment sections - std::string::size_type startComment ( currentContent.find( "<!--" ) ); - - while( startComment != currentContent.npos ) - { - std::string::size_type endComment( currentContent.find( "-->") ); - currentContent.erase( startComment, endComment-startComment+3 ); - startComment = currentContent.find( "<!--" ); - } - - //Tag <adios-config - currentPosition = 0; - - std::string tag; //use for < > tags - GetSubString( "<adios-config", ">", currentContent, tag, currentPosition ); - tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > - - std::vector< std::pair<const std::string, const std::string> > pairs; // pairs in tag - GetPairsFromTag( currentContent, tag, pairs ); - - for( auto& pair : pairs ) - if( pair.first == "host-language" ) - hostLanguage = pair.second; - - if( debugMode == true ) - { - if( Support::HostLanguages.count( hostLanguage ) == 0 ) - throw std::invalid_argument("ERROR: host language " + hostLanguage + " not supported.\n" ); - - if( hostLanguage.empty() == true ) - throw std::invalid_argument("ERROR: host language is empty.\n" ); - } - - //adios-group - currentPosition = 0; - - while( currentPosition != std::string::npos ) - { - std::string xmlGroup; - GetSubString("<adios-group ", "</adios-group>", currentContent, xmlGroup, currentPosition ); //Get all group contents - - if( xmlGroup.empty() ) //no more groups to find - break; - - //get group name - std::string::size_type groupPosition( 0 ); - GetSubString( "<adios-group ", ">", xmlGroup, tag, groupPosition ); - if( debugMode == true ) - { - if( tag.size() < 2 ) - throw std::invalid_argument( "ERROR: wrong tag " + tag + " in adios-group\n" ); //check < or <= - } - - tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > - GetPairsFromTag( xmlGroup, tag, pairs ); - std::string groupName; - - for( auto& pair : pairs ) - { - if( pair.first == "name") - groupName = pair.second; - } - - if( debugMode == true ) - { - if( groupName.empty() ) - throw std::invalid_argument( "ERROR: group name not found. \n" ); - - if( groups.count( groupName ) == 1 ) //group exists - throw std::invalid_argument( "ERROR: group " + groupName + " defined twice.\n" ); - } - - groups.emplace( groupName, Group( groupName, xmlGroup, transforms, debugMode ) ); - - currentContent.erase( currentContent.find( xmlGroup ), xmlGroup.size() ); - currentPosition = 0; - } - - //transport - //lambda function to check priority and iteration casting to unsigned int - auto lf_UIntCheck = []( const std::string method, const std::string fieldStr, const std::string fieldName, - const bool debugMode, int& field ) - { - field = 0; - if( fieldStr.empty() == false ) - { - field = std::stoi( fieldStr ); //throws invalid_argument - - if( debugMode == true ) - { - if( field < 0 ) - throw std::invalid_argument("ERROR: " + fieldName + " in transport " + method + " can't be negative\n" ); - } - } - }; - - //this section will have to change, doing nothing for now - currentPosition = 0; - while( currentPosition != std::string::npos ) - { - GetSubString( "<transport ", ">", currentContent, tag, currentPosition ); - if( tag.empty() ) break; - tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > - pairs.clear(); - GetPairsFromTag( currentContent, tag, pairs ); - - std::string groupName, method, priorityStr, iterationStr; - for( auto& pair : pairs ) - { - if( pair.first == "group" ) groupName = pair.second; - else if( pair.first == "method" ) method = pair.second; - else if( pair.first == "priority" ) priorityStr = pair.second; - else if( pair.first == "iteration" ) iterationStr = pair.second; - } - - auto itGroup = groups.find( groupName ); - if( debugMode == true ) - { - if( itGroup == groups.end() ) //not found - throw std::invalid_argument( "ERROR: in transport " + method + " group " + groupName + " not found.\n" ); - } - - int priority, iteration; - lf_UIntCheck( method, priorityStr, "priority", debugMode, priority ); - lf_UIntCheck( method, iterationStr, "iteration", debugMode, iteration ); - //here do something with the capsule - } -} - - -void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode, - std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, - std::map< std::string, Group >& groups ) -{ - int xmlFileContentSize; - std::string xmlFileContent; - - int rank; - MPI_Comm_rank( mpiComm, &rank ); - - if( rank == 0 ) //serial part - { - DumpFileToString( xmlConfigFile, xmlFileContent ); //in ADIOSFunctions.h dumps all XML Config File to xmlFileContent - xmlFileContentSize = xmlFileContent.size( ) + 1; // add one for the null character - - MPI_Bcast( &xmlFileContentSize, 1, MPI_INT, 0, mpiComm ); //broadcast size for allocation - MPI_Bcast( (char*)xmlFileContent.c_str(), xmlFileContentSize, MPI_CHAR, 0, mpiComm ); //broadcast contents - } - else - { - MPI_Bcast( &xmlFileContentSize, 1, MPI_INT, 0, mpiComm ); //receive size - - char* xmlFileContentMPI = new char[ xmlFileContentSize ]; //allocate xml C-char - MPI_Bcast( xmlFileContentMPI, xmlFileContentSize, MPI_CHAR, 0, mpiComm ); //receive xml C-char - xmlFileContent.assign( xmlFileContentMPI ); //copy to a string - - delete []( xmlFileContentMPI ); //delete char* needed for MPI, might add size is moving to C++14 for optimization, avoid memory leak - } - - SetMembers( xmlFileContent, mpiComm, debugMode, hostLanguage, transforms, groups ); -} - - -unsigned long long int GetTotalSize( const std::vector<unsigned long long int>& dimensions ) -{ - unsigned long long int product = 1; + std::size_t product = 1; for( const auto dimension : dimensions ) product *= dimension; diff --git a/src/transport/FStream.cpp b/src/transport/FStream.cpp index 5c0e2ec68219b9b4d5b15d1ac602da855ec09e98..c299a639ebdca4f970a18172f0d1801dc22b55a3 100644 --- a/src/transport/FStream.cpp +++ b/src/transport/FStream.cpp @@ -78,71 +78,5 @@ void FStream::Close( ) } -//void CFStream::Write( const CVariable& variable ) ///this is aggregation -//{ -// //local buffer, to be send over MPI -// std::vector<char> buffer; -// const std::string type( variable.m_Type ); -// auto var = GetVariableValues( variable ); - -// if( type.find( "vector" ) ) //is a vector -// { -// //find total size first -// //auto values = variable.Get< std::vector<int> >(); -// auto values = GetVariableValues( variable ); -// //auto values = GetVariableValues( variable ); -// unsigned int sizeSum = 0; -// for( auto element : *values ) -// sizeSum += (int) std::log10( (double) std::abs( element ) ) + 1; -// -// buffer.reserve( 2*sizeSum ); -// -// for( auto element : *values ) -// { -// const char* elementChar = std::to_string( element ).c_str(); -// buffer.insert( buffer.end(), elementChar, elementChar + strlen( elementChar ) ); -// buffer.push_back(' '); -// } -// -// if( m_RankMPI == 0 ) -// { -// std::cout << "Writing to file " << m_StreamName << "\n"; -// -// m_FStream << "Hello from rank " << m_RankMPI << " : "; -// m_FStream.write( &buffer[0], buffer.size() ); -// m_FStream << "\n"; -// -// MPI_Status* status = NULL; -// -// for( int r = 1; r < m_SizeMPI; ++r ) -// { -// int bufferSize; -// MPI_Recv( &bufferSize, 1, MPI_INT, r, 0, m_MPIComm, status ); //receive from r the buffer size -// std::cout << "Getting from rank: " << r << " buffer size "<< bufferSize << "\n"; -// -// buffer.resize( bufferSize ); -// MPI_Recv( &buffer[0], bufferSize, MPI_CHAR, r, 1, m_MPIComm, status ); //receive from r the buffer -// -// m_FStream << "Hello from rank " << r << " : "; -// m_FStream.write( &buffer[0], bufferSize ); -// m_FStream << "\n"; -// } -// } -// else -// { -// int bufferSize = (int)buffer.size(); -// MPI_Send( &bufferSize, 1, MPI_INT, 0, 0, m_MPIComm ); //send to rank=0 the buffer size -// -// std::cout << "Hello from rank: " << m_RankMPI << "\n"; -// std::cout << "Buffer size: " << bufferSize << "\n"; -// -// MPI_Send( &buffer[0], bufferSize, MPI_CHAR, 0, 1, m_MPIComm ); //send to rank=0 the buffer -// } -// -// MPI_Barrier( m_MPIComm ); -// } -//} - - } //end namespace diff --git a/src/transport/File.cpp b/src/transport/File.cpp index ed8a4796f99da193f4b4b2b14a59b8490f2d953f..4a5f9f3cb68051e2723fdde74ea44401f6597859 100644 --- a/src/transport/File.cpp +++ b/src/transport/File.cpp @@ -57,7 +57,7 @@ void File::SetBuffer( char* buffer, std::size_t size ) { if( status == 1 ) throw std::ios_base::failure( "ERROR: could not set buffer in rank " - + std::to_string( m_MPIRank ) + "\n" ); + + std::to_string( m_RankMPI ) + "\n" ); } }