diff --git a/examples/hello/writer/helloWriter.cpp b/examples/hello/writer/helloWriter.cpp index 57dc41ad8b44f0753345f3a83144d681f903376b..9667b3ae484d563344e62e75aced778aa644aa6b 100644 --- a/examples/hello/writer/helloWriter.cpp +++ b/examples/hello/writer/helloWriter.cpp @@ -32,7 +32,7 @@ int main( int argc, char* argv [] ) try { //Define variable and local size - auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} ); + 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 diff --git a/examples/hello/writer/helloWriter_nompi.cpp b/examples/hello/writer/helloWriter_nompi.cpp index 7ba6b4ffe90c227d6cbe72a82467293581cf36d2..7438715cc89fba5393db5bb19683995e383536d7 100644 --- a/examples/hello/writer/helloWriter_nompi.cpp +++ b/examples/hello/writer/helloWriter_nompi.cpp @@ -23,7 +23,7 @@ int main( int argc, char* argv [] ) try { //Define variable and local size - auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} ); + 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 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 933a1c3fdc2bfaf61dbff696716c5f61a1e41531..293003b45837f255c61abf1abfab0142017d881c 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 @@ -12,7 +12,9 @@ #include <string> #include <vector> -#include "ADIOS_OOP.h" +#include "ADIOS_CPP.h" + +using adiosFile = std::shared_ptr<adios::Engine>; struct MYDATA { @@ -27,23 +29,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); @@ -55,14 +54,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"; } } @@ -114,24 +113,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 @@ -144,30 +148,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); @@ -188,7 +206,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 caaeb76a440594d2e4540c46965dce2e659ee444..001334b700a30ddfb2ec300672faa5e5e72db962 100644 --- a/include/ADIOS.h +++ b/include/ADIOS.h @@ -184,7 +184,7 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO * 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 MonitorVariables( std::ostream& logStream ) const; + void MonitorVariables( std::ostream& logStream ); @@ -236,7 +236,7 @@ private: //no const to allow default empty and copy constructors const std::string methodName, const std::string hint ) const; template< class T > - unsigned int GetVariableIndex( const std::string name ) const + unsigned int GetVariableIndex( const std::string name ) { auto itVariable = m_Variables.find( name ); CheckVariableName( itVariable, name, "in call to GetVariable<" + GetType<T>() + ">" ); @@ -324,8 +324,8 @@ Variable<long int>& ADIOS::DefineVariable( const std::string name, const Dims di template<> inline -Variable<unsigned long int>& ADIOS::DefineVariable<unsigned long int>( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +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 ); @@ -438,7 +438,7 @@ Variable<double>& ADIOS::GetVariable( const std::string name ) { return m_Double[ GetVariableIndex<double>(name) ]; } template<> inline -Variable<long double>& ADIOS::GetVariable<long double>( const std::string name ) +Variable<long double>& ADIOS::GetVariable( const std::string name ) { return m_LDouble[ GetVariableIndex<long double>(name) ]; } diff --git a/include/core/Engine.h b/include/core/Engine.h index d2adc18e830e3092b60340f82d3faf8a00e35dcc..2255cbf9db60cd5d4fe0b4b40cc2d7017e26c39f 100644 --- a/include/core/Engine.h +++ b/include/core/Engine.h @@ -79,7 +79,7 @@ public: * 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 variable name of variable to the written * @param values pointer passed from the application */ template< class T > diff --git a/include/core/Variable.h b/include/core/Variable.h index 1473a59791b93657b24e8ad2cbc86606eb380851..d413ea23fd668bd4751cbec0b294cefaa625c8ec 100644 --- a/include/core/Variable.h +++ b/include/core/Variable.h @@ -85,16 +85,21 @@ public: void Monitor( std::ostream& logInfo ) const noexcept { - logInfo << "Hello from DataMan Write variable " << m_Name << "\n"; + logInfo << "Variable: " << m_Name << "\n"; logInfo << "Type: " << m_Type << "\n"; logInfo << "Size: " << TotalSize() << " elements\n"; logInfo << "Payload: " << PayLoadSize() << " bytes\n"; - logInfo << "Values: \n"; - for( unsigned int i = 0; i < TotalSize(); ++i ) + if( m_AppValues != nullptr ) { - logInfo << m_AppValues[i] << " "; + logInfo << "Values (first 10): \n"; + for( unsigned int i = 0; i < 100; ++i ) + { + logInfo << m_AppValues[i] << " "; + } + logInfo << " ..."; } + logInfo << "\n"; } diff --git a/src/ADIOS.cpp b/src/ADIOS.cpp index 1020f05330b16aa9cd0958d6bee1a999dd72cc43..a5fd9a0f096c3cc7e50acb4c98e483c00ad2e478 100644 --- a/src/ADIOS.cpp +++ b/src/ADIOS.cpp @@ -149,14 +149,53 @@ std::shared_ptr<Engine> ADIOS::Open( const std::string name, const std::string a } -void ADIOS::MonitorVariables( std::ostream& logStream ) const +void ADIOS::MonitorVariables( std::ostream& logStream ) { logStream << "\tVariable \t Type\n"; for( auto& variablePair : m_Variables ) { - logStream << "Variable:..." << variablePair.first << "\n"; - //variablePair.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 ); } }