diff --git a/.gitignore b/.gitignore index f1bfd543e5aaa390d779bd531c932df4a808fc9c..45f236b2510613e004301d6117ac37e798b04faa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ *.o *.a *.so +*.tmp #Eclipse .cproject .project .settings/ +.pydevproject + diff --git a/Makefile b/Makefile index 86b405b8d6fb215b39fc4d13322042cc9cf72a7a..27f123ee3ab70e90b313adec7b966e2ed8a41ea9 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 ./src/engine/writer ./src/engine/dataman ./src/engine/vis \ ./src/capsule ./src/transform ./src/transport ./src/format #SEPARATE EXTERNAL LIBRARIES HANDLING in Makefile.libs diff --git a/buildTest.sh b/buildTest.sh new file mode 100755 index 0000000000000000000000000000000000000000..d4a20878fc5fb73e7214badee2c590abe966a710 --- /dev/null +++ b/buildTest.sh @@ -0,0 +1,34 @@ +#!/bin/bash + + +# buildTest.sh for vis engine build and run test +# Created on: Feb 9, 2017 +# Author: wfg + + +echo "#################################################################" +echo "Start building ADIOS ./lib/libadios.a ./libadios_nompi.a" +make #build the ./lib/libadios.a and ./libadios_nompi.a +echo "#################################################################" +echo + +echo +echo "#################################################################" +echo "Building vis example" +echo "#################################################################" +make -C ./examples/hello/vis + +echo +echo +echo "#################################################################" +echo "Running vis nompi example" +echo "#################################################################" +./examples/hello/vis/helloVis_nompi + +echo +echo +echo "#################################################################" +echo "To run mpi version with 4 mpi processes: " +echo "mpirun -n 4 ./examples/hello/vis/helloVis_mpi" +echo "END" +echo "################################################################" diff --git a/examples/hello/dataman/Makefile b/examples/hello/dataman/Makefile index a256c502bdcec7d5583ea8b9774b5e4cc894c512..9ecfbc12f24b21580460c90522398550ada5970e 100644 --- a/examples/hello/dataman/Makefile +++ b/examples/hello/dataman/Makefile @@ -21,7 +21,7 @@ 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) -lpthread diff --git a/examples/hello/dataman/helloDataMan_OOP.cpp b/examples/hello/dataman/helloDataMan_OOP.cpp index da29cf6c6d81cdbd26f176a0781b6ed07f0d231a..90248225697844810cc97bcebeb443583a52aab9 100644 --- a/examples/hello/dataman/helloDataMan_OOP.cpp +++ b/examples/hello/dataman/helloDataMan_OOP.cpp @@ -43,13 +43,13 @@ int main( int argc, char* argv [] ) 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.AddTransport( "POSIX", "have_metadata_file=true" ); 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 ) { diff --git a/examples/hello/vis/Makefile b/examples/hello/vis/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f7767abd91902c0f51c32a8174394f67b87e4d5a --- /dev/null +++ b/examples/hello/vis/Makefile @@ -0,0 +1,35 @@ +# 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 new file mode 100644 index 0000000000000000000000000000000000000000..bd5c67dadaf7a8fc11eb49f0b1e0e576dc9e0472 --- /dev/null +++ b/examples/hello/vis/helloVis.cpp @@ -0,0 +1,134 @@ +/* + * 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 6fc81d67c4e2b08b318b4ae9c2bdc6d05e50e7fa..633a4445f629eddb64846e2b1c8c724485459e2c 100644 --- a/examples/hello/writer/Makefile +++ b/examples/hello/writer/Makefile @@ -18,7 +18,7 @@ ADIOS_NOMPI_LIB=$(ADIOS_DIR)/lib/libadios_nompi.a CFLAGS=-Wall -Wpedantic -Woverloaded-virtual -std=c++11 -O0 -g LDFLAGS= -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) $(LDFLAGS) -lpthread diff --git a/include/core/Engine.h b/include/core/Engine.h index 7c9b2b65f53b96f6b2192396553045833098e8b3..4543bf872ac27662712d83a7107c41669a19c103 100644 --- a/include/core/Engine.h +++ b/include/core/Engine.h @@ -67,20 +67,35 @@ public: */ 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 endMessage = "", const std::string hostLanguage = "C++" ); 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 std::string variableName, const T* values ) + 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 values pointer passed from the application + */ template< class T > - void Write( Group& group, const std::string variableName, const T* values ) + void Write( Group& group, const Var variableName, const T* values ) { Write( group, variableName, values ); } @@ -130,7 +145,7 @@ public: virtual void Write( const std::string variableName, const double* values ) = 0; virtual void Write( const std::string variableName, const long double* values ) = 0; - virtual void Close( const int transportIndex = -1 ); ///< Closes a particular transport + virtual void Close( const int transportIndex = -1 ); ///< Closes a particular transport, or all if -1 protected: @@ -140,6 +155,7 @@ protected: 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; @@ -174,8 +190,6 @@ protected: bool TransportNamesUniqueness( ) const; ///< checks if transport names are unique among the same types (file I/O) - std::string GetName( const std::vector<std::string>& arguments ) const; //might move this to adiosFunctions - }; diff --git a/include/engine/dataman/DataMan.h b/include/engine/dataman/DataMan.h index 1b45e37d26a3f6575afca4f8b4605cf94adf088f..94e1532f0cbe05fddd782bcfee22d7b51f420fa2 100644 --- a/include/engine/dataman/DataMan.h +++ b/include/engine/dataman/DataMan.h @@ -32,9 +32,11 @@ public: * @param mpiComm * @param method * @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 Method& method, const bool debugMode = false, const unsigned int cores = 1, + const std::string hostLanguage = "C++" ); ~DataMan( ); diff --git a/include/engine/vis/Vis.h b/include/engine/vis/Vis.h new file mode 100644 index 0000000000000000000000000000000000000000..ecdc2168883397980b5ae7c2931e9399a3b2955f --- /dev/null +++ b/include/engine/vis/Vis.h @@ -0,0 +1,96 @@ +/* + * 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 new file mode 100644 index 0000000000000000000000000000000000000000..0450bed88cc959e13cbdfb85b547e25883b6bee2 --- /dev/null +++ b/include/engine/vis/VisTemplates.h @@ -0,0 +1,131 @@ +/* + * 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 a5c3a309e3bc35bd8088234ee18d739677fae5a9..e4db2d40cf95214e93e72aec9eadc511cae903d2 100644 --- a/include/engine/writer/Writer.h +++ b/include/engine/writer/Writer.h @@ -31,10 +31,49 @@ public: * @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 Method& method, const bool debugMode = false, const unsigned int cores = 1, + const std::string hostLanguage = "C++" ); ~Writer( ); + + template< class T > + void WriteVariable( const Group& group, const Var variableName, const Variable<T>& variable ) + { + auto lf_CheckAllocationResult = []( const int result, const std::string variableName, const int rankMPI ) + { + if( result == -1 ) + throw std::runtime_error( "ERROR: bad_alloc when writing variable " + variableName + + " from rank " + std::to_string( rankMPI ) ); + }; + + //Check if data in buffer needs to be reallocated + const size_t indexSize = m_BP1Writer.GetVariableIndexSize( group, variableName, variable ); //metadata size + const std::size_t payloadSize = GetTotalSize( group.GetDimensions( variable.DimensionsCSV ) ) * sizeof( T ); + const std::size_t dataSize = payloadSize + indexSize + 10; //adding some bytes tolerance + const std::size_t neededSize = dataSize + m_Buffer.m_DataPosition; + // might need to write payload in batches + const bool doTransportsFlush = ( neededSize > m_MaxBufferSize )? true : false; + + int result = GrowBuffer( m_MaxBufferSize, m_GrowthFactor, m_Buffer.m_DataPosition, m_Buffer.m_Data ); + lf_CheckAllocationResult( result, variableName, m_RankMPI ); + + //WRITE INDEX// + m_BP1Writer.WriteVariableIndex( group, variableName, variable, m_Buffer, m_MetadataSet ); + + if( doTransportsFlush == true ) //in batches + { + + } + else //Write data + { + //this is the expensive part might want to use threaded memcpy + MemcpyThreads( m_Buffer.m_Data.data(), variable.Values, payloadSize, m_Cores ); + m_Buffer.m_DataPosition += payloadSize; + m_Buffer.m_DataAbsolutePosition += payloadSize; + } + } + 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 ); @@ -68,9 +107,10 @@ public: private: Heap m_Buffer; ///< heap capsule - float m_GrowthFactor = 1.5; - std::size_t m_MaxBufferSize; 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 + std::size_t m_MaxBufferSize; + float m_GrowthFactor = 1.5; void Init( ); void InitTransports( ); diff --git a/include/engine/writer/WriterTemplates.h b/include/engine/writer/WriterTemplates.h deleted file mode 100644 index 3d864ddd6b9842604e30a29adc3c8528026b44d4..0000000000000000000000000000000000000000 --- a/include/engine/writer/WriterTemplates.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * WriterTemplate.h - * - * Created on: Jan 12, 2017 - * Author: wfg - */ - -#ifndef WRITERTEMPLATES_H_ -#define WRITERTEMPLATES_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <string> -#include <vector> -#include <iostream> -#include <memory> //std::shared_ptr -#include <cmath> //std::ceil -#include <new> //std::bad_alloc -/// \endcond - - -#include "core/Group.h" -#include "core/Variable.h" -#include "capsule/Heap.h" -#include "format/BP1Writer.h" - - -namespace adios -{ - -/** - * Unique template function that replaces macros to write any variable type to a single heap capsule - * @param group variable owner - * @param variableName - * @param variable to be written - * @param growthFactor buffer growth factor - * @param maxBufferSize buffer maximum size, if reached transport will be called - * @param buffers single heap capsule containing data and metadata buffers - * @param transports all transports from Writer Engine, info is flushed in case of buffer overflow - * @param bp1Writer from Writer Engine - */ -template <class T> -void WriterWriteVariable( const Group& group, const Var variableName, const Variable<T>& variable, - const float growthFactor, const std::size_t maxBufferSize, const int rankMPI, - Heap& buffer, std::vector< std::shared_ptr<Transport> >& transports, - format::BP1Writer& bp1Writer, const unsigned int cores = 1 ) -{ - auto lf_CheckAllocationResult = []( const int result, const std::string variableName, const int rankMPI ) - { - if( result == -1 ) - throw std::runtime_error( "ERROR: bad_alloc when writing variable " + variableName + - " from rank " + std::to_string( rankMPI ) ); - }; - - //Check if data in buffer needs to be reallocated - const size_t indexSize = bp1Writer.GetVariableIndexSize( group, variableName, variable ); //metadata size - const std::size_t payloadSize = GetTotalSize( group.GetDimensions( variable.DimensionsCSV ) ) * sizeof( T ); - const std::size_t dataSize = payloadSize + indexSize + 10; //adding some bytes tolerance - - bool doTransportsFlush = false; // might need to write payload in batches - const std::size_t neededSize = dataSize + buffer.m_DataPosition; - if( neededSize > maxBufferSize ) - { - doTransportsFlush = true; - int result = GrowBuffer( maxBufferSize, growthFactor, buffer.m_DataPosition, buffer.m_Data ); - lf_CheckAllocationResult( result, variableName, rankMPI ); - } - else - { - int result = GrowBuffer( neededSize, growthFactor, buffer.m_DataPosition, buffer.m_Data ); - lf_CheckAllocationResult( result, variableName, rankMPI ); - } - - //WRITE INDEX// - auto& bpMetadataSet = bp1Writer.m_BPMetadataSets[0]; - int result = GrowBuffer( indexSize, growthFactor, bpMetadataSet.VarsIndexPosition, bpMetadataSet.VarsIndex ); - lf_CheckAllocationResult( result, variableName, rankMPI ); - - //Write in BP Format - std::vector<char*> dataBuffers { buffer.m_Data.data() }; - std::vector<std::size_t> dataPositions { buffer.m_DataPosition }; //needs to be updated - std::vector<std::size_t> dataAbsolutePositions { buffer.m_DataAbsolutePosition }; //needs to be updated at the end - std::vector<char*> metadataBuffers { bpMetadataSet.VarsIndex.data() }; - std::vector<std::size_t> metadataPositions { bpMetadataSet.VarsIndexPosition }; //needs to be updated - - bp1Writer.WriteVariableIndex( group, variableName, variable, dataBuffers, dataPositions, - dataAbsolutePositions, metadataBuffers, metadataPositions ); - - buffer.m_DataPosition = dataPositions[0]; - buffer.m_DataAbsolutePosition = dataAbsolutePositions[0]; - bpMetadataSet.VarsIndexPosition = metadataPositions[0]; - - //here write payload to data - if( doTransportsFlush == true ) //in batches - { - - } - else - { - //this is the expensive part might want to use threaded memcpy - MemcpyThreads( buffer.m_Data.data(), variable.Values, payloadSize, cores ); - buffer.m_DataPosition += payloadSize; - buffer.m_DataAbsolutePosition += buffer.m_DataPosition; - } - -// -// const std::size_t bytesToWrite = localSize * sizeof( double ); //size of values + min + max in bytes -// const std::size_t currentSize = m_Data.size(); //0 the first time -// const std::size_t newSize = currentSize + bytesToWrite; -// -// //current capacity is enough to hold new data -// if( newSize <= m_Data.capacity() ) -// { -// m_Data.resize( newSize ); //this resize should not allocate/deallocate -// MemcpyThreads( &m_Data[currentSize], variable.Values, bytesToWrite, m_Cores ); -// //need to implement metadata write -// return; -// } -// -// //newPosition exceeds current capacity -// const std::size_t newCapacity = m_GrowthFactor * m_Data.capacity(); -// -// if( newSize <= m_MaxDataSize ) -// { -// if( newCapacity <= m_MaxDataSize ) -// { -// m_Data.resize( newCapacity ); -// } -// } -// -// -// if( newPosition <= m_MaxDataSize ) // Data is sufficient -// { -// m_Data.resize( currentPosition + bytesToWrite ); -// MemcpyThreads( &m_Data[currentPosition], variable.Values, valuesBytes, m_Cores ); -// return; -// } -// -// -// -// // dataBytes > maxBufferSize == buffer.size() split the variable in buffer buckets -// buffer.resize( maxBufferSize ); //resize to maxBufferSize, this might call realloc -// const size_t buckets = dataBytes / maxBufferSize + 1; -// const size_t remainder = dataBytes % maxBufferSize; -// -// for( unsigned int bucket = 0; buckets < buckets; ++bucket ) -// { -// const size_t dataOffset = bucket * maxBufferSize / sizeof( T ); -// -// if( bucket == buckets-1 ) -// MemcpyThreads( &buffer[0], data[dataOffset], remainder, 1 ); -// else -// MemcpyThreads( &buffer[0], data[dataOffset], maxBufferSize, 1 ); -// -// lf_TransportsWrite( transportIndex, transports, buffer ); -// } -} - - - - - -} //end namespace - - - - -#endif /* WRITERTEMPLATES_H_ */ diff --git a/include/format/BP1.h b/include/format/BP1.h index 4babc3e0f27b24ac64c810626ce0528f0d61376b..02bcea1772c917145a85ed21a06156be1682d80f 100644 --- a/include/format/BP1.h +++ b/include/format/BP1.h @@ -22,6 +22,31 @@ namespace adios namespace format { +/** + * Struct that tracks metadata indices in bp format + */ +struct BP1MetadataSet +{ + 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; + std::vector<char> PGIndex = std::vector<char>( 102400 ); ///< process group index metadata + + std::uint32_t VarsCount = 0; ///< number of written Variables + 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 + std::size_t AttributesIndexPosition = 12; ///< initial position in bytes + std::vector<char> AttributeIndex = std::vector<char>( 102400 ); ///< metadata attribute index, start with 1Kb + + std::vector<char> MiniFooter = std::vector<char>( 28 ); +}; + + class BP1 { @@ -38,31 +63,6 @@ public: protected: - - /** - * Struct that tracks metadata indices in bp format - */ - struct BP1MetadataSet - { - 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; - std::vector<char> PGIndex = std::vector<char>( 102400 ); ///< process group index metadata - - std::uint32_t VarsCount = 0; ///< number of written Variables - 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 m_AttributesCount = 0; ///< number of Attributes - std::uint64_t m_AttributesLength = 0; ///< length in bytes of Attributes - std::size_t m_AttributesIndexPosition = 12; ///< initial position in bytes - std::vector<char> m_AttributeIndex = std::vector<char>( 102400 ); ///< metadata attribute index, start with 1Kb - - std::vector<char> m_MiniFooter = std::vector<char>( 28 ); - }; - /** * DataTypes mapping in BP Format */ diff --git a/include/format/BP1Writer.h b/include/format/BP1Writer.h index bd8cf81cd7f8c61ca261b8c088315f4360fc8a78..1cc60c2771ca91c54ac8d8db0b38a7640d7728e5 100644 --- a/include/format/BP1Writer.h +++ b/include/format/BP1Writer.h @@ -14,11 +14,13 @@ #include <algorithm> //std::count, std::copy, std::for_each #include <cstring> //std::memcpy #include <cmath> //std::ceil +/// \endcond #include "BP1.h" #include "core/Variable.h" #include "core/Group.h" #include "core/Capsule.h" +#include "capsule/Heap.h" #include "functions/adiosTemplates.h" #include "functions/adiosFunctions.h" @@ -34,24 +36,32 @@ class BP1Writer : public BP1 public: - std::vector<BP1MetadataSet> m_BPMetadataSets; - 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_VariablesCount = 0; + unsigned int m_VariablesTotalCount = 0; /** - * Unique constructor - * @param metadataSets number of metadata indices sets in BP format, sets the size of m_BPIndices. Typically one per capsule to separate metadata. + * 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 */ - BP1Writer( const unsigned int metadataSets ); - - - ~BP1Writer( ); - std::size_t GetProcessIndexSize( const std::string name, const std::string timeStepName ); + /** + * Writes a PGIndex, done at Open or aggregation + * @param isFortran + * @param name + * @param processID + * @param timeStepName + * @param timeStep + * @param dataBuffers + * @param dataPositions + * @param dataAbsolutePositions + * @param metadataBuffers + * @param metadataPositions + */ 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, @@ -109,26 +119,100 @@ public: //need to add transform characteristics } + /** + * Version that takes directly a single Heap buffer class and a single BP1MetadataSet + * Skip virtual if optimized to an object + * @param group + * @param variableName + * @param variable + * @param buffer + * @param metadataSet + */ + template< class T > + void WriteVariableIndex( const Group& group, const Var variableName, const Variable<T>& variable, + Heap& buffer, BP1MetadataSet& metadataSet ) 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.VarsIndex.data() }; + 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 ); + + //update positions and varsCount originally passed by value + buffer.m_DataPosition = dataPositions[0]; + buffer.m_DataAbsolutePosition = dataAbsolutePositions[0]; + metadataSet.VarsIndexPosition = metadataPositions[0]; + metadataSet.VarsCount += 1; + } /** + * Version that writes to a vector of capsules * @param group variable owner * @param variableName name of variable to be written * @param variable object carrying variable information - * @param dataBuffers buffers to which variable metadata and payload (values) will be written. Metadata is added in case of system corruption to allow regeneration. - * @param dataPosition initial data relative position - * @param dataAbsolutePosition data absolute position will be updated with dataPosition, needed for variable offset and variable payload offset - * @param metadataBuffers buffers to which only variable metadata will be written - * @param metadataPosition position in metadataBuffer + * @param capsules from Engine member m_Capsules + * @param metadataSets */ template< class T > void WriteVariableIndex( const Group& group, const Var variableName, const Variable<T>& variable, - 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 ) noexcept + std::vector< std::shared_ptr<Capsule> >& capsules, + std::vector<BP1MetadataSet>& metadataSets ) noexcept { + // adapt this part to local variables + std::vector<char*> metadataBuffers, dataBuffers; + std::vector<std::size_t> metadataPositions, dataPositions, dataAbsolutePositions; + std::vector<unsigned int> variablesCount; + + for( auto& metadataSet : metadataSets ) + { + metadataBuffers.push_back( metadataSet.VarsIndex.data() ); + metadataPositions.push_back( metadataSet.VarsIndexPosition ); + variablesCount.push_back( metadataSet.VarsCount ); + } + + for( auto& capsule : capsules ) + { + dataBuffers.push_back( capsule->GetData( ) ); + dataPositions.push_back( capsule->m_DataPosition ); + dataAbsolutePositions.push_back( capsule->m_DataAbsolutePosition ); + } + + WriteVariableCommon( group, variableName, 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() ); + for( unsigned int i = 0; i < buffersSize; ++i ) + { + metadataSets[i].VarsIndexPosition = metadataPositions[i]; + metadataSets[i].VarsCount += 1; + + capsules[i]->m_DataPosition = dataPositions[i]; + capsules[i]->m_DataAbsolutePosition = dataAbsolutePositions[i]; + } + } + + void Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ); + + +private: + + + 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 ) + { + //capture initial positions const std::vector<std::size_t> metadataLengthPositions( metadataPositions ); const std::vector<std::size_t> dataLengthPositions( dataPositions ); @@ -136,7 +220,7 @@ public: MovePositions( 8, dataPositions ); //length of var, will come at the end from this offset //memberID - MemcpyToBuffers( metadataBuffers, metadataPositions, &m_VariablesCount, 4 ); + 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 ); @@ -263,7 +347,7 @@ public: } ++characteristicsCounter; - //Characteristics count and length in Data + //Back to count and length in Data std::vector<std::uint32_t> dataCharacteristicsLengths( dataPositions.size() ); for( unsigned int i = 0; i < dataPositions.size(); ++i ) dataCharacteristicsLengths[i] = dataPositions[i] - dataCharacteristicsCountPositions[i]; @@ -296,17 +380,9 @@ public: MemcpyToBuffers( metadataBuffers, metadataCharacteristicsCountPositions, metadataCharacteristicsLengths, 4 ); //vector to vector MovePositions( -5, metadataCharacteristicsCountPositions ); //back to original position - ++m_VariablesCount; + ++m_VariablesTotalCount; } //end of function - void Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ); - - -private: - - - - /** * Writes name record using a @@ -318,12 +394,29 @@ private: void WriteNameRecord( const std::string name, const std::uint16_t length, std::vector<char*>& buffers, std::vector<std::size_t>& positions ); + /** + * Write a dimension record for a global variable used by WriteVariableCommon + * @param buffers + * @param positions + * @param localDimensions + * @param globalDimensions + * @param globalOffsets + * @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 ); + /** + * Write a dimension record for a local variable used by WriteVariableCommon + * @param buffers + * @param positions + * @param localDimensions + * @param skip + * @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 unsigned int skip, @@ -339,7 +432,8 @@ 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 ) + std::vector<char*>& buffers, std::vector<std::size_t>& positions, + const bool addLength = false ) { const std::uint8_t characteristicID = characteristic_stat; MemcpyToBuffers( buffers, positions, &characteristicID, 1 ); @@ -354,7 +448,6 @@ private: MemcpyToBuffers( buffers, positions, &value, sizeof(T) ); } - /** * Returns data type index from enum Datatypes * @param variable input variable diff --git a/src/ADIOS.cpp b/src/ADIOS.cpp index d890e933b4a527100790b53c110dd3239261b8ff..e522a976ce03e4772de2cac69ea034a97c6142bf 100644 --- a/src/ADIOS.cpp +++ b/src/ADIOS.cpp @@ -18,6 +18,7 @@ //Engines #include "engine/writer/Writer.h" #include "engine/dataman/DataMan.h" +#include "engine/vis/Vis.h" namespace adios @@ -102,15 +103,20 @@ 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 ); + return std::make_shared<Writer>( name, accessMode, mpiComm, method, m_DebugMode, cores, m_HostLanguage ); } else if( type == "SIRIUS" || type == "sirius" || type == "Sirius" ) { - //here must complete + //not yet supported + //return std::make_shared<engine::DataMan>( name, accessMode, mpiComm, method, m_DebugMode, cores, m_HostLanguage ); } else if( type == "DataMan" ) { - return std::make_shared<engine::DataMan>( name, accessMode, mpiComm, method, m_DebugMode, cores ); + return std::make_shared<engine::DataMan>( name, accessMode, mpiComm, method, m_DebugMode, cores, m_HostLanguage ); + } + else if( type == "Vis" ) + { + return std::make_shared<engine::Vis>( name, accessMode, mpiComm, method, m_DebugMode, cores, m_HostLanguage ); } else { diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 55eff35a845dee6468393991adabe68ffae00679..3c63ac8e8e9190a9085e2e7ade98a92132807d87 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -17,7 +17,8 @@ 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 bool debugMode, const unsigned int cores, const std::string endMessage, + const std::string hostLanguage ): m_MPIComm{ mpiComm }, m_EngineType{ engineType }, m_Name{ name }, @@ -26,7 +27,8 @@ Engine::Engine( const std::string engineType, const std::string name, const std: m_Group{ method.m_Group }, m_DebugMode{ debugMode }, m_Cores{ cores }, - m_EndMessage{ endMessage } + m_EndMessage{ endMessage }, + m_HostLanguage{ hostLanguage } { MPI_Comm_rank( m_MPIComm, &m_RankMPI ); MPI_Comm_size( m_MPIComm, &m_SizeMPI ); @@ -142,30 +144,4 @@ bool Engine::TransportNamesUniqueness( ) const } -std::string Engine::GetName( const std::vector<std::string>& arguments ) const -{ - bool isNameFound = false; - std::string name; - - for( const auto argument : arguments ) - { - auto namePosition = argument.find( "name=" ); - if( namePosition != argument.npos ) - { - isNameFound = true; - name = argument.substr( namePosition + 5 ); - break; - } - } - - if( m_DebugMode == true ) - { - if( name.empty() || isNameFound == false ) - std::invalid_argument( "ERROR: argument to name= is empty or not found in call to AddTransport" ); - } - - return name; -} - - } //end namespace diff --git a/src/core/Group.cpp b/src/core/Group.cpp index 0bc699ae35229d7402aca9363fa18ea8ec5248fb..003e5aa66592f2ded980cb9572420ce9f22c3354 100644 --- a/src/core/Group.cpp +++ b/src/core/Group.cpp @@ -560,7 +560,7 @@ void Group::SetDimensionVariablesFlag( const std::string csv, const std::string std::string dimensionVariable; while( std::getline( csvSS, dimensionVariable, ',' ) ) //need to test { - lf_SetVariableFlag( csv, dimensionVariable, m_DebugMode ); + lf_SetVariableFlag( dimensionVariable, " from call to DeclareVariable ", m_DebugMode ); } } } diff --git a/src/engine/dataman/DataMan.cpp b/src/engine/dataman/DataMan.cpp index aa588ff44e2cc00ca799e351f7122e0a3ad88967..844d9039e2bc2c55181ca2c6f3d84db2faf228b4 100644 --- a/src/engine/dataman/DataMan.cpp +++ b/src/engine/dataman/DataMan.cpp @@ -29,10 +29,11 @@ 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 ): - Engine( "DataMan", streamName, accessMode, mpiComm, method, debugMode, cores, " DataMan constructor (or call to ADIOS Open).\n" ), - m_Buffer( accessMode, m_RankMPI, m_DebugMode ), - m_BP1Writer( 1 ) + 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 ), + m_Buffer( accessMode, m_RankMPI, m_DebugMode ) { Init( ); } @@ -246,15 +247,12 @@ void DataMan::Write( const std::string variableName, const long double* values ) void DataMan::InitTransports( ) //maybe move this? { - std::set< std::string > transportStreamNames; //used to check for name conflict between transports + TransportNamesUniqueness( ); - //const unsigned int transportsSize = m_Method.m_TransportParameters.size(); for( const auto& parameters : m_Method.m_TransportParameters ) { auto itTransport = parameters.find( "transport" ); - if( m_DebugMode == true ) - CheckParameter( itTransport, parameters, "transport", ", in " + m_Name + m_EndMessage ); if( itTransport->second == "POSIX" ) { diff --git a/src/engine/vis/Vis.cpp b/src/engine/vis/Vis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..93bb598d1e4185c8e237281538b49e3562ac45e9 --- /dev/null +++ b/src/engine/vis/Vis.cpp @@ -0,0 +1,312 @@ +/* + * 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 05564a9a5c7fe6f34b1e975a2b60a4d08ead07bd..4d725d6f02a439738bc3131d367619d5b563d51b 100644 --- a/src/engine/writer/Writer.cpp +++ b/src/engine/writer/Writer.cpp @@ -8,7 +8,6 @@ #include <iostream> #include "engine/writer/Writer.h" -#include "engine/writer/WriterTemplates.h" #include "core/Support.h" #include "functions/adiosFunctions.h" //GetTotalSize @@ -26,11 +25,11 @@ 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 ): - Engine( "Writer", streamName, accessMode, mpiComm, method, debugMode, cores, " Writer constructor (or call to ADIOS Open).\n" ), + 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 ), m_Buffer{ Heap( accessMode, m_RankMPI, m_DebugMode ) }, - m_MaxBufferSize{ m_Buffer.m_Data.max_size() }, - m_BP1Writer{ format::BP1Writer( 1 ) } + m_MaxBufferSize{ m_Buffer.m_Data.max_size() } { Init( ); } @@ -66,7 +65,7 @@ void Writer::Write( Group& group, const std::string variableName, const char* va auto index = PreSetVariable( group, variableName, " from call to Write char*" ); Variable<char>& variable = group.m_Char[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const unsigned char* values ) @@ -74,7 +73,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned 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; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const short* values ) @@ -82,7 +81,7 @@ void Writer::Write( Group& group, const std::string variableName, const short* v auto index = PreSetVariable( group, variableName, " from call to Write short*" ); Variable<short>& variable = group.m_Short[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const unsigned short* values ) @@ -90,7 +89,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned 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; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const int* values ) @@ -98,7 +97,7 @@ void Writer::Write( Group& group, const std::string variableName, const int* val auto index = PreSetVariable( group, variableName, " from call to Write int*" ); Variable<int>& variable = group.m_Int[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const unsigned int* values ) @@ -106,7 +105,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned 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; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const long int* values ) @@ -114,7 +113,7 @@ void Writer::Write( Group& group, const std::string variableName, const long int 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; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const unsigned long int* values ) @@ -122,7 +121,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned 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; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const long long int* values ) @@ -130,7 +129,7 @@ void Writer::Write( Group& group, const std::string variableName, const long lon 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; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const unsigned long long int* values ) @@ -138,7 +137,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned 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; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } void Writer::Write( Group& group, const std::string variableName, const float* values ) @@ -146,7 +145,7 @@ void Writer::Write( Group& group, const std::string variableName, const float* v auto index = PreSetVariable( group, variableName, " from call to Write float*" ); Variable<float>& variable = group.m_Float[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } @@ -155,7 +154,7 @@ void Writer::Write( Group& group, const std::string variableName, const double* auto index = PreSetVariable( group, variableName, " from call to Write double*" ); Variable<double>& variable = group.m_Double[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } @@ -164,7 +163,7 @@ void Writer::Write( Group& group, const std::string variableName, const long dou 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; - WriterWriteVariable( group, variableName, variable, m_GrowthFactor, m_MaxBufferSize, m_RankMPI, m_Buffer, m_Transports, m_BP1Writer, m_Cores ); + WriteVariable( group, variableName, variable ); } @@ -288,7 +287,7 @@ void Writer::InitTransports( ) } else if( itTransport->second == "FStream" ) { - auto file = std::make_shared<File>( m_MPIComm, m_DebugMode ); + auto file = std::make_shared<FStream>( m_MPIComm, m_DebugMode ); m_BP1Writer.OpenRankFiles( m_Name, m_AccessMode, *file ); m_Transports.push_back( std::move( file ) ); } @@ -309,7 +308,7 @@ void Writer::InitTransports( ) void Writer::Close( const int transportIndex ) { - //flush the last of data + //flush the last piece of data if( transportIndex == -1 ) // all transports { for( auto& transport : m_Transports ) @@ -321,7 +320,6 @@ void Writer::Close( const int transportIndex ) else { m_Transports[ transportIndex ]->Write( m_Buffer.m_Data.data(), m_Buffer.m_DataPosition ); - m_Transports[ transportIndex ]->Close( ); } //BP1Writer to take care of metadata indices at Close diff --git a/src/format/BP1.cpp b/src/format/BP1.cpp index c7de9e4b69d82424b1f0f989aae1f38aaed699cb..2ea0e054b3a1f69349467f93efadca90ff6fc2f7 100644 --- a/src/format/BP1.cpp +++ b/src/format/BP1.cpp @@ -34,12 +34,12 @@ void BP1::OpenRankFiles( const std::string name, const std::string accessMode, T CreateDirectory( name +".bp.dir" ); } - std::string fileName( directory + "/" + baseName + ".bp" + std::to_string( file.m_MPIRank ) ); + std::string fileName( directory + "/" + baseName + ".bp." + std::to_string( file.m_MPIRank ) ); if( file.m_MPIComm == MPI_COMM_SELF ) fileName = name; - file.Open( fileName, accessMode ); // opens a file transport under name.bp.dir/name.bp.rank + file.Open( fileName, accessMode ); // opens a file transport under name.bp.dir/name.bp.rank reserve that location fro writing } diff --git a/src/format/BP1Writer.cpp b/src/format/BP1Writer.cpp index f512fae78c4ae044fdd0d45604110e6180925fed..eca2a094d375291c8384f324f9f0b0ad7e43146f 100644 --- a/src/format/BP1Writer.cpp +++ b/src/format/BP1Writer.cpp @@ -16,15 +16,6 @@ namespace format { -BP1Writer::BP1Writer( const unsigned int metadataSets ): - m_BPMetadataSets( metadataSets ) -{ } - - -BP1Writer::~BP1Writer( ) -{ } - - std::size_t BP1Writer::GetProcessIndexSize( const std::string name, const std::string timeStepName ) { return name.length() + timeStepName.length() + 23;