diff --git a/bindings/python/include/ADIOSPy.h b/bindings/python/include/ADIOSPy.h index b1a009370675a3bcaeee97598cc7da3a83c2f413..8d2179adb2ef62b9dd89de59dc3bb3a33a3b2d74 100644 --- a/bindings/python/include/ADIOSPy.h +++ b/bindings/python/include/ADIOSPy.h @@ -23,7 +23,7 @@ #include "adios2/pybind11/pybind11.h" #endif -#include "adios2/ADIOS.h" +#include "../../../source/adios2/core/ADIOS.h" #include "adios2/MethodPy.h" #include "adios2/VariablePy.h" #include "adios2/adiosPyFunctions.h" //ListToVector, VectorToList diff --git a/bindings/python/include/MethodPy.h b/bindings/python/include/MethodPy.h index 3b012f566dce3d9fb7f3fe49181d7ea6becebb4a..4187c5f0f41e865368e58ccb703433d736425498 100644 --- a/bindings/python/include/MethodPy.h +++ b/bindings/python/include/MethodPy.h @@ -20,7 +20,7 @@ #include "adios2/pybind11/pybind11.h" #endif -#include "adios2/core/Method.h" +#include "../../../source/adios2/core/IO.h" namespace adios { diff --git a/doc/API_design/API_example_use.cpp b/doc/API_design/API_example_use.cpp index bc1c00fc820732729e2d4fa4ffc0008fd02f2bff..a9e6d4bf162e8631cc992fd861e2401f53dfe4b2 100644 --- a/doc/API_design/API_example_use.cpp +++ b/doc/API_design/API_example_use.cpp @@ -2,7 +2,7 @@ * of the ideas */ #include <mpi.h> -#include "adios2/ADIOS.h" +#include "../../source/adios2/core/ADIOS.h" void cb_AsyncWriteAdvanceCompleted(std::shared_ptr<adios::Engine> writer) { diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index cff55b7612dea88c6033417e74a3e199434fde0a..0ea4819bccbfb48f061076bbadb16dac07818466 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,6 +3,7 @@ # accompanying file Copyright.txt for details. #------------------------------------------------------------------------------# +add_subdirectory(basics) add_subdirectory(hello) add_subdirectory(heatTransfer) add_subdirectory(experimental) diff --git a/examples/basics/CMakeLists.txt b/examples/basics/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..94fa54cd4c435d3cb4b83e199e909d21e85e8194 --- /dev/null +++ b/examples/basics/CMakeLists.txt @@ -0,0 +1,9 @@ +#------------------------------------------------------------------------------# +# Distributed under the OSI-approved Apache License, Version 2.0. See +# accompanying file Copyright.txt for details. +#------------------------------------------------------------------------------# + +add_subdirectory(globalArray) +add_subdirectory(joinedArray) +add_subdirectory(localArray) +add_subdirectory(values) diff --git a/examples/basics/globalArray/CMakeLists.txt b/examples/basics/globalArray/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7a0af15e3e998029c72366b30d034fddab35445c --- /dev/null +++ b/examples/basics/globalArray/CMakeLists.txt @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------# +# Distributed under the OSI-approved Apache License, Version 2.0. See +# accompanying file Copyright.txt for details. +#------------------------------------------------------------------------------# + +add_executable(globalArray_write globalArray_write.cpp) + +if(ADIOS_USE_MPI) + find_package(MPI COMPONENTS C REQUIRED) + + target_include_directories(globalArray_write PRIVATE ${MPI_C_INCLUDE_PATH}) + target_link_libraries(globalArray_write ${MPI_C_LIBRARIES}) + +endif() + +target_link_libraries(globalArray_write adios2) + diff --git a/examples/basics/globalArray/globalArray.xml b/examples/basics/globalArray/globalArray.xml new file mode 100644 index 0000000000000000000000000000000000000000..68b7e9f6e33fd48b7a5fffcbf36754babc6ae3ba --- /dev/null +++ b/examples/basics/globalArray/globalArray.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<adios-config> + + <io name="Output"> + <engine name="BPFileWriter"/> + <transport name= "File"/> + </io> + +</adios-config> + diff --git a/examples/basics/globalArray/globalArray_write.cpp b/examples/basics/globalArray/globalArray_write.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a8a34d46a7f8440acd36709beaa31778c8064b8 --- /dev/null +++ b/examples/basics/globalArray/globalArray_write.cpp @@ -0,0 +1,136 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Write a global array from multiple processors. + * + * A global array is an N-dimensional array. A process can write a sub-array + * into the global array by stating the N-dimensional offset and the size of + * the sub-array. At reading, one can read back any portion of the array + * regardless of how many processors wrote that data. + * + * Processes are NOT required + * - to stay in the boundaries of the global dimensions. However, one will not + * be able to read back data outside of the boundaries. + * - to fill the whole global array, i.e. one can leave holes in it. At reading, + * one will get the fill-value set for the array for those coordinates that + * are not written by any process. + * + * The global dimensions of a global array MUST NOT change over time. + * If they are, then the array should be handled as a local array. Of course, if + * only a single output step is written to a file, that still shows up at + * reading as a global array. + * + * The decomposition of the array across the processes, however, can change + * between output steps. + * + * Created on: Jun 2, 2017 + * Author: pnorbert + */ + +#include <iostream> +#include <vector> + +#include <adios2.h> +#ifdef ADIOS2_HAVE_MPI +#include <mpi.h> +#endif + +int main(int argc, char *argv[]) +{ + int rank = 0, nproc = 1; +#ifdef ADIOS2_HAVE_MPI + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); +#endif + const bool adiosDebug = true; + const int NSTEPS = 5; + +#ifdef ADIOS2_HAVE_MPI + adios::ADIOS adios("globalArray.xml", MPI_COMM_WORLD); +#else + adios::ADIOS adios("globalArray.xml"); +#endif + + // Application variables for output + const unsigned int Nx = 10; + // Global 2D array, size of nproc x Nx, with 1D decomposition + // Each process writes one "row" of the 2D matrix. + std::vector<double> row(Nx); + + try + { + // Get io settings from the config file or + // create one with default settings here + adios::IO &io = adios.DeclareIO("Output"); + + /* + * Define global array: type, name, global dimensions + * The local process' part (start, count) can be defined now or later + * before Write(). + */ + adios::Variable<double> &varGlobalArray = + io.DefineVariable<double>("GlobalArray", {(unsigned int)nproc, Nx}); + + // Open file. "w" means we overwrite any existing file on disk, + // but Advance() will append steps to the same file. + auto writer = io.Open("globalArray.bp", adios::OpenMode::Write); + + if (!writer) + throw std::ios_base::failure( + "ERROR: failed to open file with ADIOS\n"); + + for (int step = 0; step < NSTEPS; step++) + { + for (int i = 0; i < Nx; i++) + { + row[i] = step * Nx * nproc * 1.0 + rank * Nx * 1.0 + (double)i; + } + + // Make a 2D selection to describe the local dimensions of the + // variable we write and its offsets in the global spaces + adios::SelectionBoundingBox sel({(unsigned int)rank, 0}, {1, Nx}); + varGlobalArray.SetSelection(sel); + writer->Write<double>(varGlobalArray, row.data()); + + // Indicate we are done for this step. + // Disk I/O will be performed during this call unless + // time aggregation postpones all of that to some later step + writer->Advance(); + } + + // Called once: indicate that we are done with this output for the run + writer->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"; + } + } + +#ifdef ADIOS2_HAVE_MPI + MPI_Finalize(); +#endif + + return 0; +} diff --git a/examples/basics/joinedArray/CMakeLists.txt b/examples/basics/joinedArray/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c4fe971950a755f41fff0c5b0917bee2c2b20987 --- /dev/null +++ b/examples/basics/joinedArray/CMakeLists.txt @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------# +# Distributed under the OSI-approved Apache License, Version 2.0. See +# accompanying file Copyright.txt for details. +#------------------------------------------------------------------------------# + +add_executable(joinedArray_write joinedArray_write.cpp) + +if(ADIOS_USE_MPI) + find_package(MPI COMPONENTS C REQUIRED) + + target_include_directories(joinedArray_write PRIVATE ${MPI_C_INCLUDE_PATH}) + target_link_libraries(joinedArray_write ${MPI_C_LIBRARIES}) + +endif() + +target_link_libraries(joinedArray_write adios2) + diff --git a/examples/basics/joinedArray/joinedArray.xml b/examples/basics/joinedArray/joinedArray.xml new file mode 100644 index 0000000000000000000000000000000000000000..68b7e9f6e33fd48b7a5fffcbf36754babc6ae3ba --- /dev/null +++ b/examples/basics/joinedArray/joinedArray.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<adios-config> + + <io name="Output"> + <engine name="BPFileWriter"/> + <transport name= "File"/> + </io> + +</adios-config> + diff --git a/examples/basics/joinedArray/joinedArray_write.cpp b/examples/basics/joinedArray/joinedArray_write.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d878ed891430122545fc2bee66e04f0556ec014a --- /dev/null +++ b/examples/basics/joinedArray/joinedArray_write.cpp @@ -0,0 +1,138 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Write local arrays from multiple processors and make ADIOS join them + * at reading to show a global array + * + * If every process has an array that is different only in one dimension + * it can be presented as a global array by joining the arrays together. + * E.g. if every process has a table with a different number of rows, + * and one does not want to do a global communication to calculate the offsets + * in the global table, one can just write the local arrays and let ADIOS + * calculate the offsets at read time (when all sizes are known by any process). + * + * bpls can show the size of each block of the table: + * bpls -D <file> <variable> + * + * Note: only one dimension can be joinable, every other dimension must be the + * same on each process. + * + * Note: the local dimension size in the joinable dimension is allowed to change + * over time within each processor. However, if the sum of all local sizes + * changes over time, the result will look like a local array. + * (Because global arrays with changing global dimension over time can only be + * handled as local arrays in ADIOS) + * + * + * Created on: Jun 2, 2017 + * Author: pnorbert + */ + +#include <iostream> +#include <vector> + +#include <adios2.h> +#ifdef ADIOS2_HAVE_MPI +#include <mpi.h> +#endif + +int main(int argc, char *argv[]) +{ + int rank = 0, nproc = 1; +#ifdef ADIOS2_HAVE_MPI + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); +#endif + const bool adiosDebug = true; + const int NSTEPS = 5; + + // generate different random numbers on each process, + // but always the same sequence at each run + srand(rank * 32767); + +#ifdef ADIOS2_HAVE_MPI + adios::ADIOS adios("localArray.xml", MPI_COMM_WORLD); +#else + adios::ADIOS adios("localArray.xml"); +#endif + + // Application variables for output + // random size per process, 5..10 each + const unsigned int Nrows = rand() % 6 + 5; + const unsigned int Ncols = 4; + // Local array, size is fixed over time on each process + std::vector<double> mytable(Nrows * Ncols); + + try + { + // Get io settings from the config file or + // create one with default settings here + adios::IO &io = adios.DeclareIO("Output"); + + /* + * Define joinable local array: type, name, global and local size + * Starting offset can be an empty vector + * Only one global dimension can be joined + */ + adios::Variable<double> &varTable = io.DefineVariable<double>( + "table", {adios::JoinedDim, Ncols}, {}, {Nrows, Ncols}); + + // Open file. "w" means we overwrite any existing file on disk, + // but Advance() will append steps to the same file. + auto writer = io.Open("joinedArray.bp", adios::OpenMode::Write); + + if (writer == nullptr) + throw std::ios_base::failure( + "ERROR: failed to open file with ADIOS\n"); + + for (int step = 0; step < NSTEPS; step++) + { + for (int row = 0; row < Nrows; row++) + { + for (int col = 0; col < Ncols; col++) + { + mytable[row * Ncols + col] = + rank * 1.0 + row * 0.1 + col * 0.01; + } + } + + writer->Write<double>(varTable, mytable.data()); + + writer->Advance(); + } + + writer->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"; + } + } + +#ifdef ADIOS2_HAVE_MPI + MPI_Finalize(); +#endif + + return 0; +} diff --git a/examples/basics/localArray/CMakeLists.txt b/examples/basics/localArray/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..91077b8cedcd7a2abdb8412a74774f25e14e546d --- /dev/null +++ b/examples/basics/localArray/CMakeLists.txt @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------# +# Distributed under the OSI-approved Apache License, Version 2.0. See +# accompanying file Copyright.txt for details. +#------------------------------------------------------------------------------# + +add_executable(localArray_write localArray_write.cpp) + +if(ADIOS_USE_MPI) + find_package(MPI COMPONENTS C REQUIRED) + + target_include_directories(localArray_write PRIVATE ${MPI_C_INCLUDE_PATH}) + target_link_libraries(localArray_write ${MPI_C_LIBRARIES}) + +endif() + +target_link_libraries(localArray_write adios2) + diff --git a/examples/basics/localArray/localArray.xml b/examples/basics/localArray/localArray.xml new file mode 100644 index 0000000000000000000000000000000000000000..68b7e9f6e33fd48b7a5fffcbf36754babc6ae3ba --- /dev/null +++ b/examples/basics/localArray/localArray.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<adios-config> + + <io name="Output"> + <engine name="BPFileWriter"/> + <transport name= "File"/> + </io> + +</adios-config> + diff --git a/examples/basics/localArray/localArray_write.cpp b/examples/basics/localArray/localArray_write.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1efba98b20b3ab2d5b558ce609ff22027936a8bc --- /dev/null +++ b/examples/basics/localArray/localArray_write.cpp @@ -0,0 +1,151 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Write local arrays from multiple processors. + * + * If one cannot or does not want to organize arrays present on each process + * as one global array, still one can write them out with the same name. + * Reading, however, needs to be handled differently: each process' array has + * to be read separately, using Writeblock selections. The size of each process + * block should be discovered by the reading application by inquiring per-block + * size information of the variable, and allocate memory for reading + * accordingly. + * + * bpls can show the size of each block of the variable: + * bpls -D <file> <variable> + * + * + * Created on: Jun 2, 2017 + * Author: pnorbert + */ + +#include <iostream> +#include <vector> + +#include <adios2.h> +#ifdef ADIOS2_HAVE_MPI +#include <mpi.h> +#endif + +int main(int argc, char *argv[]) +{ + int rank = 0, nproc = 1; +#ifdef ADIOS2_HAVE_MPI + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); +#endif + const bool adiosDebug = true; + const int NSTEPS = 5; + + // generate different random numbers on each process, + // but always the same sequence at each run + srand(rank * 32767); + +#ifdef ADIOS2_HAVE_MPI + adios::ADIOS adios("localArray.xml", MPI_COMM_WORLD); +#else + adios::ADIOS adios("localArray.xml"); +#endif + + // Application variables for output + // random size per process, 5..10 each + unsigned int Nx = rand() % 6 + 5; + // Local array, size is fixed over time on each process + std::vector<double> v1(Nx); + + // random size per process, a different size at each step + unsigned int Nelems; + // Local array, size is changing over time on each process + std::vector<double> v2; + + try + { + // Get io settings from the config file or + // create one with default settings here + adios::IO &io = adios.DeclareIO("Output"); + + /* + * Define local array: type, name, local size + * Global dimension and starting offset must be an empty vector + */ + adios::Variable<double> &varV1 = + io.DefineVariable<double>("v1", {}, {}, {Nx}); + + /* + * Define local array: type, name + * Global dimension and starting offset must be an empty vector + * but local size must NOT be an empty vector. + * We can use {adios::UnknownDim} for this purpose or any number + * but we will modify it before writing + */ + adios::Variable<double> &varV2 = + io.DefineVariable<double>("v2", {}, {}, {adios::UnknownDim}); + + // Open file. "w" means we overwrite any existing file on disk, + // but Advance() will append steps to the same file. + auto writer = io.Open("localArray.bp", adios::OpenMode::Write); + + if (writer == nullptr) + throw std::ios_base::failure( + "ERROR: failed to open file with ADIOS\n"); + + for (int step = 0; step < NSTEPS; step++) + { + for (int i = 0; i < Nx; i++) + { + v1[i] = rank * 1.0 + step * 0.1; + } + + writer->Write<double>(varV1, v1.data()); + + // random size per process per step, 5..10 each + Nelems = rand() % 6 + 5; + v2.reserve(Nelems); + for (int i = 0; i < Nelems; i++) + { + v2[i] = rank * 1.0 + step * 0.1; + } + + // Set the size of the array now because we did not know + // the size at the time of definition + varV2.SetSelection({}, {Nelems}); + writer->Write<double>(varV2, v2.data()); + + writer->Advance(); + } + + writer->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"; + } + } + +#ifdef ADIOS2_HAVE_MPI + MPI_Finalize(); +#endif + + return 0; +} diff --git a/examples/basics/values/CMakeLists.txt b/examples/basics/values/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b5894f894d855a004bcce67448470ea633b18b67 --- /dev/null +++ b/examples/basics/values/CMakeLists.txt @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------# +# Distributed under the OSI-approved Apache License, Version 2.0. See +# accompanying file Copyright.txt for details. +#------------------------------------------------------------------------------# + +add_executable(values_write values_write.cpp) + +if(ADIOS_USE_MPI) + find_package(MPI COMPONENTS C REQUIRED) + + target_include_directories(values_write PRIVATE ${MPI_C_INCLUDE_PATH}) + target_link_libraries(values_write ${MPI_C_LIBRARIES}) + +endif() + +target_link_libraries(values_write adios2) + diff --git a/examples/basics/values/values.xml b/examples/basics/values/values.xml new file mode 100644 index 0000000000000000000000000000000000000000..68b7e9f6e33fd48b7a5fffcbf36754babc6ae3ba --- /dev/null +++ b/examples/basics/values/values.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<adios-config> + + <io name="Output"> + <engine name="BPFileWriter"/> + <transport name= "File"/> + </io> + +</adios-config> + diff --git a/examples/basics/values/values_write.cpp b/examples/basics/values/values_write.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90e3fd4bde97188564eebbb9d1bdb9936eae6171 --- /dev/null +++ b/examples/basics/values/values_write.cpp @@ -0,0 +1,158 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Write single values to a file. There are four different cases: + * 1. Global constant - same on all processes, constant over time + * 2. Global value - same on all processes, may change over time + * 3. Local constants - different across processes, constant over time + * 4. Local value - different across processes, may change over time + * + * Constants are not handled separately from time-varying values in ADIOS. + * Simply write them only in the first step. + * + * Writing a global value from multiple processes does not hurt but it is + * useless. + * + * Created on: Jun 2, 2017 + * Author: pnorbert + */ + +#include <iostream> +#include <vector> + +#include <adios2.h> +#ifdef ADIOS2_HAVE_MPI +#include <mpi.h> +#endif + +int main(int argc, char *argv[]) +{ + int rank = 0, nproc = 1; +#ifdef ADIOS2_HAVE_MPI + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); +#endif + const bool adiosDebug = true; + const int NSTEPS = 5; + + // generate different random numbers on each process, + // but always the same sequence at each run + srand(rank * 32767); + +#ifdef ADIOS2_HAVE_MPI + adios::ADIOS adios("values.xml", MPI_COMM_WORLD); +#else + adios::ADIOS adios("values.xml"); +#endif + + // Application variables for output + // 1. Global value, constant across processes, constant over time + // This is 'nproc' + + // 2. Global value, constant across processes, varying value over time + // This is 'step' + + // 3. Local value, varying across processes, constant over time + // It will appear in reading as a 1D array of nproc elements. + // This is 'rank' + + // 4. Local value, varying across processes, varying over time + unsigned int Nparts; // random size per process, 5..10 each + + try + { + // Get io settings from the config file or + // create one with default settings here + adios::IO &io = adios.DeclareIO("Output"); + + /* + * Define variables + */ + // 1. Global constant, same value across processes, constant over time + adios::Variable<int> &varNproc = io.DefineVariable<int>("Nproc"); + + // 2. Global value, same value across processes, varying value over time + adios::Variable<int> &varStep = io.DefineVariable<int>("Step"); + + // 3. Local value, varying across processes, constant over time + adios::Variable<int> &varProcessID = + io.DefineVariable<int>("ProcessID", {adios::LocalValueDim}); + + // 4. Local value, varying across processes, varying over time + adios::Variable<unsigned int> &varNparts = + io.DefineVariable<unsigned int>("Nparts", {adios::LocalValueDim}); + + // Open file. "w" means we overwrite any existing file on disk, + // but Advance() will append steps to the same file. + auto writer = io.Open("values.bp", adios::OpenMode::Write); + + if (!writer) + throw std::ios_base::failure( + "ERROR: failed to open file with ADIOS\n"); + + for (int step = 0; step < NSTEPS; step++) + { + // random size per process, 5..10 each + Nparts = rand() % 6 + 5; + + // 1. and 2. Writing a global value from only one process + if (rank == 0) + { + // 1. Writing a global constant value only once + if (step == 0) + { + writer->Write<int>("Nproc", nproc); + } + writer->Write<int>(varStep, step); + } + + // 3. and 4. Writing a local value on every process. Will be shown + // at reading as a 1D array + if (step == 0) + { + writer->Write<int>(varProcessID, rank); + } + writer->Write<unsigned int>(varNparts, Nparts); + + // Indicate we are done for this step. + // Disk I/O will be performed during this call unless + // time aggregation postpones all of that to some later step + writer->Advance(); + } + + // Called once: indicate that we are done with this output for the run + writer->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"; + } + } + +#ifdef ADIOS2_HAVE_MPI + MPI_Finalize(); +#endif + + return 0; +} diff --git a/examples/experimental/multistep/reader_allsteps.cpp b/examples/experimental/multistep/reader_allsteps.cpp index 6e669aec53ec4befb693bab12e3af9498f45f1a9..7b50a98bace368713560061a28bda4509d1671e8 100644 --- a/examples/experimental/multistep/reader_allsteps.cpp +++ b/examples/experimental/multistep/reader_allsteps.cpp @@ -73,9 +73,9 @@ int main(int argc, char *argv[]) const bool adiosDebug = true; #ifdef ADIOS2_HAVE_MPI - adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN); + adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON); #else - adios::ADIOS adios(adios::Verbose::WARN); + adios::ADIOS adios(adios::DebugON); #endif // Info variables from the file @@ -108,8 +108,8 @@ int main(int argc, char *argv[]) { // Define method for engine creation // 1. Get method def from config file or define new one - adios::Method &bpReaderSettings = adios.DeclareMethod("input"); - if (!bpReaderSettings.IsUserDefined()) + adios::IO &bpReaderSettings = adios.DeclareIO("input"); + if (!bpReaderSettings.InConfigFile()) { // if not defined by user, we can change the default settings bpReaderSettings.SetEngine( @@ -122,9 +122,10 @@ int main(int argc, char *argv[]) // 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); + auto bpReader = + bpReaderSettings.Open("myNumbers.bp", adios::OpenMode::Read); - if (bpReader == nullptr) + if (!bpReader) throw std::ios_base::failure( "ERROR: failed to open ADIOS bpReader\n"); @@ -132,7 +133,7 @@ int main(int argc, char *argv[]) * own * number of steps */ - adios::Variable<int> *vNproc = bpReader->InquireVariableInt("Nproc"); + adios::Variable<int> *vNproc = bpReader->InquireVariable<int>("Nproc"); Nwriters = vNproc->m_Data[0]; if (rank == 0) std::cout << "# of writers = " << Nwriters << std::endl; @@ -142,7 +143,7 @@ int main(int argc, char *argv[]) */ // read a Global scalar which has a single value in a step adios::Variable<unsigned int> *vNX = - bpReader->InquireVariableUInt("NX"); + bpReader->InquireVariable<unsigned int>("NX"); Nx = vNX->m_Data[0]; // bpReader->Read<unsigned int>("NX", &Nx); if (rank == 0) @@ -154,19 +155,19 @@ int main(int argc, char *argv[]) and read does not read it as array by default. */ adios::Variable<unsigned int> *vNY = - bpReader->InquireVariableUInt("NY"); - Nys.resize(vNY->GetNSteps()); // number of steps available + bpReader->InquireVariable<unsigned int>("NY"); + Nys.resize(vNY->m_AvailableSteps); // number of steps available // make a StepSelection to select multiple steps. Args: From, #of // consecutive steps // ? How do we make a selection for an arbitrary list of steps ? - vNY->SetStepSelection(0, vNY->GetNSteps()); + vNY->SetStepSelection(0, vNY->m_AvailableSteps); bpReader->Read<unsigned int>(*vNY, Nys.data()); if (rank == 0) Print1DArray(Nys.data(), Nys.size(), "NY"); /* ProcessID */ adios::Variable<int> *vProcessID = - bpReader->InquireVariableInt("ProcessID"); + bpReader->InquireVariable<int>("ProcessID"); if (vProcessID->m_Shape[0] != Nwriters) { std::cout << "ERROR: Unexpected array size of ProcessID = " @@ -183,13 +184,13 @@ int main(int argc, char *argv[]) // elements. // We can read all steps into a 2D array of nproc * Nwriters adios::Variable<unsigned int> *vNparts = - bpReader->InquireVariableUInt("Nparts"); + bpReader->InquireVariable<unsigned int>("Nparts"); unsigned int **Nparts = - Make2DArray<unsigned int>(vNparts->GetNSteps(), Nwriters); - vNparts->SetStepSelection(0, vNparts->GetNSteps()); + Make2DArray<unsigned int>(vNparts->m_AvailableSteps, Nwriters); + vNparts->SetStepSelection(0, vNparts->m_AvailableSteps); bpReader->Read<unsigned int>(*vNparts, Nparts[0]); if (rank == 0) - Print2DArray(Nparts, vNparts->GetNSteps(), Nwriters, "Nparts"); + Print2DArray(Nparts, vNparts->m_AvailableSteps, Nwriters, "Nparts"); Delete2DArray(Nparts); #ifdef ADIOS2_HAVE_MPI MPI_Barrier(MPI_COMM_WORLD); @@ -200,7 +201,7 @@ int main(int argc, char *argv[]) */ // inquiry about a variable, whose name we know adios::Variable<double> *vGlobalArrayFixedDims = - bpReader->InquireVariableDouble("GlobalArrayFixedDims"); + bpReader->InquireVariable<double>("GlobalArrayFixedDims"); if (vGlobalArrayFixedDims == nullptr) throw std::ios_base::failure( @@ -221,43 +222,39 @@ int main(int argc, char *argv[]) std::cout << "GlobalArrayFixedDims parallel read" << std::endl; double **GlobalArrayFixedDims = - Make2DArray<double>(vGlobalArrayFixedDims->GetNSteps(), count); + Make2DArray<double>(vGlobalArrayFixedDims->m_AvailableSteps, count); // Make a 1D selection to describe the local dimensions of the variable // we READ and its offsets in the global spaces vGlobalArrayFixedDims->SetSelection({start}, {count}); vGlobalArrayFixedDims->SetStepSelection( - 0, vGlobalArrayFixedDims->GetNSteps()); + 0, vGlobalArrayFixedDims->m_AvailableSteps); bpReader->Read<double>(*vGlobalArrayFixedDims, GlobalArrayFixedDims[0]); #ifdef ADIOS2_HAVE_MPI MPI_Barrier(MPI_COMM_WORLD); MPI_Status status; -#endif - int token = 0; -#ifdef ADIOS2_HAVE_MPI if (rank > 0) MPI_Recv(&token, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD, &status); +#endif std::cout << "Rank " << rank << " read start = " << start << " count = " << count << std::endl; -#endif - Print2DArray(GlobalArrayFixedDims, vGlobalArrayFixedDims->GetNSteps(), - count, "GlobalArrayFixedDims"); + Print2DArray(GlobalArrayFixedDims, + vGlobalArrayFixedDims->m_AvailableSteps, count, + "GlobalArrayFixedDims"); #ifdef ADIOS2_HAVE_MPI if (rank < nproc - 1) MPI_Send(&token, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD); -#endif - Delete2DArray(GlobalArrayFixedDims); -#ifdef ADIOS2_HAVE_MPI MPI_Barrier(MPI_COMM_WORLD); #endif + Delete2DArray(GlobalArrayFixedDims); /* * LocalArrayFixedDims */ // inquiry about a variable, whose name we know adios::Variable<float> *vLocalArrayFixedDims = - bpReader->InquireVariableFloat("LocalArrayFixedDims"); + bpReader->InquireVariable<float>("LocalArrayFixedDims"); if (vLocalArrayFixedDims->m_Shape[0] != adios::IrregularDim) { throw std::ios_base::failure( @@ -276,9 +273,9 @@ int main(int argc, char *argv[]) */ // inquiry about a variable, whose name we know adios::Variable<float> *vLocalArrayFixedDimsJoined = - bpReader->InquireVariableFloat("LocalArrayFixedDimsJoined"); + bpReader->InquireVariable<float>("LocalArrayFixedDimsJoined"); float **LocalArrayFixedDimsJoined = - Make2DArray<float>(vLocalArrayFixedDimsJoined->GetNSteps(), + Make2DArray<float>(vLocalArrayFixedDimsJoined->m_AvailableSteps, vLocalArrayFixedDimsJoined->m_Shape[0]); // Make a 1D selection to describe the local dimensions of the variable @@ -286,12 +283,12 @@ int main(int argc, char *argv[]) vLocalArrayFixedDimsJoined->SetSelection( {0}, {vLocalArrayFixedDimsJoined->m_Shape[0]}); vLocalArrayFixedDimsJoined->SetStepSelection( - 0, vLocalArrayFixedDimsJoined->GetNSteps()); + 0, vLocalArrayFixedDimsJoined->m_AvailableSteps); bpReader->Read<float>(*vLocalArrayFixedDimsJoined, LocalArrayFixedDimsJoined[0]); if (rank == 0) Print2DArray(LocalArrayFixedDimsJoined, - vLocalArrayFixedDimsJoined->GetNSteps(), + vLocalArrayFixedDimsJoined->m_AvailableSteps, vLocalArrayFixedDimsJoined->m_Shape[0], "LocalArrayFixedDimsJoined"); Delete2DArray(LocalArrayFixedDimsJoined); @@ -304,7 +301,7 @@ int main(int argc, char *argv[]) */ // inquiry about a variable, whose name we know adios::Variable<double> *vGlobalArray = - bpReader->InquireVariableDouble("GlobalArray"); + bpReader->InquireVariable<double>("GlobalArray"); std::cout << "GlobalArray [" << vGlobalArray->m_Shape[0] << "]"; std::cout << " = Cannot read this variable yet...\n"; if (vGlobalArray->m_Shape[0] != adios::IrregularDim) diff --git a/examples/experimental/multistep/reader_stepping.cpp b/examples/experimental/multistep/reader_stepping.cpp index dbb88b5f2c1e1648db7926b0f68a9ef440646c32..cdee26c1f57dfdb60bd963d54257d4da3370e742 100644 --- a/examples/experimental/multistep/reader_stepping.cpp +++ b/examples/experimental/multistep/reader_stepping.cpp @@ -26,9 +26,9 @@ int main(int argc, char *argv[]) const bool adiosDebug = true; #ifdef ADIOS2_HAVE_MPI - adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN); + adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON); #else - adios::ADIOS adios(adios::Verbose::WARN); + adios::ADIOS adios(adios::DebugON); #endif // Info variables from the file @@ -60,8 +60,8 @@ int main(int argc, char *argv[]) { // Define method for engine creation // 1. Get method def from config file or define new one - adios::Method &bpReaderSettings = adios.DeclareMethod("input"); - if (!bpReaderSettings.IsUserDefined()) + adios::IO &bpReaderSettings = adios.DeclareIO("input"); + if (!bpReaderSettings.InConfigFile()) { // if not defined by user, we can change the default settings bpReaderSettings.SetEngine( @@ -70,8 +70,9 @@ int main(int argc, char *argv[]) // this is default, nothing to be done } - auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings); - if (bpReader != nullptr) + auto bpReader = + bpReaderSettings.Open("myNumbers.bp", adios::OpenMode::Read); + if (!bpReader) { int step = 0; while (bpReader->GetAdvanceStatus() == adios::AdvanceStatus::OK) @@ -83,19 +84,19 @@ int main(int argc, char *argv[]) { // read a Global scalar which has a single value in a step adios::Variable<int> *vNproc = - bpReader->InquireVariableInt("Nproc"); + bpReader->InquireVariable<int>("Nproc"); Nwriters = vNproc->m_Data[0]; std::cout << "# of writers = " << Nwriters << std::endl; adios::Variable<unsigned int> *vNX = - bpReader->InquireVariableUInt("NX"); + bpReader->InquireVariable<unsigned int>("NX"); Nx = vNX->m_Data[0]; // bpReader->Read<unsigned int>("NX", &Nx); std::cout << "NX = " << Nx << std::endl; } adios::Variable<unsigned int> *vNY = - bpReader->InquireVariableUInt("NY"); + bpReader->InquireVariable<unsigned int>("NY"); Ny = vNY->m_Data[0]; std::cout << "NY = " << Ny << std::endl; @@ -115,27 +116,21 @@ int main(int argc, char *argv[]) } catch (std::invalid_argument &e) { - if (rank == 0) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " + << rank << "\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"; - } + std::cout + << "IO System base failure exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; } catch (std::exception &e) { - if (rank == 0) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; } #ifdef ADIOS2_HAVE_MPI diff --git a/examples/experimental/multistep/writer_multistep.cpp b/examples/experimental/multistep/writer_multistep.cpp index fce148ff74ed4e290dccf34926b08f84266daa77..dc2c4706492d19b2f29b4cd9f225aa36e1dcd9f5 100644 --- a/examples/experimental/multistep/writer_multistep.cpp +++ b/examples/experimental/multistep/writer_multistep.cpp @@ -32,9 +32,9 @@ int main(int argc, char *argv[]) srand(rank * 32767); #ifdef ADIOS2_HAVE_MPI - adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN); + adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON); #else - adios::ADIOS adios(adios::Verbose::WARN); + adios::ADIOS adios(adios::DebugON); #endif // Application variables for output @@ -61,88 +61,99 @@ int main(int argc, char *argv[]) try { + + // Define method for engine creation + // 1. Get method def from config file or define new one + adios::IO &bpWriterSettings = adios.DeclareIO("output"); + if (!bpWriterSettings.InConfigFile()) + { + // if not defined by user, we can change the default settings + bpWriterSettings.SetEngine("ADIOS1Writer"); + // ISO-POSIX file is the default transport + // Passing parameters to the transport + bpWriterSettings.AddTransport("file" +#ifdef ADIOS2_HAVE_MPI + , + "library=MPI-IO" +#endif + ); + // Passing parameters to the engine + bpWriterSettings.SetParameters("have_metadata_file=yes"); + // number of aggregators + // bpWriterSettings.SetParameters("Aggregation", (nproc + 1) / 2); + } /* * Define variables */ // 1. Global value, constant across processes, constant over time adios::Variable<unsigned int> &varNX = - adios.DefineVariable<unsigned int>("NX"); - adios::Variable<int> &varNproc = adios.DefineVariable<int>("Nproc"); + bpWriterSettings.DefineVariable<unsigned int>("NX"); + adios::Variable<int> &varNproc = + bpWriterSettings.DefineVariable<int>("Nproc"); // 2. Local value, varying across processes, constant over time adios::Variable<int> &varProcessID = - adios.DefineVariable<int>("ProcessID", {adios::LocalValueDim}); + bpWriterSettings.DefineVariable<int>("ProcessID", + {adios::LocalValueDim}); - // 3. Global array, global dimensions (shape), offsets (start) and local + // 3. Global array, global dimensions (shape), offsets (start) and + // local // dimensions (count) are constant over time adios::Variable<double> &varGlobalArrayFixedDims = - adios.DefineVariable<double>("GlobalArrayFixedDims", {nproc * Nx}); + bpWriterSettings.DefineVariable<double>("GlobalArrayFixedDims", + {nproc * Nx}); // 4. Local array, local dimensions and offsets are // constant over time. // 4.a. Want to see this at reading as a bunch of local arrays adios::Variable<float> &varLocalArrayFixedDims = - adios.DefineVariable<float>("LocalArrayFixedDims", {}, {}, - {LocalArrayFixedDims.size()}); + bpWriterSettings.DefineVariable<float>( + "LocalArrayFixedDims", {}, {}, {LocalArrayFixedDims.size()}); // 4.b. Joined array, a 1D array, with global dimension and offsets // calculated at read time adios::Variable<float> &varLocalArrayFixedDimsJoined = - adios.DefineVariable<float>("LocalArrayFixedDimsJoined", - {adios::JoinedDim}, {}, - {LocalArrayFixedDims.size()}); + bpWriterSettings.DefineVariable<float>( + "LocalArrayFixedDimsJoined", {adios::JoinedDim}, {}, + {LocalArrayFixedDims.size()}); - // 5. Global value, constant across processes, VARYING value over time + // 5. Global value, constant across processes, VARYING value over + // time adios::Variable<unsigned int> &varNY = - adios.DefineVariable<unsigned int>("NY"); + bpWriterSettings.DefineVariable<unsigned int>("NY"); // 6. Local value, varying across processes, VARYING over time adios::Variable<unsigned int> &varNparts = - adios.DefineVariable<unsigned int>("Nparts", - {adios::LocalValueDim}); + bpWriterSettings.DefineVariable<unsigned int>( + "Nparts", {adios::LocalValueDim}); // 7. Global array, dimensions and offsets are VARYING over time adios::Variable<double> &varGlobalArray = - adios.DefineVariable<double>("GlobalArray", {adios::UnknownDim}); + bpWriterSettings.DefineVariable<double>("GlobalArray", + {adios::UnknownDim}); // 8. Local array, dimensions and offsets are VARYING over time - adios::Variable<float> &varIrregularArray = adios.DefineVariable<float>( - "Irregular", {}, {}, {adios::UnknownDim}); + adios::Variable<float> &varIrregularArray = + bpWriterSettings.DefineVariable<float>("Irregular", {}, {}, + {adios::UnknownDim}); - // add transform to variable in group...not executed (just testing API) + // 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.DeclareMethod("output"); - if (!bpWriterSettings.IsUserDefined()) - { - // if not defined by user, we can change the default settings - bpWriterSettings.SetEngine("ADIOS1Writer"); - // ISO-POSIX file is the default transport - // Passing parameters to the transport - bpWriterSettings.AddTransport("File" -#ifdef ADIOS2_HAVE_MPI - , - "library=MPI-IO" -#endif - ); - // Passing parameters to the engine - bpWriterSettings.SetParameters("have_metadata_file", "yes"); - // number of aggregators - // bpWriterSettings.SetParameters("Aggregation", (nproc + 1) / 2); - } - // 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); + auto bpWriter = + bpWriterSettings.Open("myNumbers.bp", adios::OpenMode::Write); - if (bpWriter == nullptr) + if (!bpWriter) + { throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n"); + } for (int step = 0; step < NSTEPS; step++) { @@ -232,27 +243,21 @@ int main(int argc, char *argv[]) } catch (std::invalid_argument &e) { - if (rank == 0) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " + << rank << "\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"; - } + std::cout + << "IO System base failure exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; } catch (std::exception &e) { - if (rank == 0) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; } #ifdef ADIOS2_HAVE_MPI diff --git a/examples/heatTransfer/CMakeLists.txt b/examples/heatTransfer/CMakeLists.txt index 02e4cd30c850a0af1b3cd322cd386cb61a766109..09392deb58488b28cb45f1f71512678aa4bc12e9 100644 --- a/examples/heatTransfer/CMakeLists.txt +++ b/examples/heatTransfer/CMakeLists.txt @@ -3,5 +3,10 @@ # accompanying file Copyright.txt for details. #------------------------------------------------------------------------------# -add_subdirectory(write) -add_subdirectory(read) + +if(ADIOS_USE_ADIOS1) + add_subdirectory(write) + add_subdirectory(read) +endif() + + diff --git a/examples/heatTransfer/read/heatRead_adios2.cpp b/examples/heatTransfer/read/heatRead_adios2.cpp index 0bc88e911647f3166b9a2b451c6798484d47216c..93bc3faf9f691928114609678f9d8c6602a207c9 100644 --- a/examples/heatTransfer/read/heatRead_adios2.cpp +++ b/examples/heatTransfer/read/heatRead_adios2.cpp @@ -44,30 +44,32 @@ int main(int argc, char *argv[]) MPI_Comm_rank(mpiReaderComm, &rank); MPI_Comm_size(mpiReaderComm, &nproc); - adios::ADIOS ad("adios2.xml", mpiReaderComm, adios::Verbose::INFO); + adios::ADIOS ad("adios2.xml", mpiReaderComm, adios::DebugON); // Define method for engine creation // 1. Get method def from config file or define new one - adios::Method &bpReaderSettings = ad.DeclareMethod("input"); - if (!bpReaderSettings.IsUserDefined()) + adios::IO &bpReaderIO = ad.DeclareIO("input"); + if (!bpReaderIO.InConfigFile()) { // if not defined by user, we can change the default settings // BPFileWriter is the default engine - bpReaderSettings.SetEngine("ADIOS1Reader"); - // Allow an extra thread for data processing - bpReaderSettings.AllowThreads(1); + bpReaderIO.SetEngine("ADIOS1Reader"); + bpReaderIO.SetParameters("num_threads=2"); + // ISO-POSIX file is the default transport // Passing parameters to the transport - bpReaderSettings.AddTransport("File", "verbose=4"); - bpReaderSettings.SetParameters("OpenAsFile"); + bpReaderIO.AddTransport("File", "verbose=4"); } - auto bpReader = ad.Open(inputfile, "r", mpiReaderComm, bpReaderSettings); + auto bpReader = + bpReaderIO.Open(inputfile, adios::OpenMode::Read, mpiReaderComm); - if (bpReader == nullptr) + if (!bpReader) + { throw std::ios_base::failure("ERROR: failed to open " + std::string(inputfile) + "\n"); + } unsigned int gndx; unsigned int gndy; @@ -75,17 +77,19 @@ int main(int argc, char *argv[]) // bpReader->Read<unsigned int>("gndy", &gndy); adios::Variable<unsigned int> *vgndx = - bpReader->InquireVariableUInt("gndx"); + bpReader->InquireVariable<unsigned int>("gndx"); + gndx = vgndx->m_Data[0]; + adios::Variable<unsigned int> *vgndy = - bpReader->InquireVariableUInt("gndy"); + bpReader->InquireVariable<unsigned int>("gndy"); gndy = vgndy->m_Data[0]; if (rank == 0) { std::cout << "gndx = " << gndx << std::endl; std::cout << "gndy = " << gndy << std::endl; - std::cout << "# of steps = " << vgndy->GetNSteps() << std::endl; + std::cout << "# of steps = " << vgndy->m_AvailableSteps << std::endl; } // 1D decomposition of the columns, which is inefficient for reading! @@ -100,20 +104,20 @@ int main(int argc, char *argv[]) std::cout << "rank " << rank << " reads " << readsize[1] << " columns from offset " << offset[1] << std::endl; - adios::Variable<double> *vT = bpReader->InquireVariableDouble("T"); + adios::Variable<double> *vT = bpReader->InquireVariable<double>("T"); - double *T = new double[vT->GetNSteps() * readsize[0] * readsize[1]]; + double *T = new double[vT->m_AvailableSteps * readsize[0] * readsize[1]]; // Create a 2D selection for the subset vT->SetSelection(offset, readsize); - vT->SetStepSelection(0, vT->GetNSteps()); + vT->SetStepSelection(0, vT->m_AvailableSteps); // Arrays are read by scheduling one or more of them // and performing the reads at once bpReader->ScheduleRead<double>(*vT, T); - bpReader->PerformReads(adios::PerformReadMode::BLOCKINGREAD); + bpReader->PerformReads(adios::ReadMode::Blocking); - printData(T, readsize.data(), offset.data(), rank, vT->GetNSteps()); + printData(T, readsize.data(), offset.data(), rank, vT->m_AvailableSteps); bpReader->Close(); delete[] T; MPI_Finalize(); diff --git a/examples/heatTransfer/write/IO_adios1.cpp b/examples/heatTransfer/write/IO_adios1.cpp index 95e0be201a853095b8f96b23a29653e6d1cfb0bc..caba2796b3d8206d95606b6f201ce2b571dea3eb 100644 --- a/examples/heatTransfer/write/IO_adios1.cpp +++ b/examples/heatTransfer/write/IO_adios1.cpp @@ -30,7 +30,7 @@ IO::IO(const Settings &s, MPI_Comm comm) m_outputfilename = s.outputfile + ".bp"; adios_init_noxml(comm); adios_declare_group(&group, "heat", "", adios_stat_default); - adios_select_method(group, "MPI", "", ""); + adios_select_method(group, "POSIX", "", ""); adios_define_var(group, "gndx", "", adios_integer, "", "", ""); adios_define_var(group, "gndy", "", adios_integer, "", "", ""); diff --git a/examples/heatTransfer/write/IO_adios2.cpp b/examples/heatTransfer/write/IO_adios2.cpp index 13fd9a45cd9f26cd7a73d520dde7806598d389e7..7db73cacc27d93321931fad49e2c6e1a15c2a789 100644 --- a/examples/heatTransfer/write/IO_adios2.cpp +++ b/examples/heatTransfer/write/IO_adios2.cpp @@ -24,35 +24,26 @@ IO::IO(const Settings &s, MPI_Comm comm) { rank_saved = s.rank; m_outputfilename = s.outputfile + ".bp"; - ad = new adios::ADIOS("adios2.xml", comm, adios::Verbose::INFO); + ad = new adios::ADIOS("config.xml", comm, adios::DebugON); // Define method for engine creation - // 1. Get method def from config file or define new one - adios::Method &bpWriterSettings = ad->DeclareMethod("output"); - if (!bpWriterSettings.IsUserDefined()) + adios::IO &bpio = ad->DeclareIO("output"); + if (!bpio.InConfigFile()) { // if not defined by user, we can change the default settings // BPFileWriter is the default engine - bpWriterSettings.SetEngine("ADIOS1Writer"); + // Allow an extra thread for data processing - bpWriterSettings.AllowThreads(1); // ISO-POSIX file is the default transport // Passing parameters to the transport - bpWriterSettings.AddTransport("File", "library=MPI-IO"); - - const std::string aggregatorsParam("Aggregators=" + - std::to_string((s.nproc + 1) / 2)); - bpWriterSettings.SetParameters("have_metadata_file=yes", - aggregatorsParam); } - // ad->DefineScalar<unsigned int>("gndx", true); - varGndx = &ad->DefineVariable<unsigned int>("gndx"); - ad->DefineVariable<unsigned int>("gndy"); + varGndx = &bpio.DefineVariable<unsigned int>("gndx"); + bpio.DefineVariable<unsigned int>("gndy"); // define T as 2D global array - varT = &ad->DefineArray<double>( + varT = &bpio.DefineVariable<double>( "T", // Global dimensions {s.gndx, s.gndy}, @@ -66,10 +57,12 @@ IO::IO(const Settings &s, MPI_Comm comm) // varT.AddTransform( tr, "" ); // varT.AddTransform( tr,"accuracy=0.001" ); // for ZFP - bpWriter = ad->Open(m_outputfilename, "w", comm, bpWriterSettings); + bpWriter = bpio.Open(m_outputfilename, adios::OpenMode::Write, comm); - if (bpWriter == nullptr) + if (!bpWriter) + { throw std::ios_base::failure("ERROR: failed to open ADIOS bpWriter\n"); + } } IO::~IO() diff --git a/examples/heatTransfer/write/IO_ph5_adios2.cpp b/examples/heatTransfer/write/IO_ph5_adios2.cpp index e694d9f291698cbb51f4bc8b0e304e32d6d90e1f..01fca5621dc5fdb1c3a193511f08525cbe61d077 100644 --- a/examples/heatTransfer/write/IO_ph5_adios2.cpp +++ b/examples/heatTransfer/write/IO_ph5_adios2.cpp @@ -24,46 +24,44 @@ IO::IO(const Settings &s, MPI_Comm comm) { rank_saved = s.rank; m_outputfilename = s.outputfile + ".h5"; - // adios::ADIOS adios(comm, adios::Verbose::INFO, false); - ad = new adios::ADIOS(comm, adios::Verbose::INFO, false); + ad = new adios::ADIOS(comm, adios::DebugOFF); // Define method for engine creation // 1. Get method def from config file or define new one - adios::Method &h5writerSettings = ad->DeclareMethod("output"); - if (!h5writerSettings.IsUserDefined()) + adios::IO &h5io = ad->DeclareIO("output"); + if (!h5io.InConfigFile()) { // if not defined by user, we can change the default settings // BPFileWriter is the default engine - h5writerSettings.SetEngine("HDF5Writer"); + h5io.SetEngine("HDF5Writer"); // Allow an extra thread for data processing const std::string aggregatorsParam("Aggregators=" + std::to_string((s.nproc + 1) / 2)); - h5writerSettings.SetParameters("have_metadata_file=yes", - aggregatorsParam); + h5io.SetParameters("have_metadata_file=yes", aggregatorsParam); } // ad->DefineScalar<unsigned int>("gndx", true); - varGndx = &(ad->DefineVariable<unsigned int>("gndx")); - ad->DefineVariable<unsigned int>("gndy"); + varGndx = &h5io.DefineVariable<unsigned int>("gndx"); + h5io.DefineVariable<unsigned int>("gndy"); // define T as 2D global array - varT = &(ad->DefineArray<double>( + varT = &h5io.DefineVariable<double>( "T", // Global dimensions {s.gndx, s.gndy}, // starting offset of the local array in the global space {s.offsx, s.offsy}, // local size, could be defined later using SetSelection() - {s.ndx, s.ndy})); + {s.ndx, s.ndy}); // add transform to variable // adios::Transform tr = adios::transform::BZIP2( ); // varT.AddTransform( tr, "" ); // varT.AddTransform( tr,"accuracy=0.001" ); // for ZFP - h5writer = ad->Open(m_outputfilename, "w", comm, h5writerSettings); + h5writer = h5io.Open(m_outputfilename, adios::OpenMode::Write, comm); if (h5writer == nullptr) throw std::ios_base::failure("ERROR: failed to open ADIOS h5writer\n"); diff --git a/examples/hello/CMakeLists.txt b/examples/hello/CMakeLists.txt index 6719c2042ff03407a28f5e4e27c7402a2463c5d2..d01f1256fc13d301d7616c0ddf55547b8fce2b23 100644 --- a/examples/hello/CMakeLists.txt +++ b/examples/hello/CMakeLists.txt @@ -4,7 +4,7 @@ #------------------------------------------------------------------------------# add_subdirectory(bpWriter) -add_subdirectory(timeBP) +add_subdirectory(bpTimeWriter) if(ADIOS_USE_ADIOS1) add_subdirectory(adios1Writer) diff --git a/examples/hello/README.md b/examples/hello/README.md index 0c780bd6b2830759ef4f16846646dd326d3e0404..c08d40e97f23217ddf2cbf34cf72c670c8d901d7 100644 --- a/examples/hello/README.md +++ b/examples/hello/README.md @@ -1,13 +1,15 @@ examples/hello -Provides tests and illustrates how to use very basic functionality for a new component in adios2 - +Provides tests and illustrates how to use very basic functionality in adios2 * adios1Writer (ADIOS_USE_ADIOS1=ON) - 1. Write BP format files using adios1 library through adios2 interface + 1. Write BP format files using adios1 library through adios2 interface * bpWriter - 1. Write BP format files + 1. Write BP format files for one Variable + +* bpTimeWriter + 1. Write BP format files for two Variables (one is timestep) using time aggregation * datamanReader (to be deprecated, ADIOS_USE_DataMan=ON) 1. Read real-time WAN streams using dataman diff --git a/examples/hello/adios1Writer/helloADIOS1Writer.cpp b/examples/hello/adios1Writer/helloADIOS1Writer.cpp index 7403775dfe897f2e0ffbdc7fc3e3f8cb07066672..1041f895cafe00c998b1adc4a7d8a3dc7486e604 100644 --- a/examples/hello/adios1Writer/helloADIOS1Writer.cpp +++ b/examples/hello/adios1Writer/helloADIOS1Writer.cpp @@ -2,118 +2,86 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloWriter.cpp + * helloADIOS1Writer.cpp : Simple self-descriptive example of how to write a + * variable to a ADIOS1 BP File that lives in several MPI processes. Test runs + * when ADIOS2 is linked with ADIOS1 library * * Created on: Feb 16, 2017 - * Author: wfg + * Author: Norbert Podhorszki pnorbert@ornl.gov */ -#include <iostream> +#include <ios> //std::ios_base::failure +#include <iostream> //std::cout +#include <stdexcept> //std::invalid_argument std::exception #include <vector> -#include <mpi.h> - #include <adios2.h> +#ifdef ADIOS2_HAVE_MPI +#include <mpi.h> +#endif int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); - int rank, nproc; + int rank = 0, size = 1; +#ifdef ADIOS2_HAVE_MPI MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug); - - // Application variable - float frank = (float)rank; - std::vector<double> myDoubles = { - frank, frank + 0.1f, frank + 0.2f, frank + 0.3f, frank + 0.4f, - frank + 0.5f, frank + 0.6f, frank + 0.7f, frank + 0.8f, frank + 0.9f}; - const std::size_t Nx = myDoubles.size(); + MPI_Comm_size(MPI_COMM_WORLD, &size); +#endif - const std::size_t rows = 3; - const std::size_t columns = 3; - - std::vector<float> myMatrix; - myMatrix.reserve(rows * columns); - myMatrix.push_back(frank + 0.0); - myMatrix.push_back(frank + 0.1), myMatrix.push_back(frank + 0.2); - myMatrix.push_back(frank + 0.3); - myMatrix.push_back(frank + 0.4), myMatrix.push_back(frank + 0.5); - myMatrix.push_back(frank + 0.6); - myMatrix.push_back(frank + 0.7), myMatrix.push_back(frank + 0.8); - - frank = -(float)rank; - std::vector<float> myMatrix2 = {frank - 0.1f, frank - 0.2f, frank - 0.3f, - frank - 0.4f, frank - 0.5f, frank - 0.6f, - frank - 0.7f, frank - 0.8f, frank - 0.9f}; + /** Application variable */ + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); try { - // Define variable and local size - adios::Variable<double> &ioMyDoubles = adios.DefineVariable<double>( - "myDoubles", {nproc, Nx}, {rank, 0}, {1, Nx}); - adios::Variable<float> &ioMyMatrix = - adios.DefineVariable<float>("myMatrix", {nproc * rows, columns}, - {rank * rows, 0}, {rows, columns}); - adios::Variable<float> &ioMyMatrix2 = - adios.DefineVariable<float>("myMatrix2", {rows, nproc * columns}, - {0, rank * columns}, {rows, columns}); + /** ADIOS class factory of IO class objects, DebugON is recommended */ + adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON); - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &bpWriterSettings = adios.DeclareMethod("hello"); - bpWriterSettings.SetEngine("ADIOS1Writer"); - bpWriterSettings.SetParameters("profile_units=mus"); - bpWriterSettings.SetIOMode(adios::IOMode::COLLECTIVE); - bpWriterSettings.AddTransport( - "File", "profile_units=mus", - "have_metadata_file=no"); // uses default POSIX library + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios::IO &adios1IO = adios.DeclareIO("ADIOS1IO"); + adios1IO.SetEngine("ADIOS1Writer"); + adios1IO.AddTransport("file", "library=MPI"); - // Create engine smart pointer due to polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // Writer - auto bpWriter = adios.Open("hello_adios1.bp", "w", bpWriterSettings); + /** global array : name, { shape (total) }, { start (local) }, { count + * (local) }, all are constant dimensions */ + adios::Variable<float> &bpFloats = adios1IO.DefineVariable<float>( + "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios::ConstantDims); - if (bpWriter == nullptr) - throw std::ios_base::failure( - "ERROR: couldn't create bpWriter at Open\n"); + /** Engine derived class, spawned to start IO operations */ + auto adios1Writer = + adios1IO.Open("myVector.bp", adios::OpenMode::Write); - bpWriter->Write<double>(ioMyDoubles, - myDoubles.data()); // Base class Engine - // own the Write<T> - // that will call - // overloaded Write - // from Derived + if (!adios1Writer) + { + throw std::ios_base::failure( + "ERROR: adios1Writer not created at Open\n"); + } - bpWriter->Write<float>(ioMyMatrix, myMatrix.data()); - bpWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); + /** Write variable for buffering */ + adios1Writer->Write<float>(bpFloats, myFloats.data()); - bpWriter->Close(); + /** Create bp file, engine becomes unreachable after this*/ + adios1Writer->Close(); } catch (std::invalid_argument &e) { - if (rank == 0) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " + << rank << "\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"; - } + std::cout + << "IO System base failure exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; } catch (std::exception &e) { - if (rank == 0) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; } MPI_Finalize(); diff --git a/examples/hello/adios1Writer/helloADIOS1Writer_nompi.cpp b/examples/hello/adios1Writer/helloADIOS1Writer_nompi.cpp index 89487cf289afe720309b3f6885d15bdcb4d884f3..46c03b898025cf7677c4fa7f4d1dcfe156a917d9 100644 --- a/examples/hello/adios1Writer/helloADIOS1Writer_nompi.cpp +++ b/examples/hello/adios1Writer/helloADIOS1Writer_nompi.cpp @@ -2,10 +2,10 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloADIOSNoXML_OOP.cpp + * helloADIOS1Writer_nompi.cpp : non mpi version of helloADIOS1Writer * * Created on: Jan 9, 2017 - * Author: wfg + * Author: Norbert Podhorszki pnorbert@ornl.gov */ #include <iostream> @@ -15,65 +15,41 @@ int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios(adios::Verbose::INFO, adiosDebug); - - // Application variable - std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - std::vector<float> myMatrix = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - - std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; + /** Application variable */ + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); try { - // Define variable and local size - adios::Variable<double> &ioMyDoubles = - adios.DefineVariable<double>("myDoubles", adios::Dims{Nx}); - adios::Variable<float> &ioMyMatrix = - adios.DefineVariable<float>("myMatrix", adios::Dims{rows, columns}); - adios::Variable<float> &ioMyMatrix2 = adios.DefineVariable<float>( - "myMatrix2", adios::Dims{rows, columns}); - adios::Variable<float> &ioMyMatrix3 = adios.DefineVariable<float>( - "myMatrix3", adios::Dims{rows, columns}); + /** ADIOS class factory of IO class objects, DebugON is recommended */ + adios::ADIOS adios(adios::DebugON); + + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios::IO &adios1IO = adios.DeclareIO("ADIOS1IO"); + adios1IO.SetEngine("ADIOS1Writer"); + adios1IO.AddTransport("file"); - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &bpWriterSettings = adios.DeclareMethod("hello"); - bpWriterSettings.SetIOMode(adios::IOMode::COLLECTIVE); - bpWriterSettings.SetParameters("profile_units=mus"); - bpWriterSettings.AddTransport("File", "have_metadata_file=yes", - "profile_units=mus"); + /** global array : name, { shape (total) }, { start (local) }, { count + * (local) }, all are constant dimensions */ + adios::Variable<float> &bpFloats = adios1IO.DefineVariable<float>( + "bpFloats", {}, {}, {Nx}, adios::ConstantDims); - // Create engine smart pointer due to polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // Writer - auto bpFileWriter = - adios.Open("hello_adios1_nompi.bp", "w", bpWriterSettings); + /** Engine derived class, spawned to start IO operations */ + auto adios1Writer = + adios1IO.Open("myVector.bp", adios::OpenMode::Write); - if (bpFileWriter == nullptr) + if (!adios1Writer) + { throw std::ios_base::failure( - "ERROR: couldn't create bpWriter at Open\n"); + "ERROR: hdf5Writer not created at Open\n"); + } - ioMyDoubles.SetSelection({0}, {Nx}); - adios::SelectionBoundingBox box({0, 0}, {rows, columns}); - ioMyMatrix.SetSelection(box); - ioMyMatrix2.SetSelection(box); - ioMyMatrix3.SetSelection(box); + /** Write variable for buffering */ + adios1Writer->Write<float>(bpFloats, myFloats.data()); - bpFileWriter->Write<double>( - ioMyDoubles, - myDoubles.data()); // Base class Engine own the Write<T> - // that will call overloaded Write from - // Derived - bpFileWriter->Write<float>(ioMyMatrix, myMatrix.data()); // 2d Example - bpFileWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); // 2d Example - bpFileWriter->Write<float>(ioMyMatrix3, myMatrix2.data()); // 2d Example - bpFileWriter->Close(); - // + /** Create bp file, engine becomes unreachable after this*/ + adios1Writer->Close(); } catch (std::invalid_argument &e) { diff --git a/examples/hello/timeBP/CMakeLists.txt b/examples/hello/bpTimeWriter/CMakeLists.txt similarity index 55% rename from examples/hello/timeBP/CMakeLists.txt rename to examples/hello/bpTimeWriter/CMakeLists.txt index 7f5d44cc2a63e2c1d4d09cbc51634ce8b6acab62..f95bd367c6bdf59d1fba09f245f2f58c6c11bd7d 100644 --- a/examples/hello/timeBP/CMakeLists.txt +++ b/examples/hello/bpTimeWriter/CMakeLists.txt @@ -6,10 +6,10 @@ if(ADIOS_USE_MPI) find_package(MPI COMPONENTS C REQUIRED) - add_executable(hello_timeBPWriter timeBPWriter.cpp) - target_include_directories(hello_timeBPWriter PRIVATE ${MPI_C_INCLUDE_PATH}) - target_link_libraries(hello_timeBPWriter ${MPI_C_LIBRARIES}) + add_executable(hello_bpTimeWriter helloBPTimeWriter.cpp) + target_include_directories(hello_bpTimeWriter PRIVATE ${MPI_C_INCLUDE_PATH}) + target_link_libraries(hello_bpTimeWriter ${MPI_C_LIBRARIES}) else() - add_executable(hello_timeBPWriter timeBPWriter_nompi.cpp) + add_executable(hello_bpTimeWriter helloBPTimeWriter_nompi.cpp) endif() -target_link_libraries(hello_timeBPWriter adios2) +target_link_libraries(hello_bpTimeWriter adios2) diff --git a/examples/hello/bpTimeWriter/helloBPTimeWriter.cpp b/examples/hello/bpTimeWriter/helloBPTimeWriter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9290c5bc0e521c2366f2525fcf75631876b9017 --- /dev/null +++ b/examples/hello/bpTimeWriter/helloBPTimeWriter.cpp @@ -0,0 +1,98 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * helloBPTimeWriter.cpp example for writing a variable using the Advance + * function for time aggregation. Time step is saved as an additional (global) + * single value variable, just for tracking purposes. + * + * Created on: Feb 16, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include <algorithm> //std::for_each +#include <ios> //std::ios_base::failure +#include <iostream> //std::cout +#include <mpi.h> +#include <stdexcept> //std::invalid_argument std::exception +#include <vector> + +#include <adios2.h> + +int main(int argc, char *argv[]) +{ + MPI_Init(&argc, &argv); + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + // Application variable + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); + + try + { + /** ADIOS class factory of IO class objects, DebugON is recommended */ + adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON); + + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios::IO &bpIO = adios.DeclareIO("BPFile_N2N"); + + /** global array: name, { shape (total dimensions) }, { start (local) }, + * { count (local) }, all are constant dimensions */ + adios::Variable<float> &bpFloats = bpIO.DefineVariable<float>( + "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios::ConstantDims); + + /** global single value variable: name */ + adios::Variable<unsigned int> &bpTimeStep = + bpIO.DefineVariable<unsigned int>("timeStep"); + + /** Engine derived class, spawned to start IO operations */ + auto bpWriter = bpIO.Open("myVector.bp", adios::OpenMode::Write); + + if (!bpWriter) + { + throw std::ios_base::failure( + "ERROR: bpWriter not created at Open\n"); + } + + for (unsigned int timeStep = 0; timeStep < 10; ++timeStep) + { + if (rank == 0) // global single value, only saved by rank 0 + { + bpWriter->Write<unsigned int>(bpTimeStep, timeStep); + } + + myFloats[0] = timeStep; + + // template type is optional, but recommended + bpWriter->Write<float>(bpFloats, myFloats.data()); + bpWriter->Advance(); + } + + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; + } + catch (std::ios_base::failure &e) + { + std::cout + << "IO System base failure exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; + } + + MPI_Finalize(); + + return 0; +} diff --git a/examples/hello/bpTimeWriter/helloBPTimeWriter_nompi.cpp b/examples/hello/bpTimeWriter/helloBPTimeWriter_nompi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..84b531107dacd21ab262465773dc96c1355135af --- /dev/null +++ b/examples/hello/bpTimeWriter/helloBPTimeWriter_nompi.cpp @@ -0,0 +1,79 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * helloBPTimeWriter_nompi.cpp no mpi version of helloBPTimeWriter.cpp + * + * Created on: Feb 16, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include <ios> //std::ios_base::failure +#include <iostream> //std::cout +#include <stdexcept> //std::invalid_argument std::exception +#include <vector> + +#include <adios2.h> + +int main(int argc, char *argv[]) +{ + // Application variable + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); + + try + { + /** ADIOS class factory of IO class objects, DebugON is recommended */ + adios::ADIOS adios(adios::DebugON); + + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios::IO &bpIO = adios.DeclareIO("BPFile_N2N"); + + /** name, { shape (total dimensions) }, { start (local) }, { count + * {local} } */ + adios::Variable<float> &bpFloats = bpIO.DefineVariable<float>( + "bpFloats", {}, {}, {Nx}, adios::ConstantDims); + + adios::Variable<unsigned int> &bpTimeStep = + bpIO.DefineVariable<unsigned int>("timeStep"); + + /** Engine derived class, spawned to start IO operations */ + auto bpWriter = bpIO.Open("myVector.bp", adios::OpenMode::Write); + + if (!bpWriter) + { + throw std::ios_base::failure( + "ERROR: bpWriter not created at Open\n"); + } + + for (unsigned int timeStep = 0; timeStep < 10; ++timeStep) + { + // template type is optional but recommended + bpWriter->Write<unsigned int>(bpTimeStep, timeStep); + + myFloats[0] = timeStep; + bpWriter->Write<float>(bpFloats, myFloats.data()); + bpWriter->Advance(); + } + + 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 << "IO System base failure exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM from rank\n"; + std::cout << e.what() << "\n"; + } + + return 0; +} diff --git a/examples/hello/bpWriter/helloBPWriter.cpp b/examples/hello/bpWriter/helloBPWriter.cpp index 61dcf2854aa0cd3742acc8a584da884491006adf..3d250b3b14912ed494ff8ad34e5ef5877a5dc7d2 100644 --- a/examples/hello/bpWriter/helloBPWriter.cpp +++ b/examples/hello/bpWriter/helloBPWriter.cpp @@ -2,122 +2,78 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloWriter.cpp + * helloBPWriter.cpp: Simple self-descriptive example of how to write a variable + * to a BP File that lives in several MPI processes. * * Created on: Feb 16, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#include <iostream> -#include <vector> - +#include <ios> //std::ios_base::failure +#include <iostream> //std::cout #include <mpi.h> +#include <stdexcept> //std::invalid_argument std::exception +#include <vector> #include <adios2.h> int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); - int rank, nproc; + int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &nproc); + MPI_Comm_size(MPI_COMM_WORLD, &size); - const bool adiosDebug = true; - adios::ADIOS adios("config.xml", MPI_COMM_WORLD, adios::Verbose::INFO, - adiosDebug); - - // Application variable - std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - - std::vector<float> myMatrix; - if (rank % 2 == 0) // even rank - { - myMatrix.reserve(rows * columns); - myMatrix.push_back(1); - myMatrix.push_back(2), myMatrix.push_back(3); - myMatrix.push_back(4); - myMatrix.push_back(5), myMatrix.push_back(6); - myMatrix.push_back(7); - myMatrix.push_back(8), myMatrix.push_back(8); - } - - std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; + /** Application variable */ + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); try { - // Define variable and local size - adios::Variable<double> &ioMyDoubles = adios.DefineVariable<double>( - "myDoubles", {nproc, Nx}, {rank, 0}, {1, Nx}); - adios::Variable<float> &ioMyMatrix = - adios.DefineVariable<float>("myMatrix", {nproc * rows, columns}, - {rank * rows, 0}, {rows, columns}); - adios::Variable<float> &ioMyMatrix2 = - adios.DefineVariable<float>("myMatrix2", {rows, nproc * columns}, - {0, rank * columns}, {rows, columns}); + /** ADIOS class factory of IO class objects, DebugON is recommended */ + adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON); - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &bpWriterSettings = - adios.DeclareMethod("Output"); // Output is defined in config.xml - if (!bpWriterSettings.IsUserDefined()) - { - bpWriterSettings.SetParameters("profile_units=mus"); - bpWriterSettings.AddTransport( - "File", "profile_units=mus", - "have_metadata_file=no"); // uses default POSIX library - } + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios::IO &bpIO = adios.DeclareIO("BPFile_N2N"); - // Create engine smart pointer due to polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // Writer - auto bpWriter = adios.Open("myDoubles.bp", "w", bpWriterSettings); + /** global array : name, { shape (total) }, { start (local) }, { count + * (local) }, all are constant dimensions */ + adios::Variable<float> &bpFloats = bpIO.DefineVariable<float>( + "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios::ConstantDims); - 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 + /** Engine derived class, spawned to start IO operations */ + auto bpWriter = bpIO.Open("myVector.bp", adios::OpenMode::Write); - if (rank % 2 == 0) // even rank + if (!bpWriter) { - bpWriter->Write<float>(ioMyMatrix, myMatrix.data()); - bpWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); + throw std::ios_base::failure( + "ERROR: bpWriter not created at Open\n"); } + /** Write variable for buffering */ + bpWriter->Write<float>(bpFloats, myFloats.data()); + + /** Create bp file, engine becomes unreachable after this*/ bpWriter->Close(); } catch (std::invalid_argument &e) { - if (rank == 0) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " + << rank << "\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"; - } + std::cout + << "IO System base failure exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; } catch (std::exception &e) { - if (rank == 0) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; } MPI_Finalize(); diff --git a/examples/hello/bpWriter/helloBPWriter_nompi.cpp b/examples/hello/bpWriter/helloBPWriter_nompi.cpp index 9acc0b5a2104db9d6ae27aec68d88a1baa8612b1..b9ba169e39342e8faec177d3c09b4e63f48e0ab2 100644 --- a/examples/hello/bpWriter/helloBPWriter_nompi.cpp +++ b/examples/hello/bpWriter/helloBPWriter_nompi.cpp @@ -2,82 +2,53 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloADIOSNoXML_OOP.cpp + * helloBPWriter_nompi.cpp sequential non-mpi version of helloBPWriter * * Created on: Jan 9, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#include <ios> -#include <iostream> -#include <stdexcept> +#include <ios> //std::ios_base::failure +#include <iostream> //std::cout +#include <stdexcept> //std::invalid_argument std::exception #include <vector> #include <adios2.h> -int main(int /*argc*/, char ** /*argv*/) +int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios(adios::Verbose::WARN, adiosDebug); - - // Application variable - std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - std::vector<float> myMatrix = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - - std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; + /** Application variable */ + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); try { - // Define variable and local size - adios::Variable<double> &ioMyDoubles = - adios.DefineVariable<double>("myDoubles", adios::Dims{Nx}); - adios::Variable<float> &ioMyMatrix = - adios.DefineVariable<float>("myMatrix", adios::Dims{rows, columns}); - adios::Variable<float> &ioMyMatrix2 = adios.DefineVariable<float>( - "myMatrix2", adios::Dims{rows, columns}); - adios::Variable<float> &ioMyMatrix3 = adios.DefineVariable<float>( - "myMatrix3", adios::Dims{rows, columns}); + /** ADIOS class factory of IO class objects, DebugON is recommended */ + adios::ADIOS adios(adios::DebugON); + + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios::IO &bpIO = adios.DeclareIO("BPFile_N2N"); - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &bpWriterSettings = adios.DeclareMethod( - "SinglePOSIXFile"); // default method type is Writer - bpWriterSettings.SetParameters("profile_units=mus"); - bpWriterSettings.AddTransport("File", "have_metadata_file=yes", - "profile_units=mus"); + /** global array: name, { shape (total dimensions) }, { start (local) }, + * { count (local) }, all are constant dimensions */ + adios::Variable<float> &bpFloats = bpIO.DefineVariable<float>( + "bpFloats", {}, {}, {Nx}, adios::ConstantDims); - // Create engine smart pointer due to polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // Writer - auto bpFileWriter = - adios.Open("myDoubles_nompi.bp", "w", bpWriterSettings); + /** Engine derived class, spawned to start IO operations */ + auto bpWriter = bpIO.Open("myVector.bp", adios::OpenMode::Write); - if (bpFileWriter == nullptr) + if (!bpWriter) { throw std::ios_base::failure( - "ERROR: couldn't create bpWriter at Open\n"); + "ERROR: bpWriter not created at Open\n"); } - ioMyDoubles.SetSelection({0}, {Nx}); - adios::SelectionBoundingBox box({0, 0}, {rows, columns}); - ioMyMatrix.SetSelection(box); - ioMyMatrix2.SetSelection(box); - ioMyMatrix3.SetSelection(box); + /** Write variable for buffering */ + bpWriter->Write<float>(bpFloats, myFloats.data()); - bpFileWriter->Write<double>( - ioMyDoubles, - myDoubles.data()); // Base class Engine own the Write<T> - // that will call overloaded Write from - // Derived - bpFileWriter->Write<float>(ioMyMatrix, myMatrix.data()); // 2d Example - bpFileWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); // 2d Example - bpFileWriter->Write<float>(ioMyMatrix3, myMatrix2.data()); // 2d Example - bpFileWriter->Close(); - // + /** Create bp file, engine becomes unreachable after this*/ + bpWriter->Close(); } catch (std::invalid_argument &e) { @@ -86,12 +57,12 @@ int main(int /*argc*/, char ** /*argv*/) } catch (std::ios_base::failure &e) { - std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << "IO System base failure exception, STOPPING PROGRAM\n"; std::cout << e.what() << "\n"; } catch (std::exception &e) { - std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << "Exception, STOPPING PROGRAM from rank\n"; std::cout << e.what() << "\n"; } diff --git a/examples/hello/datamanReader/helloDataManReader.cpp b/examples/hello/datamanReader/helloDataManReader.cpp index 336bc0a779502415cbcc56c8372e113ee56df832..7dc984af37870f05187ff1fbd073a226b11f5d16 100644 --- a/examples/hello/datamanReader/helloDataManReader.cpp +++ b/examples/hello/datamanReader/helloDataManReader.cpp @@ -2,26 +2,22 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloDataManReader.cpp + * helloDataManReader_nompi.cpp * - * Created on: Feb 16, 2017 - * Author: wfg + * Created on: Jan 9, 2017 + * Author: Jason Wang */ -#include <functional> //std::multiplies -#include <iostream> //std::cout, std::endl -#include <numeric> //std::accumulate -#include <string> +#include <iostream> +#include <numeric> #include <vector> -#include <mpi.h> - #include <adios2.h> -void getcb(const void *data, std::string doid, std::string var, - std::string dtype, std::vector<std::size_t> varshape) +void UserCallBack(const void *data, std::string doid, std::string var, + std::string dtype, std::vector<std::size_t> varshape) { - std::cout << "data object ID = " << doid << "\n"; // do you need to flush? + std::cout << "data object ID = " << doid << "\n"; std::cout << "variable name = " << var << "\n"; std::cout << "data type = " << dtype << "\n"; @@ -35,73 +31,63 @@ void getcb(const void *data, std::string doid, std::string var, int main(int argc, char *argv[]) { + // Application variable MPI_Init(&argc, &argv); - int rank; + int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - const bool adiosDebug = true; - adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN, adiosDebug); + MPI_Comm_size(MPI_COMM_WORLD, &size); try { - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &datamanSettings = adios.DeclareMethod("WAN"); - if (!datamanSettings.IsUserDefined()) - { - // if not defined by user, we can change the default settings - datamanSettings.SetEngine("DataManReader"); - datamanSettings.SetParameters("peer-to-peer=yes"); - datamanSettings.AddTransport("Mdtm", "localIP=127.0.0.1", - "remoteIP=127.0.0.1", - "tolerances=1,2,3"); - // datamanSettings.AddTransport( "ZeroMQ", "localIP=127.0.0.1", - // "remoteIP=127.0.0.1", "tolerances=1,2,3" ); not yet supported - // , - // will throw an exception - } + adios::ADIOS adios(adios::DebugON); - // Create engine smart pointer to DataManReader Engine due to - // polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // DataManReader - auto datamanReader = adios.Open("myDoubles.bp", "r", datamanSettings); + adios::IO &dataManIO = adios.DeclareIO("WAN"); + dataManIO.SetEngine("DataManReader"); + dataManIO.SetParameters("real_time=yes", "method_type=stream", + "method=dump"); + auto dataManReader = + dataManIO.Open("myDoubles.bp", adios::OpenMode::Read); - if (datamanReader == nullptr) + if (!dataManReader) + { throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n"); + } - datamanReader->SetCallBack(getcb); + dataManReader->SetCallBack(UserCallBack); + + for (unsigned int i = 0; i < 3; ++i) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } adios::Variable<double> *ioMyDoubles = - datamanReader->InquireVariableDouble("ioMyDoubles"); + dataManReader->InquireVariable<double>("ioMyDoubles"); + if (ioMyDoubles == nullptr) + { std::cout << "Variable ioMyDoubles not read...yet\n"; + } - datamanReader->Close(); + dataManReader->Close(); } catch (std::invalid_argument &e) { - if (rank == 0) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " + << rank << "\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"; - } + std::cout + << "IO System base failure exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; } catch (std::exception &e) { - if (rank == 0) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; } MPI_Finalize(); diff --git a/examples/hello/datamanReader/helloDataManReader_nompi.cpp b/examples/hello/datamanReader/helloDataManReader_nompi.cpp index bfbed7b37f062b23a8c452a845a91c93c3aa3022..965e47c364dd527ed287bf45f11d0e62a6cacfeb 100644 --- a/examples/hello/datamanReader/helloDataManReader_nompi.cpp +++ b/examples/hello/datamanReader/helloDataManReader_nompi.cpp @@ -2,10 +2,10 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloADIOSNoXML_OOP.cpp + * helloDataManReader_nompi.cpp * * Created on: Jan 9, 2017 - * Author: wfg + * Author: Jason Wang */ #include <iostream> @@ -14,10 +14,10 @@ #include <adios2.h> -void getcb(const void *data, std::string doid, std::string var, - std::string dtype, std::vector<std::size_t> varshape) +void UserCallBack(const void *data, std::string doid, std::string var, + std::string dtype, std::vector<std::size_t> varshape) { - std::cout << "data object ID = " << doid << "\n"; // do you need to flush? + std::cout << "data object ID = " << doid << "\n"; std::cout << "variable name = " << var << "\n"; std::cout << "data type = " << dtype << "\n"; @@ -31,51 +31,40 @@ void getcb(const void *data, std::string doid, std::string var, int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios(adios::Verbose::WARN, adiosDebug); try { - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &datamanSettings = adios.DeclareMethod("WAN"); - if (!datamanSettings.IsUserDefined()) - { - // if not defined by user, we can change the default settings - datamanSettings.SetEngine("DataManReader"); - datamanSettings.SetParameters("real_time=yes", "method_type=stream", - "method=dump"); - // datamanSettings.AddTransport( "Mdtm", "localIP=127.0.0.1", - // "remoteIP=127.0.0.1", "tolerances=1,2,3" ); - // datamanSettings.AddTransport( "ZeroMQ", "localIP=127.0.0.1", - // "remoteIP=127.0.0.1", "tolerances=1,2,3" ); not yet supported - // , - // will throw an exception - } + adios::ADIOS adios(adios::DebugON); - // Create engine smart pointer to DataManReader Engine due to - // polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // DataManReader - auto datamanReader = adios.Open("myDoubles.bp", "r", datamanSettings); + adios::IO &dataManIO = adios.DeclareIO("WAN"); + dataManIO.SetEngine("DataManReader"); + dataManIO.SetParameters("real_time=yes", "method_type=stream", + "method=dump"); + auto dataManReader = + dataManIO.Open("myDoubles.bp", adios::OpenMode::Read); - if (datamanReader == nullptr) + if (!dataManReader) + { throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n"); + } - datamanReader->SetCallBack(getcb); + dataManReader->SetCallBack(UserCallBack); - for (int i = 0; i < 3; i++) + for (unsigned int i = 0; i < 3; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } adios::Variable<double> *ioMyDoubles = - datamanReader->InquireVariableDouble("ioMyDoubles"); + dataManReader->InquireVariable<double>("ioMyDoubles"); + if (ioMyDoubles == nullptr) + { std::cout << "Variable ioMyDoubles not read...yet\n"; + } - datamanReader->Close(); + dataManReader->Close(); } catch (std::invalid_argument &e) { diff --git a/examples/hello/datamanWriter/helloDataManWriter.cpp b/examples/hello/datamanWriter/helloDataManWriter.cpp index f74e7e5d8af7978fc690d0f18da14c046c089a38..dcdf4bff7f289f2d4f716e073a7d2221e3059af1 100644 --- a/examples/hello/datamanWriter/helloDataManWriter.cpp +++ b/examples/hello/datamanWriter/helloDataManWriter.cpp @@ -2,10 +2,10 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloWriter.cpp + * helloDataManWriter.cpp * * Created on: Feb 16, 2017 - * Author: wfg + * Author: Jason Wang */ #include <iostream> @@ -17,100 +17,58 @@ int main(int argc, char *argv[]) { + // Application variable MPI_Init(&argc, &argv); - int rank; + int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - const bool adiosDebug = true; - adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN, adiosDebug); - - // Application variable - std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); + MPI_Comm_size(MPI_COMM_WORLD, &size); - std::vector<std::complex<float>> myCFloats; - myCFloats.reserve(3); - myCFloats.emplace_back(1, 3); - myCFloats.emplace_back(2, 2); - myCFloats.emplace_back(3, 1); + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); try { - // Define variable and local size - auto ioMyDoubles = - adios.DefineLocalArray<double>("myDoubles", false, {Nx}); - auto ioMyCFloats = adios.DefineLocalArray<std::complex<float>>( - "myCFloats", false, {3}); + adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON); + adios::IO &dataManIO = adios.DeclareIO("WANIO"); + dataManIO.SetEngine("DataManWriter"); + dataManIO.SetParameters("peer-to-peer=yes", "real_time=yes", + "compress=no", "method=dump"); - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &datamanSettings = adios.DeclareMethod("WAN"); - if (!datamanSettings.IsUserDefined()) - { - // if not defined by user, we can change the default settings - datamanSettings.SetEngine("DataManWriter"); - datamanSettings.SetParameters("peer-to-peer=yes", "real_time=yes", - "compress=no", "method=cache"); - datamanSettings.AddTransport("Mdtm", "localIP=128.0.0.0.1", - "remoteIP=128.0.0.0.2", - "tolerances=1,2,3"); - // datamanSettings.AddTransport( "file", "name=myfile.bp", - // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - // datamanSettings.AddTransport( "file", "name=myfile.bp", - // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - // 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", - // "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 - } + // Define variable and local size + auto bpFloats = + dataManIO.DefineVariable<float>("bpFloats", {}, {}, {Nx}); // Create engine smart pointer to DataMan Engine due to polymorphism, // Open returns a smart pointer to Engine containing the Derived class - // DataMan - - // adios::DataManWriter datamanWriter; - - auto datamanWriter = adios.Open("myDoubles.bp", "w", datamanSettings); + auto dataManWriter = + dataManIO.Open("myFloats.bp", adios::OpenMode::Write); - if (datamanWriter == nullptr) + if (!dataManWriter) + { throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n"); + } - datamanWriter->Write<double>( - ioMyDoubles, - myDoubles.data()); // Base class Engine own the Write<T> - // that will call overloaded Write from - // Derived - datamanWriter->Write<std::complex<float>>(ioMyCFloats, - myCFloats.data()); - datamanWriter->Close(); + dataManWriter->Write<float>(bpFloats, myFloats.data()); + dataManWriter->Close(); } catch (std::invalid_argument &e) { - if (rank == 0) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " + << rank << "\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"; - } + std::cout + << "IO System base failure exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; } catch (std::exception &e) { - if (rank == 0) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; } MPI_Finalize(); diff --git a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp index c551d955670f6d5620802c848672ce18dc821733..cbc08fb607c34025ce4697fe8de833928234d61b 100644 --- a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp +++ b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp @@ -2,10 +2,10 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * helloADIOSNoXML_OOP.cpp + * helloDataManWriter.cpp * - * Created on: Jan 9, 2017 - * Author: wfg + * Created on: Feb 16, 2017 + * Author: Jason Wang */ #include <iostream> @@ -15,72 +15,35 @@ int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios(adios::Verbose::WARN, adiosDebug); - // Application variable std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); - - std::vector<std::complex<float>> myCFloats; - myCFloats.reserve(3); - myCFloats.emplace_back(1, 3); - myCFloats.emplace_back(2, 2); - myCFloats.emplace_back(3, 1); + const std::size_t Nx = myFloats.size(); try { - // Define variable and local size - // Define variable and local size - auto ioMyFloats = - adios.DefineVariable<float>("myfloats", adios::Dims{Nx}); - auto ioMyFloat = adios.DefineVariable<float>("myfloat", adios::Dims{1}); - // auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", - // adios::Dims{Nx} ); - // auto& ioMyCFloats = adios.DefineVariable<std::complex<float>>( - // "myCFloats", {3} ); + adios::ADIOS adios(adios::DebugON); + adios::IO &dataManIO = adios.DeclareIO("WANIO"); + dataManIO.SetEngine("DataManWriter"); + dataManIO.SetParameters("peer-to-peer=yes", "real_time=yes", + "compress=no", "method=dump"); - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &datamanSettings = adios.DeclareMethod("WAN"); - if (!datamanSettings.IsUserDefined()) - { - // if not defined by user, we can change the default settings - datamanSettings.SetEngine("DataManWriter"); - datamanSettings.SetParameters( - "real_time=yes", "method_type=stream", "method=cache", - "monitoring=yes", "local_ip=127.0.0.1", "remote_ip=127.0.0.1", - "local_port=12306", "remote_port=12307"); - // datamanSettings.AddTransport( "Mdtm", "localIP=127.0.0.1", - // "remoteIP=127.0.0.1", "tolerances=1,2,3" ); - // datamanSettings.AddTransport( "ZeroMQ", "localIP=127.0.0.1", - // "remoteIP=127.0.0.1", "tolerances=1,2,3" ); not yet supported - // , - // will throw an exception - } + // Define variable and local size + auto bpFloats = + dataManIO.DefineVariable<float>("bpFloats", {}, {}, {Nx}); // 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); + auto dataManWriter = + dataManIO.Open("myFloats.bp", adios::OpenMode::Write); - if (datamanWriter == nullptr) + if (!dataManWriter) + { throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n"); + } - datamanWriter->Write<float>( - ioMyFloats, - myFloats.data()); // Base class Engine own the Write<T> that - // will call overloaded Write from Derived - const float num = 1.12; - datamanWriter->Write<float>(ioMyFloat, - &num); // Base class Engine own the - // Write<T> that will call - // overloaded Write from - // Derived - // datamanWriter->Write( ioMyCFloats, myCFloats.data() ); - datamanWriter->Close(); + dataManWriter->Write<float>(bpFloats, myFloats.data()); + dataManWriter->Close(); } catch (std::invalid_argument &e) { @@ -89,12 +52,12 @@ int main(int argc, char *argv[]) } catch (std::ios_base::failure &e) { - std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << "IO System base failure exception, STOPPING PROGRAM\n"; std::cout << e.what() << "\n"; } catch (std::exception &e) { - std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << "Exception, STOPPING PROGRAM from rank\n"; std::cout << e.what() << "\n"; } diff --git a/examples/hello/hdf5Writer/helloHDF5Writer.cpp b/examples/hello/hdf5Writer/helloHDF5Writer.cpp index da647a8e8571d105c3941f56c2399e3eb3d4cfd7..264ee2b41be90e27d9c82106c9892683cc23e734 100644 --- a/examples/hello/hdf5Writer/helloHDF5Writer.cpp +++ b/examples/hello/hdf5Writer/helloHDF5Writer.cpp @@ -1,17 +1,22 @@ /* - * HDF5Writer.cpp + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * helloHDF5Writer.cpp: Simple self-descriptive example of how to write a + * variable to a parallel HDF5 File using MPI processes. * * Created on: March 20, 2017 * Author: Junmin */ -#include <iostream> +#include <ios> //std::ios_base::failure +#include <iostream> //std::cout +#include <mpi.h> +#include <stdexcept> //std::invalid_argument std::exception #include <vector> #include <adios2.h> -#include <mpi.h> - int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); @@ -19,144 +24,58 @@ int main(int argc, char *argv[]) MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); - const bool adiosDebug = true; - adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug); - - // Application variable - const std::size_t intDim1 = 4; - const std::size_t intDim2 = 3; - std::vector<int> myInts = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; - - std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); - - std::vector<std::complex<float>> myCFloats; - const std::size_t ComplexDataSize = 3; - myCFloats.reserve(ComplexDataSize); - myCFloats.emplace_back(1, 3); - myCFloats.emplace_back(2, 2); - myCFloats.emplace_back(3, 1); + /** Application variable */ + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); - std::vector<std::complex<double>> myCDoubles; - myCDoubles.reserve(ComplexDataSize); - myCDoubles.emplace_back(1.1, -3.3); - myCDoubles.emplace_back(2.1, -2.2); - myCDoubles.emplace_back(3.1, -1.1); - - std::vector<std::complex<long double>> myCLongDoubles; - myCLongDoubles.reserve(ComplexDataSize); - myCLongDoubles.emplace_back(1.11, -3.33); - myCLongDoubles.emplace_back(2.11, -2.22); - myCLongDoubles.emplace_back(3.11, -1.11); - - std::size_t doubleVCount = Nx / size; - std::size_t complexCount = ComplexDataSize / size; - std::size_t intCountDim1 = intDim1 / size; - - std::size_t doubleVOffset = rank * doubleVCount; - std::size_t complexOffset = rank * complexCount; - std::size_t intOffsetDim1 = rank * intCountDim1; - std::size_t intOffsetDim2 = 0; - - if ((size > 1) && (rank == size - 1)) - { - doubleVCount = Nx - rank * (Nx / size); - complexCount = ComplexDataSize - rank * (ComplexDataSize / size); - intCountDim1 = intDim1 - rank * (intDim1 / size); - } - - std::cout << " rank=" << rank << " of " << size - << ", dim1 count: " << intCountDim1 - << ", offset: " << intOffsetDim1 << std::endl; - std::cout << " intOffsetDim2=" << intOffsetDim2 << " " << intDim2 - << std::endl; try { - // Define variable and local size - auto &ioMyInts = adios.DefineArray<int>("myInts", {4, 3}, - {intOffsetDim1, intOffsetDim2}, - {intCountDim1, intDim2}); - auto &ioMyDoubles = adios.DefineArray<double>( - "myDoubles", {Nx}, {doubleVOffset}, {doubleVCount}); - auto &ioMyCFloats = adios.DefineArray<std::complex<float>>( - "myCFloats", {3}, {complexOffset}, {complexCount}); - auto &ioMyCDoubles = adios.DefineArray<std::complex<double>>( - "myCDoubles", {3}, {complexOffset}, {complexCount}); - auto &ioMyCLongDoubles = adios.DefineArray<std::complex<long double>>( - "myCLongDoubles", {3}, {complexOffset}, {complexCount}); + /** ADIOS class factory of IO class objects, DebugON is recommended */ + adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON); - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &HDF5Settings = adios.DeclareMethod("hdf5"); - HDF5Settings.SetEngine("HDF5Writer"); - HDF5Settings.SetParameters("chunck=yes", "collectiveIO=yes"); - // HDF5Settings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", - // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios::IO &hdf5IO = adios.DeclareIO("HDFFileIO"); + hdf5IO.SetEngine("HDF5Writer"); + hdf5IO.AddTransport("File"); - // Create engine smart pointer to HDF5 Engine due to polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // HDF5 - auto HDF5Writer = adios.Open("test.h5", "w", HDF5Settings); + /** global array : name, { shape (total) }, { start (local) }, { count + * (local) }, all are constant dimensions */ + adios::Variable<float> &bpFloats = hdf5IO.DefineVariable<float>( + "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios::ConstantDims); - if (HDF5Writer == nullptr) - throw std::ios_base::failure( - "ERROR: failed to create HDF5 I/O engine at Open\n"); + /** Engine derived class, spawned to start IO operations */ + auto hdf5Writer = hdf5IO.Open("myVector.bp", adios::OpenMode::Write); - int ts = 0; - int totalts = 3; - while (true) + if (!hdf5Writer) { - if (rank == 0) - { - std::cout << " total timesteps: " << totalts << " curr: " << ts - << " th" << std::endl; - } - HDF5Writer->Write(ioMyDoubles, - myDoubles.data() + - doubleVOffset); // Base class Engine - // own the Write<T> - // that will call - // overloaded Write - // from Derived - HDF5Writer->Write(ioMyInts, - myInts.data() + (intOffsetDim1 * intDim2)); - - HDF5Writer->Write(ioMyCFloats, myCFloats.data() + complexOffset); - HDF5Writer->Write(ioMyCDoubles, myCDoubles.data() + complexOffset); - HDF5Writer->Write(ioMyCLongDoubles, - myCLongDoubles.data() + complexOffset); - ts++; - if (ts >= totalts) - { - break; - } - HDF5Writer->Advance(); + throw std::ios_base::failure( + "ERROR: hdf5Writer not created at Open\n"); } - HDF5Writer->Close(); + + /** Write variable for buffering */ + hdf5Writer->Write<float>(bpFloats, myFloats.data()); + + /** Create bp file, engine becomes unreachable after this*/ + hdf5Writer->Close(); } catch (std::invalid_argument &e) { - if (rank == 0) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " + << rank << "\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"; - } + std::cout + << "IO System base failure exception, STOPPING PROGRAM from rank " + << rank << "\n"; + std::cout << e.what() << "\n"; } catch (std::exception &e) { - if (rank == 0) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; } MPI_Finalize(); diff --git a/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp b/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp index 61ed8f26b344038285c685fcd601ea54456aac28..6222e1eb1bddead70450696820827a4608b58b21 100644 --- a/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp +++ b/examples/hello/hdf5Writer/helloHDF5Writer_nompi.cpp @@ -1,87 +1,56 @@ /* - * HDF5Writer.cpp + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * helloHDF5Writer_nompi.cpp no mpi version of helloHDF5Writer.cpp * * Created on: March 20, 2017 * Author: Junmin */ -#include <iostream> +#include <ios> //std::ios_base::failure +#include <iostream> //std::cout +#include <stdexcept> //std::invalid_argument std::exception #include <vector> #include <adios2.h> int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios(adios::Verbose::INFO, adiosDebug); - - // Application variable - const std::size_t intDim1 = 4; - const std::size_t intDim2 = 3; - std::vector<int> myInts = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; - - std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); - - std::vector<std::complex<float>> myCFloats; - const std::size_t CFloatSize = 3; - myCFloats.reserve(CFloatSize); - myCFloats.emplace_back(1, 3); - myCFloats.emplace_back(2, 2); - myCFloats.emplace_back(3, 1); - - std::vector<std::complex<double>> myCDoubles; - const std::size_t CDoubleSize = 3; - myCDoubles.reserve(CDoubleSize); - myCDoubles.emplace_back(1, 3); - myCDoubles.emplace_back(2, 2); - myCDoubles.emplace_back(3, 1); - - std::size_t doubleVCount = Nx; - std::size_t floatCount = CFloatSize; - std::size_t intCountDim1 = intDim1; - - std::size_t doubleVOffset = 0; - std::size_t floatOffset = 0; - std::size_t intOffsetDim1 = 0; - std::size_t intOffsetDim2 = 0; + /** Application variable */ + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myFloats.size(); try { - // Define variable and local size - auto &ioMyDoubles = - adios.DefineVariable<double>("myDoubles", {Nx}, {Nx}); - auto &ioMyCFloats = - adios.DefineVariable<std::complex<float>>("myCFloats", {3}, {3}); - auto &ioMyCDoubles = - adios.DefineVariable<std::complex<double>>("myCDoubles", {3}, {3}); - auto &ioMyInts = adios.DefineVariable<int>("myInts", {4, 3}, {4, 3}); + /** ADIOS class factory of IO class objects, DebugON is recommended */ + adios::ADIOS adios(adios::DebugON); - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &HDF5Settings = adios.DeclareMethod("HDF5Writer"); - HDF5Settings.SetParameters("chunck=yes", "collectiveIO=yes"); - // HDF5Settings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", - // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios::IO &hdf5IO = adios.DeclareIO("HDFFileIO"); + hdf5IO.SetEngine("HDF5Writer"); + hdf5IO.AddTransport("file"); - // Create engine smart pointer to HDF5 Engine due to polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // HDF5 - auto HDF5Writer = adios.Open("test.bp", "w", HDF5Settings); + /** global array : name, { shape (total) }, { start (local) }, { count + * (local) }, all are constant dimensions */ + adios::Variable<float> &bpFloats = hdf5IO.DefineVariable<float>( + "bpFloats", {}, {}, {Nx}, adios::ConstantDims); - if (HDF5Writer == nullptr) + /** Engine derived class, spawned to start IO operations */ + auto hdf5Writer = hdf5IO.Open("myVector.bp", adios::OpenMode::Write); + + if (!hdf5Writer) { throw std::ios_base::failure( - "ERROR: failed to create HDF5 I/O engine at Open\n"); + "ERROR: hdf5Writer not created at Open\n"); } - // Base class Engine own the Write<T> that will call overloaded Write - // from Derived - HDF5Writer->Write(ioMyDoubles, myDoubles.data() + doubleVOffset); - HDF5Writer->Write(ioMyInts, myInts.data()); - HDF5Writer->Write(ioMyCFloats, myCFloats.data()); - HDF5Writer->Write(ioMyCDoubles, myCDoubles.data()); - HDF5Writer->Close(); + /** Write variable for buffering */ + hdf5Writer->Write<float>(bpFloats, myFloats.data()); + + /** Create bp file, engine becomes unreachable after this*/ + hdf5Writer->Close(); } catch (std::invalid_argument &e) { @@ -90,12 +59,12 @@ int main(int argc, char *argv[]) } catch (std::ios_base::failure &e) { - std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << "IO System base failure exception, STOPPING PROGRAM\n"; std::cout << e.what() << "\n"; } catch (std::exception &e) { - std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << "Exception, STOPPING PROGRAM from rank\n"; std::cout << e.what() << "\n"; } diff --git a/examples/hello/timeBP/timeBPWriter.cpp b/examples/hello/timeBP/timeBPWriter.cpp deleted file mode 100644 index ea3e8e6f636ede4f6646400b8f34b6bf98307415..0000000000000000000000000000000000000000 --- a/examples/hello/timeBP/timeBPWriter.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * timeBPWriter.cpp example for time aggregation - * - * Created on: Feb 16, 2017 - * Author: wfg - */ - -#include <iostream> -#include <vector> - -#include <mpi.h> - -#include <adios2.h> - -int main(int argc, char *argv[]) -{ - MPI_Init(&argc, &argv); - int rank, nproc; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::ERROR, adiosDebug); - - // Application variable - std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - - std::vector<float> myMatrix; - if (rank % 2 == 0) // even rank - { - myMatrix.reserve(rows * columns); - myMatrix.push_back(1); - myMatrix.push_back(2), myMatrix.push_back(3); - myMatrix.push_back(4); - myMatrix.push_back(5), myMatrix.push_back(6); - myMatrix.push_back(7); - myMatrix.push_back(8), myMatrix.push_back(8); - } - - std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; - - try - { - // Define variable and local size - adios::Variable<double> &ioMyDoubles = adios.DefineVariable<double>( - "myDoubles", {nproc, Nx}, {rank, 0}, {1, Nx}); - adios::Variable<float> &ioMyMatrix = - adios.DefineVariable<float>("myMatrix", {nproc * rows, columns}, - {rank * rows, 0}, {rows, columns}); - adios::Variable<float> &ioMyMatrix2 = - adios.DefineVariable<float>("myMatrix2", {rows, nproc * columns}, - {0, rank * columns}, {rows, columns}); - - // Define method for engine creation, it is basically straight-forward - // parameters - adios::Method &bpWriterSettings = - adios.DeclareMethod("MyMethod"); // default method type is BPWriter - bpWriterSettings.SetParameters("profile_units=mus"); - bpWriterSettings.AddTransport( - "File", "profile_units=mus", - "have_metadata_file=no"); // uses default POSIX library - - // Create engine smart pointer due to polymorphism, - // Open returns a smart pointer to Engine containing the Derived class - // Writer - auto bpWriter = adios.Open("time.bp", "w", bpWriterSettings); - - if (bpWriter == nullptr) - throw std::ios_base::failure( - "ERROR: couldn't create bpWriter at Open\n"); - - for (unsigned int t = 0; t < 10; ++t) - { - myDoubles[0] = t; - bpWriter->Write<double>( - ioMyDoubles, - myDoubles.data()); // Base class Engine own the Write<T> - // that will call overloaded Write - // from Derived - - if (rank % 2 == 0) // even rank - { - myMatrix[0] = t; - myMatrix2[0] = t; - - bpWriter->Write<float>(ioMyMatrix, myMatrix.data()); - bpWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); - } - bpWriter->Advance(); - } - - 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/timeBP/timeBPWriter_nompi.cpp b/examples/hello/timeBP/timeBPWriter_nompi.cpp deleted file mode 100644 index 69d3ec71c015729d8b159c367b71564174d7b239..0000000000000000000000000000000000000000 --- a/examples/hello/timeBP/timeBPWriter_nompi.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * timeBPWriter.cpp example for time aggregation - * - * Created on: Feb 16, 2017 - * Author: wfg - */ - -#include <iostream> -#include <vector> - -#include <adios2.h> - -int main(int /*argc*/, char ** /*argv*/) -{ - const bool adiosDebug = true; - adios::ADIOS adios(adios::Verbose::ERROR, adiosDebug); - - // Application variable - std::vector<double> myDoubles = {10, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - - std::vector<float> myMatrix; - myMatrix.reserve(rows * columns); - myMatrix.push_back(1); - myMatrix.push_back(2), myMatrix.push_back(3); - myMatrix.push_back(4); - myMatrix.push_back(5), myMatrix.push_back(6); - myMatrix.push_back(7); - myMatrix.push_back(8), myMatrix.push_back(8); - - std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; - - try - { - // Define variable and local size - adios::Variable<double> &ioMyDoubles = - adios.DefineVariable<double>("myDoubles", {Nx}, {0}, {Nx}); - adios::Variable<float> &ioMyMatrix = adios.DefineVariable<float>( - "myMatrix", {rows, columns}, {0, 0}, {rows, columns}); - adios::Variable<float> &ioMyMatrix2 = adios.DefineVariable<float>( - "myMatrix2", {rows, columns}, {0, 0}, {rows, columns}); - - // Define method for engine creation, it is basically straight-forward - // parameters - - // default method type is BPWriter - adios::Method &bpWriterSettings = adios.DeclareMethod("SingleFile"); - bpWriterSettings.SetParameters("profile_units=mus"); - - // uses default POSIX library - bpWriterSettings.AddTransport("File", "profile_units=mus", - "have_metadata_file=no"); - - auto bpWriter = adios.Open("time_nompi.bp", "w", bpWriterSettings); - - for (unsigned int t = 0; t < 3; ++t) - { - myDoubles[0] = t; // t * -1; - myMatrix[0] = t; - myMatrix2[0] = t; - - // Base class Engine own the Write<T> that will call overloaded - // Write from Derived - bpWriter->Write(ioMyDoubles, myDoubles.data()); - bpWriter->Write(ioMyMatrix, myMatrix.data()); - bpWriter->Write(ioMyMatrix2, myMatrix2.data()); - bpWriter->Advance(); - } - - 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/source/adios2.h b/source/adios2.h index 671ea6242aa9a38d8ac06281667fbcf421f345c3..035df18888de4b63ebba0879f6c3783c10de971e 100644 --- a/source/adios2.h +++ b/source/adios2.h @@ -8,10 +8,12 @@ #include "adios2/ADIOSConfig.h" -#include "adios2/ADIOS.h" #include "adios2/ADIOSTypes.h" +#include "adios2/core/ADIOS.h" #include "adios2/core/Engine.h" -#include "adios2/core/Method.h" +#include "adios2/core/IO.h" +#include "adios2/core/SelectionBoundingBox.h" +#include "adios2/core/SelectionPoints.h" #include "adios2/core/Transform.h" #endif /* ADIOS2_H_ */ diff --git a/source/adios2/ADIOS.cpp b/source/adios2/ADIOS.cpp deleted file mode 100644 index 791d106aa26f9e48878de6bf8b2ce276cd332430..0000000000000000000000000000000000000000 --- a/source/adios2/ADIOS.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * ADIOS.cpp - * - * Created on: Sep 29, 2016 - * Author: William F Godoy - */ - -#include "ADIOS.h" -#include "ADIOS.tcc" - -#include <fstream> -#include <ios> //std::ios_base::failure -#include <iostream> -#include <sstream> -#include <utility> - -#include "adios2/ADIOSMPI.h" -#include "adios2/ADIOSMacros.h" -#include "adios2/core/adiosFunctions.h" -#include "adios2/engine/bp/BPFileReader.h" -#include "adios2/engine/bp/BPFileWriter.h" - -#ifdef ADIOS2_HAVE_DATAMAN // external dependencies -#include "adios2/engine/dataman/DataManReader.h" -#include "adios2/engine/dataman/DataManWriter.h" -#endif - -#ifdef ADIOS2_HAVE_ADIOS1 // external dependencies -#include "adios2/engine/adios1/ADIOS1Reader.h" -#include "adios2/engine/adios1/ADIOS1Writer.h" -#endif - -#ifdef ADIOS2_HAVE_HDF5 // external dependencies -#include "adios2/engine/hdf5/HDF5ReaderP.h" -#include "adios2/engine/hdf5/HDF5WriterP.h" -#endif - -namespace adios -{ - -ADIOS::ADIOS(const Verbose verbose, const bool debugMode) -: ADIOS("", MPI_COMM_SELF, verbose, debugMode) -{ -} - -ADIOS::ADIOS(const std::string config, const Verbose verbose, - const bool debugMode) -: ADIOS(config, MPI_COMM_SELF, verbose, debugMode) -{ -} - -ADIOS::ADIOS(const std::string configFile, MPI_Comm mpiComm, - const Verbose verbose, const bool debugMode) -: m_MPIComm(mpiComm), m_ConfigFile(configFile), m_DebugMode(debugMode) -{ - InitMPI(); - // InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage, - // m_Transforms, m_Groups ); -} - -ADIOS::ADIOS(MPI_Comm mpiComm, const Verbose verbose, const bool debugMode) -: ADIOS("", mpiComm, verbose, debugMode) -{ -} - -// ADIOS::~ADIOS() {} - -void ADIOS::InitMPI() -{ - if (m_DebugMode == true) - { - if (m_MPIComm == MPI_COMM_NULL) - { - throw std::ios_base::failure( - "ERROR: engine communicator is MPI_COMM_NULL," - " in call to ADIOS Open or Constructor\n"); - } - } - - MPI_Comm_rank(m_MPIComm, &m_RankMPI); - MPI_Comm_size(m_MPIComm, &m_SizeMPI); -} - -Method &ADIOS::DeclareMethod(const std::string methodName) -{ - if (m_DebugMode == true) - { - if (m_Methods.count(methodName) == 1) - { - throw std::invalid_argument( - "ERROR: method " + methodName + - " already declared, from DeclareMethod\n"); - } - } - m_Methods.emplace(methodName, Method(methodName, m_DebugMode)); - return m_Methods.at(methodName); -} - -std::shared_ptr<Engine> ADIOS::Open(const std::string &name, - const std::string accessMode, - MPI_Comm mpiComm, const Method &method) -{ - if (m_DebugMode == true) - { - if (m_EngineNames.count(name) == 1) // Check if Engine already exists - { - throw std::invalid_argument( - "ERROR: engine name " + name + - " already created by Open, in call from Open.\n"); - } - } - - m_EngineNames.insert(name); - - const std::string type(method.m_Type); - - const bool isDefaultWriter = - (accessMode == "w" || accessMode == "write" || accessMode == "a" || - accessMode == "append") && - type.empty() - ? true - : false; - - const bool isDefaultReader = - (accessMode == "r" || accessMode == "read") && type.empty() ? true - : false; - - if (isDefaultWriter || type == "BPFileWriter" || type == "bpfilewriter") - { - return std::make_shared<BPFileWriter>(*this, name, accessMode, mpiComm, - method); - } - else if (isDefaultReader || type == "BPReader" || type == "bpreader") - { - return std::make_shared<BPFileReader>(*this, name, accessMode, mpiComm, - method); - } - else if (type == "SIRIUS" || type == "sirius" || type == "Sirius") - { - // not yet supported - // return std::make_shared<engine::DataMan>( *this, name, accessMode, - // mpiComm, method, iomode, timeout_sec, m_DebugMode, method.m_nThreads - // ); - } - else if (type == "DataManWriter") - { -#ifdef ADIOS2_HAVE_DATAMAN - return std::make_shared<DataManWriter>(*this, name, accessMode, mpiComm, - method); -#else - throw std::invalid_argument( - "ERROR: this version didn't compile with " - "Dataman library, can't Open DataManWriter\n"); -#endif - } - else if (type == "DataManReader") - { -#ifdef ADIOS2_HAVE_DATAMAN - return std::make_shared<DataManReader>(*this, name, accessMode, mpiComm, - method); -#else - throw std::invalid_argument( - "ERROR: this version didn't compile with " - "Dataman library, can't Open DataManReader\n"); -#endif - } - else if (type == "ADIOS1Writer") - { -#ifdef ADIOS2_HAVE_ADIOS1 - return std::make_shared<ADIOS1Writer>(*this, name, accessMode, mpiComm, - method); -#else - throw std::invalid_argument( - "ERROR: this version didn't compile with ADIOS " - "1.x library, can't Open ADIOS1Writer\n"); -#endif - } - else if (type == "ADIOS1Reader") - { -#ifdef ADIOS2_HAVE_ADIOS1 - return std::make_shared<ADIOS1Reader>(*this, name, accessMode, mpiComm, - method); -#else - throw std::invalid_argument( - "ERROR: this version didn't compile with ADIOS " - "1.x library, can't Open ADIOS1Reader\n"); -#endif - } - else if (type == "Vis") - { - // return std::make_shared<Vis>( *this, name, accessMode, mpiComm, - // method, - // iomode, timeout_sec, m_DebugMode, method.m_nThreads ); - } - else if (type == "HDF5Writer") // -junmin - { -#ifdef ADIOS2_HAVE_HDF5 - return std::make_shared<HDF5Writer>(*this, name, accessMode, mpiComm, - method); -#else - throw std::invalid_argument("ERROR: this version didn't compile with " - "HDF5 library, can't use HDF5\n"); -#endif - } - else if (type == "HDF5Reader") // -Junmin - { -#ifdef ADIOS2_HAVE_HDF5 - return std::make_shared<HDF5Reader>(*this, name, accessMode, mpiComm, - method); -#else - throw std::invalid_argument("ERROR: this version didn't compile with " - "HDF5 library, can't use HDF5\n"); -#endif - } - else - { - if (m_DebugMode == true) - { - throw std::invalid_argument("ERROR: method type " + type + - " not supported for " + name + - ", in call to Open\n"); - } - } - - return nullptr; // if debug mode is off -} - -std::shared_ptr<Engine> ADIOS::Open(const std::string &name, - const std::string accessMode, - const Method &method) -{ - return Open(name, accessMode, m_MPIComm, method); -} - -std::shared_ptr<Engine> ADIOS::Open(const std::string &name, - const std::string accessMode, - MPI_Comm mpiComm, - const std::string methodName) -{ - auto itMethod = m_Methods.find(methodName); - - if (m_DebugMode == true) - { - CheckMethod(itMethod, methodName, " in call to Open\n"); - } - - return Open(name, accessMode, mpiComm, itMethod->second); -} - -std::shared_ptr<Engine> ADIOS::Open(const std::string &name, - const std::string accessMode, - const std::string methodName) -{ - return Open(name, accessMode, m_MPIComm, methodName); -} - -std::shared_ptr<Engine> ADIOS::OpenFileReader(const std::string &fileName, - MPI_Comm mpiComm, - const Method &method) - -{ - return Open(fileName, "r", mpiComm, method); -} - -std::shared_ptr<Engine> ADIOS::OpenFileReader(const std::string &name, - MPI_Comm mpiComm, - const std::string methodName) - -{ - auto itMethod = m_Methods.find(methodName); - - if (m_DebugMode == true) - { - CheckMethod(itMethod, methodName, " in call to Open\n"); - } - - return Open(name, "r", m_MPIComm, itMethod->second); -} - -VariableCompound &ADIOS::GetVariableCompound(const std::string &name) -{ - return m_Compound.at(GetVariableIndex<void>(name)); -} - -void ADIOS::MonitorVariables(std::ostream &logStream) -{ - logStream << "\tVariable \t Type\n"; - - for (auto &variablePair : m_Variables) - { - 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); - } - else if (type == GetType<std::complex<float>>()) - { - GetVariable<std::complex<float>>(name).Monitor(logStream); - } - else if (type == GetType<std::complex<double>>()) - { - GetVariable<std::complex<double>>(name).Monitor(logStream); - } - else if (type == GetType<std::complex<long double>>()) - { - GetVariable<std::complex<long double>>(name).Monitor(logStream); - } - } -} - -// PRIVATE FUNCTIONS BELOW -void ADIOS::CheckVariableInput(const std::string &name, - const Dims &dimensions) const -{ - 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"); - } - } -} - -void ADIOS::CheckMethod(std::map<std::string, Method>::const_iterator itMethod, - const std::string methodName, - const std::string hint) const -{ - if (itMethod == m_Methods.end()) - { - throw std::invalid_argument("ERROR: method " + methodName + - " not found " + hint + "\n"); - } -} - -//------------------------------------------------------------------------------ - -// Explicitly instantiate the necessary template implementations -#define define_template_instantiation(T) \ - template Variable<T> &ADIOS::DefineVariable<T>( \ - const std::string &, const Dims, const Dims, const Dims, \ - bool constantShape); \ - \ - template Variable<T> &ADIOS::GetVariable<T>(const std::string &); - -ADIOS_FOREACH_TYPE_1ARG(define_template_instantiation) -template unsigned int ADIOS::GetVariableIndex<void>(const std::string &); -#undef define_template_instatiation - -//------------------------------------------------------------------------------ - -} // end namespace adios diff --git a/source/adios2/ADIOS.h b/source/adios2/ADIOS.h deleted file mode 100644 index 7baca649e921e489468badb322008f9994e3ba7c..0000000000000000000000000000000000000000 --- a/source/adios2/ADIOS.h +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * ADIOS.h - * Created on: Oct 3, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_ADIOS_H_ -#define ADIOS2_ADIOS_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <complex> -#include <map> -#include <memory> //std::shared_ptr -#include <ostream> -#include <set> -#include <string> -#include <vector> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/ADIOSMPICommOnly.h" -#include "adios2/ADIOSMacros.h" -#include "adios2/ADIOSTypes.h" -#include "adios2/core/Method.h" -#include "adios2/core/Support.h" -#include "adios2/core/Transform.h" -#include "adios2/core/Variable.h" -#include "adios2/core/VariableCompound.h" - -namespace adios -{ - -class Engine; - -/** - * @brief Unique class interface between user application and ADIOS library - */ -class ADIOS -{ -public: - /** - * Passed from parallel constructor, MPI_Comm is a pointer itself. - * Public as called from C - */ - MPI_Comm m_MPIComm; - - int m_RankMPI = 0; ///< current MPI rank process - int m_SizeMPI = 1; ///< current MPI processes size - - std::string m_HostLanguage = "C++"; ///< changed by language bindings - - /** - * @brief ADIOS empty constructor. Used for non XML config file API calls. - */ - ADIOS(const Verbose verbose = Verbose::WARN, const bool debugMode = false); - - /** - * @brief Serial constructor for config file, only allowed and compiled in - * libadios_nompi.a - * @param configFile XML config file (maybe support different formats in the - * future?) - * @param debugMode true: on throws exceptions and do additional checks, - * false: off (faster, but unsafe) - */ - ADIOS(const std::string configFile, const Verbose verbose = Verbose::WARN, - const bool debugMode = false); - - /** - * @brief Parallel constructor for XML config file and MPI - * @param config XML config file (maybe support different formats in the - * future?) - * @param mpiComm MPI communicator ...const to be discussed - * @param debugMode true: on, false: off (faster, but unsafe) - */ - ADIOS(const std::string configFile, MPI_Comm mpiComm, - const Verbose verbose = Verbose::WARN, const bool debugMode = false); - - /** - * @brief Parallel MPI communicator without XML config file - * @param mpiComm MPI communicator passed to m_MPIComm* - * @param debugMode true: on, false: off (faster) - */ - ADIOS(MPI_Comm mpiComm, const Verbose verbose = Verbose::WARN, - const bool debugMode = false); - - ~ADIOS() = default; - - void InitMPI(); ///< sets rank and size in m_rank and m_Size, respectively. - - /** - * Define a Variable for I/O. Default is a local scalar to be compatible - * with ADIOS1 - * @param name variable name, must be unique - * @param dimensions - * @param selections - * @param offsets - * @constantShape true if dimensions, offsets and local sizes don't change - * over time - * @return reference to Variable object - */ - template <class T> - Variable<T> &DefineVariable(const std::string &name, const Dims shape = {}, - const Dims start = {}, const Dims count = {}, - const bool constantShape = false); - - template <class T> - Variable<T> &DefineLocalValue(const std::string &name) - { - return DefineVariable<T>(name, {LocalValueDim}, {}, {}, false); - } - - template <class T> - Variable<T> &DefineLocalArray(const std::string &name, bool isJoined, - Dims shape = {}) - { - return DefineVariable<T>(name, shape, {}, {}, false); - } - - template <class T> - Variable<T> &DefineArray(const std::string &name, Dims shape = {}, - Dims start = {}, Dims count = {}) - { - return DefineVariable<T>(name, shape, start, count, false); - } - - template <class T> - Variable<T> &GetVariable(const std::string &name); - - template <class T> - VariableCompound &DefineVariableCompound( - const std::string &name, const Dims globalDimensions = Dims{}, - const Dims localDimensions = Dims{1}, const Dims offsets = Dims{}); - - VariableCompound &GetVariableCompound(const std::string &name); - - /** - * Declares a new method. If the method is defined in the user config file, - * it will be already created during processing the config file, - * the method is set up with the user settings and this function just - * returns - * that method. - * Otherwise it will create and return a new Method with default settings. - * Use method.isUserDefined() to distinguish between the two cases. - * @param methodName must be unique - */ - Method &DeclareMethod(const std::string methodName); - - /** - * @brief Open to Write, Read. Creates a new engine from previously defined - * method - * @param streamName unique stream or file name - * @param accessMode "w" or "write", "r" or "read", "a" or "append", "u" or - * "update" - * @param mpiComm option to modify communicator from ADIOS class constructor - * @param method looks for corresponding Method object in ADIOS to - * initialize - * the engine - * @param iomode Independent or collective open/advance by writers/readers? - * Write() operations are always independent. - * @param timeout_sec Wait some time before reporting on missing stream - * (i.e. - * wait for it for a while) - * @return Derived class of base Engine depending on Method parameters, - * shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> Open(const std::string &streamName, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); - - /** - * @brief Open to Write, Read. Creates a new engine from previously defined - * method. - * Reuses MPI communicator from ADIOS constructor. - * @param streamName unique stream or file name - * @param accessMode "w" or "write", "r" or "read", "a" or "append", "u" or - * "update" - * @param method contains engine parameters - * @param iomode Independent or collective open/advance by writers/readers? - * Write() operations are always independent. - * @param timeout_sec Wait some time before reporting on missing stream - * (i.e. - * wait for it for a while) - * @return Derived class of base Engine depending on Method parameters, - * shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> Open(const std::string &streamName, - const std::string accessMode, - const Method &method); - - /** - * Version required by the XML config file implementation, searches method - * inside ADIOS through a unique name - * @param streamName unique stream or file name - * @param accessMode "w" or "write", "r" or "read", "a" or "append" - * @param mpiComm mpi Communicator - * @param methodName used to search method object inside ADIOS object - * @param iomode Independent or collective open/advance by writers/readers? - * Write() operations are always independent. - * @param timeout_sec Wait some time before reporting on missing stream - * (i.e. - * wait for it for a while) - * @return Derived class of base Engine depending on Method parameters, - * shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> Open(const std::string &streamName, - const std::string accessMode, MPI_Comm mpiComm, - const std::string methodName); - - /** - * Version required by the XML config file implementation, searches method - * inside ADIOS through a unique name. - * Reuses ADIOS MPI Communicator from constructor. - * @param streamName unique stream or file name - * @param accessMode "w" or "write", "r" or "read", "a" or "append" - * @param methodName used to search method object inside ADIOS object - * @param iomode Independent or collective open/advance by writers/readers? - * Write() operations are always independent. - * @param timeout_sec Wait some time before reporting on missing stream - * (i.e. - * wait for it for a while) - * @return Derived class of base Engine depending on Method parameters, - * shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> Open(const std::string &streamName, - const std::string accessMode, - const std::string methodName); - - /** - * @brief Open to Read all steps from a file. No streaming, advancing is - * possible here. All steps in the file - * are immediately available for reading. Creates a new engine from - * previously - * defined method. - * @param fileName file name - * @param mpiComm option to modify communicator from ADIOS class constructor - * @param method looks for corresponding Method object in ADIOS to - * initialize - * the engine - * @param iomode Independent or collective open/advance by writers/readers? - * Write() operations are always independent. - * @return Derived class of base Engine depending on Method parameters, - * shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> OpenFileReader(const std::string &fileName, - MPI_Comm mpiComm, - const Method &method); - - /** - * @brief Open to Read all steps from a file. No streaming, advancing is - * possible here. All steps in the file - * are immediately available for reading. Creates a new engine from - * previously - * defined method. - * Version required by the XML config file implementation, searches method - * inside ADIOS through a unique name. - * @param fileName file name - * @param mpiComm option to modify communicator from ADIOS class constructor - * @param methodName used to search method object inside ADIOS object - * @param iomode Independent or collective open/advance by writers/readers? - * Write() operations are always independent. - * @return Derived class of base Engine depending on Method parameters, - * shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> OpenFileReader(const std::string &fileName, - MPI_Comm mpiComm, - const std::string methodName); - - /** - * @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 MonitorVariables(std::ostream &logStream); - -protected: // no const to allow default empty and copy constructors - std::map<unsigned int, Variable<char>> m_Char; - std::map<unsigned int, Variable<unsigned char>> m_UChar; - std::map<unsigned int, Variable<short>> m_Short; - std::map<unsigned int, Variable<unsigned short>> m_UShort; - std::map<unsigned int, Variable<int>> m_Int; - std::map<unsigned int, Variable<unsigned int>> m_UInt; - std::map<unsigned int, Variable<long int>> m_LInt; - std::map<unsigned int, Variable<unsigned long int>> m_ULInt; - std::map<unsigned int, Variable<long long int>> m_LLInt; - std::map<unsigned int, Variable<unsigned long long int>> m_ULLInt; - std::map<unsigned int, Variable<float>> m_Float; - std::map<unsigned int, Variable<double>> m_Double; - std::map<unsigned int, Variable<long double>> m_LDouble; - std::map<unsigned int, Variable<std::complex<float>>> m_CFloat; - std::map<unsigned int, Variable<std::complex<double>>> m_CDouble; - std::map<unsigned int, Variable<std::complex<long double>>> m_CLDouble; - std::map<unsigned int, VariableCompound> m_Compound; - - ///< XML File to be read containing configuration information - std::string m_ConfigFile; - - ///< if true will do more checks, exceptions, warnings, expect slower code - bool m_DebugMode = false; - - // Variables - ///< Makes variable name unique, key: variable name,value: pair.first = - /// type, pair.second = index in corresponding vector of Variable - std::map<std::string, std::pair<std::string, unsigned int>> m_Variables; - - ///< transforms associated with ADIOS run - std::vector<std::shared_ptr<Transform>> m_Transforms; - - /** - * @brief List of Methods (engine metadata) defined from either ADIOS XML - * configuration file or the DeclareMethod function. - * <pre> - * Key: std::string unique method name - * Value: Method class - * </pre> - */ - std::map<std::string, Method> m_Methods; - - ///< set used to check Engine name uniqueness in debug mode - std::set<std::string> m_EngineNames; - - /** - * @brief Checks for group existence in m_Groups, if failed throws - * std::invalid_argument exception - * @param itGroup m_Groups iterator, usually from find function - * @param groupName unique name, passed for thrown exception only - * @param hint adds information to thrown exception - */ - 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 - * @param itMethod m_Methods iterator, usually from find function - * @param methodName unique name, passed for thrown exception only - * @param hint adds information to thrown exception - */ - 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); - - // Helper function for DefineVariable - template <class T> - std::map<unsigned int, Variable<T>> &GetVariableMap(); -}; - -//------------------------------------------------------------------------------ - -// Explicit declaration of the template methods -#define declare_template_instantiation(T) \ - extern template Variable<T> &ADIOS::DefineVariable<T>( \ - const std::string &name, const Dims, const Dims, const Dims, \ - const bool constantShape); \ - \ - extern template Variable<T> &ADIOS::GetVariable<T>(const std::string &); - -ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation) -extern template unsigned int ADIOS::GetVariableIndex<void>(const std::string &); -#undef declare_template_instantiation - -} // end namespace adios - -// Include the inline implementations for the public interface -#include "adios2/ADIOS.inl" - -#endif /* ADIOS2_ADIOS_H_ */ diff --git a/source/adios2/ADIOS.inl b/source/adios2/ADIOS.inl deleted file mode 100644 index 8b82f2e85e94b1dcc15c08f841284670a57549cf..0000000000000000000000000000000000000000 --- a/source/adios2/ADIOS.inl +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * ADIOS.tcc - * This contains the template implementations for the ADIOS class - */ - -#ifndef ADIOS2_ADIOS_INL_ -#define ADIOS2_ADIOS_INL_ -#ifndef ADIOS2_ADIOS_H_ -#error "Inline file should only be included from it's header, never on it's own" -#endif - -namespace adios -{ - -template <class T> -VariableCompound &ADIOS::DefineVariableCompound(const std::string &name, - const Dims dimensions, - const Dims globalDimensions, - const Dims globalOffsets) -{ - CheckVariableInput(name, dimensions); - const unsigned int size = m_Compound.size(); - m_Compound.emplace(size, VariableCompound(name, sizeof(T), dimensions, - globalDimensions, globalOffsets, - false, m_DebugMode)); - m_Variables.emplace(name, std::make_pair(GetType<T>(), size)); - return m_Compound.at(size); -} - -} // end namespace adios - -#endif /* ADIOS2_ADIOS_INL_ */ diff --git a/source/adios2/ADIOS.tcc b/source/adios2/ADIOS.tcc deleted file mode 100644 index c6262014bec86553c5157487b5c97a4a559c950d..0000000000000000000000000000000000000000 --- a/source/adios2/ADIOS.tcc +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * ADIOS.tcc - * This contains the template specializatios for the ADIOS class - */ - -#ifndef ADIOS2_ADIOS_TCC_ -#define ADIOS2_ADIOS_TCC_ - -#include "adios2/ADIOS.h" -#include "adios2/ADIOSMacros.h" - -namespace adios -{ - -// ----------------------------------------------------------------------------- -// template specializations of GetVarMap helper function -// ----------------------------------------------------------------------------- - -template <> -std::map<unsigned int, Variable<char>> &ADIOS::GetVariableMap() -{ - return m_Char; -} - -template <> -std::map<unsigned int, Variable<unsigned char>> &ADIOS::GetVariableMap() -{ - return m_UChar; -} - -template <> -std::map<unsigned int, Variable<short>> &ADIOS::GetVariableMap() -{ - return m_Short; -} - -template <> -std::map<unsigned int, Variable<unsigned short>> &ADIOS::GetVariableMap() -{ - return m_UShort; -} - -template <> -std::map<unsigned int, Variable<int>> &ADIOS::GetVariableMap() -{ - return m_Int; -} - -template <> -std::map<unsigned int, Variable<unsigned int>> &ADIOS::GetVariableMap() -{ - return m_UInt; -} - -template <> -std::map<unsigned int, Variable<long int>> &ADIOS::GetVariableMap() -{ - return m_LInt; -} - -template <> -std::map<unsigned int, Variable<unsigned long int>> &ADIOS::GetVariableMap() -{ - return m_ULInt; -} - -template <> -std::map<unsigned int, Variable<long long int>> &ADIOS::GetVariableMap() -{ - return m_LLInt; -} - -template <> -std::map<unsigned int, Variable<unsigned long long int>> & -ADIOS::GetVariableMap() -{ - return m_ULLInt; -} - -template <> -std::map<unsigned int, Variable<float>> &ADIOS::GetVariableMap() -{ - return m_Float; -} - -template <> -std::map<unsigned int, Variable<double>> &ADIOS::GetVariableMap() -{ - return m_Double; -} - -template <> -std::map<unsigned int, Variable<long double>> &ADIOS::GetVariableMap() -{ - return m_LDouble; -} - -template <> -std::map<unsigned int, Variable<std::complex<float>>> &ADIOS::GetVariableMap() -{ - return m_CFloat; -} - -template <> -std::map<unsigned int, Variable<std::complex<double>>> &ADIOS::GetVariableMap() -{ - return m_CDouble; -} - -template <> -std::map<unsigned int, Variable<std::complex<long double>>> & -ADIOS::GetVariableMap() -{ - return m_CLDouble; -} - -// ----------------------------------------------------------------------------- - -template <typename T> -Variable<T> &ADIOS::DefineVariable(const std::string &name, const Dims shape, - const Dims start, const Dims count, - const bool constantShape) -{ - auto &variableMap = GetVariableMap<T>(); - CheckVariableInput(name, shape); - const unsigned int size = variableMap.size(); - variableMap.emplace(size, Variable<T>(name, shape, start, count, - constantShape, m_DebugMode)); - m_Variables.emplace(name, std::make_pair(GetType<T>(), size)); - return variableMap.at(size); -} - -// ----------------------------------------------------------------------------- - -template <class T> -unsigned int ADIOS::GetVariableIndex(const std::string &name) -{ - auto itVariable = m_Variables.find(name); - CheckVariableName( - itVariable, name, - "in call to GetVariable<" + GetType<T>() + - ">, or call to GetVariableCompound if <T> = <compound>\n"); - return itVariable->second.second; -} - -template <typename T> -Variable<T> &ADIOS::GetVariable(const std::string &name) -{ - return GetVariableMap<T>().at(GetVariableIndex<T>(name)); -} - -} // end namespace adios - -#endif // ADIOS2_ADIOS_TCC_ diff --git a/source/adios2/ADIOSMacros.h b/source/adios2/ADIOSMacros.h index 0a15f131de7c3c715807482830179a9692eac3ed..8f1471a4a7067ea274f5620ba439320856679df0 100644 --- a/source/adios2/ADIOSMacros.h +++ b/source/adios2/ADIOSMacros.h @@ -8,6 +8,7 @@ #ifndef ADIOS2_ADIOSMACROS_H #define ADIOS2_ADIOSMACROS_H +#include "adios2/ADIOSTypes.h" // The ADIOS_FOREACH_TYPE_1ARG macro assumes the given argument is a macro which // takes a single argument that is a type and then inserts the given MACRO for // each of the known primitive types @@ -21,7 +22,7 @@ // ADIOS_FOREACH_TYPE_1ARG(instantiate_foo) // #undef instantiate_foo // -#define ADIOS_FOREACH_TYPE_1ARG(MACRO) \ +#define ADIOS2_FOREACH_TYPE_1ARG(MACRO) \ MACRO(char) \ MACRO(unsigned char) \ MACRO(short) \ @@ -29,8 +30,8 @@ MACRO(int) \ MACRO(unsigned int) \ MACRO(long int) \ - MACRO(unsigned long int) \ MACRO(long long int) \ + MACRO(unsigned long int) \ MACRO(unsigned long long int) \ MACRO(float) \ MACRO(double) \ @@ -39,7 +40,7 @@ MACRO(std::complex<double>) \ MACRO(std::complex<long double>) -#define ADIOS_FOREACH_PRIMITIVE_TYPE_1ARG(MACRO) \ +#define ADIOS2_FOREACH_PRIMITIVE_TYPE_1ARG(MACRO) \ MACRO(char) \ MACRO(unsigned char) \ MACRO(short) \ @@ -48,15 +49,11 @@ MACRO(unsigned int) \ MACRO(long int) \ MACRO(unsigned long int) \ - MACRO(long long int) \ - MACRO(unsigned long long int) \ MACRO(float) \ - MACRO(double) \ - MACRO(long double) + MACRO(double) -#define ADIOS_FOREACH_COMPLEX_TYPE_1ARG(MACRO) \ +#define ADIOS2_FOREACH_COMPLEX_TYPE_1ARG(MACRO) \ MACRO(float) \ - MACRO(double) \ - MACRO(long double) + MACRO(double) #endif /* ADIOS2_ADIOSMACROS_H */ diff --git a/source/adios2/ADIOSTypes.h b/source/adios2/ADIOSTypes.h index b460d41f4e5932e4c3fe4180e968e1a99e1bd664..455b7a42b7715de48a93f0eb5fe4e93dd2ddb554 100644 --- a/source/adios2/ADIOSTypes.h +++ b/source/adios2/ADIOSTypes.h @@ -2,45 +2,182 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * ADIOS_Types.h + * ADIOSTypes.h * * Created on: Mar 23, 2017 - * Author: pnb + * Author: Chuck Atkins chuck.atkins@kitware.com + * Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov + * */ #ifndef ADIOS2_ADIOSTYPES_H_ #define ADIOS2_ADIOSTYPES_H_ -#include <complex> +/// \cond EXCLUDE_FROM_DOXYGEN #include <cstddef> #include <cstdint> + +#include <complex> #include <limits> +#include <map> +#include <string> #include <type_traits> +#include <vector> +/// \endcond #include "adios2/ADIOSConfig.h" namespace adios { -// Alias the fixed sized typed into the adios namespace to make sure we're -// always using the right ones. +/** Variable shape type identifier */ +enum class ShapeID +{ + GlobalValue, ///< single global value, common case + GlobalArray, ///< global (across MPI_Comm) array, common case + JoinedArray, ///< global array with a common (joinable) dimension + LocalValue, ///< special case, local independent value + LocalArray ///< special case, local independent array +}; + +/** Used to set IO class */ +enum class IOMode +{ + Independent, ///< all I/O operations are independent per rank + Collective ///< expect collective I/O operations +}; + +/** OpenMode in IO Open */ +enum class OpenMode +{ + Undefined, + Write, + Read, + Append, + ReadWrite, +}; + +enum class ReadMultiplexPattern +{ + GlobalReaders, + RoundRobin, + FirstInFirstOut, + OpenAllSteps +}; + +enum class StreamOpenMode +{ + Wait, + NoWait +}; + +enum class TransformType +{ + BZip2, + Zfp +}; + +enum class TransportType +{ + File, + WAN +}; + +/** Just for info purposes */ +enum class IOEngine +{ + Unknown, + BPFileWriter, ///< produces bp files + BPFileReader, ///< read bp files + HDF5Writer, ///< + HDF5Reader, ///< + ADIOS1Writer, + ADIOS1Reader, + DataManWriter, + DataManReader +}; + +enum class ReadMode +{ + NonBlocking, + Blocking +}; + +enum class AdvanceMode +{ + Append, + Update, // writer advance mode + NextAvailable, + LatestAvailable // reader advance mode +}; + +enum class AdvanceStatus +{ + OK, + StepNotReady, + EndOfStream, + OtherError +}; + +enum class TimeUnit +{ + Microseconds, + Milliseconds, + Seconds, + Minutes, + Hours +}; + +/** Type of selection */ +enum class SelectionType +{ + BoundingBox, ///< Contiguous block of data defined by offsets and counts per + /// dimension + Points, ///< List of individual points + WriteBlock, ///< Selection of an individual block written by a writer + /// process + Auto ///< Let the engine decide what to return +}; + +// adios defaults +const std::string DefaultFileLibrary("POSIX"); +const std::string DefaultTimeUnit("Microseconds"); +constexpr TimeUnit DefaultTimeUnitEnum(TimeUnit::Microseconds); +constexpr size_t DefaultBufferSize(16384); ///< in bytes + +// adios alias values and types +constexpr bool DebugON = true; +constexpr bool DebugOFF = false; +constexpr size_t UnknownDim = 0; +constexpr size_t JoinedDim = std::numeric_limits<size_t>::max() - 1; +constexpr size_t LocalValueDim = std::numeric_limits<size_t>::max() - 2; +constexpr size_t IrregularDim = std::numeric_limits<size_t>::max() - 3; +constexpr bool ConstantDims = true; +constexpr bool ReadIn = true; + using std::size_t; +using Dims = std::vector<size_t>; +using Params = std::map<std::string, std::string>; + +// Primitives +// using schar = signed char; using std::int8_t; -using std::uint8_t; using std::int16_t; -using std::uint16_t; using std::int32_t; -using std::uint32_t; using std::int64_t; + +// using uchar = unsigned char; +using std::uint8_t; +using std::uint16_t; +using std::uint32_t; using std::uint64_t; -// Not sure if we're really use these ones but we'll round it out for -// completion -using real32_t = float; -using real64_t = double; -using complex32_t = std::complex<real32_t>; -using complex64_t = std::complex<real64_t>; +// Complex +using cfloat = std::complex<float>; +using cdouble = std::complex<double>; +using cldouble = std::complex<long double>; // Get a fixed width integer type from a size specification template <size_t Bytes, bool Signed> @@ -115,35 +252,6 @@ struct TypeInfo<T, typename std::enable_if<std::is_same< using ValueType = typename T::value_type; }; -const size_t UnknownDim = 0; -const size_t JoinedDim = std::numeric_limits<size_t>::max() - 1; -const size_t LocalValueDim = JoinedDim - 1; -const size_t IrregularDim = JoinedDim - 2; -const bool ConstantShape = true; - -enum class VarClass -{ - GlobalValue, - LocalValue, - GlobalArray, - JoinedArray, - LocalArray -}; - -enum class Verbose -{ - ERROR = 0, - WARN = 1, - INFO = 2, - DEBUG = 3 -}; - -enum class IOMode -{ - INDEPENDENT = 0, - COLLECTIVE = 1 -}; - } // end namespace adios #endif /* ADIOS2_ADIOSTYPES_H_ */ diff --git a/source/adios2/CMakeLists.txt b/source/adios2/CMakeLists.txt index cdaa1eaacef41b863687a1bde37a8821c4299ad2..30c544588c2e48b2d3e6aedbcbd9a7ee0488d3f3 100644 --- a/source/adios2/CMakeLists.txt +++ b/source/adios2/CMakeLists.txt @@ -4,35 +4,44 @@ #------------------------------------------------------------------------------# add_library(adios2 - ADIOS.cpp ADIOS.tcc - - capsule/heap/STLVector.cpp - capsule/shmem/ShmSystemV.cpp - - core/Capsule.cpp + core/ADIOS.cpp core/Engine.cpp - core/Method.cpp - core/Support.cpp - core/Timer.cpp + core/IO.cpp core/IO.tcc + core/Selection.cpp + core/SelectionBoundingBox.cpp + core/SelectionPoints.cpp core/Transform.cpp - core/Transport.cpp - core/adiosFunctions.cpp + core/VariableBase.cpp + core/VariableCompound.cpp core/VariableCompound.tcc + +#helper + helper/adiosMath.cpp + helper/adiosMemory.cpp + helper/adiosString.cpp + helper/adiosSystem.cpp + helper/adiosType.cpp + helper/adiosXML.cpp - engine/bp/BPFileReader.cpp - engine/bp/BPFileWriter.cpp +# engine/bp/BPFileReader.cpp + engine/bp/BPFileWriter.cpp engine/bp/BPFileWriter.tcc - utilities/format/bp1/BP1Base.cpp - utilities/format/bp1/BP1Aggregator.cpp - utilities/format/bp1/BP1Writer.cpp - - transport/file/FStream.cpp - transport/file/FileDescriptor.cpp - transport/file/FilePointer.cpp - - utilities/format/bp1/BP1Base.cpp - utilities/format/bp1/BP1Aggregator.cpp - utilities/format/bp1/BP1Writer.cpp - utilities/format/bp1/BP1Writer.tcc + toolkit/capsule/Capsule.cpp + toolkit/capsule/heap/STLVector.cpp + toolkit/capsule/shmem/ShmSystemV.cpp + + toolkit/format/bp1/BP1Base.cpp toolkit/format/bp1/BP1Base.tcc + toolkit/format/bp1/BP1Aggregator.cpp + toolkit/format/bp1/BP1Writer.cpp toolkit/format/bp1/BP1Writer.tcc + + toolkit/profiling/iochrono/Timer.cpp + + toolkit/transport/Transport.cpp + toolkit/transport/file/FileDescriptor.cpp + toolkit/transport/file/FilePointer.cpp + toolkit/transport/file/FileStream.cpp + + toolkit/transportman/TransportMan.cpp + ) target_include_directories(adios2 PUBLIC @@ -49,7 +58,6 @@ if(ADIOS_USE_DataMan) target_sources(adios2 PRIVATE engine/dataman/DataManReader.cpp engine/dataman/DataManWriter.cpp - transport/wan/MdtmMan.cpp ) target_link_libraries(adios2 PRIVATE dataman) endif() @@ -85,6 +93,9 @@ if(ADIOS_USE_ADIOS1) target_sources(adios2 PRIVATE engine/adios1/ADIOS1Reader.cpp engine/adios1/ADIOS1Writer.cpp + + toolkit/interop/adios1/ADIOS1Common.cpp toolkit/interop/adios1/ADIOS1Common.tcc + ) target_link_libraries(adios2 PRIVATE adios1::adios) endif() @@ -110,13 +121,13 @@ if(ADIOS_USE_HDF5) target_sources(adios2 PRIVATE engine/hdf5/HDF5ReaderP.cpp engine/hdf5/HDF5WriterP.cpp - engine/hdf5/HDF5Common.cpp + toolkit/interop/hdf5/HDF5Common.cpp toolkit/interop/hdf5/HDF5Common.tcc ) target_link_libraries(adios2 PRIVATE ${HDF5_C_LIBRARIES}) endif() install( - FILES ADIOS.h ADIOS.inl ADIOSMacros.h ADIOSTypes.h ADIOSMPICommOnly.h + FILES ADIOSMacros.h ADIOSTypes.h ADIOSMPICommOnly.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/adios2 ) install( diff --git a/source/adios2/core/ADIOS.cpp b/source/adios2/core/ADIOS.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ee373fb869ae75a4d98457b0624646fbfb31af55 --- /dev/null +++ b/source/adios2/core/ADIOS.cpp @@ -0,0 +1,86 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * ADIOS.cpp + * + * Created on: Sep 29, 2016 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "ADIOS.h" + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <fstream> +#include <ios> //std::ios_base::failure +#include <iostream> +#include <sstream> +#include <utility> +/// \endcond + +#include "adios2/ADIOSMPI.h" + +namespace adios +{ + +ADIOS::ADIOS(const std::string configFile, MPI_Comm mpiComm, + const bool debugMode) +: m_MPIComm(mpiComm), m_ConfigFile(configFile), m_DebugMode(debugMode) +{ + if (m_DebugMode) + { + CheckMPI(); + } + // XML to be implemented later + // InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage, + // m_Transforms, m_Groups ); +} + +ADIOS::ADIOS(const std::string configFile, const bool debugMode) +: ADIOS(configFile, MPI_COMM_SELF, debugMode) +{ +} + +ADIOS::ADIOS(MPI_Comm mpiComm, const bool debugMode) +: ADIOS("", mpiComm, debugMode) +{ +} + +ADIOS::ADIOS(const bool debugMode) : ADIOS("", MPI_COMM_SELF, debugMode) {} + +IO &ADIOS::DeclareIO(const std::string ioName) +{ + auto itIO = m_IOs.find(ioName); + + if (itIO != m_IOs.end()) // exists + { + if (m_DebugMode) + { + if (itIO->second.InConfigFile()) + { + throw std::invalid_argument( + "ERROR: IO class object with name " + ioName + + " previously declared, name must be unique " + " , in call to DeclareIO\n"); + } + } + return itIO->second; + } + + // doesn't exist, then create new pair + auto ioPair = + m_IOs.emplace(ioName, IO(ioName, m_MPIComm, false, m_DebugMode)); + return ioPair.first->second; +} + +// PRIVATE FUNCTIONS +void ADIOS::CheckMPI() const +{ + if (m_MPIComm == MPI_COMM_NULL) + { + throw std::ios_base::failure("ERROR: MPI communicator is MPI_COMM_NULL," + " in call to ADIOS constructor\n"); + } +} + +} // end namespace adios diff --git a/source/adios2/core/ADIOS.h b/source/adios2/core/ADIOS.h new file mode 100644 index 0000000000000000000000000000000000000000..f13ae4974c21ea90985c081a144f1695a0db1fb8 --- /dev/null +++ b/source/adios2/core/ADIOS.h @@ -0,0 +1,110 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * ADIOS.h : ADIOS library starting point, factory class for IO and + * (polymorphic) Engines + * Created on: Oct 3, 2016 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_CORE_ADIOS_H_ +#define ADIOS2_CORE_ADIOS_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <map> +#include <memory> //std::shared_ptr +#include <string> +#include <vector> +/// \endcond + +#include "adios2/ADIOSConfig.h" +#include "adios2/ADIOSMPICommOnly.h" +#include "adios2/core/IO.h" +#include "adios2/core/Transform.h" + +namespace adios +{ + +/** @brief Point of entry class for an application. + * Serves as factory of IO class objects and Transforms */ +class ADIOS +{ +public: + /** Passed from parallel constructor, MPI_Comm is a pointer itself. */ + MPI_Comm m_MPIComm; + std::string m_HostLanguage = "C++"; ///< changed by language bindings + + /** + * @brief Constructor for MPI applications WITH a XML config file + * @param configFile XML format (maybe support different formats in the + * future?) + * @param mpiComm MPI communicator from application + * @param debugMode true: extra exception checks (recommended) + */ + ADIOS(const std::string configFile, MPI_Comm mpiComm, + const bool debugMode = false); + + /** + * @brief Constructor for non-MPI applications WITH a XML config file + * @param configFile XML format (maybe support different formats in the + * future?) + * @param debugMode true: extra exception checks (recommended) + */ + ADIOS(const std::string configFile, const bool debugMode = false); + + /** + * @brief Constructor for MPI apps WITHOUT a XML config file + * @param mpiComm MPI communicator from application + * @param debugMode true: extra exception checks (recommended) + */ + ADIOS(MPI_Comm mpiComm, const bool debugMode = false); + + /** + * @brief ADIOS no-MPI default empty constructor + * @param debugMode true: extra exception checks (recommended) + */ + ADIOS(const bool debugMode = false); + + ~ADIOS() = default; + + /** + * Declares a new IO class object. If IO object is defined in the user + * config file, by name, it will be already created during the processing + * the config file. So this function returns a reference to that object. + * Otherwise it will create and return a new IO object with default + * settings. + * Use function InConfigFile() to distinguish between the two cases. + * @param ioName must be unique + * @return reference to existing (or newly created) method inside ADIOS + */ + IO &DeclareIO(const std::string ioName); + +protected: // no const member to allow default empty and copy constructors + /** XML File to be read containing configuration information */ + std::string m_ConfigFile; + + /** if true will do more checks, exceptions, warnings, expect slower code */ + bool m_DebugMode = false; + + /** transforms associated with ADIOS run */ + std::vector<std::shared_ptr<Transform>> m_Transforms; + + /** + * @brief List of IO class objects defined from either ADIOS + * configuration file (XML) or the DeclareIO function explicitly. + * Using map (binary tree) to preserve references returned by DeclareIO. + * <pre> + * Key: unique method name + * Value: IO class object + * </pre> + */ + std::map<std::string, IO> m_IOs; + + /** throws exception if m_MPIComm = MPI_COMM_NULL */ + void CheckMPI() const; +}; + +} // end namespace adios + +#endif /* ADIOS2_ADIOS_H_ */ diff --git a/source/adios2/core/Attribute.h b/source/adios2/core/Attribute.h deleted file mode 100644 index 146e72486ae4da7275af68b45f2a447a01c8558d..0000000000000000000000000000000000000000 --- a/source/adios2/core/Attribute.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Attribute.h - * - * Created on: Oct 5, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_ATTRIBUTE_H_ -#define ADIOS2_CORE_ATTRIBUTE_H_ - -#include <string> - -#include "adios2/ADIOSConfig.h" - -namespace adios -{ - -/** - * Plain-old data struct that defines an attribute in an ADIOS group in Group.h - */ -struct Attribute -{ - const char TypeID; ///< '0': string, '1': numeric - const std::string Value; ///< information about the attribute -}; - -} // end namespace - -#endif /* ADIOS2_CORE_ATTRIBUTE_H_ */ diff --git a/source/adios2/core/Engine.cpp b/source/adios2/core/Engine.cpp index af390ee594eeb1be3f0123d1575a39ea58f5978f..8595d6db4441c0cc400374a670ec10658f09875b 100644 --- a/source/adios2/core/Engine.cpp +++ b/source/adios2/core/Engine.cpp @@ -5,525 +5,209 @@ * Engine.cpp * * Created on: Dec 19, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "Engine.h" +#include "Engine.tcc" +/// \cond EXCLUDE_FROM_DOXYGEN #include <ios> //std::ios_base::failure - -#include "adios2/ADIOSMPI.h" -#include "adios2/core/Support.h" -#include "adios2/core/adiosFunctions.h" +#include <set> +/// \endcond namespace adios { -Engine::Engine(ADIOS &adios, const std::string engineType, - const std::string &name, const std::string accessMode, - MPI_Comm mpiComm, const Method &method, - const std::string endMessage) -: m_MPIComm(mpiComm), m_EngineType(engineType), m_Name(name), - m_AccessMode(accessMode), m_Method(method), m_ADIOS(adios), - m_DebugMode(m_Method.m_DebugMode), m_EndMessage(endMessage) +Engine::Engine(const std::string engineType, IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: m_EngineType(engineType), m_IO(io), m_Name(name), m_OpenMode(openMode), + m_MPIComm(mpiComm), m_DebugMode(io.m_DebugMode) { - if (m_DebugMode == true) - { - if (m_MPIComm == MPI_COMM_NULL) - { - throw std::ios_base::failure( - "ERROR: engine communicator is MPI_COMM_NULL," - " in call to ADIOS Open or Constructor\n"); - } - } - - MPI_Comm_rank(m_MPIComm, &m_RankMPI); - MPI_Comm_size(m_MPIComm, &m_SizeMPI); } -void Engine::SetCallBack(std::function<void(const void *, std::string, - std::string, std::string, Dims)> - callback) +void Engine::SetCallBack( + std::function<void(const void *, std::string, std::string, std::string, + std::vector<size_t>)> + callback) { } -static void EngineThrowUp(const std::string &engineType, - const std::string &func) -{ - throw std::invalid_argument( - "ERROR: Engine bass class " + func + "() called. " + engineType + - " child class is not implementing this function\n"); -} - // should these functions throw an exception? -void Engine::Write(Variable<char> & /*variable*/, const char * /*values*/) {} -void Engine::Write(Variable<unsigned char> & /*variable*/, - const unsigned char * /*values*/) -{ -} -void Engine::Write(Variable<short> & /*variable*/, const short * /*values*/) {} -void Engine::Write(Variable<unsigned short> & /*variable*/, - const unsigned short * /*values*/) -{ -} -void Engine::Write(Variable<int> & /*variable*/, const int * /*values*/) {} -void Engine::Write(Variable<unsigned int> & /*variable*/, - const unsigned int * /*values*/) -{ -} -void Engine::Write(Variable<long int> & /*variable*/, - const long int * /*values*/) -{ -} -void Engine::Write(Variable<unsigned long int> & /*variable*/, - const unsigned long int * /*values*/) -{ -} -void Engine::Write(Variable<long long int> & /*variable*/, - const long long int * /*values*/) -{ -} -void Engine::Write(Variable<unsigned long long int> & /*variable*/, - const unsigned long long int * /*values*/) -{ -} -void Engine::Write(Variable<float> & /*variable*/, const float * /*values*/) {} -void Engine::Write(Variable<double> & /*variable*/, const double * /*values*/) -{ -} -void Engine::Write(Variable<long double> & /*variable*/, - const long double * /*values*/) -{ -} -void Engine::Write(Variable<std::complex<float>> & /*variable*/, - const std::complex<float> * /*values*/) -{ -} -void Engine::Write(Variable<std::complex<double>> & /*variable*/, - const std::complex<double> * /*values*/) -{ -} -void Engine::Write(Variable<std::complex<long double>> & /*variable*/, - const std::complex<long double> * /*values*/) -{ -} -void Engine::Write(VariableCompound & /*variable*/, const void * /*values*/) {} -void Engine::Write(const std::string & /*variableName*/, - const char * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const unsigned char * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const short * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const unsigned short * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, const int * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const unsigned int * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const long int * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const unsigned long int * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const long long int * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const unsigned long long int * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const float * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const double * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const long double * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const std::complex<float> * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const std::complex<double> * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const std::complex<long double> * /*values*/) -{ -} -void Engine::Write(const std::string & /*variableName*/, - const void * /*values*/) -{ -} - -void Engine::Advance(float /*timeout_sec*/) {} -void Engine::Advance(AdvanceMode /*mode*/, float /*timeout_sec*/) {} +void Engine::Advance(const float /*timeout_sec*/) {} +void Engine::Advance(const AdvanceMode /*mode*/, const float /*timeout_sec*/) {} void Engine::AdvanceAsync( AdvanceMode /*mode*/, std::function<void(std::shared_ptr<adios::Engine>)> /*callback*/) { } +AdvanceStatus Engine::GetAdvanceStatus() { return m_AdvanceStatus; } + void Engine::Close(const int /*transportIndex*/) {} // READ -Variable<void> *Engine::InquireVariable(const std::string & /*name*/, - const bool /*readIn*/) -{ - return nullptr; +void Engine::Release() {} +void Engine::PerformReads(ReadMode /*mode*/){}; + +// PROTECTED +void Engine::Init() {} + +void Engine::InitParameters() {} + +void Engine::InitTransports() {} + +// DoWrite +#define declare_type(T) \ + void Engine::DoWrite(Variable<T> &variable, const T *values) \ + { \ + ThrowUp("Write"); \ + } +ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type + +void Engine::DoWrite(VariableCompound &variable, const void *values) +{ // TODO } -Variable<char> *Engine::InquireVariableChar(const std::string & /*name*/, - const bool /*readIn*/) + +void Engine::DoWrite(const std::string &variableName, const void *values) { - return nullptr; -} -Variable<unsigned char> * -Engine::InquireVariableUChar(const std::string & /*name*/, - const bool /*readIn*/) + const std::string type(m_IO.GetVariableType(variableName)); + if (m_DebugMode) + { + if (type.empty()) + { + throw std::invalid_argument( + "ERROR: variable " + variableName + + " was not created with IO.DefineVariable for Engine " + m_Name + + ", in call to Write\n"); + } + } + + if (type == "compound") + { + DoWrite(m_IO.GetVariableCompound(variableName), values); + } +#define declare_type(T) \ + else if (type == GetType<T>()) \ + { \ + DoWrite(m_IO.GetVariable<T>(variableName), \ + reinterpret_cast<const T *>(values)); \ + } + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type +} // end DoWrite + +// READ +VariableBase *Engine::InquireVariableUnknown(const std::string &name, + const bool readIn) { return nullptr; } -Variable<short> *Engine::InquireVariableShort(const std::string & /*name*/, - const bool /*readIn*/) +Variable<char> *Engine::InquireVariableChar(const std::string &name, + const bool readIn) { return nullptr; } -Variable<unsigned short> * -Engine::InquireVariableUShort(const std::string & /*name*/, - const bool /*readIn*/) +Variable<unsigned char> *Engine::InquireVariableUChar(const std::string &name, + const bool readIn) { return nullptr; } -Variable<int> *Engine::InquireVariableInt(const std::string & /*name*/, - const bool /*readIn*/) +Variable<short> *Engine::InquireVariableShort(const std::string &name, + const bool readIn) { return nullptr; } -Variable<unsigned int> * -Engine::InquireVariableUInt(const std::string & /*name*/, const bool /*readIn*/) +Variable<unsigned short> *Engine::InquireVariableUShort(const std::string &name, + const bool readIn) { - EngineThrowUp(m_EngineType, "InquireVariableUInt"); return nullptr; } -Variable<long int> *Engine::InquireVariableLInt(const std::string & /*name*/, - const bool /*readIn*/) +Variable<int> *Engine::InquireVariableInt(const std::string &name, + const bool readIn) { return nullptr; } -Variable<unsigned long int> * -Engine::InquireVariableULInt(const std::string & /*name*/, - const bool /*readIn*/) +Variable<unsigned int> *Engine::InquireVariableUInt(const std::string &name, + const bool readIn) { return nullptr; } -Variable<long long int> * -Engine::InquireVariableLLInt(const std::string & /*name*/, - const bool /*readIn*/) +Variable<long int> *Engine::InquireVariableLInt(const std::string &name, + const bool readIn) { return nullptr; } -Variable<unsigned long long int> * -Engine::InquireVariableULLInt(const std::string & /*name*/, - const bool /*readIn*/) +Variable<unsigned long int> * +Engine::InquireVariableULInt(const std::string &name, const bool readIn) { return nullptr; } -Variable<float> *Engine::InquireVariableFloat(const std::string & /*name*/, - const bool /*readIn*/) +Variable<long long int> *Engine::InquireVariableLLInt(const std::string &name, + const bool readIn) { return nullptr; } -Variable<double> *Engine::InquireVariableDouble(const std::string & /*name*/, - const bool /*readIn*/) +Variable<unsigned long long int> * +Engine::InquireVariableULLInt(const std::string &name, const bool readIn) { return nullptr; } -Variable<long double> * -Engine::InquireVariableLDouble(const std::string & /*name*/, - const bool /*readIn*/) + +Variable<float> *Engine::InquireVariableFloat(const std::string &name, + const bool readIn) { return nullptr; } -Variable<std::complex<float>> * -Engine::InquireVariableCFloat(const std::string & /*name*/, - const bool /*readIn*/) +Variable<double> *Engine::InquireVariableDouble(const std::string &name, + const bool readIn) { return nullptr; } -Variable<std::complex<double>> * -Engine::InquireVariableCDouble(const std::string & /*name*/, - const bool /*readIn*/) +Variable<long double> *Engine::InquireVariableLDouble(const std::string &name, + const bool readIn) { return nullptr; } -Variable<std::complex<long double>> * -Engine::InquireVariableCLDouble(const std::string & /*name*/, - const bool /*readIn*/) +Variable<cfloat> *Engine::InquireVariableCFloat(const std::string &name, + const bool readIn) { return nullptr; } -VariableCompound *Engine::InquireVariableCompound(const std::string & /*name*/, - const bool /*readIn*/) +Variable<cdouble> *Engine::InquireVariableCDouble(const std::string &name, + const bool readIn) { return nullptr; } -void Engine::ScheduleRead(Variable<char> &variable, char *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<unsigned char> &variable, - unsigned char *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<short> &variable, short *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<unsigned short> &variable, - unsigned short *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<int> &variable, int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<unsigned int> &variable, - unsigned int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<long int> &variable, long int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<unsigned long int> &variable, - unsigned long int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<long long int> &variable, - long long int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<unsigned long long int> &variable, - unsigned long long int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<float> &variable, float *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<double> &variable, double *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<long double> &variable, long double *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<std::complex<float>> &variable, - std::complex<float> *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<std::complex<double>> &variable, - std::complex<double> *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(Variable<std::complex<long double>> &variable, - std::complex<long double> *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} - -void Engine::ScheduleRead(const std::string &variableName, char *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, - unsigned char *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, short *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, - unsigned short *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, unsigned int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, long int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, - unsigned long int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, - long long int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, - unsigned long long int *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, float *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, double *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, long double *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, - std::complex<float> *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, - std::complex<double> *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} -void Engine::ScheduleRead(const std::string &variableName, - std::complex<long double> *values) -{ - EngineThrowUp(m_EngineType, "ScheduleRead"); -} - -void Engine::ScheduleRead(const std::string & /*variableName*/) +Variable<cldouble> *Engine::InquireVariableCLDouble(const std::string &name, + const bool readIn) { - EngineThrowUp(m_EngineType, "ScheduleRead"); + return nullptr; } -void Engine::ScheduleRead() { EngineThrowUp(m_EngineType, "ScheduleRead"); } -void Engine::Release() {} -void Engine::PerformReads(PerformReadMode /*mode*/){}; - -// PROTECTED -void Engine::Init() {} -void Engine::InitParameters() {} - -void Engine::InitTransports() {} - -void Engine::CheckParameter( - const std::map<std::string, std::string>::const_iterator itParameter, - const std::map<std::string, std::string> ¶meters, - const std::string parameterName, const std::string hint) const -{ - if (itParameter == parameters.end()) - { - { - throw std::invalid_argument("ERROR: parameter name " + - parameterName + " not found " + hint); - } +#define declare_type(T) \ + void Engine::DoScheduleRead(Variable<T> &variable, const T *values) \ + { \ + ThrowUp("ScheduleRead"); \ + } \ + \ + void Engine::DoScheduleRead(const std::string &variableName, \ + const T *values) \ + { \ + ThrowUp("ScheduleRead"); \ } -} - -bool Engine::TransportNamesUniqueness() const -{ - auto lf_CheckTransportsType = - [&](const std::set<std::string> &specificType) -> bool - - { - std::set<std::string> transportNames; +ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type - for (const auto ¶meters : m_Method.m_TransportParameters) - { - auto itTransport = parameters.find("transport"); - if (m_DebugMode == true) - { - if (itTransport == parameters.end()) - { - throw std::invalid_argument("ERROR: transport not defined " - "in Method input to Engine " + - m_Name); - } - } - - const std::string type(itTransport->second); - if (specificType.count(type) == 1) // file transports type - { - std::string name(m_Name); - auto itName = parameters.find("name"); - if (itName != parameters.end()) - { - name = itName->second; - } - - if (transportNames.count(name) == 0) - { - transportNames.insert(name); - } - else - { - return false; - } - } - } - return true; - }; - - return lf_CheckTransportsType(Support::FileTransports); -} - -void Engine::CheckTransportIndex(const int transportIndex) +// PRIVATE +void Engine::ThrowUp(const std::string function) const { - if (m_DebugMode == true) - { - if (transportIndex >= static_cast<int>(m_Transports.size()) || - transportIndex < -1) - { - throw std::invalid_argument( - "ERROR: transport index " + std::to_string(transportIndex) + - " is out of range, in call to " + m_Name + "Close \n"); - } - } + throw std::invalid_argument("ERROR: Engine derived class " + m_EngineType + + " doesn't implement function " + function + + "\n"); } } // end namespace adios diff --git a/source/adios2/core/Engine.h b/source/adios2/core/Engine.h index 60f32d1bde14582270813f9034a0615ed6ee693c..f18e561df28e38dc610c09bff8646f443bdafc69 100644 --- a/source/adios2/core/Engine.h +++ b/source/adios2/core/Engine.h @@ -2,128 +2,54 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * Engine.h + * Engine.h Base abstract class for the core Open, Write/Read, Advance, Close + * functionality. Use toolkit components to build your own Engine extending this + * class. + * Examples of derived classes in: adios2/engine/ * * Created on: Nov 7, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_CORE_ENGINE_H_ #define ADIOS2_CORE_ENGINE_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <complex> //std::complex #include <functional> //std::function #include <map> #include <memory> //std::shared_ptr #include <string> -#include <utility> //std::pair #include <vector> /// \endcond -#include "adios2/ADIOS.h" #include "adios2/ADIOSConfig.h" #include "adios2/ADIOSMPICommOnly.h" #include "adios2/ADIOSTypes.h" -#include "adios2/core/Capsule.h" -#include "adios2/core/Method.h" -#include "adios2/core/Transform.h" -#include "adios2/core/Transport.h" +#include "adios2/core/IO.h" #include "adios2/core/Variable.h" #include "adios2/core/VariableCompound.h" namespace adios { -typedef enum { NONBLOCKINGREAD = 0, BLOCKINGREAD = 1 } PerformReadMode; - -typedef enum { - APPEND = 0, - UPDATE = 1, // writer advance modes - NEXT_AVAILABLE = 2, - LATEST_AVAILABLE = 3, // reader advance modes -} AdvanceMode; - -enum class AdvanceStatus -{ - OK = 0, - STEP_NOT_READY = 1, - END_OF_STREAM = 2, - OTHER_ERROR = 3 -}; - -/** - * Base class for Engine operations managing shared-memory, and buffer and - * variables transform and transport operations - */ +/** Base Abstract class for IO operations: Read/Write, Schedule, Advance and + * Close */ class Engine { public: - MPI_Comm m_MPIComm; - - const std::string m_EngineType; ///< from derived class - 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 - - int m_RankMPI = 0; ///< current MPI rank process - int m_SizeMPI = 1; ///< current MPI processes size - - const std::string m_HostLanguage = "C++"; ///< default host language - /** - * Unique constructor - * @param adios - * @param engineType - * @param name - * @param accessMode - * @param mpiComm - * @param method - * @param endMessage + * Unique Base class constructor + * @param io object that generates this Engine + * @param name unique engine name within IO class object + * @param openMode open mode from ADIOSTypes.h OpenMode + * @param mpiComm new communicator passed at Open or from ADIOS class */ - Engine(ADIOS &adios, const std::string engineType, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, const Method &method, - const std::string endMessage); + Engine(const std::string engineType, IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm); virtual ~Engine() = default; - /** @brief Let ADIOS allocate memory for a variable, which can be used by - * the user. - * To decrease the cost of copying memory, a user may let ADIOS allocate the - * memory for a user-variable, - * according to the definition of an ADIOS-variable. The memory will be part - * of the ADIOS buffer used - * by the engine and it lives until the engine (file, stream) is closed. - * A variable that has been allocated this way (cannot have its local - * dimensions changed, and AdvanceAsync() should be - * used instead of Advance() and the user-variable must not be modified by - * the application until the notification arrives. - * This is required so that any reader can access the written data before - * the application overwrites it. - * @param var Variable with defined local dimensions and offsets in global - * space - * @param fillValue Fill the allocated array with this value - * @return A constant pointer to the non-constant allocated array. User - * should - * not deallocate this pointer. - */ - template <class T> - inline T *const AllocateVariable(Variable<T> &var, T fillValue = 0) - { - throw std::invalid_argument("ERROR: type not supported for variable " + - var->name + " in call to GetVariable\n"); - } - - /** - * Needed for DataMan Engine - * @param callback function passed from the user - */ - virtual void SetCallBack(std::function<void(const void *, std::string, - std::string, std::string, Dims)> - callback); - /** * Write function that adds static checking on the variable to be passed by * values @@ -133,10 +59,7 @@ public: * @param values pointer passed from the application */ template <class T> - void Write(Variable<T> &variable, const T *values) - { - Write(variable, values); - } + void Write(Variable<T> &variable, const T *values); /** * String version @@ -144,10 +67,7 @@ public: * @param values */ template <class T> - void Write(const std::string &variableName, const T *values) - { - Write(variableName, values); - } + void Write(const std::string &variableName, const T *values); /** * Single value version @@ -155,11 +75,7 @@ public: * @param values */ template <class T> - void Write(Variable<T> &variable, const T values) - { - const T val = values; - Write(variable, &val); - } + void Write(Variable<T> &variable, const T values); /** * Single value version using string as variable handlers, allows rvalues to @@ -168,77 +84,18 @@ public: * @param values */ template <class T> - void Write(const std::string &variableName, const T values) - { - const T val = values; - Write(variableName, &val); - } - - virtual void Write(Variable<char> &variable, const char *values); - virtual void Write(Variable<unsigned char> &variable, - const unsigned char *values); - virtual void Write(Variable<short> &variable, const short *values); - virtual void Write(Variable<unsigned short> &variable, - const unsigned short *values); - virtual void Write(Variable<int> &variable, const int *values); - virtual void Write(Variable<unsigned int> &variable, - const unsigned int *values); - virtual void Write(Variable<long int> &variable, const long int *values); - virtual void Write(Variable<unsigned long int> &variable, - const unsigned long int *values); - virtual void Write(Variable<long long int> &variable, - const long long int *values); - virtual void Write(Variable<unsigned long long int> &variable, - const unsigned long long int *values); - virtual void Write(Variable<float> &variable, const float *values); - virtual void Write(Variable<double> &variable, const double *values); - virtual void Write(Variable<long double> &variable, - const long double *values); - virtual void Write(Variable<std::complex<float>> &variable, - const std::complex<float> *values); - virtual void Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values); - virtual void Write(Variable<std::complex<long double>> &variable, - const std::complex<long double> *values); - virtual void Write(VariableCompound &variable, const void *values); + void Write(const std::string &variableName, const T values); + + /// Read API /** - * @brief Write functions can be overridden by derived classes. Base class - * behavior is to: - * 1) Write to Variable values (m_Values) using the pointer to default group - * *m_Group set with SetDefaultGroup function - * 2) Transform the data - * 3) Write to all capsules -> data and metadata + * * @param variableName - * @param values coming from user app + * @return */ - virtual void Write(const std::string &variableName, const char *values); - virtual void Write(const std::string &variableName, - const unsigned char *values); - virtual void Write(const std::string &variableName, const short *values); - virtual void Write(const std::string &variableName, - const unsigned short *values); - virtual void Write(const std::string &variableName, const int *values); - virtual void Write(const std::string &variableName, - const unsigned int *values); - virtual void Write(const std::string &variableName, const long int *values); - virtual void Write(const std::string &variableName, - const unsigned long int *values); - virtual void Write(const std::string &variableName, - const long long int *values); - virtual void Write(const std::string &variableName, - const unsigned long long int *values); - virtual void Write(const std::string &variableName, const float *values); - virtual void Write(const std::string &variableName, const double *values); - virtual void Write(const std::string &variableName, - const long double *values); - virtual void Write(const std::string &variableName, - const std::complex<float> *values); - virtual void Write(const std::string &variableName, - const std::complex<double> *values); - virtual void Write(const std::string &variableName, - const std::complex<long double> *values); - virtual void Write(const std::string &variableName, const void *values); + template <class T> + Variable<T> *InquireVariable(const std::string &variableName, + const bool readIn = false); /** * Read function that adds static checking on the variable to be passed by @@ -250,11 +107,7 @@ public: * must use Read(variable) instead intentionally */ template <class T> - void Read(Variable<T> &variable, T *values) - { - ScheduleRead(variable, values); - PerformReads(PerformReadMode::BLOCKINGREAD); - } + void Read(Variable<T> &variable, T *values); /** * String version @@ -262,11 +115,7 @@ public: * @param values */ template <class T> - void Read(const std::string &variableName, T *values) - { - ScheduleRead(variableName, values); - PerformReads(PerformReadMode::BLOCKINGREAD); - } + void Read(const std::string &variableName, T *values); /** * Single value version @@ -274,11 +123,7 @@ public: * @param values */ template <class T> - void Read(Variable<T> &variable, T &values) - { - ScheduleRead(variable, &values); - PerformReads(PerformReadMode::BLOCKINGREAD); - } + void Read(Variable<T> &variable, T &values); /** * Single value version using string as variable handlers @@ -286,33 +131,21 @@ public: * @param values */ template <class T> - void Read(const std::string &variableName, T &values) - { - ScheduleRead(variableName, &values); - PerformReads(PerformReadMode::BLOCKINGREAD); - } + void Read(const std::string &variableName, T &values); /** * Unallocated version, ADIOS will allocate space for incoming data * @param variable */ template <class T> - void Read(Variable<T> &variable) - { - ScheduleRead(variable); - PerformReads(PerformReadMode::BLOCKINGREAD); - } + void Read(Variable<T> &variable); /** * Unallocated version, ADIOS will allocate space for incoming data * @param variableName */ template <class T> - void Read(const std::string &variableName) - { - ScheduleRead(variableName); - PerformReads(PerformReadMode::BLOCKINGREAD); - } + void Read(const std::string &variableName); /** * Read function that adds static checking on the variable to be passed by @@ -323,10 +156,7 @@ public: * @param values pointer passed from the application */ template <class T> - void ScheduleRead(Variable<T> &variable, T *values) - { - ScheduleRead(variable, values); - } + void ScheduleRead(Variable<T> &variable, T *values); /** * String version @@ -334,10 +164,7 @@ public: * @param values */ template <class T> - void ScheduleRead(const std::string &variableName, T *values) - { - ScheduleRead(variableName, values); - } + void ScheduleRead(const std::string &variableName, T *values); /** * Single value version @@ -345,10 +172,7 @@ public: * @param values */ template <class T> - void ScheduleRead(Variable<T> &variable, T &values) - { - ScheduleRead(variable, &values); - } + void ScheduleRead(Variable<T> &variable, T &values); /** * Single value version using string as variable handlers @@ -356,77 +180,19 @@ public: * @param values */ template <class T> - void ScheduleRead(const std::string &variableName, T &values) - { - ScheduleRead(variableName, &values); - } + void ScheduleRead(const std::string &variableName, T &values); /** * Unallocated version, ADIOS will allocate space for incoming data * @param variableName */ - virtual void ScheduleRead(const std::string &variableName); + // virtual void ScheduleRead(const std::string &variableName); /** * Unallocated unspecified version, ADIOS will receive any variable and will * allocate space for incoming data */ - virtual void ScheduleRead(); - - virtual void ScheduleRead(Variable<char> &variable, char *values); - virtual void ScheduleRead(Variable<unsigned char> &variable, - unsigned char *values); - virtual void ScheduleRead(Variable<short> &variable, short *values); - virtual void ScheduleRead(Variable<unsigned short> &variable, - unsigned short *values); - virtual void ScheduleRead(Variable<int> &variable, int *values); - virtual void ScheduleRead(Variable<unsigned int> &variable, - unsigned int *values); - virtual void ScheduleRead(Variable<long int> &variable, long int *values); - virtual void ScheduleRead(Variable<unsigned long int> &variable, - unsigned long int *values); - virtual void ScheduleRead(Variable<long long int> &variable, - long long int *values); - virtual void ScheduleRead(Variable<unsigned long long int> &variable, - unsigned long long int *values); - virtual void ScheduleRead(Variable<float> &variable, float *values); - virtual void ScheduleRead(Variable<double> &variable, double *values); - virtual void ScheduleRead(Variable<long double> &variable, - long double *values); - virtual void ScheduleRead(Variable<std::complex<float>> &variable, - std::complex<float> *values); - virtual void ScheduleRead(Variable<std::complex<double>> &variable, - std::complex<double> *values); - virtual void ScheduleRead(Variable<std::complex<long double>> &variable, - std::complex<long double> *values); - - virtual void ScheduleRead(const std::string &variableName, char *values); - virtual void ScheduleRead(const std::string &variableName, - unsigned char *values); - virtual void ScheduleRead(const std::string &variableName, short *values); - virtual void ScheduleRead(const std::string &variableName, - unsigned short *values); - virtual void ScheduleRead(const std::string &variableName, int *values); - virtual void ScheduleRead(const std::string &variableName, - unsigned int *values); - virtual void ScheduleRead(const std::string &variableName, - long int *values); - virtual void ScheduleRead(const std::string &variableName, - unsigned long int *values); - virtual void ScheduleRead(const std::string &variableName, - long long int *values); - virtual void ScheduleRead(const std::string &variableName, - unsigned long long int *values); - virtual void ScheduleRead(const std::string &variableName, float *values); - virtual void ScheduleRead(const std::string &variableName, double *values); - virtual void ScheduleRead(const std::string &variableName, - long double *values); - virtual void ScheduleRead(const std::string &variableName, - std::complex<float> *values); - virtual void ScheduleRead(const std::string &variableName, - std::complex<double> *values); - virtual void ScheduleRead(const std::string &variableName, - std::complex<long double> *values); + // virtual void ScheduleRead(); /** * Perform all scheduled reads, either blocking until all reads completed, @@ -434,7 +200,7 @@ public: * return immediately. * @param mode Blocking or non-blocking modes */ - virtual void PerformReads(PerformReadMode mode); + virtual void PerformReads(ReadMode mode); /** * Reader application indicates that no more data will be read from the @@ -447,7 +213,7 @@ public: * Indicates that a new step is going to be written as new variables come * in. */ - virtual void Advance(const float timeout_sec = 0.0); + virtual void Advance(const float timeoutSeconds = 0.0); /** * Indicates that a new step is going to be written as new variables come @@ -455,7 +221,8 @@ public: * @param mode Advance mode, there are different options for writers and * readers */ - virtual void Advance(AdvanceMode mode, const float timeout_sec = 0.0); + virtual void Advance(const AdvanceMode mode, + const float timeoutSeconds = 0.0); /** @brief Advance asynchronously and get a callback when readers release * access to the buffered step. @@ -467,141 +234,167 @@ public: * @param callback Will be called when advance is completed. */ virtual void - AdvanceAsync(AdvanceMode mode, + AdvanceAsync(const AdvanceMode mode, std::function<void(std::shared_ptr<adios::Engine>)> callback); - AdvanceStatus GetAdvanceStatus() { return m_AdvanceStatus; } + AdvanceStatus GetAdvanceStatus(); - // Read API /** - * Inquires and (optionally) allocates and copies the contents of a variable - * If success: it returns a pointer to the internal stored variable object - * in - * ADIOS class. - * If failure: it returns nullptr - * @param name variable name to look for - * @param readIn if true: reads the full variable and payload, allocating - * values in memory, if false: internal payload is nullptr - * @return success: it returns a pointer to the internal stored variable - * object in ADIOS class, failure: nullptr + * @brief Let ADIOS allocate memory for a variable in the buffer (bp), + * to be populated by the user. Variable dimensions are fixed. + * To decrease the cost of copying memory, a user may let ADIOS allocate + * the memory for a user-variable, + * according to the definition of an ADIOS-variable. The memory will be + * part + * of the ADIOS buffer used + * by the engine and it lives until the engine (file, stream) is closed. + * A variable that has been allocated this way (cannot have its local + * dimensions changed, and AdvanceAsync() should be + * used instead of Advance() and the user-variable must not be modified + * by + * the application until the notification arrives. + * This is required so that any reader can access the written data + * before + * the application overwrites it. + * @param var Variable with defined local dimensions and offsets in + * global + * space + * @param fillValue Fill the allocated array with this value + * @return A constant pointer reference to the allocated array. */ - virtual Variable<void> *InquireVariable(const std::string &variableName, - const bool readIn = true); - virtual Variable<char> *InquireVariableChar(const std::string &variableName, - const bool readIn = true); - virtual Variable<unsigned char> * - InquireVariableUChar(const std::string &variableName, - const bool readIn = true); - virtual Variable<short> * - InquireVariableShort(const std::string &variableName, - const bool readIn = true); - - virtual Variable<unsigned short> * - InquireVariableUShort(const std::string &variableName, - const bool readIn = true); - - virtual Variable<int> *InquireVariableInt(const std::string &variableName, - const bool readIn = true); - virtual Variable<unsigned int> * - InquireVariableUInt(const std::string &variableName, - const bool readIn = true); - - virtual Variable<long int> * - InquireVariableLInt(const std::string &variableName, - const bool readIn = true); - - virtual Variable<unsigned long int> * - InquireVariableULInt(const std::string &variableName, - const bool readIn = true); - - virtual Variable<long long int> * - InquireVariableLLInt(const std::string &variableName, - const bool readIn = true); - - virtual Variable<unsigned long long int> * - InquireVariableULLInt(const std::string &variableName, - const bool readIn = true); - - virtual Variable<float> * - InquireVariableFloat(const std::string &variableName, - const bool readIn = true); - - virtual Variable<double> * - InquireVariableDouble(const std::string &variableName, - const bool readIn = true); - - virtual Variable<long double> * - InquireVariableLDouble(const std::string &variableName, - const bool readIn = true); - - virtual Variable<std::complex<float>> * - InquireVariableCFloat(const std::string &variableName, - const bool readIn = true); - - virtual Variable<std::complex<double>> * - InquireVariableCDouble(const std::string &variableName, - const bool readIn = true); - - virtual Variable<std::complex<long double>> * - InquireVariableCLDouble(const std::string &variableName, - const bool readIn = true); + template <class T> + T *AllocateVariable(Variable<T> &var, T fillValue = 0); - virtual VariableCompound * - InquireVariableCompound(const std::string &variableName, - const bool readIn = true); + /** + * Needed for DataMan Engine + * @param callback function passed from the user + */ + virtual void + SetCallBack(std::function<void(const void *, std::string, std::string, + std::string, std::vector<size_t>)> + callback); /** Return the names of all variables present in a stream/file opened for * reading - * * @return a vector of strings */ std::vector<std::string> VariableNames(); /** * Closes a particular transport, or all if -1 - * @param transportIndex order from Method AddTransport + * @param transportIndex order from IO AddTransport */ virtual void Close(const int transportIndex = -1) = 0; protected: - ADIOS &m_ADIOS; ///< creates Engine at Open - std::vector<std::shared_ptr<Transport>> - m_Transports; ///< transports managed - const bool m_DebugMode = false; ///< true: additional exceptions checks - unsigned int m_nThreads = 0; ///< from Method nthreads - const std::string - m_EndMessage; ///< added to exceptions to improve debugging + /** from derived class */ + const std::string m_EngineType; + + /** IO class object that creates this Engine at Open */ + IO &m_IO; + + /** Unique name for this Engine within m_IO */ + const std::string &m_Name; + + /** open mode from ADIOSTypes.h OpenMode */ + const OpenMode m_OpenMode; + + /** from ADIOS class passed to Engine created with Open + * if no new communicator is passed */ + MPI_Comm m_MPIComm; + + /** true: additional exceptions */ + const bool m_DebugMode = false; + + /** added to exceptions to improve debugging */ + std::string m_EndMessage; + + /** Tracks written variables */ std::set<std::string> m_WrittenVariables; + AdvanceStatus m_AdvanceStatus = AdvanceStatus::OK; - virtual void Init(); ///< Initialize m_Capsules and m_Transports - virtual void InitParameters(); ///< Initialize parameters from Method - virtual void InitTransports(); ///< Initialize transports from Method + /** Called from constructors */ + virtual void Init(); - /** - * Used to verify parameters in m_Method containers - * @param itParameter iterator to a certain parameter - * @param parameters map of parameters, from m_Method - * @param parameterName used if exception is thrown to provide debugging - * information - * @param hint used if exception is thrown to provide debugging information - */ - void CheckParameter( - const std::map<std::string, std::string>::const_iterator itParameter, - const std::map<std::string, std::string> ¶meters, - const std::string parameterName, const std::string hint) const; + /** From IO SetParameters */ + virtual void InitParameters(); + + /** From IO AddTransport */ + virtual void InitTransports(); + +// Known-type +#define declare_type(T) \ + virtual void DoWrite(Variable<T> &variable, const T *values); + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type - bool TransportNamesUniqueness() const; ///< checks if transport names are - /// unique among the same types (file - /// I/O) + virtual void DoWrite(VariableCompound &variable, const void *values); /** - * Throws an exception in debug mode if transport index is out of range. - * @param transportIndex must be in the range [ -1 , m_Transports.size()-1 ] + * Finds the variable and call the corresponding DoWrite by + * type + * @param variableName + * @param values application values */ - void CheckTransportIndex(const int transportIndex); + void DoWrite(const std::string &variableName, const void *values); + + // READ + virtual VariableBase *InquireVariableUnknown(const std::string &name, + const bool readIn); + virtual Variable<char> *InquireVariableChar(const std::string &name, + const bool readIn); + virtual Variable<unsigned char> * + InquireVariableUChar(const std::string &name, const bool readIn); + virtual Variable<short> *InquireVariableShort(const std::string &name, + const bool readIn); + virtual Variable<unsigned short> * + InquireVariableUShort(const std::string &name, const bool readIn); + virtual Variable<int> *InquireVariableInt(const std::string &name, + const bool readIn); + virtual Variable<unsigned int> *InquireVariableUInt(const std::string &name, + const bool readIn); + virtual Variable<long int> *InquireVariableLInt(const std::string &name, + const bool readIn); + virtual Variable<unsigned long int> * + InquireVariableULInt(const std::string &name, const bool readIn); + virtual Variable<long long int> * + InquireVariableLLInt(const std::string &name, const bool readIn); + virtual Variable<unsigned long long int> * + InquireVariableULLInt(const std::string &name, const bool readIn); + + virtual Variable<float> *InquireVariableFloat(const std::string &name, + const bool readIn); + virtual Variable<double> *InquireVariableDouble(const std::string &name, + const bool readIn); + virtual Variable<long double> * + InquireVariableLDouble(const std::string &name, const bool readIn); + + virtual Variable<cfloat> *InquireVariableCFloat(const std::string &name, + const bool readIn); + virtual Variable<cdouble> *InquireVariableCDouble(const std::string &name, + const bool readIn); + virtual Variable<cldouble> *InquireVariableCLDouble(const std::string &name, + const bool readIn); + +// Known-type +#define declare_type(T) \ + virtual void DoScheduleRead(Variable<T> &variable, const T *values); \ + virtual void DoScheduleRead(const std::string &variableName, \ + const T *values); + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type + + void DoScheduleRead(const std::string &variableName, void *values); + +private: + /** Throw exception by Engine virtual functions not implemented by a derived + * class */ + void ThrowUp(const std::string function) const; }; -} // end namespace +} // end namespace adios + +#include "Engine.inl" #endif /* ADIOS2_CORE_ENGINE_H_ */ diff --git a/source/adios2/core/Engine.inl b/source/adios2/core/Engine.inl new file mode 100644 index 0000000000000000000000000000000000000000..e4e76bda9a287a7bd88139350aabb3b55007bfca --- /dev/null +++ b/source/adios2/core/Engine.inl @@ -0,0 +1,127 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Engine.inl + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_CORE_ENGINE_INL_ +#define ADIOS2_CORE_ENGINE_INL_ +#ifndef ADIOS2_CORE_ENGINE_H_ +#error "Inline file should only be included from it's header, never on it's own" +#endif + +namespace adios +{ + +template <class T> +T *Engine::AllocateVariable(Variable<T> &variable, T fillValue) +{ + throw std::invalid_argument("ERROR: type not supported for variable " + + variable.m_Name + " in call to \n"); +} + +template <class T> +void Engine::Write(Variable<T> &variable, const T *values) +{ + if (m_DebugMode) + { + variable.CheckDims("in call to Write"); + } + + DoWrite(variable, values); +} + +template <class T> +void Engine::Write(const std::string &variableName, const T *values) +{ + Write(m_IO.GetVariable<T>(variableName), values); +} + +template <class T> +void Engine::Write(Variable<T> &variable, const T values) +{ + const T val = values; // need an address for memory copy + Write(variable, &values); +} + +template <class T> +void Engine::Write(const std::string &variableName, const T values) +{ + const T val = values; // need an address for memory copy + Write(m_IO.GetVariable<T>(variableName), &values); +} + +template <class T> +void Engine::Read(Variable<T> &variable, T *values) +{ + DoScheduleRead(variable, values); + PerformReads(ReadMode::Blocking); +} + +template <class T> +void Engine::Read(const std::string &variableName, T *values) +{ + DoScheduleRead(variableName, values); + PerformReads(ReadMode::Blocking); +} + +template <class T> +void Engine::Read(Variable<T> &variable, T &values) +{ + DoScheduleRead(variable, &values); + PerformReads(ReadMode::Blocking); +} + +template <class T> +void Engine::Read(const std::string &variableName, T &values) +{ + DoScheduleRead(variableName, &values); + PerformReads(ReadMode::Blocking); +} + +template <class T> +void Engine::Read(Variable<T> &variable) +{ + DoScheduleRead(variable); + PerformReads(ReadMode::Blocking); +} + +template <class T> +void Engine::Read(const std::string &variableName) +{ + // TODO + // DoScheduleRead(variableName); + // PerformReads(PerformReadMode::BLOCKINGREAD); +} + +template <class T> +void Engine::ScheduleRead(Variable<T> &variable, T *values) +{ + DoScheduleRead(variable, values); +} + +template <class T> +void Engine::ScheduleRead(const std::string &variableName, T *values) +{ + DoScheduleRead(variableName, values); +} + +template <class T> +void Engine::ScheduleRead(Variable<T> &variable, T &values) +{ + DoScheduleRead(variable, &values); +} + +template <class T> +void Engine::ScheduleRead(const std::string &variableName, T &values) +{ + DoScheduleRead(variableName, &values); +} + +} // end namespace adios + +#endif /* ADIOS2_CORE_ENGINE_INL_ */ diff --git a/source/adios2/core/Engine.tcc b/source/adios2/core/Engine.tcc new file mode 100644 index 0000000000000000000000000000000000000000..f370a64bf06cdbc7ca61ae505cef2944f64e7610 --- /dev/null +++ b/source/adios2/core/Engine.tcc @@ -0,0 +1,145 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Engine.tcc + * + * Created on: Jun 2, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_CORE_ENGINE_TCC_ +#define ADIOS2_CORE_ENGINE_TCC_ + +#include "Engine.h" + +namespace adios +{ + +template <> +Variable<char> *Engine::InquireVariable<char>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableChar(variableName, readIn); +} + +template <> +Variable<unsigned char> * +Engine::InquireVariable<unsigned char>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableUChar(variableName, readIn); +} + +template <> +Variable<short> *Engine::InquireVariable<short>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableShort(variableName, readIn); +} + +template <> +Variable<unsigned short> * +Engine::InquireVariable<unsigned short>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableUShort(variableName, readIn); +} + +template <> +Variable<int> *Engine::InquireVariable<int>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableInt(variableName, readIn); +} + +template <> +Variable<unsigned int> * +Engine::InquireVariable<unsigned int>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableUInt(variableName, readIn); +} + +template <> +Variable<long int> * +Engine::InquireVariable<long int>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableLInt(variableName, readIn); +} + +template <> +Variable<long long int> * +Engine::InquireVariable<long long int>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableLLInt(variableName, readIn); +} + +template <> +Variable<unsigned long int> * +Engine::InquireVariable<unsigned long int>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableULInt(variableName, readIn); +} + +template <> +Variable<unsigned long long int> * +Engine::InquireVariable<unsigned long long int>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableULLInt(variableName, readIn); +} + +template <> +Variable<float> *Engine::InquireVariable<float>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableFloat(variableName, readIn); +} + +template <> +Variable<double> * +Engine::InquireVariable<double>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableDouble(variableName, readIn); +} + +template <> +Variable<long double> * +Engine::InquireVariable<long double>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableLDouble(variableName, readIn); +} + +template <> +Variable<cfloat> * +Engine::InquireVariable<cfloat>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableCFloat(variableName, readIn); +} + +template <> +Variable<cdouble> * +Engine::InquireVariable<cdouble>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableCDouble(variableName, readIn); +} + +template <> +Variable<cldouble> * +Engine::InquireVariable<cldouble>(const std::string &variableName, + const bool readIn) +{ + return InquireVariableCLDouble(variableName, readIn); +} + +} // end namespace adios + +#endif /** ADIOS2_CORE_ENGINE_TCC_ */ diff --git a/source/adios2/core/IO.cpp b/source/adios2/core/IO.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9753acc3aa3a178605d8eb2ef2eadb06b7b791e --- /dev/null +++ b/source/adios2/core/IO.cpp @@ -0,0 +1,288 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * IO.cpp + * + * Created on: Jan 6, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "IO.h" +#include "IO.tcc" + +#include "adios2/ADIOSMPI.h" +#include "adios2/helper/adiosFunctions.h" //BuildParametersMap + +#include "adios2/engine/bp/BPFileWriter.h" + +#ifdef ADIOS2_HAVE_DATAMAN // external dependencies +#include "adios2/engine/dataman/DataManReader.h" +#include "adios2/engine/dataman/DataManWriter.h" +#endif + +#ifdef ADIOS2_HAVE_ADIOS1 // external dependencies +#include "adios2/engine/adios1/ADIOS1Reader.h" +#include "adios2/engine/adios1/ADIOS1Writer.h" +#endif + +#ifdef ADIOS2_HAVE_HDF5 // external dependencies +#include "adios2/engine/hdf5/HDF5ReaderP.h" +#include "adios2/engine/hdf5/HDF5WriterP.h" +#endif + +namespace adios +{ + +IO::IO(const std::string name, MPI_Comm mpiComm, const bool inConfigFile, + const bool debugMode) +: m_Name(name), m_MPIComm(mpiComm), m_InConfigFile(inConfigFile), + m_DebugMode(debugMode) +{ +} + +void IO::SetEngine(const std::string engineType) { m_EngineType = engineType; } +void IO::SetIOMode(const IOMode ioMode) { m_IOMode = ioMode; }; + +VariableCompound &IO::GetVariableCompound(const std::string &name) +{ + return m_Compound.at(GetVariableIndex(name)); +} + +std::string IO::GetVariableType(const std::string &name) const +{ + std::string type; + + auto itVariable = m_Variables.find(name); + if (itVariable != m_Variables.end()) + { + type = itVariable->second.first; + } + + return type; +} + +bool IO::InConfigFile() const { return m_InConfigFile; }; + +bool IO::RemoveVariable(const std::string &name) noexcept +{ + bool isRemoved = false; + auto itVariable = m_Variables.find(name); + // variable exists + if (itVariable != m_Variables.end()) + { + // first remove the Variable object + const std::string type(itVariable->second.first); + const unsigned int index(itVariable->second.second); + + if (type == "compound") + { + auto variableMap = m_Compound; + variableMap.erase(index); + } +#define declare_type(T) \ + else if (type == GetType<T>()) \ + { \ + auto variableMap = GetVariableMap<T>(); \ + variableMap.erase(index); \ + } + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type + + isRemoved = true; + } + + if (isRemoved) + { + m_Variables.erase(name); + } + + return isRemoved; +} + +std::shared_ptr<Engine> IO::Open(const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +{ + if (m_DebugMode) + { + // Check if Engine already exists + if (m_EngineNames.count(name) == 1) + { + throw std::invalid_argument( + "ERROR: IO Engine with name " + name + + " already created by Open, in call from Open.\n"); + } + } + + std::shared_ptr<Engine> engine; + m_EngineNames.insert(name); + + const bool isDefaultWriter = + m_EngineType.empty() && + (openMode == OpenMode::Write || openMode == OpenMode::Append) + ? true + : false; + + const bool isDefaultReader = + m_EngineType.empty() && + (openMode == OpenMode::Read || openMode == OpenMode::ReadWrite) + ? true + : false; + + if (isDefaultWriter || m_EngineType == "BPFileWriter") + { + engine = std::make_shared<BPFileWriter>(*this, name, openMode, mpiComm); + } + else if (isDefaultReader || m_EngineType == "BPFileReader") + { + // engine = std::make_shared<BPFileReader>(*this, name, openMode, + // mpiComm); + } + else if (m_EngineType == "DataManWriter") + { +#ifdef ADIOS2_HAVE_DATAMAN + engine = + std::make_shared<DataManWriter>(*this, name, openMode, mpiComm); +#else + throw std::invalid_argument( + "ERROR: this version didn't compile with " + "DataMan library, can't Open DataManWriter\n"); +#endif + } + else if (m_EngineType == "DataManReader") + { +#ifdef ADIOS2_HAVE_DATAMAN + engine = + std::make_shared<DataManReader>(*this, name, openMode, mpiComm); +#else + throw std::invalid_argument( + "ERROR: this version didn't compile with " + "DataMan library, can't Open DataManReader\n"); +#endif + } + else if (m_EngineType == "ADIOS1Writer") + { +#ifdef ADIOS2_HAVE_ADIOS1 + engine = std::make_shared<ADIOS1Writer>(*this, name, openMode, mpiComm); +#else + throw std::invalid_argument( + "ERROR: this version didn't compile with ADIOS " + "1.x library, can't Open ADIOS1Writer\n"); +#endif + } + else if (m_EngineType == "ADIOS1Reader") + { +#ifdef ADIOS2_HAVE_ADIOS1 + engine = std::make_shared<ADIOS1Reader>(*this, name, openMode, mpiComm); +#else + throw std::invalid_argument( + "ERROR: this version didn't compile with ADIOS " + "1.x library, can't Open ADIOS1Reader\n"); +#endif + } + else if (m_EngineType == "HDF5Writer") + { +#ifdef ADIOS2_HAVE_HDF5 + engine = std::make_shared<HDF5WriterP>(*this, name, openMode, mpiComm); +#else + throw std::invalid_argument("ERROR: this version didn't compile with " + "HDF5 library, can't use HDF5\n"); +#endif + } + else if (m_EngineType == "HDF5Reader") + { +#ifdef ADIOS2_HAVE_HDF5 + engine = std::make_shared<HDF5ReaderP>(*this, name, openMode, mpiComm); +#else + throw std::invalid_argument("ERROR: this version didn't compile with " + "HDF5 library, can't use HDF5\n"); +#endif + } + else + { + if (m_DebugMode) + { + throw std::invalid_argument("ERROR: engine " + m_EngineType + + " not supported, IO SetEngine must add " + "a supported engine, in call to " + "Open\n"); + } + } + + return engine; +} + +std::shared_ptr<Engine> IO::Open(const std::string &name, + const OpenMode openMode) +{ + return Open(name, openMode, m_MPIComm); +} + +// PRIVATE Functions +unsigned int +IO::AddTransportParameters(const std::string type, + const std::vector<std::string> ¶meters) +{ + if (m_DebugMode) + { + if (type.empty() || type.find("=") != type.npos) + { + throw std::invalid_argument( + "ERROR: first argument in AddTransport must " + "be a single word for transport\n"); + } + } + + Params mapParameters = BuildParametersMap(parameters, m_DebugMode); + + if (m_DebugMode) + { + if (mapParameters.count("transport") == 1) + { + std::invalid_argument("ERROR: transport can't be redefined with " + "\"transport=type\", " + "type must be the first argument\n"); + } + } + + mapParameters["transport"] = type; + m_TransportsParameters.push_back(std::move(mapParameters)); + return static_cast<unsigned int>(m_TransportsParameters.size() - 1); +} + +unsigned int IO::GetVariableIndex(const std::string &name) const +{ + if (m_DebugMode) + { + if (!VariableExists(name)) + { + throw std::invalid_argument( + "ERROR: variable " + m_Name + + " wasn't created with DefineVariable, in call to IO object " + + m_Name + " GetVariable\n"); + } + } + auto itVariable = m_Variables.find(name); + return itVariable->second.second; +} + +bool IO::VariableExists(const std::string &name) const +{ + bool exists = false; + if (m_Variables.count(name) == 1) + { + exists = true; + } + return exists; +} + +// Explicitly instantiate the necessary public template implementations +#define define_template_instantiation(T) \ + template Variable<T> &IO::DefineVariable<T>( \ + const std::string &, const Dims, const Dims, const Dims, const bool); \ + template Variable<T> &IO::GetVariable<T>(const std::string &); + +ADIOS2_FOREACH_TYPE_1ARG(define_template_instantiation) +#undef define_template_instatiation + +} // end namespace adios diff --git a/source/adios2/core/IO.h b/source/adios2/core/IO.h new file mode 100644 index 0000000000000000000000000000000000000000..87df704d816b8d62df8180bfb7c72eac1b0399e0 --- /dev/null +++ b/source/adios2/core/IO.h @@ -0,0 +1,284 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * IO.h factory class of Parameters, Variables, Transports to Engines + * + * Created on: Dec 16, 2016 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_CORE_IO_H_ +#define ADIOS2_CORE_IO_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <map> +#include <string> +#include <utility> //std::pair +#include <vector> +/// \endcond + +#include "adios2/ADIOSConfig.h" +#include "adios2/ADIOSMPICommOnly.h" +#include "adios2/ADIOSMacros.h" +#include "adios2/ADIOSTypes.h" +#include "adios2/core/Variable.h" +#include "adios2/core/VariableCompound.h" + +namespace adios +{ + +// forward declaration needed as IO is passed to Engine derived +// classes +class Engine; + +/** Factory class IO for settings, variables, and transports to an engine */ +class IO +{ + +public: + /** unique identifier */ + const std::string m_Name; + + /** from ADIOS class passed to Engine created with Open + * if no new communicator is passed */ + MPI_Comm m_MPIComm; + + /** true: extra exceptions checks */ + const bool m_DebugMode = false; + + /** from ADIOS class passed to Engine created with Open */ + const std::string m_HostLanguage = "C++"; + + /** From SetParameter, parameters for a particular engine from m_Type */ + Params m_Parameters; + + /** From AddTransport, parameters in map for each transport in vector */ + std::vector<Params> m_TransportsParameters; + + /** + * Constructor called from ADIOS factory class + * @param name unique identifier for this IO object + * @param mpiComm MPI communicator from ADIOS factory class + * @param inConfigFile IO defined in config file (XML) + * @param debugMode true: extra exception checks (recommended) + */ + IO(const std::string name, MPI_Comm mpiComm, const bool inConfigFile, + const bool debugMode); + + ~IO() = default; + + /** + * Sets the engine type for this IO class object + * @param engine + */ + void SetEngine(const std::string engine); + + /** Set the IO mode (collective or independent) + * @param IO mode */ + void SetIOMode(const IOMode mode); + + /** + * Sets parameters for the method in "parameter=value" format + * @param args list of parameters with format "parameter1=value1", ..., + * "parameterN=valueN" + */ + template <class... Args> + void SetParameters(Args... args); + + /** + * Adds a transport and its parameters for the method + * @param type must be a supported transport type under /include/transport + * @param args list of parameters for a transport with format + * "parameter1=value1", ..., "parameterN=valueN" + */ + template <class... Args> + unsigned int AddTransport(const std::string type, Args... args); + + /** + * Define a Variable of primitive data type for I/O. + * Default (name only) is a local single value, + * in order to be compatible with ADIOS1. + * @param name variable name, must be unique within Method + * @param shape overall dimensions e.g. {Nx*size, Ny*size, Nz*size} + * @param start point (offset) for MPI rank e.g. {Nx*rank, Ny*rank, Nz*rank} + * @param count length for MPI rank e.g. {Nx, Ny, Nz} + * @param constantShape true if dimensions, offsets and local sizes don't + * change over time + * @return reference to Variable object + */ + template <class T> + Variable<T> &DefineVariable(const std::string &name, const Dims shape = {}, + const Dims start = {}, const Dims count = {}, + const bool constantShape = false); + + /** + * Define a Variable of primitive data type for I/O. + * Default (name only) is a local single value, + * in order to be compatible with ADIOS1. + * @param name variable name, must be unique within Method + * @param shape overall dimensions e.g. {Nx*size, Ny*size, Nz*size} + * @param start point (offset) for MPI rank e.g. {Nx*rank, Ny*rank, Nz*rank} + * @param count length for MPI rank e.g. {Nx, Ny, Nz} + * @param constantShape true if dimensions, offsets and local sizes don't + * change over time + * @return reference to Variable object + */ + template <class T> + VariableCompound & + DefineVariableCompound(const std::string &name, const Dims shape = Dims{}, + const Dims start = Dims{}, const Dims count = Dims{}, + const bool constantShape = false); + + /** + * Removes an existing Variable previously created with DefineVariable or + * DefineVariableCompound + * @param name + * @return true: found and removed variable, false: not found, nothing to + * remove + */ + bool RemoveVariable(const std::string &name) noexcept; + + /** + * Gets an existing variable of primitive type by name + * @param name of variable to be retrieved + * @return reference to an existing variable created with DefineVariable + * throws an exception if Variable is not found + */ + template <class T> + Variable<T> &GetVariable(const std::string &name); + + /** + * Gets an existing variable of compound type by name + * @param name of variable to be retrieved + * @return reference to an existing variable created with DefineVariable + * throws an exception if VariableCompound is not found + */ + VariableCompound &GetVariableCompound(const std::string &name); + + /** + * Get the type if variable (by name id) exists + * @param name input id + * @return type as string, if not found returns an empty string + */ + std::string GetVariableType(const std::string &name) const; + + /** + * Check existence in config file passed to ADIOS class + * @return true: defined in config file + */ + bool InConfigFile() const; + + /** + * Creates a polymorphic object that derives the Engine class, + * based on the SetEngine function or config file input + * @param name unique engine identifier within IO object + * (file name in case of File transports) + * @param openMode write, read, append from ADIOSTypes.h OpenMode + * @param mpiComm assigns a new communicator to the Engine + * @return a smart pointer to a derived object of the Engine class + */ + std::shared_ptr<Engine> Open(const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm); + + /** + * Overloaded version that reuses the MPI_Comm object passed + * from the ADIOS class to the IO class + * @param name unique engine identifier within IO object + * (file name in case of File transports) + * @param openMode write, read, append from ADIOSTypes.h OpenMode + * @return a smart pointer to a derived object of the Engine class + */ + std::shared_ptr<Engine> Open(const std::string &name, + const OpenMode openMode); + + // READ FUNCTIONS: + void SetReadMultiplexPattern(const ReadMultiplexPattern pattern); + void SetStreamOpenMode(const StreamOpenMode mode); + +private: + /** true: exist in config file (XML) */ + const bool m_InConfigFile = false; + + /** BPFileWriter engine default if unknown */ + std::string m_EngineType; + + /** Independent (default) or Collective */ + adios::IOMode m_IOMode = adios::IOMode::Independent; + + // Variables + /** + * Map holding variable identifiers + * <pre> + * key: unique variable name, + * value: pair.first = type as string GetType<T> from adiosTemplates.h + * pair.second = index in fixed size map (e.g. m_Int8, m_Double) + * </pre> + */ + std::map<std::string, std::pair<std::string, unsigned int>> m_Variables; + + /** Variable containers based on fixed-size type */ + std::map<unsigned int, Variable<char>> m_Char; + std::map<unsigned int, Variable<unsigned char>> m_UChar; + std::map<unsigned int, Variable<short>> m_Short; + std::map<unsigned int, Variable<unsigned short>> m_UShort; + std::map<unsigned int, Variable<int>> m_Int; + std::map<unsigned int, Variable<unsigned int>> m_UInt; + std::map<unsigned int, Variable<long int>> m_LInt; + std::map<unsigned int, Variable<unsigned long int>> m_ULInt; + std::map<unsigned int, Variable<long long int>> m_LLInt; + std::map<unsigned int, Variable<unsigned long long int>> m_ULLInt; + std::map<unsigned int, Variable<float>> m_Float; + std::map<unsigned int, Variable<double>> m_Double; + std::map<unsigned int, Variable<long double>> m_LDouble; + std::map<unsigned int, Variable<cfloat>> m_CFloat; + std::map<unsigned int, Variable<cdouble>> m_CDouble; + std::map<unsigned int, Variable<cldouble>> m_CLDouble; + std::map<unsigned int, VariableCompound> m_Compound; + + std::map<std::string, std::string> m_AttributesString; + std::map<std::string, double> m_AttributesNumeric; + + std::set<std::string> m_EngineNames; + + /** + * Called from AddTransport to transform parameter to a map + * @param type + * @param parameters + * @return transport index + */ + unsigned int + AddTransportParameters(const std::string type, + const std::vector<std::string> ¶meters); + + /** Gets the internal reference to a variable map for type T + * This function is specialized in IO.tcc */ + template <class T> + std::map<unsigned int, Variable<T>> &GetVariableMap(); + + /** Gets the internal index in variable map for an existing variable */ + unsigned int GetVariableIndex(const std::string &name) const; + + /** + * Checks if variable exists by checking its name + * @param name unique variable name to be checked against existing variables + * @return true: variable name exists, false: variable name doesn't exist + */ + bool VariableExists(const std::string &name) const; +}; + +// Explicit declaration of the public template methods +#define declare_template_instantiation(T) \ + extern template Variable<T> &IO::DefineVariable<T>( \ + const std::string &name, const Dims, const Dims, const Dims, \ + const bool constantShape); \ + extern template Variable<T> &IO::GetVariable<T>(const std::string &name); + +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation + +} // end namespace adios + +#include "adios2/core/IO.inl" + +#endif /* ADIOS2_CORE_IO_H_ */ diff --git a/source/adios2/core/IO.inl b/source/adios2/core/IO.inl new file mode 100644 index 0000000000000000000000000000000000000000..d7a8505442911b709dcaa079c624cc42daae98e2 --- /dev/null +++ b/source/adios2/core/IO.inl @@ -0,0 +1,62 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * IO.inl inline template functions implementation of IO class + * + * Created on: May 15, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_CORE_IO_INL_ +#define ADIOS2_CORE_IO_INL_ +#ifndef ADIOS2_CORE_IO_H_ +#error "Inline file should only be included from it's header, never on it's own" +#endif + +#include "adios2/ADIOSMacros.h" +#include "adios2/helper/adiosFunctions.h" //BuildParametersMap + +namespace adios +{ + +template <class... Args> +void IO::SetParameters(Args... args) +{ + std::vector<std::string> parameters = {args...}; + m_Parameters = BuildParametersMap(parameters, m_DebugMode); +} + +template <class... Args> +unsigned int IO::AddTransport(const std::string type, Args... args) +{ + std::vector<std::string> parameters = {args...}; + return AddTransportParameters(type, parameters); +} + +template <class T> +VariableCompound &IO::DefineVariableCompound(const std::string &name, + const Dims shape, const Dims start, + const Dims count, + const bool constantShape) +{ + if (m_DebugMode) + { + if (VariableExists(name)) + { + std::invalid_argument("ERROR: variable " + name + + " exists in IO object " + m_Name + + ", in call to DefineVariable\n"); + } + } + const unsigned int size = m_Compound.size(); + auto itVariableCompound = m_Compound.emplace( + size, VariableCompound(name, sizeof(T), shape, start, count, + constantShape, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<T>(), size)); + return itVariableCompound.first->second; +} + +} // end namespace adios + +#endif /* ADIOS2_CORE_IO_INL_ */ diff --git a/source/adios2/core/IO.tcc b/source/adios2/core/IO.tcc new file mode 100644 index 0000000000000000000000000000000000000000..335e257ae50ae73f6e1275412ae456cfb5b37081 --- /dev/null +++ b/source/adios2/core/IO.tcc @@ -0,0 +1,157 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * IO.tcc template implementations with fix types and specializations + * + * Created on: May 15, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_CORE_IO_TCC_ +#define ADIOS2_CORE_IO_TCC_ + +#include "IO.h" + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <iostream> +#include <stdexcept> //std::invalid_argument +/// \endcond + +#include "adios2/ADIOSMPI.h" +#include "adios2/ADIOSMacros.h" + +namespace adios +{ + +template <class T> +Variable<T> &IO::DefineVariable(const std::string &name, const Dims shape, + const Dims start, const Dims count, + const bool constantShape) +{ + if (m_DebugMode) + { + if (VariableExists(name)) + { + throw std::invalid_argument("ERROR: variable " + name + + " exists in IO object " + m_Name + + ", in call to DefineVariable\n"); + } + } + + auto &variableMap = GetVariableMap<T>(); + const unsigned int size = variableMap.size(); + auto itVariablePair = + variableMap.emplace(size, Variable<T>(name, shape, start, count, + constantShape, m_DebugMode)); + + m_Variables.emplace(name, std::make_pair(GetType<T>(), size)); + return itVariablePair.first->second; +} + +template <class T> +Variable<T> &IO::GetVariable(const std::string &name) +{ + return GetVariableMap<T>().at(GetVariableIndex(name)); +} + +// PRIVATE +template <> +std::map<unsigned int, Variable<char>> &IO::GetVariableMap() +{ + return m_Char; +} + +template <> +std::map<unsigned int, Variable<unsigned char>> &IO::GetVariableMap() +{ + return m_UChar; +} + +template <> +std::map<unsigned int, Variable<short>> &IO::GetVariableMap() +{ + return m_Short; +} + +template <> +std::map<unsigned int, Variable<unsigned short>> &IO::GetVariableMap() +{ + return m_UShort; +} + +template <> +std::map<unsigned int, Variable<int>> &IO::GetVariableMap() +{ + return m_Int; +} + +template <> +std::map<unsigned int, Variable<unsigned int>> &IO::GetVariableMap() +{ + return m_UInt; +} + +template <> +std::map<unsigned int, Variable<long int>> &IO::GetVariableMap() +{ + return m_LInt; +} + +template <> +std::map<unsigned int, Variable<unsigned long int>> &IO::GetVariableMap() +{ + return m_ULInt; +} + +template <> +std::map<unsigned int, Variable<long long int>> &IO::GetVariableMap() +{ + return m_LLInt; +} + +template <> +std::map<unsigned int, Variable<unsigned long long int>> &IO::GetVariableMap() +{ + return m_ULLInt; +} + +template <> +std::map<unsigned int, Variable<float>> &IO::GetVariableMap() +{ + return m_Float; +} + +template <> +std::map<unsigned int, Variable<double>> &IO::GetVariableMap() +{ + return m_Double; +} + +template <> +std::map<unsigned int, Variable<long double>> &IO::GetVariableMap() +{ + return m_LDouble; +} + +template <> +std::map<unsigned int, Variable<cfloat>> &IO::GetVariableMap() +{ + return m_CFloat; +} + +template <> +std::map<unsigned int, Variable<cdouble>> &IO::GetVariableMap() +{ + return m_CDouble; +} + +template <> +std::map<unsigned int, Variable<cldouble>> &IO::GetVariableMap() +{ + return m_CLDouble; +} + +} // end namespace adios + +#endif /* ADIOS2_CORE_IO_TCC_ */ diff --git a/source/adios2/core/IOChrono.h b/source/adios2/core/IOChrono.h deleted file mode 100644 index 2f17b497fccf281fcd53e2aa7f8fa49b43c02aa4..0000000000000000000000000000000000000000 --- a/source/adios2/core/IOChrono.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * IOChrono.h - * - * Created on: Mar 9, 2017 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_IOCHRONO_H_ -#define ADIOS2_CORE_IOCHRONO_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <vector> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/core/Timer.h" - -namespace adios -{ -namespace profiling -{ - -/** - * Struct used to track - */ -struct IOChrono -{ - ///< one timer for each process (open, write, buffering, etc.) - std::vector<Timer> Timers; - - ///< tracks bytes for buffering - std::vector<unsigned long long int> TotalBytes; - - ///< flag to determine if profiling is used - bool IsActive = false; -}; - -} // end namespace profiling -} // end namespace adios - -#endif /* ADIOS2_CORE_IOCHRONO_H_ */ diff --git a/source/adios2/core/Method.cpp b/source/adios2/core/Method.cpp deleted file mode 100644 index 083e19135c5fe100f4b0d02b309c106892d6bd74..0000000000000000000000000000000000000000 --- a/source/adios2/core/Method.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Method.cpp - * - * Created on: Jan 6, 2017 - * Author: wfg - */ - -#include "Method.h" - -#include <utility> - -#include "adios2/core/adiosFunctions.h" - -namespace adios -{ - -Method::Method(const std::string name, const bool debugMode) -: m_Name{name}, m_DebugMode{debugMode} -{ -} - -Method::~Method() {} - -bool Method::IsUserDefined() -{ - return false; // TODO(wfg): check if XML has the method defined -} - -void Method::SetEngine(const std::string type) { m_Type = type; } -void Method::SetIOMode(const IOMode mode) { m_IOMode = mode; }; - -void Method::AllowThreads(const unsigned int nThreads) -{ - if (nThreads > 1) - { - m_nThreads = nThreads; - } - else - { - m_nThreads = 1; - } -} - -// PRIVATE Functions -void Method::AddTransportParameters(const std::string type, - const std::vector<std::string> ¶meters) -{ - if (m_DebugMode == true) - { - if (type.empty() || type.find("=") != type.npos) - { - throw std::invalid_argument( - "ERROR: first argument in AddTransport must " - "be a single word for transport\n"); - } - } - - std::map<std::string, std::string> mapParameters = - BuildParametersMap(parameters, m_DebugMode); - if (m_DebugMode == true) - { - if (mapParameters.count("transport") == 1) - { - std::invalid_argument("ERROR: transport can't be redefined with " - "\"transport=type\", " - "type must be the first argument\n"); - } - } - - mapParameters["transport"] = type; - m_TransportParameters.push_back(mapParameters); -} - -} // end namespace adios diff --git a/source/adios2/core/Method.h b/source/adios2/core/Method.h deleted file mode 100644 index 26ab2ffe0c62efc7cd1cadb1953797eba75123f5..0000000000000000000000000000000000000000 --- a/source/adios2/core/Method.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Method.h - * - * Created on: Dec 16, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_METHOD_H_ -#define ADIOS2_CORE_METHOD_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <map> -#include <string> -#include <vector> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/ADIOSTypes.h" -#include "adios2/core/adiosFunctions.h" - -namespace adios -{ - -typedef enum { - GLOBAL_READERS = 2, - ROUNDROBIN_READERS = 3, - FIFO_READERS = 4, - OPEN_ALL_STEPS = 5 -} ReadMultiplexPattern; - -typedef enum { - NOWAITFORSTREAM = 0, - WAITFORSTREAM = 1 -} StreamOpenMode; // default: wait for stream - -/** - * Serves as metadata to define an engine - */ -class Method -{ - -public: - const std::string m_Name; ///< Method name (as defined in XML) - const bool m_DebugMode = false; ///< true: on, throws exceptions and do - /// additional checks, false: off, faster - /// unsafe - std::string m_Type; ///< Method's engine type - unsigned int m_nThreads = 1; - - 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 - - /** - * Constructor - * @param name is a label that can be used in the config file to set up the - * method at runtime - */ - Method(const std::string name, const bool debugMode = false); - - ~Method(); - - /** Check if the method was defined by the user in the config file. - * @return true if the method was user-defined, false otherwise when method - * is - * set with default parameters - */ - bool IsUserDefined(); - - /** - * Define the engine type - * @param type must be a valid engine type - */ - void SetEngine(const std::string type); - - /** - * Set the IO mode (collective or independent) - * @param IO mode - */ - void SetIOMode(const IOMode mode); - - /** - * Set how many threads the engine can use for its operations (e.g. file io, - * compression, staging). - * If 1 is allowed, no extra threads will be created during the ADIOS calls - * for asynchronous operations. - * Note that some transports may require and use extra thread(s). See their - * documentation for their - * requirements. E.g. some staging transports always create an extra thread - * for communication. - * Set this parameter like you set it for OpenMP, i.e. count one thread for - * the main process that calls - * ADIOS functions. - * @param nThreads, minimum 1 is required - */ - void AllowThreads(const unsigned int nThreads); - - /** - * Sets parameters for the method in "parameter=value" format - * @param args list of parameters with format "parameter1=value1", ..., - * "parameterN=valueN" - */ - template <class... Args> - void SetParameters(Args... args) - { - std::vector<std::string> parameters = {args...}; - m_Parameters = BuildParametersMap(parameters, m_DebugMode); - } - - /** - * Adds a transport and its parameters for the method - * @param type must be a supported transport type under /include/transport - * @param args list of parameters for a transport with format - * "parameter1=value1", ..., "parameterN=valueN" - */ - template <class... Args> - void AddTransport(const std::string type, Args... args) - { - std::vector<std::string> parameters = {args...}; - AddTransportParameters(type, parameters); - } - - void SetReadMultiplexPattern( - const ReadMultiplexPattern - pattern); // How to split stream content among readers - void SetStreamOpenMode(const StreamOpenMode mode); // In Read mode, should - // Open() wait for the - // first step appear - // (default) - - void SetVerbose(const Verbose verbose = Verbose::WARN) - { - m_Verbose = verbose; - }; - Verbose GetVerbose() { return m_Verbose; }; - -private: - Verbose m_Verbose = Verbose::WARN; - adios::IOMode m_IOMode = adios::IOMode::INDEPENDENT; - - void AddTransportParameters(const std::string type, - const std::vector<std::string> ¶meters); -}; - -} // end namespace adios - -#endif /* ADIOS2_CORE_METHOD_H_ */ diff --git a/source/adios2/core/Selection.cpp b/source/adios2/core/Selection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1eb98987cdb6fb888915de0c7d73f019aaed3ad2 --- /dev/null +++ b/source/adios2/core/Selection.cpp @@ -0,0 +1,22 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Selection.cpp + * + * Created on: May 19, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov + */ + +#include "Selection.h" + +namespace adios +{ + +Selection::Selection(const SelectionType type, const bool debugMode) +: m_Type(type), m_DebugMode(debugMode) +{ +} + +} // end namespace adios diff --git a/source/adios2/core/Selection.h b/source/adios2/core/Selection.h index b5e7e01280f8f4971c4391a78473e568193561c9..8ef27634d3f4f78d0606237ef0b7c1ae579f2e3a 100644 --- a/source/adios2/core/Selection.h +++ b/source/adios2/core/Selection.h @@ -1,6 +1,10 @@ /* * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. + * + * Created on: May 17, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov */ /* @@ -35,32 +39,28 @@ #define ADIOS2_CORE_SELECTION_H_ #include "adios2/ADIOSConfig.h" +#include "adios2/ADIOSTypes.h" namespace adios { - -/* Type of selection */ -enum class SelectionType -{ - // Contiguous block of data defined by offsets and counts in each - // dimension - BoundingBox, - - // List of individual points - Points, - - // Selection of an individual block written by a writer process - WriteBlock, - - // Let the method decide what to return - Auto -}; - +/** Base class for Selection (query) types */ class Selection { public: - Selection(const SelectionType t) : m_Type(t){}; + /** from derived class */ const SelectionType m_Type; + + /** + * Unique constructor + * @param type derived class type + */ + Selection(const SelectionType type, const bool debugMode = false); + + virtual ~Selection() = default; + +protected: + /** true: extra checks (recommended) */ + const bool m_DebugMode; }; } // namespace adios diff --git a/source/adios2/core/SelectionBoundingBox.cpp b/source/adios2/core/SelectionBoundingBox.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ccb0ff709deefc514736eb2e915c22143e063e79 --- /dev/null +++ b/source/adios2/core/SelectionBoundingBox.cpp @@ -0,0 +1,60 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * SelectionBoundingBox.cpp + * + * Created on: May 17, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov + * + */ + +#include "SelectionBoundingBox.h" + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <stdexcept> +/// \endcond + +#include "adios2/helper/adiosFunctions.h" //Uint64VectorToSizetVector + +namespace adios +{ + +SelectionBoundingBox::SelectionBoundingBox(const Dims start, const Dims count, + const bool debugMode) +: Selection(SelectionType::BoundingBox, debugMode), m_Start(start), + m_Count(count) +{ + if (m_DebugMode) + { + CheckBoundingBox(); + } +} + +void SelectionBoundingBox::CheckBoundingBox() const +{ + + auto lf_Throw = [](const std::string &message) { + throw std::invalid_argument( + "ERROR: " + message + + ", in call to SelectionBoundingBox constructor\n"); + }; + + if (m_Start.size() != m_Count.size()) + { + lf_Throw("start and count must have the same size"); + } + + if (m_Start.empty()) + { + lf_Throw("start is empty"); + } + + if (m_Count.empty()) + { + lf_Throw("count is empty"); + } +} + +} // end namespace adios diff --git a/source/adios2/core/SelectionBoundingBox.h b/source/adios2/core/SelectionBoundingBox.h index 6e8cdd1cc0547a0537f02499d745d7820f4cfdf9..280ec8df1105da8ec7d0f77ef79d615131457532 100644 --- a/source/adios2/core/SelectionBoundingBox.h +++ b/source/adios2/core/SelectionBoundingBox.h @@ -1,14 +1,20 @@ /* * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. + * + * SelectionBoundingBox.h + * + * Created on: May 17, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_CORE_SELECTIONBOUNDINGBOX_H_ #define ADIOS2_CORE_SELECTIONBOUNDINGBOX_H_ -#include <cstdint> - +/// \cond EXCLUDE_FROM_DOXYGEN #include <vector> +/// \endcond #include "adios2/ADIOSConfig.h" #include "adios2/core/Selection.h" @@ -16,23 +22,42 @@ namespace adios { -/** Boundingbox selection to read a subset of a non-scalar variable. +/** Bounding box selection to read a subset of a non-scalar variable. * @param start array of offsets to start reading in each dimension * @param count number of data elements to read in each dimension */ class SelectionBoundingBox : public Selection { public: - SelectionBoundingBox(const std::vector<std::uint64_t> start, - const std::vector<std::uint64_t> count) - : Selection(SelectionType::BoundingBox), m_Start(start), m_Count(count) - { - } - - std::vector<std::uint64_t> m_Start; - std::vector<std::uint64_t> m_Count; + /** Starting coodinates of bounding box */ + Dims m_Start; + /** From start of bounding box */ + Dims m_Count; + + /** + * Constructor using uint64_t vectors + * @param start of bounding box + * @param count from start of bounding box + */ + // SelectionBoundingBox(const std::vector<uint64_t> start, + // const std::vector<uint64_t> count, + // const bool debugMode = false); + + /** + * Constructor using size_t vectors + * @param start of bounding box + * @param count from start of bounding box + */ + SelectionBoundingBox(const Dims start, const Dims count, + const bool debugMode = false); + + ~SelectionBoundingBox() = default; + +private: + /** Check in debug mode to make sure bounding box is valid */ + void CheckBoundingBox() const; }; -} // namespace adios +} // end namespace adios #endif /* ADIOS2_CORE_SELECTIONBOUNDINGBOX_H_ */ diff --git a/source/adios2/core/SelectionPoints.cpp b/source/adios2/core/SelectionPoints.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b86f134f65698572857760d089287954047c158a --- /dev/null +++ b/source/adios2/core/SelectionPoints.cpp @@ -0,0 +1,31 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * SelectionPoints.cpp + * + * Created on: May 17, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov + */ + +#include "SelectionPoints.h" + +namespace adios +{ + +SelectionPoints::SelectionPoints(size_t dimensionsSize, + std::vector<uint64_t> &points) +: Selection(SelectionType::Points), m_DimensionsSize(dimensionsSize), + m_PointsVec(&points), m_PointsSize(points.size()) +{ +} + +SelectionPoints::SelectionPoints(size_t dimensionsSize, size_t pointsSize, + uint64_t *points) +: Selection(SelectionType::Points), m_DimensionsSize(dimensionsSize), + m_PointsSize(pointsSize), m_PointsPointer(points) +{ +} + +} // end namespace adios diff --git a/source/adios2/core/SelectionPoints.h b/source/adios2/core/SelectionPoints.h index 75dfec84d9054766971b70120d3fdb83afa87fa4..5338e53f20110940593fa83bed5d363bd1ebdb9f 100644 --- a/source/adios2/core/SelectionPoints.h +++ b/source/adios2/core/SelectionPoints.h @@ -1,18 +1,23 @@ /* * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. + * + * SelectionPoints.h + * + * Created on: May 17, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_CORE_SELECTIONPOINTS_H_ #define ADIOS2_CORE_SELECTIONPOINTS_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <cstdint> -/// \endcond - #include <vector> +/// \endcond #include "adios2/ADIOSConfig.h" +#include "adios2/ADIOSTypes.h" #include "adios2/core/Selection.h" namespace adios @@ -28,30 +33,31 @@ namespace adios class SelectionPoints : public Selection { public: - SelectionPoints(std::size_t ndim, std::size_t npoints, - std::vector<std::uint64_t> &points) - : Selection(SelectionType::Points), m_Ndim(ndim), m_Npoints(npoints), - m_Points(points) - { - } - - ///< C-style constructor to be used in the C-to-C++ wrapper - SelectionPoints(std::size_t ndim, std::size_t npoints, uint64_t *points) - : Selection(SelectionType::Points), m_Ndim(ndim), m_Npoints(npoints), - m_Points(std::vector<std::uint64_t>()), m_PointsC(points) - { - } + /** number of dimensions from constructor */ + const size_t m_DimensionsSize; - virtual ~SelectionPoints() = default; + /** reference to points in constructor, must use a pointer as nullptr is + * valid if an array is passed in the constructor instead */ + std::vector<uint64_t> *m_PointsVec = nullptr; - const std::size_t m_Ndim; - const std::size_t m_Npoints; - std::vector<std::uint64_t> &m_Points; - ///< C-to-C++ wrapper needs a pointer to hold the points created by the C - /// application - std::uint64_t *m_PointsC = nullptr; + /** pointer based applications needed size*/ + const size_t m_PointsSize; + /** pointer based applications needed array*/ + uint64_t *m_PointsPointer = nullptr; + + /** + * Constructor that takes a vector<uint64_t> for points + * @param dimensionsSize + * @param pointsSize + * @param points + */ + SelectionPoints(size_t dimensionsSize, std::vector<uint64_t> &points); + + SelectionPoints(size_t dimensionsSize, size_t pointsSize, uint64_t *points); + + virtual ~SelectionPoints() = default; }; -} // namespace adios +} // end namespace adios #endif /* ADIOS2_CORE_SELECTIONPOINTS_H_ */ diff --git a/source/adios2/core/Support.cpp b/source/adios2/core/Support.cpp deleted file mode 100644 index c1db02342d3e45a618a2b7638deb737de3ff289a..0000000000000000000000000000000000000000 --- a/source/adios2/core/Support.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Support.cpp - * - * Created on: Oct 18, 2016 - * Author: wfg - */ - -#include "Support.h" - -#include "adios2/core/adiosTemplates.h" - -namespace adios -{ - -const std::string Support::Version{"2.00"}; - -const std::set<std::string> Support::HostLanguages{{"C++", "C", "Fortran"}}; - -const std::set<std::string> Support::Transports{ - {"NULL", "POSIX", "FStream", "MdtmMan"}}; -// TODO(chuckatkins): Add transports MPI, MPI_LUSTRE, MPI_AGGREGATE, -// DATASPACES, DIMES, FLEXPATH, PHDF5, NC4, ICEE - -const std::set<std::string> Support::Transforms{ - {"none", "identity", "bzip2", "isobar", "szip", "zlib"}}; - -const std::map<std::string, std::set<std::string>> Support::Datatypes{ - {"C++", {"char", - "std::string", - "string", - "unsigned char", - "short", - "unsigned short", - "int", - "integer", - "unsigned int", - "long int", - "long", - "unsigned long int", - "unsigned long", - "long long int", - "long long", - "unsigned long long int", - "unsigned long long", - "float", - "float complex", - "double", - "long double", - "double complex", - "std::complex<double>", - "complex<double>"}}, - {"C", - {"char", "unsigned char", "short", "unsigned short", "int", "integer" - "unsigned int", - "unsigned integer", "long int", "long", "long integer", - "unsigned long int", "unsigned long", "unsigned long integer", - "long long int", "long long", "long long integer", - "unsigned long long int", "unsigned long long", - "unsigned long long integer", "float", "float complex" - "double", - "long double", "double complex"}}, - {"Fortran", - {"character", "integer*2", "integer", "real*2", "real", "real*4", - "double precision", "real*8", "complex", "double complex"}}}; - -const std::map<std::string, std::set<std::string>> Support::DatatypesAliases{ - {GetType<char>(), {GetType<char>(), "character"}}, - {GetType<unsigned char>(), - {GetType<unsigned char>(), "unsigned character"}}, - {GetType<short>(), {GetType<short>(), "integer*2"}}, - {GetType<unsigned short>(), {GetType<unsigned short>()}}, - {GetType<int>(), {GetType<int>(), "integer"}}, - {GetType<unsigned int>(), {GetType<unsigned int>(), "unsigned integer"}}, - {GetType<long int>(), {GetType<long int>(), "long", "long integer"}}, - {GetType<unsigned long int>(), - {GetType<unsigned long int>(), "unsigned long", "unsigned long integer"}}, - {GetType<long long int>(), - {GetType<long long int>(), "long long", "long long integer"}}, - {GetType<unsigned long long int>(), - {GetType<unsigned long long int>(), "unsigned long long", - "unsigned long long integer"}}, - {GetType<float>(), {GetType<float>(), "real", "real*4"}}, - {GetType<double>(), {GetType<double>(), "double precision", "real*8"}}, - {GetType<long double>(), - {GetType<long double>(), "long double precision", "real*16"}}}; - -const std::set<std::string> Support::FileTransports{ - {"POSIX", "File", "FStream", "MPIFile"}}; - -} // end namespace adios diff --git a/source/adios2/core/Support.h b/source/adios2/core/Support.h deleted file mode 100644 index c836724b168a73c51063cd5177d90b4a943a2495..0000000000000000000000000000000000000000 --- a/source/adios2/core/Support.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Support.h - * - * Created on: Oct 10, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_SUPPORT_H_ -#define ADIOS2_CORE_SUPPORT_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <map> -#include <set> -#include <string> -/// \endcond - -#include "adios2/ADIOSConfig.h" - -namespace adios -{ - -struct Support -{ - ///< current ADIOS version - static const std::string Version; - - ///< supported languages: C, C++, Fortran, Python, Java - static const std::set<std::string> HostLanguages; - - static const std::set<std::string> Numbers; - - ///< supported transport methods - static const std::set<std::string> Transports; - - ///< supported data transform methods - static const std::set<std::string> Transforms; - - ///< supported data types, key: host language, value: all supported types - static const std::map<std::string, std::set<std::string>> Datatypes; - - ///< all supported int aliases, key: C++ type (e.g. int), value: aliases to - /// type in key (e.g. int, integer) - static const std::map<std::string, std::set<std::string>> DatatypesAliases; - - ///< file I/O transports - static const std::set<std::string> FileTransports; - - enum class Resolutions - { - mus, - ms, - s, - m, - h - }; -}; - -} // end namespace adios - -#endif /* ADIOS2_CORE_SUPPORT_H_ */ diff --git a/source/adios2/core/Timer.cpp b/source/adios2/core/Timer.cpp deleted file mode 100644 index 2ae983fe859962158d3fd00faf6861d5ee4db86f..0000000000000000000000000000000000000000 --- a/source/adios2/core/Timer.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Timer.cpp - * - * Created on: Apr 4, 2017 - * Author: wfg - */ - -#include "Timer.h" - -namespace adios -{ -namespace profiling -{ - -Timer::Timer(const std::string process, const Support::Resolutions resolution, - const bool debug) -: m_Process{process}, m_Resolution{resolution}, m_DebugMode{debug} -{ -} - -void Timer::SetInitialTime() -{ - m_InitialTime = std::chrono::high_resolution_clock::now(); - m_InitialTimeSet = true; -} - -void Timer::SetTime() -{ - m_ElapsedTime = std::chrono::high_resolution_clock::now(); - m_ProcessTime += GetCurrentTime(); -} - -std::string Timer::GetUnits() const -{ - std::string units; - if (m_Resolution == Support::Resolutions::mus) - units = "mus"; - else if (m_Resolution == Support::Resolutions::ms) - units = "ms"; - else if (m_Resolution == Support::Resolutions::s) - units = "s"; - else if (m_Resolution == Support::Resolutions::m) - units = "m"; - else if (m_Resolution == Support::Resolutions::h) - units = "h"; - return units; -} - -// PRIVATE - -long long int Timer::GetCurrentTime() -{ - if (m_DebugMode == true) - { - if (m_InitialTimeSet == false) - throw std::invalid_argument("ERROR: SetInitialTime() in process " + - m_Process + " not called\n"); - } - - if (m_Resolution == Support::Resolutions::mus) - { - return std::chrono::duration_cast<std::chrono::microseconds>( - m_ElapsedTime - m_InitialTime) - .count(); - } - else if (m_Resolution == Support::Resolutions::ms) - { - return std::chrono::duration_cast<std::chrono::milliseconds>( - m_ElapsedTime - m_InitialTime) - .count(); - } - else if (m_Resolution == Support::Resolutions::s) - { - return std::chrono::duration_cast<std::chrono::seconds>(m_ElapsedTime - - m_InitialTime) - .count(); - } - else if (m_Resolution == Support::Resolutions::m) - { - return std::chrono::duration_cast<std::chrono::minutes>(m_ElapsedTime - - m_InitialTime) - .count(); - } - else if (m_Resolution == Support::Resolutions::h) - { - return std::chrono::duration_cast<std::chrono::hours>(m_ElapsedTime - - m_InitialTime) - .count(); - } - - return -1; // failure -} - -} // end namespace -} // end namespace diff --git a/source/adios2/core/Timer.h b/source/adios2/core/Timer.h deleted file mode 100644 index 59796aedcb3744babcbd0fdb738d56ca29b0c47f..0000000000000000000000000000000000000000 --- a/source/adios2/core/Timer.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Timer.h - * - * Created on: Apr 4, 2017 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_TIMER_H_ -#define ADIOS2_CORE_TIMER_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <chrono> -#include <string> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/core/Support.h" - -namespace adios -{ -namespace profiling -{ - -class Timer -{ - -public: - const std::string m_Process; - unsigned long long int m_ProcessTime = 0; - - /** - * Timer object constructor using std::chrono class - * @param process name of process to be measured - * @param resolution time resolution (mus, ms, s, etc.) from Resolutions in - * core/Support.h - * @param debugMode true: additional checks and exceptions, false: no checks - */ - Timer(const std::string process, const Support::Resolutions resolution, - const bool debugMode = false); - - ~Timer() = default; - - ///< set time to start counting for a process - void SetInitialTime(); - - ///< sets time to measure, it will add to overall process time - void SetTime(); - - std::string GetUnits() const; - -private: - const Support::Resolutions m_Resolution; - const bool m_DebugMode = false; - std::chrono::time_point<std::chrono::high_resolution_clock> m_InitialTime; - std::chrono::time_point<std::chrono::high_resolution_clock> m_ElapsedTime; - bool m_InitialTimeSet = false; - long long int GetCurrentTime(); ///< called by SetTime -}; - -} // end namespace profiling -} // end namespace adios - -#endif /* ADIOS2_CORE_TIMER_H_ */ diff --git a/source/adios2/core/Transform.cpp b/source/adios2/core/Transform.cpp index ac75b66adf3470058fe0bc5487d0b7be544c0b51..470215622cc6220cfc72aac35f1665c3664f098a 100644 --- a/source/adios2/core/Transform.cpp +++ b/source/adios2/core/Transform.cpp @@ -5,17 +5,15 @@ * Transform.cpp * * Created on: Dec 5, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "Transform.h" -#include <utility> - namespace adios { -Transform::Transform(std::string method) : m_Method(std::move(method)) {} +Transform::Transform(const std::string method) : m_Method(method) {} void Transform::Compress(const std::vector<char> & /*bufferIn*/, std::vector<char> & /*bufferOut*/) diff --git a/source/adios2/core/Transform.h b/source/adios2/core/Transform.h index 8073ba4002e4b0412b20b0092b9b4d98adb65bbe..cc147a11467e23f4a3fc5b11d7afd9bf9f90d224 100644 --- a/source/adios2/core/Transform.h +++ b/source/adios2/core/Transform.h @@ -2,10 +2,10 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * Transform.h + * Transform.h : Base class for all transforms under adios2/transform * * Created on: Oct 17, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_CORE_TRANSFORM_H_ @@ -21,21 +21,19 @@ namespace adios { -/** - * Parent class that defines data variable transformations. Used as a member of - * CVariable - */ +/** Base class that defines data variable transformations */ class Transform { public: + /** From derived class to identify the transform */ const std::string m_Method; /** * Initialize parent method * @param method zlib, bzip2, szip */ - Transform(std::string method); + Transform(const std::string method); virtual ~Transform() = default; diff --git a/source/adios2/core/Transport.cpp b/source/adios2/core/Transport.cpp deleted file mode 100644 index 6b0e0772d584b52ae4f3a4fa3b4757ebb235ab3b..0000000000000000000000000000000000000000 --- a/source/adios2/core/Transport.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Transport.cpp - * - * Created on: Dec 5, 2016 - * Author: wfg - */ - -#include "Transport.h" - -#include <utility> - -#include "adios2/ADIOSMPI.h" - -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_RankMPI); - MPI_Comm_size(m_MPIComm, &m_SizeMPI); -} - -void Transport::SetBuffer(char * /*buffer*/, size_t /*size*/) {} - -void Transport::Flush() {} - -void Transport::Close() {} - -void Transport::InitProfiler(const std::string accessMode, - const Support::Resolutions resolution) -{ - m_Profiler.Timers.emplace_back("open", Support::Resolutions::mus); - - if (accessMode == "w" || accessMode == "write") - m_Profiler.Timers.emplace_back("write", resolution); - - else if (accessMode == "a" || accessMode == "append") - m_Profiler.Timers.emplace_back("append", resolution); - - else if (accessMode == "r" || accessMode == "read") - m_Profiler.Timers.emplace_back("read", resolution); - - m_Profiler.Timers.emplace_back("close", Support::Resolutions::mus); - - m_Profiler.TotalBytes.push_back(0); - m_Profiler.IsActive = true; -} - -} // end namespace adios diff --git a/source/adios2/core/Transport.h b/source/adios2/core/Transport.h deleted file mode 100644 index 1a5cf845de38e67bafe1250c53cd0813a103b164..0000000000000000000000000000000000000000 --- a/source/adios2/core/Transport.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Transport.h - * - * Created on: Oct 6, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_TRANSPORT_H_ -#define ADIOS2_CORE_TRANSPORT_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <string> -#include <vector> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/ADIOSMPICommOnly.h" -#include "adios2/core/IOChrono.h" - -namespace adios -{ - -class Transport -{ - -public: - const std::string m_Type; ///< transport type from derived class - std::string m_Name; ///< from Open - std::string m_AccessMode; ///< from Open - bool m_IsOpen = false; - - MPI_Comm m_MPIComm; - - int m_RankMPI = 0; ///< current MPI rank process - int m_SizeMPI = 1; ///< current MPI processes size - profiling::IOChrono m_Profiler; ///< profiles Open, Write/Read, Close - - /** - * Base constructor that all derived classes pass - * @param - * @param mpiComm passed to m_MPIComm - * @param debugMode passed to m_DebugMode - */ - Transport(const std::string type, MPI_Comm mpiComm, const bool debugMode); - - virtual ~Transport() = default; - - /** - * Open Output file accesing a mode - * @param name name of stream or file - * @param accessMode r or read, w or write, a or append - */ - virtual void Open(const std::string &name, - const std::string accessMode) = 0; - - /** - * Set buffer and size for a particular transport - * @param buffer raw data buffer - * @param size raw data buffer size - */ - virtual void SetBuffer(char *buffer, std::size_t size); - - /** - * Write function for a transport - * @param buffer pointer to buffer to be written - * @param size size of buffer to be written - */ - virtual void Write(const char *buffer, std::size_t size) = 0; - - virtual void - Flush(); ///< flushes current contents to physical medium without - /// closing the transport - - virtual void Close(); ///< closes current transport and flushes everything, - /// transport becomes unreachable - - /** - * Inits the profiler - * @param accessMode - * @param resolution - */ - virtual void InitProfiler(const std::string accessMode, - const Support::Resolutions resolution); - -protected: - const bool m_DebugMode = false; ///< true: turn on exceptions -}; - -} // end namespace adios - -#endif /* ADIOS2_CORE_TRANSPORT_H_ */ diff --git a/source/adios2/core/Variable.h b/source/adios2/core/Variable.h index 0773aff308bfc011b1f605317d46b7c4739ab95d..9b859f3fabf94a8a907e20586f1402df638ffa50 100644 --- a/source/adios2/core/Variable.h +++ b/source/adios2/core/Variable.h @@ -2,10 +2,10 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * Variable.h + * Variable.h : template class for self-describing primitive variables * * Created on: Oct 6, 2016 - * Author: wfg + * Author: William F Godoy */ #ifndef ADIOS2_CORE_VARIABLE_H_ @@ -18,101 +18,50 @@ #include <vector> /// \endcond +#include "VariableBase.h" #include "adios2/ADIOSConfig.h" +#include "adios2/ADIOSMacros.h" #include "adios2/core/Transform.h" -#include "adios2/core/VariableBase.h" namespace adios { -struct TransformData -{ - Transform &Operation; ///< from ADIOS.DefineTransform - 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. + * @param Base (parent) class for template derived (child) class Variable. */ template <class T> class Variable : public VariableBase { public: - const T *m_AppValues = nullptr; ///< pointer to values passed from user in - /// ADIOS Write + /** pointer to values passed from application in Engine Write*/ + const T *m_AppValues = nullptr; - ///< vector of values as a possible result of ADIOS Read or InquireVariable - std::vector<T> m_Data; + /** reference to non-const data, mostly used for reading */ + T *m_AppPointer = nullptr; - 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). + std::vector<T> m_Data; + /** + * Unique constructor + * @param name + * @param shape + * @param start + * @param count + * @param constantShape + * @param debugMode + */ Variable<T>(const std::string &name, const Dims shape, const Dims start, const Dims count, const bool constantShape, - const bool debugMode) - : VariableBase(name, GetType<T>(), sizeof(T), shape, start, count, - constantShape, debugMode) - { - } + const bool debugMode); - 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 - } + virtual ~Variable<T>() = default; - /** Return the global dimensions of the variable - * @return vector of std::size_t values - */ - std::vector<std::size_t> GetGlobalDimensions(); - - 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; - - if (m_Type.find("complex") != m_Type.npos) // it's complex - { - for (unsigned int i = 0; i < size; ++i) - { - logInfo << "( " << std::real(m_AppValues[i]) << " , " - << std::imag(m_AppValues[i]) << " ) "; - } - } - else - { - for (unsigned int i = 0; i < size; ++i) - { - logInfo << m_AppValues[i] << " "; - } - } - - logInfo << " ..."; - } - logInfo << "\n"; - } + void ApplyTransforms() final; }; -} // end namespace +} // end namespace adios + +#include "Variable.inl" #endif /* ADIOS2_CORE_VARIABLE_H_ */ diff --git a/source/adios2/core/Variable.inl b/source/adios2/core/Variable.inl new file mode 100644 index 0000000000000000000000000000000000000000..4abb6e3c45592bf362aec74f2786619d94d04eb8 --- /dev/null +++ b/source/adios2/core/Variable.inl @@ -0,0 +1,40 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Variable.inl + * + * Created on: May 1, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_CORE_VARIABLE_INL_ +#define ADIOS2_CORE_VARIABLE_INL_ +#ifndef ADIOS2_CORE_VARIABLE_H_ +#error "Inline file should only be included from it's header, never on it's own" +#endif + +#include "Variable.h" + +#include "adios2/helper/adiosFunctions.h" //GetType + +namespace adios +{ + +template <class T> +Variable<T>::Variable(const std::string &name, const Dims shape, + const Dims start, const Dims count, + const bool constantShape, const bool debugMode) +: VariableBase(name, GetType<T>(), sizeof(T), shape, start, count, + constantShape, debugMode) +{ +} + +template <class T> +void Variable<T>::ApplyTransforms() +{ +} + +} // end namespace adios + +#endif /* ADIOS2_CORE_VARIABLE_INL_ */ diff --git a/source/adios2/core/VariableBase.cpp b/source/adios2/core/VariableBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..db50a21db91c2ab96911c5cc74a4b76d7888da84 --- /dev/null +++ b/source/adios2/core/VariableBase.cpp @@ -0,0 +1,230 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * VariableBase.cpp + * + * Created on: May 11, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "VariableBase.h" + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <algorithm> //std::count +#include <stdexcept> //std::invalid_argument +/// \endcond + +namespace adios +{ + +VariableBase::VariableBase(const std::string &name, const std::string type, + const size_t elementSize, const Dims shape, + const Dims start, const Dims count, + const bool constantShape, const bool debugMode) +: m_Name(name), m_Type(type), m_ElementSize(elementSize), m_Shape(shape), + m_Start(start), m_Count(count), m_ConstantShape(constantShape), + m_DebugMode(debugMode) +{ + InitShapeType(); +} + +size_t VariableBase::PayLoadSize() const noexcept +{ + return GetTotalSize(m_Count) * m_ElementSize; +} + +size_t VariableBase::TotalSize() const noexcept +{ + return GetTotalSize(m_Count); +} + +void VariableBase::SetSelection(const Dims start, const Dims count) +{ + if (m_DebugMode) + { + if (m_SingleValue) + { + throw std::invalid_argument( + "ERROR: selection is not valid for single value variable " + + m_Name + ", in call to SetSelection\n"); + } + + if (m_ConstantShape) + { + throw std::invalid_argument( + "ERROR: selection is not valid for constant shape variable " + + m_Name + ", in call to SetSelection\n"); + } + + if (m_ShapeID == ShapeID::GlobalArray && + (m_Shape.size() != m_Count.size() || + m_Shape.size() != m_Start.size())) + { + throw std::invalid_argument("ERROR: count and start must be the " + "same size as shape for variable " + + m_Name + ", in call to SetSelection\n"); + } + + if (m_ShapeID == ShapeID::LocalArray && !start.empty()) + { + throw std::invalid_argument("ERROR: start argument must be empty " + "for local array variable " + + m_Name + ", in call to SetSelection\n"); + } + + if (m_ShapeID == ShapeID::JoinedArray && !start.empty()) + { + throw std::invalid_argument("ERROR: start argument must be empty " + "for joined array variable " + + m_Name + ", in call to SetSelection\n"); + } + } + + m_Count = count; + m_Start = start; +} + +void VariableBase::SetSelection(const SelectionBoundingBox &selection) +{ + SetSelection(selection.m_Start, selection.m_Count); +} + +void VariableBase::SetMemorySelection(const SelectionBoundingBox &selection) +{ + if (m_DebugMode) + { + if (m_SingleValue) + { + throw std::invalid_argument("ERROR: memory selection is not valid " + "for single value variable " + + m_Name + + ", in call to SetMemorySelection\n"); + } + if (m_Shape.size() != selection.m_Count.size() || + m_Shape.size() != selection.m_Start.size()) + { + throw std::invalid_argument( + "ERROR: selection argument m_Count and m_Start sizes must be " + "the " + "same as variable " + + m_Name + " m_Shape, in call to SetMemorySelction\n"); + } + } + + m_MemoryCount = selection.m_Count; + m_MemoryStart = selection.m_Start; +} + +void VariableBase::SetStepSelection(const unsigned int startStep, + const unsigned int countStep) +{ + m_ReadFromStep = startStep; + m_ReadNSteps = countStep; +} + +// transforms related functions +void VariableBase::ClearTransforms() { m_TransformsInfo.clear(); } + +// PRIVATE +void VariableBase::InitShapeType() +{ + if (!m_Shape.empty() && m_Start.empty() && m_Count.empty()) + { + if (m_DebugMode) + { + if (m_ConstantShape) + { + throw std::invalid_argument( + "ERROR: isConstantShape (true) argument is invalid " + "with empty start and count " + "arguments\n"); + } + } + + m_ShapeID = ShapeID::GlobalArray; + } + else if (!m_Shape.empty() && m_Shape.size() == m_Start.size() && + m_Shape.size() == m_Count.size()) + { + if (m_DebugMode) + { + auto lf_LargerThanError = [&](const unsigned int i, + const std::string dims1, + const std::string dims2) { + + const std::string iString(std::to_string(i)); + throw std::invalid_argument( + "ERROR: " + dims1 + "[" + iString + "] > " + dims2 + "[" + + iString + "], in DefineVariable " + m_Name + "\n"); + }; + + for (unsigned int i = 0; i < m_Shape.size(); ++i) + { + if (m_Count[i] > m_Shape[i]) + { + lf_LargerThanError(i, "count", "shape"); + } + if (m_Start[i] > m_Shape[i]) + { + lf_LargerThanError(i, "start", "shape"); + } + } + } + + m_ShapeID = ShapeID::GlobalArray; + } + else if (m_Shape.empty() && m_Start.empty() && m_Count.empty()) + { + m_ShapeID = ShapeID::GlobalValue; + m_SingleValue = true; + } + else if (m_Shape.empty() && m_Start.empty() && !m_Count.empty()) + { + m_ShapeID = ShapeID::LocalArray; + } + else if (m_Shape.size() == 1 && m_Shape.front() == LocalValueDim) + { + m_ShapeID = ShapeID::LocalValue; + m_SingleValue = true; + } + else if (!m_Shape.empty() && + std::count(m_Shape.begin(), m_Shape.end(), JoinedDim) == 1) + { + m_ShapeID = ShapeID::JoinedArray; + } + else if (!m_Shape.empty() && + std::count(m_Shape.begin(), m_Shape.end(), JoinedDim) > 1) + { + throw std::invalid_argument("ERROR: variable can't have more than one " + "JoinedDim in shape argument, in call to " + "DefineVariable " + + m_Name + "\n"); + } + else + { + throw std::invalid_argument("ERROR: the " + "combination of shape, start and count " + "arguments is inconsistent, in call to " + "DefineVariable " + + m_Name + "\n"); + } +} + +void VariableBase::CheckDims(const std::string hint) const +{ + if (m_ShapeID == ShapeID::GlobalArray) + { + if (m_Start.empty() || m_Count.empty()) + { + throw std::invalid_argument( + "ERROR: GlobalArray variable " + m_Name + + " start and count dimensions must be defined by either " + "DefineVariable or a Selection " + + hint + "\n"); + } + } + // TODO need to think more exceptions here +} + +} // end namespace adios diff --git a/source/adios2/core/VariableBase.h b/source/adios2/core/VariableBase.h index 2ba2d8432f52fee6c39540d52da3313ec2f9fdc6..7c17a1687623d7fa5ea3e5263557f1b5e3cffcfd 100644 --- a/source/adios2/core/VariableBase.h +++ b/source/adios2/core/VariableBase.h @@ -2,18 +2,17 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * VariableBase.h + * VariableBase.h Base class for Variable and VariableCompound types. Contains + * common elements. * * Created on: Feb 20, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_CORE_VARIABLEBASE_H_ #define ADIOS2_CORE_VARIABLEBASE_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <exception> -#include <iterator> #include <sstream> #include <string> #include <vector> @@ -22,222 +21,132 @@ #include "adios2/ADIOSConfig.h" #include "adios2/ADIOSTypes.h" #include "adios2/core/SelectionBoundingBox.h" -#include "adios2/core/adiosFunctions.h" -#include "adios2/core/adiosTemplates.h" +#include "adios2/core/Transform.h" +#include "adios2/helper/adiosFunctions.h" namespace adios { - -using Dims = std::vector<std::size_t>; - +/** Base class for Variable<T> (primitives) and VariableCompound classes */ class VariableBase { public: - const std::string m_Name; ///< variable name - const std::string m_Type; ///< variable type - const bool m_ConstantShape; ///< dimensions and offsets cannot change after - /// declaration + /** unique identifier inside Method that creates a Variable */ + const std::string m_Name; - /** - * Variable -> sizeof(T), - * VariableCompound -> from constructor sizeof(struct) - */ - const std::size_t m_ElementSize; + /** primitive from <T> or compound from struct */ + const std::string m_Type; - Dims m_Shape; ///< total dimensions across MPI - Dims m_Start; ///< offsets of local writer in global shape - Dims m_Count; ///< dimensions of the local writer in global shape - Dims m_MemoryDimensions; ///< array of memory dimensions - Dims m_MemoryOffsets; ///< array of memory offsets + /** Variable -> sizeof(T), + * VariableCompound -> from constructor sizeof(struct) */ + const size_t m_ElementSize; - VarClass m_VarClass; - bool m_IsScalar = false; /// Global value or Loval value - const bool m_IsDimension = false; - const bool m_DebugMode = false; + ShapeID m_ShapeID; ///< see shape types in ADIOSTypes.h + bool m_SingleValue = false; ///< true: single value, false: array + const bool m_ConstantShape = false; ///< true: fix m_Shape, m_Start, m_Count + Dims m_Shape; ///< total dimensions across MPI + Dims m_Start; ///< starting point (offsets) in global shape + Dims m_Count; ///< dimensions from m_Start in global shape - VariableBase(const std::string &name, const std::string type, - const std::size_t elementSize, const Dims shape, - const Dims start, const Dims count, const bool constantShape, - const bool debugMode) - : m_Name{name}, m_Type{type}, m_ConstantShape{constantShape}, - m_ElementSize{elementSize}, m_Count{count}, m_Shape{shape}, - m_Start{start}, m_DebugMode{debugMode} - { - if (shape.empty() && start.empty()) - { - if (count.empty()) - { - m_VarClass = VarClass::GlobalValue; - m_IsScalar = true; - } - else - { - m_VarClass = VarClass::LocalArray; - } - } - else if (shape.size() == 1 && shape[0] == LocalValueDim) - { - m_VarClass = VarClass::LocalValue; - m_IsScalar = true; - } - else if (shape.size() > 0 && shape[0] == JoinedDim) - { - m_VarClass = VarClass::JoinedArray; - } - else - { - if ((start.empty() && count.empty()) || - (shape.size() == start.size() && shape.size() == count.size())) - { - m_VarClass = VarClass::GlobalArray; - } - else - { - throw std::invalid_argument("DefineVariable() is invalid. The " - "combination of dimension " - "specifications cannot be " - "interpreted\n"); - } - } - } + Dims m_MemoryStart; ///< offset of memory selection + Dims m_MemoryCount; ///< subset of m_Shape (e.g. remove ghost points) - virtual ~VariableBase() {} + /** Read from this step (must be 0 in staging) */ + unsigned int m_ReadFromStep = 0; + /** Read this many steps at once (must be 1 in staging) */ + unsigned int m_ReadNSteps = 1; + /** Global array was written as Joined array, so read accordingly */ + bool m_ReadAsJoined = false; + /** Global array was written as Local value, so read accordingly */ + bool m_ReadAsLocalValue = false; + /** number of steps available in a file (or 1 in staging) filled by + * InquireVariable*/ + unsigned int m_AvailableSteps = 1; + + VariableBase(const std::string &name, const std::string type, + const size_t elementSize, const Dims shape, const Dims start, + const Dims count, const bool constantShape, + const bool debugMode); - std::size_t DimensionsSize() const noexcept { return m_Count.size(); } + virtual ~VariableBase() = default; /** * Returns the payload size in bytes - * @return TotalSize * sizeof(T) + * @return TotalSize * m_ElementSize */ - std::size_t PayLoadSize() const noexcept - { - return GetTotalSize(m_Count) * m_ElementSize; - } + size_t PayLoadSize() const noexcept; /** - * Returns the total size + * Returns the total number of elements * @return number of elements */ - std::size_t TotalSize() const noexcept { return GetTotalSize(m_Count); } + size_t TotalSize() const noexcept; - /** - * Set the local dimension and global offset of the variable - */ - void SetSelection(const Dims start, const Dims count) - { - if (m_IsScalar) - { - throw std::invalid_argument("Variable.SetSelection() is an invalid " - "call for single value variable '" + - m_Name + "'\n"); - } - if (m_ConstantShape) - { - throw std::invalid_argument( - "Variable.SetSelection() is not allowed " - "for constant shape variable '" + - m_Name + "'\n"); - } - if (m_VarClass == VarClass::GlobalArray && - m_Shape.size() != count.size()) - { - throw std::invalid_argument("Variable.SetSelection() selection " - "dimension must equal the global " - "dimension of the variable '" + - m_Name + "'\n"); - } - if ((m_VarClass == VarClass::LocalArray || - m_VarClass == VarClass::JoinedArray) && - !start.empty()) - { - throw std::invalid_argument( - "Variable.SetSelection() for local or joined array '" + m_Name + - "' should pass an empty 'start' argument\n"); - } - m_Count = count; - m_Start = start; - } + /** Set the local dimension and global offset of the variable */ + void SetSelection(const Dims start, const Dims count); - /** - * Set the local dimension and global offset of the variable using a - * selection - */ - void SetSelection(const SelectionBoundingBox &sel) - { - Dims start, count; - ConvertUint64VectorToSizetVector(sel.m_Start, start); - ConvertUint64VectorToSizetVector(sel.m_Count, count); - SetSelection(start, count); - } + /** Overloaded version of SetSelection using a SelectionBoundingBox */ + void SetSelection(const SelectionBoundingBox &selection); /** * Set the local dimension and global offset of the variable using a * selection * Only bounding boxes are allowed */ - void SetMemorySelection(const SelectionBoundingBox &sel) - { - if (m_Shape.size() == 0) - { - throw std::invalid_argument( - "Variable.SetMemorySelection() is an invalid " - "call for single value variables\n"); - } - if (m_Shape.size() != sel.m_Count.size()) - { - throw std::invalid_argument( - "Variable.SetMemorySelection() bounding box " - "dimension must equal the global " - "dimension of the variable\n"); - } - - ConvertUint64VectorToSizetVector(sel.m_Count, m_MemoryDimensions); - ConvertUint64VectorToSizetVector(sel.m_Start, m_MemoryOffsets); - } + void SetMemorySelection(const SelectionBoundingBox &selection); /** * Set the steps for the variable to read from. The pointer passed at * reading must be able to hold enough memory to store multiple steps in a * single read. - * @param fromStep The first step to read. Steps start from 0 - * @param nSteps Number of consecutive steps to read at once. + * @param startStep The first step to read. Steps start from 0 + * @param countStep Number of consecutive steps to read at once. * */ - void SetStepSelection(const unsigned int fromStep, - const unsigned int nSteps) + void SetStepSelection(const unsigned int startStep, + const unsigned int countStep); + + template <class... Args> + void AddTransform(Transform &transform, Args... args) { - m_ReadFromStep = fromStep; - m_ReadNSteps = nSteps; + std::vector<std::string> parameters = {args...}; + m_TransformsInfo.emplace_back( + transform, + BuildParametersMap(parameters, m_DebugMode)); // need to check } - /** Return the number of steps available for the variable - * @return Number of steps - */ - unsigned int GetNSteps() { return m_NStepsAvailable; } + /** Apply current sequence of transforms defined by AddTransform */ + virtual void ApplyTransforms() = 0; + + /** Clears out the transform sequence defined by AddTransform */ + void ClearTransforms(); - ///< Should only be called by read engines - void SetNSteps(unsigned int steps) { m_NStepsAvailable = steps; } - unsigned int GetReadFromStep() { return m_ReadFromStep; } - unsigned int GetReadNSteps() { return m_ReadNSteps; } - void SetReadAsJoinedArray() { m_ReadAsJoined = true; } - void SetReadAsLocalValue() { m_ReadAsLocalValue = true; } - bool ReadAsJoinedArray() { return m_ReadAsJoined; } - bool ReadAsLocalValue() { return m_ReadAsLocalValue; } + /** Self-check dims according to type, called from Engine before Write + * @param hint extra debugging info for the exception */ + void CheckDims(const std::string hint) const; private: - ///< Read from this step (must be 0 in staging) - unsigned int m_ReadFromStep = 0; - ///< Read this many steps at once (must be 1 in staging) - unsigned int m_ReadNSteps = 1; - ///< Global array was written as Joined array, so read accordingly - bool m_ReadAsJoined = false; - ///< Global array was written as Local value, so read accordingly - bool m_ReadAsLocalValue = false; + const bool m_DebugMode = false; - /* Values filled by InquireVariable() */ - ///< number of steps available in a file (or 1 in staging), - unsigned int m_NStepsAvailable = 1; + void InitShapeType(); + + /** Transforms metadata info */ + struct TransformInfo + { + /** reference to object derived from Transform class */ + Transform &Object; + /** parameters from AddTransform */ + std::map<std::string, std::string> Parameters; + /** resulting sizes from transformation */ + std::vector<std::size_t> Sizes; + }; + + /** + * Sequence determines application order, e.g. + * first Transforms[0] then Transforms[1]. Pointer used as + * reference (no memory management). + */ + std::vector<TransformInfo> m_TransformsInfo; }; } // end namespace diff --git a/source/adios2/core/VariableCompound.cpp b/source/adios2/core/VariableCompound.cpp new file mode 100644 index 0000000000000000000000000000000000000000..525ecbf19130e560821a1730d4ca9129d3826894 --- /dev/null +++ b/source/adios2/core/VariableCompound.cpp @@ -0,0 +1,37 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * VariableCompound.cpp + * + * Created on: May 16, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "VariableCompound.h" +#include "VariableCompound.tcc" + +#include "adios2/ADIOSConfig.h" + +namespace adios +{ + +VariableCompound::VariableCompound(const std::string name, + const size_t sizeOfStruct, const Dims shape, + const Dims start, const Dims count, + const bool constantShape, + const bool debugMode) +: VariableBase(name, "compound", sizeOfStruct, shape, start, count, + constantShape, debugMode) +{ +} + +void VariableCompound::ApplyTransforms() {} + +#define declare_template_instantiation(T) \ + template void VariableCompound::InsertMember<T>(const std::string, \ + const size_t); +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation + +} // end namespace diff --git a/source/adios2/core/VariableCompound.h b/source/adios2/core/VariableCompound.h index 5153a7c44a773a472c031b36d5fd79c000c465c6..9fc71d766f7a0d56c424e939b411a861d656876c 100644 --- a/source/adios2/core/VariableCompound.h +++ b/source/adios2/core/VariableCompound.h @@ -5,24 +5,18 @@ * VariableCompound.h * * Created on: Feb 20, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_CORE_VARIABLECOMPOUND_H_ #define ADIOS2_CORE_VARIABLECOMPOUND_H_ -#include "adios2/ADIOSConfig.h" -#include "adios2/core/VariableBase.h" +#include "VariableBase.h" -namespace adios -{ +#include "adios2/ADIOSMacros.h" -struct CompoundElement +namespace adios { - const std::string m_Name; - const std::size_t m_Offset; - const std::string m_Type; -}; /** * @param Base (parent) class for template derived (child) class CVariable. @@ -34,33 +28,41 @@ class VariableCompound : public VariableBase public: const void *m_AppValue = nullptr; - VariableCompound(const std::string name, const std::size_t sizeOfStruct, - const Dims dimensions, const Dims globalDimensions, - const Dims globalOffsets, const bool constantShape, - const bool debugMode) - : VariableBase(name, "compound", sizeOfStruct, dimensions, globalDimensions, - globalOffsets, constantShape, debugMode) + /** Primitive type element */ + struct Element { - } + const std::string m_Name; + const std::string m_Type; ///< from GetType<T> + const size_t m_Offset; ///< element offset in struct + }; - template <class U> - void InsertMember(const std::string name, const std::size_t offset) - { - m_Elements.push_back(CompoundElement{name, offset, GetType<U>()}); - } + /** vector of primitve element types defining compound struct */ + std::vector<Element> m_Elements; - void Monitor(std::ostream &logInfo) const noexcept - { - logInfo << "Variable Compound: " << m_Name << "\n"; - logInfo << "Type: " << m_Type << "\n"; - logInfo << "Size: " << TotalSize() << " elements\n"; - logInfo << "Payload: " << PayLoadSize() << " bytes\n"; - } + VariableCompound(const std::string name, const std::size_t sizeOfStruct, + const Dims shape, const Dims start, const Dims count, + const bool constantShape, const bool debugMode); + + ~VariableCompound() = default; -private: - std::vector<CompoundElement> m_Elements; ///< vector of element types + void ApplyTransforms() final; + + /** + * Inserts an Element into the compound struct definition + * @param name + * @param offset + */ + template <class T> + void InsertMember(const std::string name, const size_t offset); }; -} // end namespace +// Explicit declaration of the public template methods +#define declare_template_instantiation(T) \ + extern template void VariableCompound::InsertMember<T>(const std::string, \ + const size_t); +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation + +} // end namespace adios #endif /* ADIOS2_CORE_VARIABLECOMPOUND_H_ */ diff --git a/source/adios2/core/VariableCompound.tcc b/source/adios2/core/VariableCompound.tcc new file mode 100644 index 0000000000000000000000000000000000000000..8293bce149e8278fc6f18c167a36fc0c1cfc13d4 --- /dev/null +++ b/source/adios2/core/VariableCompound.tcc @@ -0,0 +1,29 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * VariableCompound.tcc + * + * Created on: May 16, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_CORE_VARIABLECOMPOUND_TCC_ +#define ADIOS2_CORE_VARIABLECOMPOUND_TCC_ + +#include "VariableCompound.h" + +#include "adios2/ADIOSConfig.h" + +namespace adios +{ + +template <class T> +void VariableCompound::InsertMember(const std::string name, const size_t offset) +{ + m_Elements.push_back(Element{name, GetType<T>(), offset}); +} + +} // end namespace + +#endif /* ADIOS2_CORE_VARIABLECOMPOUND_TCC_ */ diff --git a/source/adios2/core/adiosFunctions.h b/source/adios2/core/adiosFunctions.h deleted file mode 100644 index c5336daa1c1ac9fa16123b2bf9d4a94a204ba4e2..0000000000000000000000000000000000000000 --- a/source/adios2/core/adiosFunctions.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * adiosFunctions.h Long helper functions used by ADIOS class - * - * Created on: Oct 10, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_ADIOSFUNCTIONS_H_ -#define ADIOS2_CORE_ADIOSFUNCTIONS_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <cstring> //std::size_t -#include <map> -#include <memory> //std::shared_ptr -#include <string> -#include <vector> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/ADIOSMPICommOnly.h" -#include "adios2/core/Transform.h" - -namespace adios -{ - -/** - * Opens and checks for file and dumps contents to a single string - * @param fileName file to be opened - * @param fileContents output contains the entire file - */ -void DumpFileToString(const std::string fileName, std::string &fileContents); - -/** - * Extracts a substring between two tags from content - * @param initialTag - * @param finalTag - * @param content full string - * @param subString if found return substring between initialTag and finalTag, - * otherwise returns empty - * @param currentPosition to start the search, moved forward to finalTag - * position - */ -void GetSubString(const std::string initialTag, const std::string finalTag, - const std::string content, std::string &subString, - std::string::size_type ¤tPosition); - -/** - * Extracts the value inside quotes in a string currentTag ( Example: currentTag - * --> field1="value1" field2="value2" ) - * @param quote double " or single ' - * @param quotePosition position of the opening quote in currentTag - * @param currentTag initial tag value, modified by cutting the first found " " - * portion, currentTag --> field2="value2" - * @param value value1 in the example above - */ -void GetQuotedValue(const char quote, - const std::string::size_type "ePosition, - std::string ¤tTag, std::string &value); - -/** - * Get attributes field1="value1" field2="value2" by looping through a single - * XML tag - * @param tag field0="value0" field1="value1" in a single string - * @param pairs pairs[0].first=field0 pairs[0].second=value0 - * pairs[1].first=field1 pairs[1].second=value1 - */ -void GetPairs(const std::string tag, - std::vector<std::pair<const std::string, const std::string>> - &pairs) noexcept; - -/** - * Determine tag type and call GetPairs to populate pairs - * @param fileContent file Content in a single string - * @param tag field0="value0" field1="value1" in a single string - * @param pairs pairs[0].first=field0 pairs[0].second=value0 - * pairs[1].first=field1 pairs[1].second=value1 - */ -void GetPairsFromTag( - const std::string &fileContent, const std::string tag, - std::vector<std::pair<const std::string, const std::string>> &pairs); - -/** - * Set members m_Groups and m_HostLanguage from XML file content, called within - * Init functions - * @param fileContent file Content in a single string - * @param mpiComm MPI Communicator passed from application passed to Transport - * method if required - * @param hostLanguage return the host language from fileContent - * @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 ); - -/** - * Called inside the ADIOS XML constructors to get contents from file, broadcast - * and set hostLanguage and groups from ADIOS class - * @param xmlConfigFile xml config file name - * @param mpiComm communicator used from broadcasting - * @param debugMode from ADIOS m_DebugMode passed to CGroup in groups - * @param hostLanguage set from host-language in xml file - * @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 ); - -/** - * Loops through a vector containing dimensions and returns the product of all - * elements - * @param dimensions input containing size on each dimension {Nx, Ny, Nz} - * @return product of all dimensions Nx * Ny * Nz - */ -std::size_t GetTotalSize(const std::vector<size_t> &dimensions); - -/** - * Might need to add exceptions for debug mode - * Creates a chain of directories using POSIX systems calls (stat, mkdir), - * Verifies if directory exists before creating a new one. Permissions are 777 - * for now - * @param fullPath /full/path/for/directory - */ -void CreateDirectory(const std::string fullPath) noexcept; - -/** - * Identifies, verifies the corresponding transform method and adds it the - * transforms container if neccesary. - * This functions must be updated as new transform methods are supported. - * @param variableTransforms methods to be added to transforms with format - * "method:compressionLevel", or "method" with compressionLevel=0 (default) - * @param transforms container of existing transform methods, owned by ADIOS - * class - * @param debugMode if true will do more checks, exceptions, warnings, expect - * slower code - * @param transformIndices returns the corresponding indices in ADIOS - * m_Transforms for a single variable - * @param parameters returns the corresponding parameters understood by a - * collection of transform="method:parameter" - */ -void SetTransformsHelper(const std::vector<std::string> &transformNames, - std::vector<std::shared_ptr<Transform>> &transforms, - const bool debugMode, - std::vector<short> &transformIndices, - std::vector<short> ¶meters); - -/** - * Transforms a vector - * @param parameters vector of parameters with format "field=value" - * @param debugMode true=check parameters format, false=no checks - * @return a map with unique key=field, value=corresponding value - */ -std::map<std::string, std::string> -BuildParametersMap(const std::vector<std::string> ¶meters, - const bool debugMode); - -/** - * Single call that extract data buffers information from Capsule. That way - * virtual Capsule functions are called a few times - * @param capsules input - * @param dataBuffers from Capsule.GetData() - * @param positions - * @param absolutePositions - */ -// void GetDataBuffers( const std::vector<Capsule*>& capsules, -// std::vector<char*>& dataBuffers, std::vector<std::size_t>& positions, -// std::vector<std::size_t>& absolutePositions ); - -/** - * Converts comma-separated values to a vector of integers - * @param csv "1,2,3" - * @return vector<int> = { 1, 2, 3 } - */ -std::vector<int> CSVToVectorInt(const std::string csv); - -/** Convert a vector of uint64_t elements to a vector of std::size_t elements - * @param input vector of uint64_t elements - * @param output vector of std::size_t elements - */ -void ConvertUint64VectorToSizetVector(const std::vector<std::uint64_t> &in, - std::vector<std::size_t> &out); -/** Convert a C array of uint64_t elements to a vector of std::size_t elements - * @param number of elements - * @param input array of uint64_t elements - * @param vector of std::size_t elements. It will be resized to nElements. - */ -void Uint64ArrayToSizetVector(const std::size_t nElements, const uint64_t *in, - std::vector<std::size_t> &out); - -/** Convert a C array of uint64_t elements to a vector of std::size_t elements - * @param number of elements - * @param input array of uint64_t elements - * @return vector of std::size_t elements - */ -std::vector<std::size_t> Uint64ArrayToSizetVector(const std::size_t nElements, - const uint64_t *in); -/** - * Converts a vector of dimensions to a CSV string - * @param dims vector of dimensions - * @return comma separate value (CSV) - */ -std::string DimsToCSV(const std::vector<std::size_t> &dims); - -/** - * Grows a buffer by a factor of n . growthFactor . currentCapacity to - * accommodate for incomingDataSize - * @param incomingDataSize size of new data required to be stored in buffer - * @param growthFactor buffer grows in multiples of the growth buffer - * @param buffer to be resized - * @param position, current buffer position - * @return -1: failed to allocate (bad_alloc), 0: didn't have to allocate - * (enough space), 1: successful allocation - */ -int GrowBuffer(const size_t incomingDataSize, const float growthFactor, - std::vector<char> &buffer, const size_t position); - -/** - * Check if system is little endian - * @return true: little endian, false: big endian - */ -bool IsLittleEndian() noexcept; - -} // end namespace - -#endif /* ADIOS2_CORE_ADIOSFUNCTIONS_H_ */ diff --git a/source/adios2/core/adiosTemplates.h b/source/adios2/core/adiosTemplates.h deleted file mode 100644 index 3c94ff392d5dfbcd2b66d230a5187874ccdc0b80..0000000000000000000000000000000000000000 --- a/source/adios2/core/adiosTemplates.h +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * adiosTemplates.h - * - * Created on: Jan 26, 2017 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_ADIOSTEMPLATES_H_ -#define ADIOS2_CORE_ADIOSTEMPLATES_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <algorithm> //std::minmax_element -#include <cmath> //std::sqrt -#include <complex> -#include <cstring> //std::memcpy -#include <iostream> -#include <set> -#include <thread> -#include <vector> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/ADIOSTypes.h" - -namespace adios -{ -/** - * Get the primitive type in a string from a template - * @return if T is a char, returns string = "char" - */ -template <class T> -inline std::string GetType() noexcept -{ - return "compound"; -} -template <> -inline std::string GetType<void>() noexcept -{ - return "unknown"; -} -template <> -inline std::string GetType<char>() noexcept -{ - return "char"; -} -template <> -inline std::string GetType<unsigned char>() noexcept -{ - return "unsigned char"; -} -template <> -inline std::string GetType<short>() noexcept -{ - return "short"; -} -template <> -inline std::string GetType<unsigned short>() noexcept -{ - return "unsigned short"; -} -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"; -} -template <> -inline std::string GetType<std::complex<float>>() noexcept -{ - return "float complex"; -} -template <> -inline std::string GetType<std::complex<double>>() noexcept -{ - return "double complex"; -} -template <> -inline std::string GetType<std::complex<long double>>() noexcept -{ - return "long double complex"; -} - -/** - * Check in types set if "type" is one of the aliases for a certain type, - * (e.g. if type = integer is an accepted alias for "int", returning true) - * @param type input to be compared with an alias - * @param aliases set containing aliases to a certain type, typically - * Support::DatatypesAliases from Support.h - * @return true: is an alias, false: is not - */ -template <class T> -bool IsTypeAlias( - const std::string type, - const std::map<std::string, std::set<std::string>> &aliases) noexcept -{ - if (type == GetType<T>()) // most of the time we will pass the same type, - // which is a key in aliases - return true; - - bool isAlias = false; - if (aliases.at(GetType<T>()).count(type) == 1) - isAlias = true; - - return isAlias; -} - -template <class T> -void GetMinMax(const T *values, const size_t size, T &min, T &max) noexcept -{ - auto bounds = std::minmax_element(values, values + size); - min = *bounds.first; - max = *bounds.second; -} - -/** - * Get the minimum and maximum values in one loop - * @param values array of primitives - * @param size of the values array - * @param min from values - * @param max from values - */ -template <class T> -void GetMinMaxThreads(const T *values, const size_t size, T &min, T &max, - const unsigned int threads = 1) noexcept -{ - if (threads == 1) - { - GetMinMax(values, size, min, max); - return; - } - - const size_t stride = size / threads; // elements per thread - const size_t remainder = size % threads; // remainder if not aligned - const size_t last = stride + remainder; - - std::vector<T> mins(threads); // zero init - std::vector<T> maxs(threads); // zero init - - std::vector<std::thread> getMinMaxThreads; - getMinMaxThreads.reserve(threads); - - for (unsigned int t = 0; t < threads; ++t) - { - const size_t position = stride * t; - - if (t == threads - 1) - { - getMinMaxThreads.push_back( - std::thread(adios::GetMinMax<T>, &values[position], last, - std::ref(mins[t]), std::ref(maxs[t]))); - } - else - { - getMinMaxThreads.push_back( - std::thread(adios::GetMinMax<T>, &values[position], stride, - std::ref(mins[t]), std::ref(maxs[t]))); - } - } - - for (auto &getMinMaxThread : getMinMaxThreads) - { - getMinMaxThread.join(); - } - - auto itMin = std::min_element(mins.begin(), mins.end()); - min = *itMin; - - auto itMax = std::max_element(maxs.begin(), maxs.end()); - max = *itMax; -} - -/** - * Overloaded version for complex types, gets the "doughnut" range between min - * and max modulus - * @param values array of complex numbers - * @param size of the values array - * @param min modulus from values - * @param max modulus from values - */ -template <class T> -void GetMinMaxComplex(const std::complex<T> *values, const size_t size, T &min, - T &max) noexcept -{ - - min = std::norm(values[0]); - max = min; - - for (size_t i = 1; i < size; ++i) - { - T norm = std::norm(values[i]); - - if (norm < min) - { - min = norm; - continue; - } - - if (norm > max) - { - max = norm; - } - } - - min = std::sqrt(min); - max = std::sqrt(max); -} - -template <class T> -void GetMinMaxThreads(const std::complex<T> *values, const size_t size, T &min, - T &max, const unsigned int threads = 1) noexcept -{ - if (threads == 1) - { - GetMinMaxComplex(values, size, min, max); - return; - } - - const size_t stride = size / threads; // elements per thread - const size_t remainder = size % threads; // remainder if not aligned - const size_t last = stride + remainder; - - std::vector<T> mins(threads); // zero init - std::vector<T> maxs(threads); // zero init - - std::vector<std::thread> getMinMaxThreads; - getMinMaxThreads.reserve(threads); - - for (unsigned int t = 0; t < threads; ++t) - { - const size_t position = stride * t; - - if (t == threads - 1) - { - getMinMaxThreads.push_back( - std::thread(GetMinMaxComplex<T>, &values[position], last, - std::ref(mins[t]), std::ref(maxs[t]))); - } - else - { - getMinMaxThreads.push_back( - std::thread(GetMinMaxComplex<T>, &values[position], stride, - std::ref(mins[t]), std::ref(maxs[t]))); - } - } - - for (auto &getMinMaxThread : getMinMaxThreads) - { - getMinMaxThread.join(); - } - - auto itMin = std::min_element(mins.begin(), mins.end()); - min = *itMin; - - auto itMax = std::max_element(maxs.begin(), maxs.end()); - max = *itMax; -} - -/** - * threaded version of std::memcpy - * @param dest - * @param source - * @param count total number of bytes (as in memcpy) - * @param nthreads - */ -template <class T, class U> -void MemcpyThreads(T *destination, const U *source, size_t count, - const unsigned int threads = 1) -{ - // do not decompose tasks to less than 4MB pieces - const size_t minBlockSize = 4194304; - const size_t maxNThreads = std::max((size_t)threads, count / minBlockSize); - - if (maxNThreads == 1) - { - std::memcpy(destination, source, count); - return; - } - - const std::size_t stride = count / maxNThreads; - const std::size_t remainder = count % maxNThreads; - const std::size_t last = stride + remainder; - - std::vector<std::thread> memcpyThreads; - memcpyThreads.reserve(maxNThreads); - - for (unsigned int t = 0; t < maxNThreads; ++t) - { - const size_t initialDestination = stride * t / sizeof(T); - const size_t initialSource = stride * t / sizeof(U); - - if (t == maxNThreads - 1) - memcpyThreads.push_back( - std::thread(std::memcpy, &destination[initialDestination], - &source[initialSource], last)); - else - memcpyThreads.push_back( - std::thread(std::memcpy, &destination[initialDestination], - &source[initialSource], stride)); - } - // Now join the threads (is this really needed?) - for (auto &thread : memcpyThreads) - thread.join(); -} - -template <class T> -void MemcpyToBuffer(std::vector<char> &raw, std::size_t &position, - const T *source, std::size_t size) noexcept -{ - std::memcpy(&raw[position], source, size); - position += size; -} - -/** - * Version that pushed to the end of the buffer, updates vec.size() - * automatically - * @param raw - * @param source using pointer notation - * @param elements - */ -template <class T> -void InsertToBuffer(std::vector<char> &buffer, const T *source, - const std::size_t elements = 1) noexcept -{ - const char *src = reinterpret_cast<const char *>(source); - buffer.insert(buffer.end(), src, src + elements * sizeof(T)); -} - -/** - * Copies data to a specific location in the buffer. - * Updates position. - * Does not update vec.size(). - * @param raw - * @param position - * @param source - * @param elements - */ -template <class T> -void CopyToBuffer(std::vector<char> &buffer, size_t &position, const T *source, - const size_t elements = 1) noexcept -{ - const char *src = reinterpret_cast<const char *>(source); - std::copy(src, src + elements * sizeof(T), buffer.begin() + position); - position += elements * sizeof(T); -} - -template <class T> -void CopyToBufferThreads(std::vector<char> &buffer, size_t &position, - const T *source, const size_t elements = 1, - const unsigned int threads = 1) noexcept -{ - if (threads == 1) - { - CopyToBuffer(buffer, position, source, elements); - return; - } - - const size_t stride = elements / threads; // elements per thread - const size_t remainder = elements % threads; // remainder if not aligned - const size_t last = stride + remainder; - - std::vector<std::thread> copyThreads; - copyThreads.reserve(threads); - - for (unsigned int t = 0; t < threads; ++t) - { - size_t bufferPosition = stride * t * sizeof(T); - const size_t sourcePosition = stride * t; - - if (t == threads - 1) // last thread takes stride + remainder - { - copyThreads.push_back(std::thread(CopyToBuffer<T>, std::ref(buffer), - std::ref(bufferPosition), - &source[sourcePosition], last)); - position = bufferPosition; // last position - } - else - { - copyThreads.push_back(std::thread(CopyToBuffer<T>, std::ref(buffer), - std::ref(bufferPosition), - &source[sourcePosition], stride)); - } - } - - for (auto ©Thread : copyThreads) - { - copyThread.join(); - } -} - -template <class T> -void CopyFromBuffer(T *destination, std::size_t elements, - const std::vector<char> &raw, - std::size_t &position) noexcept -{ - std::copy(raw.begin() + position, - raw.begin() + position + sizeof(T) * elements, - reinterpret_cast<char *>(destination)); - position += elements * sizeof(T); -} - -template <class T> -void PrintValues(const std::string name, const char *buffer, - const std::size_t position, const std::size_t elements) -{ - std::vector<T> values(elements); - std::memcpy(values.data(), &buffer[position], elements * sizeof(T)); - - std::cout << "Read " << name << "\n"; - for (const auto value : values) - std::cout << value << " "; - - std::cout << "\n"; -} - -} // end namespace - -#endif /* ADIOS2_CORE_ADIOSTEMPLATES_H_ */ diff --git a/source/adios2/core/capsuleTemplates.h b/source/adios2/core/capsuleTemplates.h deleted file mode 100644 index 76c022f2775a7421a6926697a7ed9a7a1a0770a9..0000000000000000000000000000000000000000 --- a/source/adios2/core/capsuleTemplates.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * capsuleTemplates.h - * - * Created on: Nov 18, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_CORE_CAPSULETEMPLATES_H_ -#define ADIOS2_CORE_CAPSULETEMPLATES_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <cstring> //std::memcpy -#include <thread> -#include <vector> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/core/Transport.h" - -namespace adios -{ - -/** - * - * @param data - * @param size - * @param transportIndex - * @param transports - * @param maxBufferSize - * @param buffer - */ -// template<class T> -// void WriteToBuffer( const T* data, const size_t size, -// std::vector< std::shared_ptr<Transport> >& transports, -// const size_t maxBufferSize, std::vector<char>& buffer ) -//{ -// auto lf_TransportsWrite = []( const int transportIndex, std::vector< -// std::shared_ptr<Transport> >& transports, -// std::vector<char>& buffer ) -// { -// if( transportIndex == -1 ) // all transports -// { -// for( auto& transport : transports ) -// transport->Write( buffer ); -// } -// else -// transports[ transportIndex ]->Write( buffer ); -// }; -// -// //FUNCTION starts here -// const size_t dataBytes = size * sizeof( T ); //size of data in bytes -// -// //check for DataMan transport -// if( transportIndex == -1 ) // all transports -// { -// for( auto& transport : transports ) -// { -// if( transport->m_Method == "DataMan" ) //DataMan needs all the -// information -// buffer.resize( dataBytes ); //resize buffer to fit all data -// } -// } -// else //just one transport -// { -// if( transports[transportIndex]->m_Method == "DataMan" ) -// buffer.resize( dataBytes ); //resize buffer to fit all data -// } -// -// if( dataBytes <= buffer.size() ) // dataBytes < buffer.size() -// { -// buffer.resize( dataBytes ); //this resize shouldn't change capacity or -// call realloc -// MemcpyThreads( &buffer[0], data, dataBytes, 1 ); //copy memory in -// threaded fashion, need to test with size, serial for now -// lf_TransportsWrite( transportIndex, transports, buffer ); -// return; -// } -// -// if( buffer.size() < dataBytes && dataBytes <= maxBufferSize ) // -// buffer.size() < dataBytes < maxBufferSize -// { -// buffer.resize( dataBytes ); -// MemcpyThreads( &buffer[0], data, dataBytes, 1 ); //copy memory in -// threaded fashion, need to test with size, serial for now -// lf_TransportsWrite( transportIndex, transports, buffer ); -// 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 /* ADIOS2_CORE_CAPSULETEMPLATES_H_ */ diff --git a/source/adios2/engine/adios1/ADIOS1Reader.cpp b/source/adios2/engine/adios1/ADIOS1Reader.cpp index 2571139cbf93b40488b78787872b9b5412e47a82..9556bdb27200c17a2e6e9073423c72dfe28e8159 100644 --- a/source/adios2/engine/adios1/ADIOS1Reader.cpp +++ b/source/adios2/engine/adios1/ADIOS1Reader.cpp @@ -5,28 +5,24 @@ * ADIOS1Reader.cpp * * Created on: Feb 27, 2017 - * Author: wfg + * Author: Norbert Podhorszki pnorbert@ornl.gov */ #include "ADIOS1Reader.h" -#include "adios2/core/Support.h" -#include "adios2/core/adiosFunctions.h" // CSVToVector -#include "adios2/transport/file/FStream.h" // uses C++ fstream -#include "adios2/transport/file/FileDescriptor.h" // uses POSIX -#include "adios2/transport/file/FilePointer.h" // uses C FILE* - #include <adios_error.h> +#include "adios2/helper/adiosFunctions.h" // CSVToVector + namespace adios { -ADIOS1Reader::ADIOS1Reader(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method) -: Engine(adios, "ADIOS1Reader", name, accessMode, mpiComm, method, - " ADIOS1Reader constructor (or call to ADIOS Open).\n") +ADIOS1Reader::ADIOS1Reader(IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: Engine("ADIOS1Reader", io, name, openMode, mpiComm) { + m_EndMessage = " in call to IO Open ADIOS1Reader " + m_Name + "\n"; + Init(); adios_read_init_method(m_ReadMethod, mpiComm, ""); if (m_OpenAsFile) @@ -47,11 +43,12 @@ ADIOS1Reader::~ADIOS1Reader() adios_read_finalize_method(m_ReadMethod); } -Variable<void> * -ADIOS1Reader::InquireVariable(const std::string &variableName, - const bool readIn) // not yet implemented +// PRIVATE +VariableBase * +ADIOS1Reader::InquireVariableUnknown(const std::string &variableName, + const bool readIn) { - return nullptr; + return nullptr; // not yet implemented } Variable<char> * @@ -224,210 +221,25 @@ void ADIOS1Reader::ScheduleReadCommon(const std::string &name, const Dims &offs, } } -void ADIOS1Reader::ScheduleRead(Variable<char> &variable, char *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<unsigned char> &variable, - unsigned char *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<short> &variable, short *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<unsigned short> &variable, - unsigned short *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<int> &variable, int *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<unsigned int> &variable, - unsigned int *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<long int> &variable, long int *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<unsigned long int> &variable, - unsigned long int *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<long long int> &variable, - long long int *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<unsigned long long int> &variable, - unsigned long long int *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<float> &variable, float *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<double> &variable, double *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<long double> &variable, - long double *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<std::complex<float>> &variable, - std::complex<float> *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<std::complex<double>> &variable, - std::complex<double> *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} -void ADIOS1Reader::ScheduleRead(Variable<std::complex<long double>> &variable, - std::complex<long double> *values) -{ - ScheduleReadCommon(variable.m_Name, variable.m_Start, variable.m_Count, - variable.GetReadFromStep(), variable.GetReadNSteps(), - variable.ReadAsLocalValue(), - variable.ReadAsJoinedArray(), (void *)values); -} +#define declare_type(T) \ + void ADIOS1Reader::DoScheduleRead(Variable<T> &variable, const T *values) \ + { \ + ScheduleReadCommon(variable.m_Name, variable.m_Start, \ + variable.m_Count, variable.m_ReadFromStep, \ + variable.m_ReadNSteps, variable.m_ReadAsLocalValue, \ + variable.m_ReadAsJoined, (void *)values); \ + } \ + \ + void ADIOS1Reader::DoScheduleRead(const std::string &variableName, \ + const T *values) \ + { \ + DoScheduleRead(m_IO.GetVariable<T>(variableName), values); \ + } -void ADIOS1Reader::ScheduleRead(const std::string &variableName, char *values) -{ - ScheduleRead(m_ADIOS.GetVariable<char>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - unsigned char *values) -{ - ScheduleRead(m_ADIOS.GetVariable<unsigned char>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, short *values) -{ - ScheduleRead(m_ADIOS.GetVariable<short>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - unsigned short *values) -{ - ScheduleRead(m_ADIOS.GetVariable<unsigned short>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, int *values) -{ - ScheduleRead(m_ADIOS.GetVariable<int>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - unsigned int *values) -{ - ScheduleRead(m_ADIOS.GetVariable<unsigned int>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - long int *values) -{ - ScheduleRead(m_ADIOS.GetVariable<long int>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - unsigned long int *values) -{ - ScheduleRead(m_ADIOS.GetVariable<unsigned long int>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - long long int *values) -{ - ScheduleRead(m_ADIOS.GetVariable<long long int>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - unsigned long long int *values) -{ - ScheduleRead(m_ADIOS.GetVariable<unsigned long long int>(variableName), - values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, float *values) -{ - ScheduleRead(m_ADIOS.GetVariable<float>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, double *values) -{ - ScheduleRead(m_ADIOS.GetVariable<double>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - long double *values) -{ - ScheduleRead(m_ADIOS.GetVariable<long double>(variableName), values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - std::complex<float> *values) -{ - ScheduleRead(m_ADIOS.GetVariable<std::complex<float>>(variableName), - values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - std::complex<double> *values) -{ - ScheduleRead(m_ADIOS.GetVariable<std::complex<double>>(variableName), - values); -} -void ADIOS1Reader::ScheduleRead(const std::string &variableName, - std::complex<long double> *values) -{ - ScheduleRead(m_ADIOS.GetVariable<std::complex<long double>>(variableName), - values); -} +ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type -void ADIOS1Reader::PerformReads(PerformReadMode mode) +void ADIOS1Reader::PerformReads(ReadMode mode) { adios_perform_reads(m_fh, (int)mode); } @@ -436,7 +248,7 @@ void ADIOS1Reader::Release() { adios_release_step(m_fh); } void ADIOS1Reader::Advance(const float timeout_sec) { - Advance(AdvanceMode::NEXT_AVAILABLE, timeout_sec); + Advance(AdvanceMode::NextAvailable, timeout_sec); } void ADIOS1Reader::Advance(AdvanceMode mode, const float timeout_sec) @@ -447,7 +259,7 @@ void ADIOS1Reader::Advance(AdvanceMode mode, const float timeout_sec) "Advance() on a file which was opened for " "read as File\n"); } - int last = (mode == AdvanceMode::NEXT_AVAILABLE ? 0 : 1); + int last = (mode == AdvanceMode::NextAvailable ? 0 : 1); float *to = const_cast<float *>(&timeout_sec); adios_advance_step(m_fh, last, *to); @@ -457,13 +269,13 @@ void ADIOS1Reader::Advance(AdvanceMode mode, const float timeout_sec) m_AdvanceStatus = AdvanceStatus::OK; break; case err_end_of_stream: - m_AdvanceStatus = AdvanceStatus::END_OF_STREAM; + m_AdvanceStatus = AdvanceStatus::EndOfStream; break; case err_step_notready: - m_AdvanceStatus = AdvanceStatus::STEP_NOT_READY; + m_AdvanceStatus = AdvanceStatus::StepNotReady; break; default: - m_AdvanceStatus = AdvanceStatus::OTHER_ERROR; + m_AdvanceStatus = AdvanceStatus::OtherError; break; } } @@ -485,13 +297,15 @@ void ADIOS1Reader::Close(const int transportIndex) // PRIVATE void ADIOS1Reader::Init() { - if (m_DebugMode == true) + if (m_DebugMode) { - if (m_AccessMode != "r" && m_AccessMode != "read") + if (m_OpenMode != OpenMode::Read) + { throw std::invalid_argument( - "ERROR: ADIOS1Reader doesn't support access mode " + - m_AccessMode + - ", in call to ADIOS Open or ADIOS1Reader constructor\n"); + "ERROR: ADIOS1Reader only supports OpenMode::r (read) access " + "mode " + + m_EndMessage); + } } InitParameters(); InitTransports(); @@ -499,8 +313,8 @@ void ADIOS1Reader::Init() void ADIOS1Reader::InitParameters() { - auto itOpenAsFile = m_Method.m_Parameters.find("OpenAsFile"); - if (itOpenAsFile != m_Method.m_Parameters.end()) + auto itOpenAsFile = m_IO.m_Parameters.find("OpenAsFile"); + if (itOpenAsFile != m_IO.m_Parameters.end()) { m_OpenAsFile = true; } @@ -509,18 +323,7 @@ void ADIOS1Reader::InitParameters() void ADIOS1Reader::InitTransports() { - if (m_DebugMode == true) - { - if (TransportNamesUniqueness() == false) - { - throw std::invalid_argument( - "ERROR: two transports of the same kind (e.g file IO) " - "can't have the same name, modify with name= in Method " - "AddTransport\n"); - } - } - - for (const auto ¶meters : m_Method.m_TransportParameters) + for (const auto ¶meters : m_IO.m_TransportsParameters) { auto itTransport = parameters.find("transport"); if (itTransport->second == "file" || itTransport->second == "File" || @@ -530,11 +333,13 @@ void ADIOS1Reader::InitTransports() } else { - if (m_DebugMode == true) + if (m_DebugMode) + { throw std::invalid_argument( "ERROR: transport " + itTransport->second + " (you mean File?) not supported, in " + m_Name + m_EndMessage); + } } } } diff --git a/source/adios2/engine/adios1/ADIOS1Reader.h b/source/adios2/engine/adios1/ADIOS1Reader.h index a30894d5df688e9b78ff4124278c9115c089a0ed..882b6b6490fdf222e66a9b275dcfb7fe6813b027 100644 --- a/source/adios2/engine/adios1/ADIOS1Reader.h +++ b/source/adios2/engine/adios1/ADIOS1Reader.h @@ -7,7 +7,7 @@ * It requires adios 1.x installed * * Created on: Mar 27, 2017 - * Author: pnb + * Author: Norbert Podhorszki pnorbert@ornl.gov */ #ifndef ADIOS2_ENGINE_ADIOS1_ADIOS1READER_H_ @@ -15,11 +15,10 @@ #include <iostream> //this must go away -#include "adios2/ADIOS.h" #include "adios2/ADIOSConfig.h" -#include "adios2/capsule/heap/STLVector.h" +#include "adios2/core/ADIOS.h" #include "adios2/core/Engine.h" -#include "adios2/core/adiosFunctions.h" +#include "adios2/helper/adiosFunctions.h" // Fake out the include guard from ADIOS1's mpidummy.h to prevent it from // getting included @@ -50,102 +49,12 @@ public: * @param debugMode * @param hostLanguage */ - ADIOS1Reader(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); + ADIOS1Reader(IO &adios, const std::string &name, const OpenMode openMode, + MPI_Comm mpiComm); ~ADIOS1Reader(); - Variable<void> *InquireVariable(const std::string &name, - const bool readIn = true); - Variable<char> *InquireVariableChar(const std::string &name, - const bool readIn = true); - Variable<unsigned char> *InquireVariableUChar(const std::string &name, - const bool readIn = true); - Variable<short> *InquireVariableShort(const std::string &name, - const bool readIn = true); - Variable<unsigned short> *InquireVariableUShort(const std::string &name, - const bool readIn = true); - Variable<int> *InquireVariableInt(const std::string &name, - const bool readIn = true); - Variable<unsigned int> *InquireVariableUInt(const std::string &name, - const bool readIn = true); - Variable<long int> *InquireVariableLInt(const std::string &name, - const bool readIn = true); - Variable<unsigned long int> *InquireVariableULInt(const std::string &name, - const bool readIn = true); - Variable<long long int> *InquireVariableLLInt(const std::string &name, - const bool readIn = true); - Variable<unsigned long long int> * - InquireVariableULLInt(const std::string &name, const bool readIn = true); - Variable<float> *InquireVariableFloat(const std::string &name, - const bool readIn = true); - Variable<double> *InquireVariableDouble(const std::string &name, - const bool readIn = true); - Variable<long double> *InquireVariableLDouble(const std::string &name, - const bool readIn = true); - Variable<std::complex<float>> * - InquireVariableCFloat(const std::string &name, const bool readIn = true); - Variable<std::complex<double>> * - InquireVariableCDouble(const std::string &name, const bool readIn = true); - Variable<std::complex<long double>> * - InquireVariableCLDouble(const std::string &name, const bool readIn = true); - - /** - * Not implemented - * @param name - * @param readIn - * @return - */ - VariableCompound *InquireVariableCompound(const std::string &name, - const bool readIn = true); - - void ScheduleRead(Variable<char> &variable, char *values); - void ScheduleRead(Variable<unsigned char> &variable, unsigned char *values); - void ScheduleRead(Variable<short> &variable, short *values); - void ScheduleRead(Variable<unsigned short> &variable, - unsigned short *values); - void ScheduleRead(Variable<int> &variable, int *values); - void ScheduleRead(Variable<unsigned int> &variable, unsigned int *values); - void ScheduleRead(Variable<long int> &variable, long int *values); - void ScheduleRead(Variable<unsigned long int> &variable, - unsigned long int *values); - void ScheduleRead(Variable<long long int> &variable, long long int *values); - void ScheduleRead(Variable<unsigned long long int> &variable, - unsigned long long int *values); - void ScheduleRead(Variable<float> &variable, float *values); - void ScheduleRead(Variable<double> &variable, double *values); - void ScheduleRead(Variable<long double> &variable, long double *values); - void ScheduleRead(Variable<std::complex<float>> &variable, - std::complex<float> *values); - void ScheduleRead(Variable<std::complex<double>> &variable, - std::complex<double> *values); - void ScheduleRead(Variable<std::complex<long double>> &variable, - std::complex<long double> *values); - - void ScheduleRead(const std::string &variableName, char *values); - void ScheduleRead(const std::string &variableName, unsigned char *values); - void ScheduleRead(const std::string &variableName, short *values); - void ScheduleRead(const std::string &variableName, unsigned short *values); - void ScheduleRead(const std::string &variableName, int *values); - void ScheduleRead(const std::string &variableName, unsigned int *values); - void ScheduleRead(const std::string &variableName, long int *values); - void ScheduleRead(const std::string &variableName, - unsigned long int *values); - void ScheduleRead(const std::string &variableName, long long int *values); - void ScheduleRead(const std::string &variableName, - unsigned long long int *values); - void ScheduleRead(const std::string &variableName, float *values); - void ScheduleRead(const std::string &variableName, double *values); - void ScheduleRead(const std::string &variableName, long double *values); - void ScheduleRead(const std::string &variableName, - std::complex<float> *values); - void ScheduleRead(const std::string &variableName, - std::complex<double> *values); - void ScheduleRead(const std::string &variableName, - std::complex<long double> *values); - - void PerformReads(PerformReadMode mode); + void PerformReads(ReadMode mode); void Release(); void Advance(const float timeout_sec = 0.0); @@ -160,120 +69,59 @@ private: ADIOS_FILE *m_fh = nullptr; ///< ADIOS1 file handler bool m_OpenAsFile = false; - void Init(); ///< called from constructor, gets the selected ADIOS1 - /// transport method from settings - void InitParameters(); - void InitTransports(); + void Init() final; ///< called from constructor, gets the selected ADIOS1 + /// transport method from settings + void InitParameters() final; + void InitTransports() final; - template <class T> - Variable<T> *InquireVariableCommon(const std::string &name, - const bool readIn) - { - // here read variable metadata (dimensions, type, etc.)...then create a - // Variable like below: - // Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" + - // name, ) - // return &variable; //return address if success - ADIOS_VARINFO *vi = adios_inq_var(m_fh, name.c_str()); - adios::Variable<T> *var = nullptr; - if (vi != nullptr) - { - CheckADIOS1TypeCompatibility(name, GetType<T>(), - vi->type); // throws + VariableBase *InquireVariableUnknown(const std::string &name, + const bool readIn) final; + Variable<char> *InquireVariableChar(const std::string &name, + const bool readIn) final; + Variable<unsigned char> *InquireVariableUChar(const std::string &name, + const bool readIn) final; + Variable<short> *InquireVariableShort(const std::string &name, + const bool readIn) final; + Variable<unsigned short> *InquireVariableUShort(const std::string &name, + const bool readIn) final; + Variable<int> *InquireVariableInt(const std::string &name, + const bool readIn) final; + Variable<unsigned int> *InquireVariableUInt(const std::string &name, + const bool readIn) final; + Variable<long int> *InquireVariableLInt(const std::string &name, + const bool readIn) final; + Variable<unsigned long int> *InquireVariableULInt(const std::string &name, + const bool readIn) final; + Variable<long long int> *InquireVariableLLInt(const std::string &name, + const bool readIn) final; + Variable<unsigned long long int> * + InquireVariableULLInt(const std::string &name, const bool readIn) final; - if (vi->ndim > 0) - { - Dims gdims = Uint64ArrayToSizetVector(vi->ndim, vi->dims); + Variable<float> *InquireVariableFloat(const std::string &name, + const bool readIn) final; + Variable<double> *InquireVariableDouble(const std::string &name, + const bool readIn) final; + Variable<long double> *InquireVariableLDouble(const std::string &name, + const bool readIn) final; + Variable<cfloat> *InquireVariableCFloat(const std::string &name, + const bool readIn) final; + Variable<cdouble> *InquireVariableCDouble(const std::string &name, + const bool readIn) final; + Variable<cldouble> *InquireVariableCLDouble(const std::string &name, + const bool readIn) final; + /** Not yet implemented */ + VariableCompound *InquireVariableCompound(const std::string &name, + const bool readIn); - bool joinedread = false; - if (gdims[0] == JoinedDim) - { - /* Joined Array */ - adios_inq_var_blockinfo(m_fh, vi); - size_t joined_size = 0; - for (int i = 0; i < *vi->nblocks; i++) - { - joined_size += vi->blockinfo[i].count[0]; - } - gdims[0] = joined_size; - joinedread = true; - } + template <class T> + Variable<T> *InquireVariableCommon(const std::string &name, + const bool readIn); - if (!vi->global) - { - /* Local array */ - for (int j = 0; j < vi->ndim; ++j) - { - gdims[j] = IrregularDim; - } - } - else - { - /* Check if dimensions change in time */ - for (int step = 1; step < vi->nsteps; ++step) - { - Dims dims = - gdims; // GetGlobalDimsAtStep(vi, step, joinedread); - for (int j = 0; j < vi->ndim; ++j) - { - if (dims[j] != gdims[j]) - gdims[j] = IrregularDim; - } - } - } - var = &m_ADIOS.DefineArray<T>(name, gdims); - if (joinedread) - var->SetReadAsJoinedArray(); - } - else /* Scalars */ - { - /* scalar variable but global value or local value*/ - std::string aname = name + "/ReadAsArray"; - bool isLocalValue = false; - for (int i = 0; i < vi->nattrs; ++i) - { - if (!strcmp(m_fh->attr_namelist[vi->attr_ids[i]], - aname.c_str())) - { - isLocalValue = true; - } - } - if (isLocalValue) - { - /* Local Value */ - bool changingDims = false; - for (int step = 1; step < vi->nsteps; ++step) - { - if (vi->nblocks[step] != vi->nblocks[0]) - changingDims = true; - } - if (changingDims) - { - var = &m_ADIOS.DefineVariable<T>(name, {IrregularDim}); - } - else - { - var = &m_ADIOS.DefineVariable<T>( - name, {(unsigned int)vi->nblocks[0]}); - } - var->SetReadAsLocalValue(); - } - else - { - /* Global value: store only one value */ - var = &m_ADIOS.DefineVariable<T>(name); - if (var) - { - var->m_Data = std::vector<T>(1); - var->m_Data[0] = *static_cast<T *>(vi->value); - } - } - } - var->SetNSteps(vi->nsteps); - adios_free_varinfo(vi); - } - return var; - } +#define declare_type(T) \ + void DoScheduleRead(Variable<T> &variable, const T *values) final; \ + void DoScheduleRead(const std::string &variableName, const T *values) final; + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type void ScheduleReadCommon(const std::string &name, const Dims &offs, const Dims &ldims, const int fromStep, @@ -293,4 +141,6 @@ private: } // end namespace adios +#include "ADIOS1Reader.inl" + #endif /* ADIOS2_ENGINE_ADIOS1_ADIOS1READER_H_ */ diff --git a/source/adios2/engine/adios1/ADIOS1Reader.inl b/source/adios2/engine/adios1/ADIOS1Reader.inl new file mode 100644 index 0000000000000000000000000000000000000000..d6b3742faf314fadc5c42e0a23d8de7a84da74bf --- /dev/null +++ b/source/adios2/engine/adios1/ADIOS1Reader.inl @@ -0,0 +1,133 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * ADIOS1Reader.inl + * + * Created on: Jun 2, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + */ + +#ifndef ADIOS2_ENGINE_ADIOS1_ADIOS1READER_INL_ +#define ADIOS2_ENGINE_ADIOS1_ADIOS1READER_INL_ +#ifndef ADIOS2_ENGINE_ADIOS1_ADIOS1READER_H_ +#error "Inline file should only be included from it's header, never on it's own" +#endif + +namespace adios +{ + +template <class T> +Variable<T> *ADIOS1Reader::InquireVariableCommon(const std::string &name, + const bool readIn) +{ + // here read variable metadata (dimensions, type, etc.)...then create a + // Variable like below: + // Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" + + // name, ) + // return &variable; //return address if success + ADIOS_VARINFO *vi = adios_inq_var(m_fh, name.c_str()); + adios::Variable<T> *var = nullptr; + if (vi != nullptr) + { + CheckADIOS1TypeCompatibility(name, GetType<T>(), vi->type); // throws + + if (vi->ndim > 0) + { + Dims gdims = Uint64ArrayToSizetVector(vi->ndim, vi->dims); + + bool joinedread = false; + if (gdims[0] == JoinedDim) + { + /* Joined Array */ + adios_inq_var_blockinfo(m_fh, vi); + size_t joined_size = 0; + for (int i = 0; i < *vi->nblocks; i++) + { + joined_size += vi->blockinfo[i].count[0]; + } + gdims[0] = joined_size; + joinedread = true; + } + + if (!vi->global) + { + /* Local array */ + for (int j = 0; j < vi->ndim; ++j) + { + gdims[j] = IrregularDim; + } + } + else + { + /* Check if dimensions change in time */ + for (int step = 1; step < vi->nsteps; ++step) + { + Dims dims = + gdims; // GetGlobalDimsAtStep(vi, step, joinedread); + for (int j = 0; j < vi->ndim; ++j) + { + if (dims[j] != gdims[j]) + gdims[j] = IrregularDim; + } + } + } + var = &m_IO.DefineVariable<T>(name, gdims); + if (joinedread) + { + var->m_ReadAsJoined = true; + } + } + else /* Scalars */ + { + /* scalar variable but global value or local value*/ + std::string aname = name + "/ReadAsArray"; + bool isLocalValue = false; + for (int i = 0; i < vi->nattrs; ++i) + { + if (!strcmp(m_fh->attr_namelist[vi->attr_ids[i]], + aname.c_str())) + { + isLocalValue = true; + } + } + if (isLocalValue) + { + /* Local Value */ + bool changingDims = false; + for (int step = 1; step < vi->nsteps; ++step) + { + if (vi->nblocks[step] != vi->nblocks[0]) + changingDims = true; + } + if (changingDims) + { + var = &m_IO.DefineVariable<T>(name, {IrregularDim}); + } + else + { + var = &m_IO.DefineVariable<T>( + name, {(unsigned int)vi->nblocks[0]}); + } + var->m_ReadAsLocalValue = true; + } + else + { + /* Global value: store only one value */ + var = &m_IO.DefineVariable<T>(name); + if (var) + { + var->m_Data = std::vector<T>(1); + var->m_Data[0] = *static_cast<T *>(vi->value); + } + } + } + var->m_AvailableSteps = vi->nsteps; + adios_free_varinfo(vi); + } + return var; +} + +} // end namespace adios + +#endif /* ADIOS2_ENGINE_ADIOS1_ADIOS1READER_INL_ */ diff --git a/source/adios2/engine/adios1/ADIOS1Writer.cpp b/source/adios2/engine/adios1/ADIOS1Writer.cpp index 71a6d5485b4e333b391717d92025239f04c8892d..e6290d9ee9a0332d0008b803db3111ca666d7195 100644 --- a/source/adios2/engine/adios1/ADIOS1Writer.cpp +++ b/source/adios2/engine/adios1/ADIOS1Writer.cpp @@ -7,15 +7,12 @@ * It requires adios 1.x installed * * Created on: Mar 27, 2017 - * Author: pnb + * Author: Norbert Podhorszki pnorbert@ornl.gov */ #include "ADIOS1Writer.h" -#include "adios2/core/adiosFunctions.h" - -extern int adios_verbose_level; -extern int adios_errno; +#include "adios2/helper/adiosFunctions.h" // Enable compatibility with ADIOS 1.10 adios_declare_group signature #if !ADIOS_VERSION_GE(1, 11, 0) @@ -25,469 +22,45 @@ extern int adios_errno; namespace adios { -ADIOS1Writer::ADIOS1Writer(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method) -: Engine(adios, "ADIOS1Writer", name, accessMode, mpiComm, method, - " ADIOS1Writer constructor (or call to ADIOS Open).\n"), - m_groupname{method.m_Name.c_str()}, m_filename{name.c_str()}, m_comm{mpiComm} +ADIOS1Writer::ADIOS1Writer(IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: Engine("ADIOS1Writer", io, name, openMode, mpiComm), + m_ADIOS1(io.m_Name, name, mpiComm, io.m_DebugMode) { + m_EndMessage = " in call to ADIOS1Writer " + m_Name + " Open\n"; Init(); - adios_open(&m_adios_file, m_groupname, m_filename, accessMode.c_str(), - m_comm); - if (adios_errno == err_no_error) - { - m_IsFileOpen = true; - } -} - -ADIOS1Writer::~ADIOS1Writer() -{ - if (m_IsFileOpen) - { - adios_close(m_adios_file); - m_IsFileOpen = false; - } } void ADIOS1Writer::Init() { - if (!m_initialized) - { - adios_init_noxml(m_comm); - m_initialized = true; - } - adios_declare_group(&m_adios_group, m_groupname, "", adios_stat_default); - InitParameters(); InitTransports(); + m_ADIOS1.Open(m_OpenMode); } -bool ADIOS1Writer::ReOpenAsNeeded() -{ - if (!m_IsFileOpen) - { - adios_open(&m_adios_file, m_groupname, m_filename, "a", m_comm); - if (adios_errno == err_no_error) - { - m_IsFileOpen = true; - adios_delete_vardefs(m_adios_group); - } - } - return m_IsFileOpen; -} - -void ADIOS1Writer::DefineVariable(std::string name, VarClass varclass, - enum ADIOS_DATATYPES vartype, - std::string ldims, std::string gdims, - std::string offs) -{ - switch (varclass) - { - case VarClass::GlobalValue: - adios_define_var(m_adios_group, name.c_str(), "", vartype, "", "", ""); - break; - case VarClass::LocalValue: - adios_define_var(m_adios_group, name.c_str(), "", vartype, "", "", ""); - adios_define_attribute(m_adios_group, "ReadAsArray", name.c_str(), - adios_byte, "1", nullptr); - break; - case VarClass::GlobalArray: - case VarClass::LocalArray: - case VarClass::JoinedArray: - adios_define_var(m_adios_group, name.c_str(), "", vartype, - ldims.c_str(), gdims.c_str(), offs.c_str()); - break; - } -} - -void ADIOS1Writer::WriteVariable(std::string name, VarClass varclass, - enum ADIOS_DATATYPES vartype, - std::string ldims, std::string gdims, - std::string offs, const void *values) -{ - if (ReOpenAsNeeded()) - { - DefineVariable(name, varclass, vartype, ldims, gdims, offs); - adios_write(m_adios_file, name.c_str(), values); - } -} - -static std::string DimsToCSV_LocalAware(const std::vector<std::size_t> &dims) -{ - std::string dimsCSV; - bool localVar = false; - - for (const auto dim : dims) - { - dimsCSV += std::to_string(dim) + ","; - if (dim == JoinedDim || dim == IrregularDim) - localVar = true; - } - - if (dimsCSV.empty() == false) - { - dimsCSV.pop_back(); - } - - /*if (localVar) - { - dimsCSV.clear(); - }*/ - - return dimsCSV; -} - -void ADIOS1Writer::Write(Variable<char> &variable, const char *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_byte, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<unsigned char> &variable, - const unsigned char *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_unsigned_byte, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<short> &variable, const short *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_short, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<unsigned short> &variable, - const unsigned short *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_unsigned_short, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<int> &variable, const int *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_integer, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<unsigned int> &variable, - const unsigned int *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_unsigned_integer, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<long int> &variable, const long int *values) -{ - enum ADIOS_DATATYPES type = - adios_integer; // long int is usually 4 bytes which is adios_integer - if (sizeof(long int) == 8) - { - type = adios_long; +#define declare_type(T) \ + void ADIOS1Writer::DoWrite(Variable<T> &variable, const T *values) \ + { \ + m_ADIOS1.WriteVariable(variable.m_Name, variable.m_ShapeID, \ + variable.m_Count, variable.m_Shape, \ + variable.m_Start, values); \ } - WriteVariable(variable.m_Name, variable.m_VarClass, type, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<unsigned long int> &variable, - const unsigned long int *values) -{ - enum ADIOS_DATATYPES type = - adios_unsigned_integer; // long int is usually 4 bytes - if (sizeof(long int) == 8) - { - type = adios_unsigned_long; - } - WriteVariable(variable.m_Name, variable.m_VarClass, type, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<long long int> &variable, - const long long int *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_long, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<unsigned long long int> &variable, - const unsigned long long int *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_unsigned_long, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<float> &variable, const float *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_real, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<double> &variable, const double *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_double, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<long double> &variable, - const long double *values) -{ - /* TODO: This is faulty: adios_long_double expects 16 bytes per elements, - * but - * long double is compiler dependent */ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_long_double, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<std::complex<float>> &variable, - const std::complex<float> *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_complex, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values) -{ - WriteVariable(variable.m_Name, variable.m_VarClass, adios_double_complex, - DimsToCSV_LocalAware(variable.m_Count), - DimsToCSV_LocalAware(variable.m_Shape), - DimsToCSV_LocalAware(variable.m_Start), values); -} - -void ADIOS1Writer::Write(Variable<std::complex<long double>> &variable, - const std::complex<long double> *values) -{ - throw std::invalid_argument( - "ERROR: Adios 1.x does not support complex<long " - "double> type, so it cannot write variable " + - variable.m_Name + "\n"); -} - -void ADIOS1Writer::Write(VariableCompound &variable, const void *values) -{ - throw std::invalid_argument("ERROR: Adios 1.x does not support compound " - "types, so it cannot write variable " + - variable.m_Name + "\n"); -} - -// String version -void ADIOS1Writer::Write(const std::string &variableName, const char *values) -{ - Write(m_ADIOS.GetVariable<char>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const unsigned char *values) -{ - Write(m_ADIOS.GetVariable<unsigned char>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, const short *values) -{ - Write(m_ADIOS.GetVariable<short>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const unsigned short *values) -{ - Write(m_ADIOS.GetVariable<unsigned short>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, const int *values) -{ - Write(m_ADIOS.GetVariable<int>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const unsigned int *values) -{ - Write(m_ADIOS.GetVariable<unsigned int>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const long int *values) -{ - Write(m_ADIOS.GetVariable<long int>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const unsigned long int *values) -{ - Write(m_ADIOS.GetVariable<unsigned long int>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const long long int *values) -{ - Write(m_ADIOS.GetVariable<long long int>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const unsigned long long int *values) -{ - Write(m_ADIOS.GetVariable<unsigned long long int>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, const float *values) -{ - Write(m_ADIOS.GetVariable<float>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, const double *values) -{ - Write(m_ADIOS.GetVariable<double>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const long double *values) -{ - Write(m_ADIOS.GetVariable<long double>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const std::complex<float> *values) -{ - Write(m_ADIOS.GetVariable<std::complex<float>>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const std::complex<double> *values) -{ - Write(m_ADIOS.GetVariable<std::complex<double>>(variableName), values); -} - -void ADIOS1Writer::Write(const std::string &variableName, - const std::complex<long double> *values) -{ - Write(m_ADIOS.GetVariable<std::complex<long double>>(variableName), values); -} +ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type -void ADIOS1Writer::Write(const std::string &variableName, - const void *values) // Compound type -{ - throw std::invalid_argument("ERROR: Adios 1.x does not support compound " - "types, so it cannot write variable " + - variableName + "\n"); -} +void ADIOS1Writer::Advance(const float /*timeout_sec*/) { m_ADIOS1.Advance(); } -void ADIOS1Writer::Advance(const float /*timeout_sec*/) -{ - if (m_IsFileOpen) - { - adios_close(m_adios_file); - m_IsFileOpen = false; - } -} - -void ADIOS1Writer::Close(const int transportIndex) -{ - if (m_IsFileOpen) - { - adios_close(m_adios_file); - m_IsFileOpen = false; - } -} +void ADIOS1Writer::Close(const int transportIndex) { m_ADIOS1.Close(); } // PRIVATE FUNCTIONS void ADIOS1Writer::InitParameters() { - auto itMaxBufferSize = m_Method.m_Parameters.find("max_size_MB"); - if (itMaxBufferSize != m_Method.m_Parameters.end()) - { - adios_set_max_buffer_size(std::stoul(itMaxBufferSize->second)); - } - - auto itVerbosity = m_Method.m_Parameters.find("verbose"); - if (itVerbosity != m_Method.m_Parameters.end()) - { - int verbosity = std::stoi(itVerbosity->second); - if (m_DebugMode == true) - { - if (verbosity < 0 || verbosity > 5) - throw std::invalid_argument( - "ERROR: Method verbose argument must be an " - "integer in the range [0,5], in call to " - "Open or Engine constructor\n"); - } - adios_verbose_level = verbosity; - } + m_ADIOS1.InitParameters(m_IO.m_Parameters); } void ADIOS1Writer::InitTransports() { - if (m_DebugMode == true) - { - if (TransportNamesUniqueness() == false) - { - throw std::invalid_argument( - "ERROR: two transports of the same kind (e.g file IO) " - "can't have the same name, modify with name= in Method " - "AddTransport\n"); - } - } - - for (const auto ¶meters : m_Method.m_TransportParameters) - { - auto itTransport = parameters.find("transport"); - - if (itTransport->second == "file" || itTransport->second == "File") - { - auto itLibrary = parameters.find("library"); - if (itLibrary == parameters.end() || - itLibrary->second == "POSIX") // use default POSIX - { - adios_select_method(m_adios_group, "POSIX", "", ""); - } - else if (itLibrary->second == "MPI_File" || - itLibrary->second == "MPI-IO") - { - adios_select_method(m_adios_group, "MPI", "", ""); - } - else - { - if (m_DebugMode == true) - throw std::invalid_argument( - "ERROR: file transport library " + itLibrary->second + - " not supported, in " + m_Name + m_EndMessage); - } - } - else - { - if (m_DebugMode == true) - throw std::invalid_argument( - "ERROR: transport " + itTransport->second + - " (you mean File?) not supported, in " + m_Name + - m_EndMessage); - } - } + m_ADIOS1.InitTransports(m_IO.m_TransportsParameters); } } // end namespace adios diff --git a/source/adios2/engine/adios1/ADIOS1Writer.h b/source/adios2/engine/adios1/ADIOS1Writer.h index 8a932da8e378788f789feab6242a255d47789152..6f8e9704e6ff7fd98759dbd3699c243da78c092e 100644 --- a/source/adios2/engine/adios1/ADIOS1Writer.h +++ b/source/adios2/engine/adios1/ADIOS1Writer.h @@ -4,10 +4,10 @@ * * ADIOS1Writer.h * Class to write files using old adios 1.x library. - * It requires adios 1.x installed + * It requires at least adios 1.12.0 installed * * Created on: Mar 27, 2017 - * Author: pnb + * Author: Norbert Podhorszki pnorbert@ornl.gov */ #ifndef ADIOS2_ENGINE_ADIOS1_ADIOS1WRITER_H_ @@ -15,18 +15,7 @@ #include "adios2/ADIOSConfig.h" #include "adios2/core/Engine.h" - -// Fake out the include guard from ADIOS1's mpidummy.h to prevent it from -// getting included -#ifdef _NOMPI -#define __MPI_DUMMY_H__ -#define MPI_Comm int -#endif -#include <adios.h> -#ifdef _NOMPI -#undef MPI_Comm -#undef __MPI_DUMMY_H__ -#endif +#include "adios2/toolkit/interop/adios1/ADIOS1Common.h" namespace adios { @@ -43,60 +32,12 @@ public: * @param method * @param debugMode */ - ADIOS1Writer(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); - - ~ADIOS1Writer(); + ADIOS1Writer(IO &adios, const std::string &name, const OpenMode openMode, + MPI_Comm mpiComm); - 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(Variable<std::complex<float>> &variable, - const std::complex<float> *values); - void Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values); - void Write(Variable<std::complex<long double>> &variable, - const std::complex<long double> *values); - void Write(VariableCompound &variable, const void *values); + ~ADIOS1Writer() = default; - 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 Write(const std::string &variableName, - const std::complex<float> *values); - void Write(const std::string &variableName, - const std::complex<double> *values); - void Write(const std::string &variableName, - const std::complex<long double> *values); - void Write(const std::string &variableName, const void *values); - - void Advance(const float timeout_sec = 0.); + void Advance(const float timeoutSeconds = 0.) final; /** * Closes a single transport or all transports @@ -106,35 +47,19 @@ public: * latter * is bounds-checked. */ - void Close(const int transportIndex = -1); + void Close(const int transportIndex = -1) final; private: - const char *m_groupname; ///< ADIOS1 group name created from the method's - /// name. Must be a unique group name. - const char *m_filename; ///< Save file name from constructor for Advance() - /// when we re-open in ADIOS1 - MPI_Comm m_comm; ///< Save MPI communicator from constructor for Advance() - /// when we re-open in ADIOS1 - - bool m_initialized = false; ///< set to true after calling adios_init() - int64_t m_adios_file = 0; ///< ADIOS1 file handler returned by adios_open() - int64_t m_adios_group = 0; ///< ADIOS1 group pointer that holds the ADIOS1 - /// variable definitions - bool m_IsFileOpen = false; + interop::ADIOS1Common m_ADIOS1; - void Init(); - // these are unused yet, keeping here to see if we need them - void InitParameters(); - void InitTransports(); - void InitProcessGroup(); + void Init() final; + void InitParameters() final; + void InitTransports() final; - bool ReOpenAsNeeded(); // return true if file is open or reopened - void DefineVariable(std::string name, VarClass varclass, - enum ADIOS_DATATYPES vartype, std::string ldims, - std::string gdims, std::string offs); - void WriteVariable(std::string name, VarClass varclass, - enum ADIOS_DATATYPES vartype, std::string ldims, - std::string gdims, std::string offs, const void *values); +#define declare_type(T) \ + void DoWrite(Variable<T> &variable, const T *values) final; + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type }; } // end namespace adios diff --git a/source/adios2/engine/bp/BPFileReader.cpp b/source/adios2/engine/bp/BPFileReader.cpp index d74d94adac0ab80f5b2a5cef3b0cfb56803b6b7a..47daed9e45b8cfc89b54e22fd6e8ec673b7b0c96 100644 --- a/source/adios2/engine/bp/BPFileReader.cpp +++ b/source/adios2/engine/bp/BPFileReader.cpp @@ -5,32 +5,45 @@ * BPFileReader.cpp * * Created on: Feb 27, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "BPFileReader.h" -#include "adios2/core/Support.h" -#include "adios2/core/adiosFunctions.h" // CSVToVector -#include "adios2/transport/file/FStream.h" // uses C++ fstream -#include "adios2/transport/file/FileDescriptor.h" // uses POSIX -#include "adios2/transport/file/FilePointer.h" // uses C FILE* +#include "adios2/helper/adiosFunctions.h" // CSVToVector namespace adios { -BPFileReader::BPFileReader(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method) -: Engine(adios, "BPFileReader", name, accessMode, mpiComm, method, - " BPFileReader constructor (or call to ADIOS Open).\n"), - m_Heap(m_DebugMode) +BPFileReader::BPFileReader(IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: Engine("BPFileReader", io, name, openMode, mpiComm) { Init(); } -Variable<void> *BPFileReader::InquireVariable(const std::string & /*name*/, - const bool /*readIn*/) +void BPFileReader::Close(const int /*transportIndex*/) {} + +// PRIVATE +void BPFileReader::Init() +{ + if (m_DebugMode) + { + if (m_OpenMode != OpenMode::Read) + { + throw std::invalid_argument( + "ERROR: BPFileReader only supports OpenMode::r from" + m_Name + + " " + m_EndMessage); + } + } + + InitTransports(); +} + +void BPFileReader::InitTransports() {} + +VariableBase *BPFileReader::InquireVariableUnknown(const std::string & /*name*/, + const bool /*readIn*/) { // not yet implemented return nullptr; @@ -140,92 +153,4 @@ BPFileReader::InquireVariableCompound(const std::string & /*name*/, return nullptr; } -void BPFileReader::Close(const int /*transportIndex*/) {} - -// PRIVATE -void BPFileReader::Init() -{ - if (m_DebugMode == true) - { - if (m_AccessMode != "r" && m_AccessMode != "read") - { - throw std::invalid_argument( - "ERROR: BPFileReader doesn't support access mode " + - m_AccessMode + - ", in call to ADIOS Open or BPFileReader constructor\n"); - } - } - - InitTransports(); -} - -void BPFileReader::InitTransports() // maybe move this? -{ - if (m_DebugMode == true) - { - if (TransportNamesUniqueness() == false) - { - throw std::invalid_argument( - "ERROR: two transports of the same kind (e.g file IO) " - "can't have the same name, modify with name= in Method " - "AddTransport\n"); - } - } - - for (const auto ¶meters : m_Method.m_TransportParameters) - { - auto itTransport = parameters.find("transport"); - if (itTransport->second == "file" || itTransport->second == "File") - { - auto itLibrary = parameters.find("library"); - if (itLibrary == parameters.end() || - itLibrary->second == "POSIX") // use default POSIX - { - auto file = std::make_shared<transport::FileDescriptor>( - m_MPIComm, m_DebugMode); - // m_BP1Reader.OpenRankFiles( m_Name, m_AccessMode, *file ); - m_Transports.push_back(std::move(file)); - } - else if (itLibrary->second == "FILE*" || - itLibrary->second == "stdio.h") - { - auto file = std::make_shared<transport::FilePointer>( - m_MPIComm, m_DebugMode); - // m_BP1Reader.OpenRankFiles( m_Name, m_AccessMode, *file ); - m_Transports.push_back(std::move(file)); - } - else if (itLibrary->second == "fstream" || - itLibrary->second == "std::fstream") - { - auto file = std::make_shared<transport::FStream>(m_MPIComm, - m_DebugMode); - // m_BP1Reader.OpenRankFiles( m_Name, m_AccessMode, *file ); - m_Transports.push_back(std::move(file)); - } - else if (itLibrary->second == "MPI-IO") - { - } - else - { - if (m_DebugMode == true) - { - throw std::invalid_argument( - "ERROR: file transport library " + itLibrary->second + - " not supported, in " + m_Name + m_EndMessage); - } - } - } - else - { - if (m_DebugMode == true) - { - throw std::invalid_argument( - "ERROR: transport " + itTransport->second + - " (you mean File?) not supported, in " + m_Name + - m_EndMessage); - } - } - } -} - } // end namespace adios diff --git a/source/adios2/engine/bp/BPFileReader.h b/source/adios2/engine/bp/BPFileReader.h index 6f36b4f336810ec97aff3ff6b437c0a221a7092c..5302d485425532ad62949385ff14ab96cfc35a09 100644 --- a/source/adios2/engine/bp/BPFileReader.h +++ b/source/adios2/engine/bp/BPFileReader.h @@ -2,19 +2,16 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * BPReader.h + * BPFileReader.h * * Created on: Feb 27, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_ENGINE_BP_BPFILEREADER_H_ #define ADIOS2_ENGINE_BP_BPFILEREADER_H_ -#include <iostream> //this must go away - #include "adios2/ADIOSConfig.h" -#include "adios2/capsule/heap/STLVector.h" #include "adios2/core/Engine.h" namespace adios @@ -25,24 +22,23 @@ class BPFileReader : 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 - * @param mpiComm - * @param method - * @param debugMode - * @param hostLanguage + * */ - BPFileReader(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); + BPFileReader(IO &io, const std::string &name, const OpenMode openMode, + MPI_Comm mpiComm); virtual ~BPFileReader() = default; - Variable<void> *InquireVariable(const std::string &variableName, - const bool readIn = true); + void Close(const int transportIndex = -1); + +private: + void Init(); ///< calls InitCapsules and InitTransports based on Method, + /// called from constructor + + void InitTransports(); ///< from Transports + + VariableBase *InquireVariableUnknown(const std::string &variableName, + const bool readIn = true); Variable<char> *InquireVariableChar(const std::string &variableName, const bool readIn = true); @@ -109,24 +105,6 @@ public: VariableCompound *InquireVariableCompound(const std::string &variableName, const bool readIn = true); - void Close(const int transportIndex = -1); - -private: - capsule::STLVector - m_Heap; ///< heap capsule, contains data and metadata buffers - // 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 InitTransports(); ///< from Transports - - std::string - GetMdtmParameter(const std::string parameter, - const std::map<std::string, std::string> &mdtmParameters); - template <class T> Variable<T> *InquireVariableCommon(const std::string &name, const bool readIn) diff --git a/source/adios2/engine/bp/BPFileWriter.cpp b/source/adios2/engine/bp/BPFileWriter.cpp index 314519912b4aa3f961046415dad7eae99b43534d..b397681b336dc7a81790bd5b6b9758b2b3c3605c 100644 --- a/source/adios2/engine/bp/BPFileWriter.cpp +++ b/source/adios2/engine/bp/BPFileWriter.cpp @@ -5,28 +5,30 @@ * BPFileWriter.cpp * * Created on: Dec 19, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "BPFileWriter.h" +#include "BPFileWriter.tcc" -#include <utility> +#include <iostream> -#include "adios2/ADIOS.h" -#include "adios2/transport/file/FStream.h" -#include "adios2/transport/file/FileDescriptor.h" -#include "adios2/transport/file/FilePointer.h" +#include "adios2/ADIOSMPI.h" +#include "adios2/core/IO.h" +#include "adios2/helper/adiosFunctions.h" //CheckIndexRange +#include "adios2/toolkit/transport/file/FileDescriptor.h" +#include "adios2/toolkit/transport/file/FilePointer.h" +#include "adios2/toolkit/transport/file/FileStream.h" namespace adios { -BPFileWriter::BPFileWriter(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method) -: Engine(adios, "BPFileWriter", name, accessMode, mpiComm, method, - " BPFileWriter constructor (or call to ADIOS Open).\n"), - m_BP1Writer(mpiComm, m_DebugMode) +BPFileWriter::BPFileWriter(IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: Engine("BPFileWriter", io, name, openMode, mpiComm), + m_BP1Writer(mpiComm, m_DebugMode), m_TransportsManager(mpiComm, m_DebugMode) { + m_EndMessage = " in call to IO Open BPFileWriter " + m_Name + "\n"; Init(); } @@ -36,244 +38,56 @@ void BPFileWriter::Init() { InitParameters(); InitTransports(); - InitProcessGroup(); + InitBPBuffer(); } -void BPFileWriter::Write(Variable<char> &variable, const char *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<unsigned char> &variable, - const unsigned char *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<short> &variable, const short *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<unsigned short> &variable, - const unsigned short *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<int> &variable, const int *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<unsigned int> &variable, - const unsigned int *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<long int> &variable, const long int *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<unsigned long int> &variable, - const unsigned long int *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<long long int> &variable, - const long long int *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<unsigned long long int> &variable, - const unsigned long long int *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<float> &variable, const float *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<double> &variable, const double *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<long double> &variable, - const long double *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<std::complex<float>> &variable, - const std::complex<float> *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(Variable<std::complex<long double>> &variable, - const std::complex<long double> *values) -{ - WriteVariableCommon(variable, values); -} - -void BPFileWriter::Write(VariableCompound & /*variable*/, - const void * /*values*/) -{ -} - -// String version -void BPFileWriter::Write(const std::string &variableName, const char *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<char>(variableName), values); -} - -void BPFileWriter::Write(const std::string &variableName, - const unsigned char *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<unsigned char>(variableName), - values); -} - -void BPFileWriter::Write(const std::string &variableName, const short *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<short>(variableName), values); -} - -void BPFileWriter::Write(const std::string &variableName, - const unsigned short *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<unsigned short>(variableName), - values); -} - -void BPFileWriter::Write(const std::string &variableName, const int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<int>(variableName), values); -} - -void BPFileWriter::Write(const std::string &variableName, - const unsigned int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<unsigned int>(variableName), - values); -} - -void BPFileWriter::Write(const std::string &variableName, - const long int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<long int>(variableName), values); -} - -void BPFileWriter::Write(const std::string &variableName, - const unsigned long int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<unsigned long int>(variableName), - values); -} - -void BPFileWriter::Write(const std::string &variableName, - const long long int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<long long int>(variableName), - values); -} - -void BPFileWriter::Write(const std::string &variableName, - const unsigned long long int *values) -{ - WriteVariableCommon( - m_ADIOS.GetVariable<unsigned long long int>(variableName), values); -} - -void BPFileWriter::Write(const std::string &variableName, const float *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<float>(variableName), values); -} - -void BPFileWriter::Write(const std::string &variableName, const double *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<double>(variableName), values); -} - -void BPFileWriter::Write(const std::string &variableName, - const long double *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<long double>(variableName), values); -} - -void BPFileWriter::Write(const std::string &variableName, - const std::complex<float> *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<std::complex<float>>(variableName), - values); -} - -void BPFileWriter::Write(const std::string &variableName, - const std::complex<double> *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<std::complex<double>>(variableName), - values); -} - -void BPFileWriter::Write(const std::string &variableName, - const std::complex<long double> *values) -{ - WriteVariableCommon( - m_ADIOS.GetVariable<std::complex<long double>>(variableName), values); -} +#define declare_type(T) \ + void BPFileWriter::DoWrite(Variable<T> &variable, const T *values) \ + { \ + DoWriteCommon(variable, values); \ + } +ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type -void BPFileWriter::Write(const std::string & /*variableName*/, - const void * /*values*/) // Compound type +void BPFileWriter::Advance(const float /*timeout_sec*/) { + m_BP1Writer.Advance(); } -void BPFileWriter::Advance(float /*timeout_sec*/) { m_BP1Writer.Advance(); } - void BPFileWriter::Close(const int transportIndex) { - CheckTransportIndex(transportIndex); - if (transportIndex == -1) + if (m_DebugMode) { - for (auto &transport : m_Transports) + if (!m_TransportsManager.CheckTransportIndex(transportIndex)) { - // false: not using aggregation for now - m_BP1Writer.Close(*transport, m_IsFirstClose, false); + auto transportsSize = m_TransportsManager.m_Transports.size(); + throw std::invalid_argument( + "ERROR: transport index " + std::to_string(transportIndex) + + " outside range, -1 (default) to " + + std::to_string(transportsSize - 1) + ", in call to Close\n"); } } - else - { - // false: not using aggregation for now - m_BP1Writer.Close(*m_Transports[transportIndex], m_IsFirstClose, false); - } - if (m_BP1Writer.m_MetadataSet.Log.IsActive == true) + // close bp buffer by flattening data and metadata + m_BP1Writer.Close(); + // send data to corresponding transport + m_TransportsManager.CloseFiles(transportIndex, + m_BP1Writer.m_HeapBuffer.m_Data.data(), + m_BP1Writer.m_HeapBuffer.m_DataPosition); + + if (m_BP1Writer.m_Profiler.IsActive) { - bool allClose = true; - for (auto &transport : m_Transports) + // aggregate and write profiling.log + if (m_TransportsManager.AllTransportsClosed()) { - if (transport->m_IsOpen == true) - { - allClose = false; - break; - } - } + auto transportTypes = m_TransportsManager.GetTransportsTypes(); + auto transportProfilers = + m_TransportsManager.GetTransportsProfilers(); - if (allClose == true) // aggregate and write profiling.log - { - m_BP1Writer.WriteProfilingLogFile(m_Name, m_RankMPI, m_Transports); + const std::string log(m_BP1Writer.GetRankProfilingLog( + transportTypes, transportProfilers)); + // TODO profiling.log + // m_BP1Writer.m_BP1Aggregator.WriteProfilingLog( ) } } } @@ -281,277 +95,41 @@ void BPFileWriter::Close(const int transportIndex) // PRIVATE FUNCTIONS void BPFileWriter::InitParameters() { - auto itProfile = m_Method.m_Parameters.find("profile_units"); - if (itProfile != m_Method.m_Parameters.end()) - { - auto &log = m_BP1Writer.m_MetadataSet.Log; - - if (itProfile->second == "mus" || itProfile->second == "microseconds") - { - log.Timers.emplace_back("buffering", Support::Resolutions::mus); - } - else if (itProfile->second == "ms" || - itProfile->second == "milliseconds") - { - log.Timers.emplace_back("buffering", Support::Resolutions::ms); - } - else if (itProfile->second == "s" || itProfile->second == "seconds") - { - log.Timers.emplace_back("buffering", Support::Resolutions::s); - } - else if (itProfile->second == "min" || itProfile->second == "minutes") - { - log.Timers.emplace_back("buffering", Support::Resolutions::m); - } - else if (itProfile->second == "h" || itProfile->second == "hours") - { - log.Timers.emplace_back("buffering", Support::Resolutions::h); - } - else - { - if (m_DebugMode == true) - { - throw std::invalid_argument( - "ERROR: Method profile_buffering_units " - "argument must be mus, ms, s, min or h, in " - "call to Open or Engine constructor\n"); - } - } - - log.IsActive = true; - } - - auto itGrowthFactor = m_Method.m_Parameters.find("buffer_growth"); - if (itGrowthFactor != m_Method.m_Parameters.end()) - { - const float growthFactor = std::stof(itGrowthFactor->second); - if (m_DebugMode == true) - { - if (growthFactor == 1.f) - { - throw std::invalid_argument("ERROR: buffer_growth argument " - "can't be less of equal than 1, " - "in " + - m_EndMessage + "\n"); - } - } - - m_BP1Writer.m_GrowthFactor = growthFactor; - } - - auto itMaxBufferSize = m_Method.m_Parameters.find("max_size_MB"); - if (itMaxBufferSize != m_Method.m_Parameters.end()) - { - if (m_DebugMode == true) - { - if (m_GrowthFactor <= 1.f) - { - throw std::invalid_argument( - "ERROR: Method buffer_growth argument " - "can't be less of equal than 1, in " + - m_EndMessage + "\n"); - } - } - - // convert from MB to bytes - m_BP1Writer.m_MaxBufferSize = - std::stoul(itMaxBufferSize->second) * 1048576; - } - - auto itVerbosity = m_Method.m_Parameters.find("verbose"); - if (itVerbosity != m_Method.m_Parameters.end()) - { - int verbosity = std::stoi(itVerbosity->second); - if (m_DebugMode == true) - { - if (verbosity < 0 || verbosity > 5) - { - throw std::invalid_argument( - "ERROR: Method verbose argument must be an " - "integer in the range [0,5], in call to " - "Open or Engine constructor\n"); - } - } - m_BP1Writer.m_Verbosity = verbosity; - } + m_BP1Writer.InitParameters(m_IO.m_Parameters); } void BPFileWriter::InitTransports() { - if (m_DebugMode == true) + // TODO need to add support for aggregators here later + if (m_IO.m_TransportsParameters.empty()) { - if (TransportNamesUniqueness() == false) - { - throw std::invalid_argument( - "ERROR: two transports of the same kind (e.g file IO) " - "can't have the same name, modify with name= in Method " - "AddTransport\n"); - } + Params defaultTransportParameters; + defaultTransportParameters["transport"] = "File"; + m_IO.m_TransportsParameters.push_back(defaultTransportParameters); } - bool setBuffer = false; - - for (const auto ¶meters : m_Method.m_TransportParameters) - { - auto itProfile = parameters.find("profile_units"); - bool doProfiling = false; - // default is seconds for this engine - Support::Resolutions resolution = Support::Resolutions::s; - if (itProfile != parameters.end()) - { - if (itProfile->second == "mus" || - itProfile->second == "microseconds") - { - resolution = Support::Resolutions::mus; - } - else if (itProfile->second == "ms" || - itProfile->second == "milliseconds") - { - resolution = Support::Resolutions::ms; - } - else if (itProfile->second == "s" || itProfile->second == "seconds") - { - resolution = Support::Resolutions::s; - } - else if (itProfile->second == "min" || - itProfile->second == "minutes") - { - resolution = Support::Resolutions::m; - } - else if (itProfile->second == "h" || itProfile->second == "hours") - { - resolution = Support::Resolutions::h; - } - else - { - if (m_DebugMode == true) - { - throw std::invalid_argument( - "ERROR: Transport profile_units argument " - "must be mus, ms, s, min or h " + - m_EndMessage); - } - } - doProfiling = true; - } - - auto itTransport = parameters.find("transport"); - - if (itTransport->second == "file" || itTransport->second == "File") - { - auto itLibrary = parameters.find("library"); - if (itLibrary == parameters.end() || - itLibrary->second == "POSIX") // use default POSIX - { - auto file = std::make_shared<transport::FileDescriptor>( - m_MPIComm, m_DebugMode); - if (doProfiling == true) - { - file->InitProfiler(m_AccessMode, resolution); - } - - m_BP1Writer.OpenRankFiles(m_Name, m_AccessMode, *file); - m_Transports.push_back(std::move(file)); - setBuffer = true; - } - else if (itLibrary->second == "FILE*" || - itLibrary->second == "stdio") - { - auto file = std::make_shared<transport::FilePointer>( - m_MPIComm, m_DebugMode); - if (doProfiling == true) - { - file->InitProfiler(m_AccessMode, resolution); - } - - m_BP1Writer.OpenRankFiles(m_Name, m_AccessMode, *file); - m_Transports.push_back(std::move(file)); - setBuffer = true; - } - else if (itLibrary->second == "fstream" || - itLibrary->second == "std::fstream") - { - auto file = std::make_shared<transport::FStream>(m_MPIComm, - m_DebugMode); - - if (doProfiling == true) - { - file->InitProfiler(m_AccessMode, resolution); - } + // Names are std::vector<std::string> + auto transportsNames = m_TransportsManager.GetFilesBaseNames( + m_Name, m_IO.m_TransportsParameters); + auto bpBaseNames = m_BP1Writer.GetBPBaseNames(transportsNames); + auto bpNames = m_BP1Writer.GetBPNames(bpBaseNames); - m_BP1Writer.OpenRankFiles(m_Name, m_AccessMode, *file); - m_Transports.push_back(std::move(file)); - setBuffer = true; - } - else if (itLibrary->second == "MPI_File" || - itLibrary->second == "MPI-IO") - { - } - else - { - if (m_DebugMode == true) - { - throw std::invalid_argument( - "ERROR: file transport library " + itLibrary->second + - " not supported, in " + m_Name + m_EndMessage); - } - } - } - else - { - if (m_DebugMode == true) - { - throw std::invalid_argument( - "ERROR: transport " + itTransport->second + - " (you mean File?) not supported, in " + m_Name + - m_EndMessage); - } - } - } - - if (setBuffer == false) - { - if (m_DebugMode == true) - { - throw std::invalid_argument( - "ERROR: file transport not declared in Method " - "need call to Method.AddTransport, in " + - m_Name + m_EndMessage); - } - } - - // initial size is 16KB, memory is initialized to zero - m_BP1Writer.m_Heap.ResizeData(16777216); + m_TransportsManager.OpenFiles(bpBaseNames, bpNames, m_OpenMode, + m_IO.m_TransportsParameters, + m_BP1Writer.m_Profiler.IsActive); } -void BPFileWriter::InitProcessGroup() +void BPFileWriter::InitBPBuffer() { - if (m_BP1Writer.m_MetadataSet.Log.IsActive == true) + if (m_OpenMode == OpenMode::Append) { - m_BP1Writer.m_MetadataSet.Log.Timers[0].SetInitialTime(); + // TODO: Get last pg timestep and update timestep counter in } - - if (m_AccessMode == "a") - { - // Get last pg timestep and update timestep counter in - // format::BP1MetadataSet - } - - WriteProcessGroupIndex(); - - if (m_BP1Writer.m_MetadataSet.Log.IsActive == true) + else { - m_BP1Writer.m_MetadataSet.Log.Timers[0].SetTime(); + m_BP1Writer.WriteProcessGroupIndex( + m_IO.m_HostLanguage, m_TransportsManager.GetTransportsTypes()); } } -void BPFileWriter::WriteProcessGroupIndex() -{ - const bool isFortran = (m_HostLanguage == "Fortran") ? true : false; - - m_BP1Writer.WriteProcessGroupIndex(isFortran, std::to_string(m_RankMPI), - static_cast<uint32_t>(m_RankMPI), - m_Transports); -} - } // end namespace adios diff --git a/source/adios2/engine/bp/BPFileWriter.h b/source/adios2/engine/bp/BPFileWriter.h index 343c3167c48b6f6f39dda8bdd85ddaa1fc55a789..24ce235b0e1c0a27d0da4032e95f7354b38c9aeb 100644 --- a/source/adios2/engine/bp/BPFileWriter.h +++ b/source/adios2/engine/bp/BPFileWriter.h @@ -2,19 +2,19 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * BPWriter.h + * BPFileWriter.h * * Created on: Dec 16, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_ENGINE_BP_BPFILEWRITER_H_ #define ADIOS2_ENGINE_BP_BPFILEWRITER_H_ #include "adios2/ADIOSConfig.h" -#include "adios2/capsule/heap/STLVector.h" #include "adios2/core/Engine.h" -#include "adios2/utilities/format/bp1/BP1.h" +#include "adios2/toolkit/format/bp1/BP1.h" //format::BP1Writer +#include "adios2/toolkit/transportman/TransportMan.h" //transport::TransportsMan namespace adios { @@ -24,67 +24,17 @@ class BPFileWriter : public Engine public: /** - * Constructor for Writer writes in BP format into a single heap capsule, - * manages several transports + * Constructor for file Writer in BP format * @param name unique name given to the engine - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode + * @param openMode w (supported), r, a from OpenMode in ADIOSTypes.h + * @param mpiComm MPI communicator */ - BPFileWriter(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); + BPFileWriter(IO &io, const std::string &name, const OpenMode openMode, + MPI_Comm mpiComm); + ~BPFileWriter(); - 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(Variable<std::complex<float>> &variable, - const std::complex<float> *values); - void Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values); - void Write(Variable<std::complex<long double>> &variable, - const std::complex<long double> *values); - void Write(VariableCompound &variable, const void *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 Write(const std::string &variableName, - const std::complex<float> *values); - void Write(const std::string &variableName, - const std::complex<double> *values); - void Write(const std::string &variableName, - const std::complex<long double> *values); - void Write(const std::string &variableName, const void *values); - - void Advance(float timeout_sec = 0.0); + void Advance(const float timeoutSeconds = 0.0) final; /** * Closes a single transport or all transports @@ -94,88 +44,39 @@ public: * latter * is bounds-checked. */ - void Close(const int transportIndex = -1); + void Close(const int transportIndex = -1) final; private: + /** Single object controlling BP buffering */ format::BP1Writer m_BP1Writer; - /** set to false after first Close is reached so metadata - doesn't have to be accommodated for a subsequent Close */ - bool m_IsFirstClose = true; + /** single object controlling a vector of Transports from IO AddTransport */ + transportman::TransportMan m_TransportsManager; - /** data buffer exponential growth factor */ - float m_GrowthFactor = 1.5; + /** true: due to buffer overflow, move to transports manager */ + bool m_DoTransportFlush = false; - ///< true: due to buffer overflow - bool m_TransportFlush = false; + void Init() final; - /** set to true if advance is called, this - prevents flattening the data and metadata in Close*/ - bool m_CloseProcessGroup = false; + /** Parses parameters from IO SetParameters */ + void InitParameters() final; + /** Parses transports and parameters from IO AddTransport */ + void InitTransports() final; - void Init(); - void InitParameters(); - void InitTransports(); - void InitProcessGroup(); + void InitBPBuffer(); - void WriteProcessGroupIndex(); +#define declare_type(T) \ + void DoWrite(Variable<T> &variable, const T *values) final; + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type /** * Common function for primitive (including std::complex) writes - * @param group - * @param variableName * @param variable + * @param values */ template <class T> - void WriteVariableCommon(Variable<T> &variable, const T *values) - { - if (m_BP1Writer.m_MetadataSet.Log.IsActive == true) - { - m_BP1Writer.m_MetadataSet.Log.Timers[0].SetInitialTime(); - } - - // set variable - variable.m_AppValues = values; - m_WrittenVariables.insert(variable.m_Name); - - // if first timestep Write create a new pg index - if (m_BP1Writer.m_MetadataSet.DataPGIsOpen == false) - { - WriteProcessGroupIndex(); - } - - // pre-calculate new metadata and payload sizes - // m_TransportFlush = CheckBufferAllocation( - // m_BP1Writer.GetVariableIndexSize( variable ) + - // variable.PayLoadSize(), - // m_GrowthFactor, - // m_MaxBufferSize, - // m_Buffer.m_Data ); - - // WRITE INDEX to data buffer and metadata structure (in memory)// - m_BP1Writer.WriteVariableMetadata(variable); - - if (m_TransportFlush == true) // in batches - { - // write pg index - - // flush to transports - - // reset relative positions to zero, update absolute position - } - else // Write data to buffer - { - m_BP1Writer.WriteVariablePayload(variable); - } - - // not needed after write - variable.m_AppValues = nullptr; - - if (m_BP1Writer.m_MetadataSet.Log.IsActive == true) - { - m_BP1Writer.m_MetadataSet.Log.Timers[0].SetTime(); - } - } + void DoWriteCommon(Variable<T> &variable, const T *values); }; } // end namespace adios diff --git a/source/adios2/engine/bp/BPFileWriter.tcc b/source/adios2/engine/bp/BPFileWriter.tcc new file mode 100644 index 0000000000000000000000000000000000000000..baf8999269438db0c6c34e39c950e8e5f1b2cc07 --- /dev/null +++ b/source/adios2/engine/bp/BPFileWriter.tcc @@ -0,0 +1,56 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * BPFileWriter.tcc implementation of template functions with known type + * + * Created on: May 22, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "BPFileWriter.h" + +namespace adios +{ + +template <class T> +void BPFileWriter::DoWriteCommon(Variable<T> &variable, const T *values) +{ + // set variable + variable.m_AppValues = values; + m_WrittenVariables.insert(variable.m_Name); + + // if first timestep Write create a new pg index + if (!m_BP1Writer.m_MetadataSet.DataPGIsOpen) + { + m_BP1Writer.WriteProcessGroupIndex( + m_IO.m_HostLanguage, m_TransportsManager.GetTransportsTypes()); + } + + // pre-calculate new metadata and payload sizes + // m_TransportFlush = CheckBufferAllocation( + // m_BP1Writer.GetVariableIndexSize( variable ) + + // variable.PayLoadSize(), + // m_GrowthFactor, + // m_MaxBufferSize, + // m_Buffer.m_Data ); + + // WRITE INDEX to data buffer and metadata structure (in memory)// + m_BP1Writer.WriteVariableMetadata(variable); + + if (m_DoTransportFlush) // in batches + { + // flatten data + + // flush to transports + + // reset relative positions to zero, update absolute position + } + else // Write data to buffer + { + m_BP1Writer.WriteVariablePayload(variable); + } + variable.m_AppValues = nullptr; // not needed after write +} + +} // end namespace adios diff --git a/source/adios2/engine/dataman/DataManReader.cpp b/source/adios2/engine/dataman/DataManReader.cpp index e9349adad5708bc94a1492b35ae22b3196743cdb..d05cac30116e5e038d3472809eb809897d759770 100644 --- a/source/adios2/engine/dataman/DataManReader.cpp +++ b/source/adios2/engine/dataman/DataManReader.cpp @@ -10,22 +10,16 @@ #include "DataManReader.h" -#include "adios2/core/Support.h" -#include "adios2/core/adiosFunctions.h" //CSVToVector -#include "adios2/transport/file/FStream.h" // uses C++ fstream -#include "adios2/transport/file/FileDescriptor.h" // uses POSIX -#include "adios2/transport/file/FilePointer.h" // uses C FILE* -#include "adios2/transport/wan/MdtmMan.h" //uses Mdtm library +#include "adios2/helper/adiosFunctions.h" //CSVToVector namespace adios { -DataManReader::DataManReader(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method) -: Engine(adios, "DataManReader", name, accessMode, mpiComm, method, - " DataManReader constructor (or call to ADIOS Open).\n") +DataManReader::DataManReader(IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: Engine("DataManReader", io, name, openMode, mpiComm) { + m_EndMessage = " in call to IO Open DataManReader " + m_Name + "\n"; Init(); } @@ -38,135 +32,13 @@ void DataManReader::SetCallBack( m_Man.reg_callback(callback); } -Variable<void> * -DataManReader::InquireVariable(const std::string &name, - const bool readIn) // not yet implemented -{ - return nullptr; -} - -Variable<char> *DataManReader::InquireVariableChar(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<char>(name, readIn); -} - -Variable<unsigned char> * -DataManReader::InquireVariableUChar(const std::string &name, const bool readIn) -{ - return InquireVariableCommon<unsigned char>(name, readIn); -} - -Variable<short> *DataManReader::InquireVariableShort(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<short>(name, readIn); -} - -Variable<unsigned short> * -DataManReader::InquireVariableUShort(const std::string &name, const bool readIn) -{ - return InquireVariableCommon<unsigned short>(name, readIn); -} - -Variable<int> *DataManReader::InquireVariableInt(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<int>(name, readIn); -} - -Variable<unsigned int> * -DataManReader::InquireVariableUInt(const std::string &name, const bool readIn) -{ - return InquireVariableCommon<unsigned int>(name, readIn); -} - -Variable<long int> *DataManReader::InquireVariableLInt(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<long int>(name, readIn); -} - -Variable<unsigned long int> * -DataManReader::InquireVariableULInt(const std::string &name, const bool readIn) -{ - return InquireVariableCommon<unsigned long int>(name, readIn); -} - -Variable<long long int> * -DataManReader::InquireVariableLLInt(const std::string &name, const bool readIn) -{ - return InquireVariableCommon<long long int>(name, readIn); -} - -Variable<unsigned long long int> * -DataManReader::InquireVariableULLInt(const std::string &name, const bool readIn) -{ - return InquireVariableCommon<unsigned long long int>(name, readIn); -} - -Variable<float> *DataManReader::InquireVariableFloat(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<float>(name, readIn); -} - -Variable<double> *DataManReader::InquireVariableDouble(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<double>(name, readIn); -} - -Variable<long double> * -DataManReader::InquireVariableLDouble(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<long double>(name, readIn); -} - -Variable<std::complex<float>> * -DataManReader::InquireVariableCFloat(const std::string &name, const bool readIn) -{ - return InquireVariableCommon<std::complex<float>>(name, readIn); -} - -Variable<std::complex<double>> * -DataManReader::InquireVariableCDouble(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<std::complex<double>>(name, readIn); -} - -Variable<std::complex<long double>> * -DataManReader::InquireVariableCLDouble(const std::string &name, - const bool readIn) -{ - return InquireVariableCommon<std::complex<long double>>(name, readIn); -} - -VariableCompound * -DataManReader::InquireVariableCompound(const std::string &name, - const bool readIn) -{ - return nullptr; -} - void DataManReader::Close(const int transportIndex) {} // PRIVATE void DataManReader::Init() { - if (m_DebugMode == true) - { - if (m_AccessMode != "r" && m_AccessMode != "read") - throw std::invalid_argument( - "ERROR: DataManReader doesn't support access mode " + - m_AccessMode + - ", in call to ADIOS Open or DataManReader constructor\n"); - } - - auto itRealTime = m_Method.m_Parameters.find("real_time"); - if (itRealTime != m_Method.m_Parameters.end()) + auto itRealTime = m_IO.m_Parameters.find("real_time"); + if (itRealTime != m_IO.m_Parameters.end()) { if (itRealTime->second == "yes" || itRealTime->second == "true") m_DoRealTime = true; @@ -181,8 +53,8 @@ void DataManReader::Init() */ auto lf_AssignString = [this](const std::string parameter, std::string &localVariable) { - auto it = m_Method.m_Parameters.find(parameter); - if (it != m_Method.m_Parameters.end()) + auto it = m_IO.m_Parameters.find(parameter); + if (it != m_IO.m_Parameters.end()) { localVariable = it->second; } @@ -195,8 +67,8 @@ void DataManReader::Init() */ auto lf_AssignInt = [this](const std::string parameter, int &localVariable) { - auto it = m_Method.m_Parameters.find(parameter); - if (it != m_Method.m_Parameters.end()) + auto it = m_IO.m_Parameters.find(parameter); + if (it != m_IO.m_Parameters.end()) { localVariable = std::stoi(it->second); } @@ -209,7 +81,7 @@ void DataManReader::Init() }; json jmsg; - for (auto &i : m_Method.m_Parameters) + for (auto &i : m_IO.m_Parameters) { if (is_number(i.second)) { @@ -234,80 +106,4 @@ void DataManReader::Init() } } -void DataManReader::InitTransports() // maybe move this? -{ - TransportNamesUniqueness(); - - for (const auto ¶meters : m_Method.m_TransportParameters) - { - auto itTransport = parameters.find("transport"); - - if (itTransport->second == "Mdtm" || itTransport->second == "MdtmMan") - { - const std::string localIP( - GetMdtmParameter("localIP", parameters)); // mandatory - const std::string remoteIP( - GetMdtmParameter("remoteIP", parameters)); // mandatory - const std::string prefix(GetMdtmParameter("prefix", parameters)); - const int numberOfPipes = - std::stoi(GetMdtmParameter("pipes", parameters)); - const std::vector<int> tolerances = - CSVToVectorInt(GetMdtmParameter("tolerances", parameters)); - const std::vector<int> priorities = - CSVToVectorInt(GetMdtmParameter("priorities", parameters)); - - // m_Transports.push_back(std::make_shared<transport::MdtmMan>( - // localIP, remoteIP, m_AccessMode, prefix, - // numberOfPipes, - // tolerances, priorities, m_MPIComm, m_DebugMode)); - } - else if (itTransport->second == "Zmq") - { - } - else - { - if (m_DebugMode == true) - throw std::invalid_argument( - "ERROR: transport + " + itTransport->second + - " not supported, in " + m_Name + m_EndMessage); - } - } -} - -std::string DataManReader::GetMdtmParameter( - const std::string parameter, - const std::map<std::string, std::string> &mdtmParameters) -{ - auto itParam = mdtmParameters.find(parameter); - if (itParam != mdtmParameters.end()) // found - { - return itParam->second; // return value - } - // if not found - // mandatory ones - if (parameter == "localIP" || parameter == "remoteIP") - { - if (m_DebugMode == true) - throw std::invalid_argument( - "ERROR: " + parameter + - " parameter not found in Method, in call to " - "DataManWriter constructor\n"); - } - else if (parameter == "prefix") - { - return ""; - } - else if (parameter == "pipes") - { - return "0"; // or 1? - } - else if (parameter == "tolerances") // so far empty string - { - } - else if (parameter == "priority") - { - } - - return ""; // return empty string -} -} +} // end namespace adios diff --git a/source/adios2/engine/dataman/DataManReader.h b/source/adios2/engine/dataman/DataManReader.h index 43588fbc89be78604b92fd9df9d438ac7207e0fd..af45f1054804199c74986ac46fcafea79c4e08f2 100644 --- a/source/adios2/engine/dataman/DataManReader.h +++ b/source/adios2/engine/dataman/DataManReader.h @@ -16,9 +16,7 @@ #include <DataMan.h> #include "adios2/ADIOSConfig.h" -#include "adios2/capsule/heap/STLVector.h" #include "adios2/core/Engine.h" -#include "adios2/utilities/format/bp1/BP1Writer.h" namespace adios { @@ -38,9 +36,8 @@ public: * @param nthreads */ using json = nlohmann::json; - DataManReader(ADIOS &adios, const std::string &name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); + DataManReader(IO &io, const std::string &name, const OpenMode openMode, + MPI_Comm mpiComm); virtual ~DataManReader() = default; @@ -53,41 +50,6 @@ public: std::string, Dims)> callback); - Variable<void> *InquireVariable(const std::string &name, - const bool readIn = true); - Variable<char> *InquireVariableChar(const std::string &name, - const bool readIn = true); - Variable<unsigned char> *InquireVariableUChar(const std::string &name, - const bool readIn = true); - Variable<short> *InquireVariableShort(const std::string &name, - const bool readIn = true); - Variable<unsigned short> *InquireVariableUShort(const std::string &name, - const bool readIn = true); - Variable<int> *InquireVariableInt(const std::string &name, - const bool readIn = true); - Variable<unsigned int> *InquireVariableUInt(const std::string &name, - const bool readIn = true); - Variable<long int> *InquireVariableLInt(const std::string &name, - const bool readIn = true); - Variable<unsigned long int> *InquireVariableULInt(const std::string &name, - const bool readIn = true); - Variable<long long int> *InquireVariableLLInt(const std::string &name, - const bool readIn = true); - Variable<unsigned long long int> * - InquireVariableULLInt(const std::string &name, const bool readIn = true); - Variable<float> *InquireVariableFloat(const std::string &name, - const bool readIn = true); - Variable<double> *InquireVariableDouble(const std::string &name, - const bool readIn = true); - Variable<long double> *InquireVariableLDouble(const std::string &name, - const bool readIn = true); - Variable<std::complex<float>> * - InquireVariableCFloat(const std::string &name, const bool readIn = true); - Variable<std::complex<double>> * - InquireVariableCDouble(const std::string &name, const bool readIn = true); - Variable<std::complex<long double>> * - InquireVariableCLDouble(const std::string &name, const bool readIn = true); - /** * Not implemented * @param name @@ -106,22 +68,19 @@ private: Dims)> m_CallBack; ///< call back function - void Init(); ///< calls InitCapsules and InitTransports based on Method, - /// called from constructor - void InitTransports(); ///< from Transports - - std::string - GetMdtmParameter(const std::string parameter, - const std::map<std::string, std::string> &mdtmParameters); + void Init(); template <class T> Variable<T> *InquireVariableCommon(const std::string name, const bool readIn) { - std::cout << "I am hooked to the DataMan library\n"; - std::cout << "Hello DatamanReader from rank " << m_RankMPI << "\n"; - std::cout << "Trying to read variable " << name - << " from one of the variables coming from a WAN transport\n"; + // int rank = 0; + // MPI_Comm_rank(m_MPIComm, &rank); + + // std::cout << "I am hooked to the DataMan library\n"; + // std::cout << "Hello DatamanReader from rank " << rank << "\n"; + // std::cout << "Trying to read variable " << name + // << " from one of the variables coming from a WAN transport\n"; // here read variable metadata (dimensions, type, etc.)...then create a // Variable like below: @@ -132,6 +91,6 @@ private: } }; -} // end namespace +} // end namespace adios #endif /* ADIOS2_ENGINE_DATAMAN_DATAMANREADER_H_ */ diff --git a/source/adios2/engine/dataman/DataManWriter.cpp b/source/adios2/engine/dataman/DataManWriter.cpp index 11eba0ac5afa927c01abb29af92f99370bca0a27..bf0b140161b8503b72e60ec26607bb0d11f4c1d4 100644 --- a/source/adios2/engine/dataman/DataManWriter.cpp +++ b/source/adios2/engine/dataman/DataManWriter.cpp @@ -13,20 +13,16 @@ #include <iostream> //needs to go away, this is just for demo purposes -#include "adios2/core/Support.h" -#include "adios2/core/adiosFunctions.h" //CSVToVector -#include "adios2/transport/file/FStream.h" // uses C++ fstream -#include "adios2/transport/wan/MdtmMan.h" //uses Mdtm library +#include "adios2/helper/adiosFunctions.h" //CSVToVector namespace adios { -DataManWriter::DataManWriter(ADIOS &adios, const std::string name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method) -: Engine(adios, "DataManWriter", name, accessMode, mpiComm, method, - " DataManWriter constructor (or call to ADIOS Open).\n") +DataManWriter::DataManWriter(IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: Engine("DataManWriter", io, name, openMode, mpiComm) { + m_EndMessage = ", in call to Open DataManWriter\n"; Init(); } @@ -39,231 +35,31 @@ void DataManWriter::SetCallBack( m_Man.reg_callback(callback); } -void DataManWriter::Write(Variable<char> &variable, const char *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<unsigned char> &variable, - const unsigned char *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<short> &variable, const short *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<unsigned short> &variable, - const unsigned short *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<int> &variable, const int *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<unsigned int> &variable, - const unsigned int *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<long int> &variable, const long int *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<unsigned long int> &variable, - const unsigned long int *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<long long int> &variable, - const long long int *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<unsigned long long int> &variable, - const unsigned long long int *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<float> &variable, const float *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<double> &variable, const double *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<long double> &variable, - const long double *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<std::complex<float>> &variable, - const std::complex<float> *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values) -{ - WriteVariableCommon(variable, values); -} - -void DataManWriter::Write(Variable<std::complex<long double>> &variable, - const std::complex<long double> *values) -{ - WriteVariableCommon(variable, values); -} - -// String version -void DataManWriter::Write(const std::string &variableName, const char *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<char>(variableName), values); -} - -void DataManWriter::Write(const std::string &variableName, - const unsigned char *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<unsigned char>(variableName), - values); -} - -void DataManWriter::Write(const std::string &variableName, const short *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<short>(variableName), values); -} - -void DataManWriter::Write(const std::string &variableName, - const unsigned short *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<unsigned short>(variableName), - values); -} - -void DataManWriter::Write(const std::string &variableName, const int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<int>(variableName), values); -} - -void DataManWriter::Write(const std::string &variableName, - const unsigned int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<unsigned int>(variableName), - values); -} - -void DataManWriter::Write(const std::string &variableName, - const long int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<long int>(variableName), values); -} - -void DataManWriter::Write(const std::string &variableName, - const unsigned long int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<unsigned long int>(variableName), - values); -} +void DataManWriter::Advance(const float timeoutSeconds) { m_Man.flush(); } -void DataManWriter::Write(const std::string &variableName, - const long long int *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<long long int>(variableName), - values); -} - -void DataManWriter::Write(const std::string &variableName, - const unsigned long long int *values) -{ - WriteVariableCommon( - m_ADIOS.GetVariable<unsigned long long int>(variableName), values); -} - -void DataManWriter::Write(const std::string &variableName, const float *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<float>(variableName), values); -} - -void DataManWriter::Write(const std::string &variableName, const double *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<double>(variableName), values); -} - -void DataManWriter::Write(const std::string &variableName, - const long double *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<long double>(variableName), values); -} - -void DataManWriter::Write(const std::string &variableName, - const std::complex<float> *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<std::complex<float>>(variableName), - values); -} - -void DataManWriter::Write(const std::string &variableName, - const std::complex<double> *values) -{ - WriteVariableCommon(m_ADIOS.GetVariable<std::complex<double>>(variableName), - values); -} - -void DataManWriter::Write(const std::string &variableName, - const std::complex<long double> *values) -{ - WriteVariableCommon( - m_ADIOS.GetVariable<std::complex<long double>>(variableName), values); -} - -void DataManWriter::Close(const int transportIndex) -{ - m_Man.flush(); - // here close IPs and deallocate or free/close resources (if using STL no - // need - // for memory deallocation) -} +void DataManWriter::Close(const int transportIndex) { m_Man.flush(); } // PRIVATE functions below void DataManWriter::Init() { - if (m_DebugMode == true) - { - if (m_AccessMode != "w" && m_AccessMode != "write" && - m_AccessMode != "a" && m_AccessMode != "append") - throw std::invalid_argument( - "ERROR: DataManWriter doesn't support access mode " + - m_AccessMode + - ", in call to ADIOS Open or DataManWriter constructor\n"); - } + auto lf_SetBoolParameter = [&](const std::string key, bool ¶meter) { - auto itRealTime = m_Method.m_Parameters.find("real_time"); - if (itRealTime != m_Method.m_Parameters.end()) - { - if (itRealTime->second == "yes" || itRealTime->second == "true") - m_DoRealTime = true; - } + auto itKey = m_IO.m_Parameters.find(key); + if (itKey != m_IO.m_Parameters.end()) + { + if (itKey->second == "yes" || itKey->second == "true") + { + parameter = true; + } + else if (itKey->second == "no" || itKey->second == "false") + { + parameter = false; + } + } + }; - itRealTime = m_Method.m_Parameters.find("monitoring"); - if (itRealTime != m_Method.m_Parameters.end()) - { - if (itRealTime->second == "yes" || itRealTime->second == "true") - m_DoMonitor = true; - } + lf_SetBoolParameter("real_time", m_DoRealTime); + lf_SetBoolParameter("monitoring", m_DoMonitor); if (m_DoRealTime) { @@ -272,10 +68,10 @@ void DataManWriter::Init() * localVariable * of type std::string */ - auto lf_AssignString = [this](const std::string parameter, - std::string &localVariable) { - auto it = m_Method.m_Parameters.find(parameter); - if (it != m_Method.m_Parameters.end()) + auto lf_AssignString = [&](const std::string parameter, + std::string &localVariable) { + auto it = m_IO.m_Parameters.find(parameter); + if (it != m_IO.m_Parameters.end()) { localVariable = it->second; } @@ -286,25 +82,25 @@ void DataManWriter::Init() * localVariable * of type int */ - auto lf_AssignInt = [this](const std::string parameter, - int &localVariable) { - auto it = m_Method.m_Parameters.find(parameter); - if (it != m_Method.m_Parameters.end()) + auto lf_AssignInt = [&](const std::string parameter, + int &localVariable) { + auto it = m_IO.m_Parameters.find(parameter); + if (it != m_IO.m_Parameters.end()) { localVariable = std::stoi(it->second); } }; - auto is_number = [](const std::string &s) { + auto lf_IsNumber = [](const std::string &s) { return !s.empty() && std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c); }) == s.end(); }; json jmsg; - for (auto &i : m_Method.m_Parameters) + for (const auto &i : m_IO.m_Parameters) { - if (is_number(i.second)) + if (lf_IsNumber(i.second)) { jmsg[i.first] = std::stoi(i.second); } @@ -317,91 +113,19 @@ void DataManWriter::Init() m_Man.add_stream(jmsg); std::string method_type; - int num_channels = 0; lf_AssignString("method_type", method_type); - lf_AssignInt("num_channels", num_channels); - } - else - { - InitTransports(); - } -} - -void DataManWriter::InitTransports() // maybe move this? -{ - TransportNamesUniqueness(); - - for (const auto ¶meters : m_Method.m_TransportParameters) - { - auto itTransport = parameters.find("transport"); - - if (itTransport->second == "Mdtm" || itTransport->second == "MdtmMan") - { - const std::string localIP( - GetMdtmParameter("localIP", parameters)); // mandatory - const std::string remoteIP( - GetMdtmParameter("remoteIP", parameters)); // mandatory - const std::string prefix(GetMdtmParameter("prefix", parameters)); - const int numberOfPipes = - std::stoi(GetMdtmParameter("pipes", parameters)); - const std::vector<int> tolerances = - CSVToVectorInt(GetMdtmParameter("tolerances", parameters)); - const std::vector<int> priorities = - CSVToVectorInt(GetMdtmParameter("priorities", parameters)); - // m_Transports.push_back(std::make_shared<transport::MdtmMan>( - // localIP, remoteIP, m_AccessMode, prefix, - // numberOfPipes, - // tolerances, priorities, m_MPIComm, m_DebugMode)); - } - else if (itTransport->second == "Zmq") - { - } - else - { - if (m_DebugMode == true) - throw std::invalid_argument( - "ERROR: transport + " + itTransport->second + - " not supported, in " + m_Name + m_EndMessage); - } + int num_channels = 0; + lf_AssignInt("num_channels", num_channels); } } -std::string DataManWriter::GetMdtmParameter( - const std::string parameter, - const std::map<std::string, std::string> &mdtmParameters) -{ - auto itParam = mdtmParameters.find(parameter); - if (itParam != mdtmParameters.end()) // found - { - return itParam->second; // return value - } - // if not found - // mandatory ones - if (parameter == "localIP" || parameter == "remoteIP") - { - if (m_DebugMode == true) - throw std::invalid_argument( - "ERROR: " + parameter + - " parameter not found in Method, in call to " - "DataManWriter constructor\n"); - } - else if (parameter == "prefix") - { - return ""; +#define declare_type(T) \ + void DataManWriter::DoWrite(Variable<T> &variable, const T *values) \ + { \ + DoWriteCommon(variable, values); \ } - else if (parameter == "pipes") - { - return "0"; // or 1? - } - else if (parameter == "tolerances") // so far empty string - { - } - else if (parameter == "priority") - { - } - - return ""; // return empty string -} +ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type } // end namespace adios diff --git a/source/adios2/engine/dataman/DataManWriter.h b/source/adios2/engine/dataman/DataManWriter.h index f9fe6131ee637d2f14c58c090230a6ea3ee11666..f9a1e017321c18a8d91bf148a1a62a6c0e3922f5 100644 --- a/source/adios2/engine/dataman/DataManWriter.h +++ b/source/adios2/engine/dataman/DataManWriter.h @@ -17,9 +17,7 @@ #include <DataMan.h> #include "adios2/ADIOSConfig.h" -#include "adios2/capsule/heap/STLVector.h" #include "adios2/core/Engine.h" -#include "adios2/utilities/format/bp1/BP1Writer.h" namespace adios { @@ -29,72 +27,19 @@ class DataManWriter : public Engine public: using json = nlohmann::json; - /** - * Constructor for dataman engine Writer for WAN communications - * @param adios - * @param name unique name given to the engine - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode - * @param nthreads - */ - DataManWriter(ADIOS &adios, const std::string name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); + + DataManWriter(IO &io, const std::string &name, const OpenMode openMode, + MPI_Comm mpiComm); virtual ~DataManWriter() = default; void SetCallBack(std::function<void(const void *, std::string, std::string, std::string, Dims)> - callback); - - 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(Variable<std::complex<float>> &variable, - const std::complex<float> *values); - void Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values); - void Write(Variable<std::complex<long double>> &variable, - const std::complex<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 Write(const std::string &variableName, - const std::complex<float> *values); - void Write(const std::string &variableName, - const std::complex<double> *values); - void Write(const std::string &variableName, - const std::complex<long double> *values); - - void Close(const int transportIndex = -1); + callback) final; + + void Advance(const float timeoutSeconds = 0.0) final; + + void Close(const int transportIndex = -1) final; private: bool m_DoRealTime = false; @@ -106,21 +51,14 @@ private: void Init(); ///< calls InitCapsules and InitTransports based on Method, /// called from constructor - void InitTransports(); ///< from Transports - - /** - * From transport Mdtm in m_Method - * @param parameter must be an accepted parameter - * @param mdtmParameters - * @return value either returns user-defined from "parameter=value" or a - * default - */ - std::string - GetMdtmParameter(const std::string parameter, - const std::map<std::string, std::string> &mdtmParameters); + +#define declare_type(T) \ + void DoWrite(Variable<T> &variable, const T *values) final; + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type template <class T> - void WriteVariableCommon(Variable<T> &variable, const T *values); + void DoWriteCommon(Variable<T> &variable, const T *values); }; } // end namespace adios diff --git a/source/adios2/engine/dataman/DataManWriter.tcc b/source/adios2/engine/dataman/DataManWriter.tcc index 149830a06401752f41f710ab505ba74a627d47d1..9c3023e4574142d4cc4af2137923339ad1128237 100644 --- a/source/adios2/engine/dataman/DataManWriter.tcc +++ b/source/adios2/engine/dataman/DataManWriter.tcc @@ -19,7 +19,7 @@ namespace adios { template <class T> -void DataManWriter::WriteVariableCommon(Variable<T> &variable, const T *values) +void DataManWriter::DoWriteCommon(Variable<T> &variable, const T *values) { // here comes your magic at Writing now variable.m_UserValues has the // data @@ -53,15 +53,19 @@ void DataManWriter::WriteVariableCommon(Variable<T> &variable, const T *values) { MPI_Barrier(m_MPIComm); std::cout << "I am hooked to the DataMan library\n"; - std::cout << "putshape " << variable.m_Count.size() << std::endl; - std::cout << "varshape " << variable.m_Shape.size() << std::endl; - std::cout << "offset " << variable.m_Start.size() << std::endl; - for (int i = 0; i < m_SizeMPI; ++i) + std::cout << "Variable " << variable.m_Name << "\n"; + std::cout << "putshape " << variable.m_Count.size() << "\n"; + std::cout << "varshape " << variable.m_Shape.size() << "\n"; + std::cout << "offset " << variable.m_Start.size() << "\n"; + + int rank = 0, size = 1; + MPI_Comm_size(m_MPIComm, &size); + + for (int i = 0; i < size; ++i) { - if (i == m_RankMPI) + if (i == rank) { - std::cout << "Rank: " << m_RankMPI << "\n"; - variable.Monitor(std::cout); + std::cout << "Rank: " << i << "\n"; std::cout << std::endl; } else diff --git a/source/adios2/engine/hdf5/HDF5Common.h b/source/adios2/engine/hdf5/HDF5Common.h deleted file mode 100644 index d5a6a77190b1ed2465bf62b82073835b061afe27..0000000000000000000000000000000000000000 --- a/source/adios2/engine/hdf5/HDF5Common.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * HDF5CommonP.h - * - * Created on: March 20, 2017 - * Author: Junmin - */ - -#ifndef ADIOS2_ENGINE_HDF5_HDF5COMMON_P_H_ -#define ADIOS2_ENGINE_HDF5_HDF5COMMON_P_H_ - -#include <string> - -#include "adios2/ADIOSMPICommOnly.h" - -#include <hdf5.h> - -namespace adios -{ - -class HDF5Common -{ - -public: - /** - * Constructor for HDF5 file - */ - HDF5Common(); - - void Init(const std::string name, MPI_Comm comm, bool toWrite); - void Close(); - void Advance(); - - unsigned int GetNumTimeSteps(); - void WriteTimeSteps(); - - hid_t m_PropertyListId, m_FileId; - hid_t m_GroupId; - - hid_t m_DefH5TypeComplexDouble; - hid_t m_DefH5TypeComplexFloat; - hid_t m_DefH5TypeComplexLongDouble; - - unsigned int m_CurrentTimeStep; - - void CheckWriteGroup(); - -private: - bool m_WriteMode; - unsigned int m_NumTimeSteps; -}; - -} // end namespace adios - -#endif /* ADIOS2_ENGINE_HDF5_HDF5COMMON_P_H_ */ diff --git a/source/adios2/engine/hdf5/HDF5ReaderP.cpp b/source/adios2/engine/hdf5/HDF5ReaderP.cpp index 7f3ead729cae47aaa634e6a0d2365a2294584a06..e880f6f5ca1fbce296f88fe47207a797754babee 100644 --- a/source/adios2/engine/hdf5/HDF5ReaderP.cpp +++ b/source/adios2/engine/hdf5/HDF5ReaderP.cpp @@ -15,177 +15,53 @@ namespace adios { -HDF5Reader::HDF5Reader(ADIOS &adios, const std::string name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method) -: Engine(adios, "HDF5Reader", name, accessMode, mpiComm, method, - " HDF5Reader constructor (or call to ADIOS Open).\n") - +HDF5ReaderP::HDF5ReaderP(IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: Engine("HDF5Reader", io, name, openMode, mpiComm), m_H5File(io.m_DebugMode) { + m_EndMessage = ", in call to IO HDF5Reader Open " + m_Name + "\n"; Init(); } -HDF5Reader::~HDF5Reader() { Close(); } +HDF5ReaderP::~HDF5ReaderP() { Close(); } -bool HDF5Reader::isValid() +bool HDF5ReaderP::IsValid() { - if (m_AccessMode != "r" && m_AccessMode != "read") + bool isValid = false; + + if (m_OpenMode != OpenMode::Read) { - return false; + return isValid; } if (m_H5File.m_FileId >= 0) { - return true; + isValid = true; } + return isValid; } -void HDF5Reader::Init() +void HDF5ReaderP::Init() { - if (m_AccessMode != "r" && m_AccessMode != "read") + if (m_OpenMode != OpenMode::Read) { throw std::invalid_argument( - "ERROR: HDF5Reader doesn't support access mode " + m_AccessMode + - ", in call to ADIOS Open or HDF5Reader constructor\n"); + "ERROR: HDF5Reader only supports OpenMode::Read " + ", in call to Open\n"); } m_H5File.Init(m_Name, m_MPIComm, false); m_H5File.GetNumTimeSteps(); } -Variable<void> *HDF5Reader::InquireVariable(const std::string &variableName, - const bool readIn) -{ - std::cout << "Not implemented: HDF5Reader::InquireVariable()" << std::endl; - return nullptr; -} - -Variable<char> *HDF5Reader::InquireVariableChar(const std::string &variableName, - const bool readIn) -{ - return nullptr; -} - -Variable<unsigned char> * -HDF5Reader::InquireVariableUChar(const std::string &variableName, - const bool readIn) -{ - return nullptr; -} - -Variable<short> * -HDF5Reader::InquireVariableShort(const std::string &variableName, - const bool readIn) -{ - return nullptr; -} - -Variable<unsigned short> * -HDF5Reader::InquireVariableUShort(const std::string &variableName, - const bool readIn) -{ - return nullptr; -} - -Variable<int> *HDF5Reader::InquireVariableInt(const std::string &variableName, - const bool) -{ - return nullptr; -} - -Variable<unsigned int> * -HDF5Reader::InquireVariableUInt(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<long int> * -HDF5Reader::InquireVariableLInt(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<unsigned long int> * -HDF5Reader::InquireVariableULInt(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<long long int> * -HDF5Reader::InquireVariableLLInt(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<unsigned long long int> * -HDF5Reader::InquireVariableULLInt(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<float> * -HDF5Reader::InquireVariableFloat(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<double> * -HDF5Reader::InquireVariableDouble(const std::string &variableName, const bool) -{ - - if (m_RankMPI == 0) - { - std::cout << " ... reading var: " << variableName << std::endl; - } - int totalts = m_H5File.GetNumTimeSteps(); - - if (m_RankMPI == 0) - { - std::cout << " ... I saw total timesteps: " << totalts << std::endl; - } - - return nullptr; -} - -Variable<long double> * -HDF5Reader::InquireVariableLDouble(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<std::complex<float>> * -HDF5Reader::InquireVariableCFloat(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<std::complex<double>> * -HDF5Reader::InquireVariableCDouble(const std::string &variableName, const bool) -{ - return nullptr; -} - -Variable<std::complex<long double>> * -HDF5Reader::InquireVariableCLDouble(const std::string &variableName, const bool) -{ - return nullptr; -} - -VariableCompound * -HDF5Reader::InquireVariableCompound(const std::string &variableName, - const bool readIn) -{ - return nullptr; -} - template <class T> -void HDF5Reader::UseHDFRead(const std::string &variableName, T *values, - hid_t h5Type) +void HDF5ReaderP::UseHDFRead(const std::string &variableName, T *values, + hid_t h5Type) { + int rank, size; + MPI_Comm_rank(m_MPIComm, &rank); + MPI_Comm_size(m_MPIComm, &size); + hid_t dataSetId = H5Dopen(m_H5File.m_GroupId, variableName.c_str(), H5P_DEFAULT); - if (m_RankMPI == 0) - { - std::cout << " opened to read: " << variableName << std::endl; - } if (dataSetId < 0) { @@ -206,18 +82,15 @@ void HDF5Reader::UseHDFRead(const std::string &variableName, T *values, int totalElements = 1; for (int i = 0; i < ndims; i++) { - std::cout << " [" << i << "] th dimension: " << dims[i] << std::endl; count[i] = dims[i]; totalElements *= dims[i]; } - start[0] = m_RankMPI * dims[0] / m_SizeMPI; - count[0] = dims[0] / m_SizeMPI; - if (m_RankMPI == m_SizeMPI - 1) + start[0] = rank * dims[0] / size; + count[0] = dims[0] / size; + if (rank == size - 1) { - count[0] = dims[0] - count[0] * (m_SizeMPI - 1); - std::cout << " rank = " << m_RankMPI << ", count=" << count[0] - << std::endl; + count[0] = dims[0] - count[0] * (size - 1); } hid_t ret = H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, start, stride, @@ -239,20 +112,14 @@ void HDF5Reader::UseHDFRead(const std::string &variableName, T *values, ret = H5Dread(dataSetId, h5Type, memDataSpace, fileSpace, H5P_DEFAULT, data_array); - for (int i = 0; i < elementsRead; i++) - { - std::cout << "... rank " << m_RankMPI << " , " << data_array[i] - << std::endl; - } - H5Sclose(memDataSpace); H5Sclose(fileSpace); H5Dclose(dataSetId); } -void HDF5Reader::Advance(float timeoutSec) { m_H5File.Advance(); } +void HDF5ReaderP::Advance(const float timeoutSeconds) { m_H5File.Advance(); } -void HDF5Reader::Close(const int transportIndex) { m_H5File.Close(); } +void HDF5ReaderP::Close(const int transportIndex) { m_H5File.Close(); } } // end namespace adios diff --git a/source/adios2/engine/hdf5/HDF5ReaderP.h b/source/adios2/engine/hdf5/HDF5ReaderP.h index 70c71137b5c6a4f7edc92600cae66a2ec67fb07d..90584bd6cf94b8c6f19c459aac640e5a1429913c 100644 --- a/source/adios2/engine/hdf5/HDF5ReaderP.h +++ b/source/adios2/engine/hdf5/HDF5ReaderP.h @@ -11,15 +11,14 @@ #ifndef ADIOS2_ENGINE_HDF5_HDF5READERP_H_ #define ADIOS2_ENGINE_HDF5_HDF5READERP_H_ -#include "HDF5Common.h" - -#include "adios2/ADIOSMPICommOnly.h" #include "adios2/core/Engine.h" +#include "adios2/core/IO.h" +#include "adios2/toolkit/interop/hdf5/HDF5Common.h" namespace adios { -class HDF5Reader : public Engine +class HDF5ReaderP : public Engine { public: @@ -30,96 +29,23 @@ public: * @param mpiComm * @param method */ - HDF5Reader(ADIOS &adios, const std::string name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); - - virtual ~HDF5Reader(); - - bool isValid(); - - Variable<void> *InquireVariable(const std::string &variableName, - const bool readIn = true); - - Variable<char> *InquireVariableChar(const std::string &variableName, - const bool readIn = true); - - Variable<unsigned char> * - InquireVariableUChar(const std::string &variableName, - const bool readIn = true); - - Variable<short> *InquireVariableShort(const std::string &variableName, - const bool readIn = true); - - Variable<unsigned short> * - InquireVariableUShort(const std::string &variableName, - const bool readIn = true); - - Variable<int> *InquireVariableInt(const std::string &variableName, - const bool readIn = true); - - Variable<unsigned int> *InquireVariableUInt(const std::string &variableName, - const bool readIn = true); - - Variable<long int> *InquireVariableLInt(const std::string &variableName, - const bool readIn = true); + HDF5ReaderP(IO &adios, const std::string &name, const OpenMode openMode, + MPI_Comm mpiComm); - Variable<unsigned long int> * - InquireVariableULInt(const std::string &variableName, - const bool readIn = true); + ~HDF5ReaderP(); - Variable<long long int> * - InquireVariableLLInt(const std::string &variableName, - const bool readIn = true); + bool IsValid(); - Variable<unsigned long long int> * - InquireVariableULLInt(const std::string &variableName, - const bool readIn = true); + void Advance(const float timeoutSeconds = 0.0) final; - Variable<float> *InquireVariableFloat(const std::string &variableName, - const bool readIn = true); + void Close(const int transportIndex = -1) final; - Variable<double> *InquireVariableDouble(const std::string &variableName, - const bool readIn = true); - Variable<long double> * - InquireVariableLDouble(const std::string &variableName, - const bool readIn = true); - - Variable<std::complex<float>> * - InquireVariableCFloat(const std::string &variableName, - const bool readIn = true); - - Variable<std::complex<double>> * - InquireVariableCDouble(const std::string &variableName, - const bool readIn = true); - - Variable<std::complex<long double>> * - InquireVariableCLDouble(const std::string &variableName, - const bool readIn = true); - - /** - * Not implemented - * @param name - * @param readIn - * @return - */ - VariableCompound *InquireVariableCompound(const std::string &variableName, - const bool readIn = true); - - void Advance(float timeoutSecc = 0.0); - - void Close(const int transportIndex = -1); - - template <typename T> + template <class T> void UseHDFRead(const std::string &variableName, T *values, hid_t h5Type); - /* - template <class T> - void ReadMe(Variable<T> &variable, T *values, hid_t h5type); - */ private: - HDF5Common m_H5File; - void Init(); + interop::HDF5Common m_H5File; + void Init() final; }; }; #endif /* ADIOS2_ENGINE_HDF5_HDF5READERP_H_ */ diff --git a/source/adios2/engine/hdf5/HDF5WriterP.cpp b/source/adios2/engine/hdf5/HDF5WriterP.cpp index db9d6c4e6e0e1a7d31e54aa5055eb2a325b9deb3..e21be47f660d999ef809efb3bdc9cb03ca1f9ea4 100644 --- a/source/adios2/engine/hdf5/HDF5WriterP.cpp +++ b/source/adios2/engine/hdf5/HDF5WriterP.cpp @@ -11,333 +11,54 @@ #include "HDF5WriterP.h" #include "adios2/ADIOSMPI.h" -#include "adios2/core/Support.h" -#include "adios2/core/adiosFunctions.h" //CSVToVector +#include "adios2/helper/adiosFunctions.h" //CSVToVector namespace adios { -HDF5Writer::HDF5Writer(ADIOS &adios, const std::string name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method) -: Engine(adios, "HDF5Writer", name, accessMode, mpiComm, - method, /*debugMode, cores,*/ - " HDF5Writer constructor (or call to ADIOS Open).\n") -// m_Buffer(m_DebugMode) +HDF5WriterP::HDF5WriterP(IO &io, const std::string &name, + const OpenMode openMode, MPI_Comm mpiComm) +: Engine("HDF5Writer", io, name, openMode, mpiComm), m_H5File(io.m_DebugMode) { + m_EndMessage = ", in call to IO HDF5Writer Open " + m_Name + "\n"; Init(); } -HDF5Writer::~HDF5Writer() { Close(); } +HDF5WriterP::~HDF5WriterP() { Close(); } -void HDF5Writer::Init() +// PRIVATE +void HDF5WriterP::Init() { - if (m_AccessMode != "w" && m_AccessMode != "write" && m_AccessMode != "a" && - m_AccessMode != "append") + if (m_OpenMode != OpenMode::Write && m_OpenMode != OpenMode::Append) { throw std::invalid_argument( - "ERROR: HDF5Writer doesn't support access mode " + m_AccessMode + + "ERROR: HDF5Writer only support OpenMode::Write or " + "OpenMode::Append " ", in call to ADIOS Open or HDF5Writer constructor\n"); } m_H5File.Init(m_Name, m_MPIComm, true); } -void HDF5Writer::Write(Variable<char> &variable, const char *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_CHAR); -} - -void HDF5Writer::Write(Variable<unsigned char> &variable, - const unsigned char *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_UCHAR); -} - -void HDF5Writer::Write(Variable<short> &variable, const short *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_SHORT); -} - -void HDF5Writer::Write(Variable<unsigned short> &variable, - const unsigned short *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_USHORT); -} - -void HDF5Writer::Write(Variable<int> &variable, const int *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_INT); -} - -void HDF5Writer::Write(Variable<unsigned int> &variable, - const unsigned int *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_UINT); -} - -void HDF5Writer::Write(Variable<long int> &variable, const long int *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_LONG); -} - -void HDF5Writer::Write(Variable<unsigned long int> &variable, - const unsigned long int *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_ULONG); -} - -void HDF5Writer::Write(Variable<long long int> &variable, - const long long int *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_LLONG); -} - -void HDF5Writer::Write(Variable<unsigned long long int> &variable, - const unsigned long long int *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_ULLONG); -} - -void HDF5Writer::Write(Variable<float> &variable, const float *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_FLOAT); -} - -void HDF5Writer::Write(Variable<double> &variable, const double *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_DOUBLE); -} - -void HDF5Writer::Write(Variable<long double> &variable, - const long double *values) -{ - UseHDFWrite(variable, values, H5T_NATIVE_LDOUBLE); -} - -void HDF5Writer::Write(Variable<std::complex<float>> &variable, - const std::complex<float> *values) -{ - UseHDFWrite(variable, values, m_H5File.m_DefH5TypeComplexFloat); -} - -void HDF5Writer::Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values) -{ - UseHDFWrite(variable, values, m_H5File.m_DefH5TypeComplexDouble); -} - -void HDF5Writer::Write(Variable<std::complex<long double>> &variable, - const std::complex<long double> *values) -{ - UseHDFWrite(variable, values, m_H5File.m_DefH5TypeComplexLongDouble); -} - -// String version -void HDF5Writer::Write(const std::string &variableName, const char *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<char>(variableName), values, - H5T_NATIVE_CHAR); -} - -void HDF5Writer::Write(const std::string &variableName, - const unsigned char *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<unsigned char>(variableName), values, - H5T_NATIVE_UCHAR); -} - -void HDF5Writer::Write(const std::string &variableName, const short *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<short>(variableName), values, - H5T_NATIVE_SHORT); -} - -void HDF5Writer::Write(const std::string &variableName, - const unsigned short *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<unsigned short>(variableName), values, - H5T_NATIVE_USHORT); -} - -void HDF5Writer::Write(const std::string &variableName, const int *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<int>(variableName), values, H5T_NATIVE_INT); -} - -void HDF5Writer::Write(const std::string &variableName, - const unsigned int *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<unsigned int>(variableName), values, - H5T_NATIVE_UINT); -} - -void HDF5Writer::Write(const std::string &variableName, const long int *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<long int>(variableName), values, - H5T_NATIVE_LONG); -} - -void HDF5Writer::Write(const std::string &variableName, - const unsigned long int *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<unsigned long int>(variableName), values, - H5T_NATIVE_ULONG); -} - -void HDF5Writer::Write(const std::string &variableName, - const long long int *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<long long int>(variableName), values, - H5T_NATIVE_LLONG); -} - -void HDF5Writer::Write(const std::string &variableName, - const unsigned long long int *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<unsigned long long int>(variableName), - values, H5T_NATIVE_ULLONG); -} - -void HDF5Writer::Write(const std::string &variableName, const float *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<float>(variableName), values, - H5T_NATIVE_FLOAT); -} - -void HDF5Writer::Write(const std::string &variableName, const double *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<double>(variableName), values, - H5T_NATIVE_DOUBLE); -} - -void HDF5Writer::Write(const std::string &variableName, - const long double *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<long double>(variableName), values, - H5T_NATIVE_LDOUBLE); -} - -void HDF5Writer::Write(const std::string &variableName, - const std::complex<float> *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<std::complex<float>>(variableName), values, - m_H5File.m_DefH5TypeComplexFloat); -} - -void HDF5Writer::Write(const std::string &variableName, - const std::complex<double> *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<std::complex<double>>(variableName), values, - m_H5File.m_DefH5TypeComplexDouble); -} +#define declare_type(T) \ + void HDF5WriterP::DoWrite(Variable<T> &variable, const T *values) \ + { \ + DoWriteCommon(variable, values); \ + } -void HDF5Writer::Write(const std::string &variableName, - const std::complex<long double> *values) -{ - UseHDFWrite(m_ADIOS.GetVariable<std::complex<long double>>(variableName), - values, m_H5File.m_DefH5TypeComplexLongDouble); -} +ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type -void HDF5Writer::Advance(float timeoutSec) { m_H5File.Advance(); } +void HDF5WriterP::Advance(const float timeoutSeconds) { m_H5File.Advance(); } -void HDF5Writer::Close(const int transportIndex) { m_H5File.Close(); } +void HDF5WriterP::Close(const int transportIndex) { m_H5File.Close(); } template <class T> -void HDF5Writer::UseHDFWrite(Variable<T> &variable, const T *values, - hid_t h5Type) +void HDF5WriterP::DoWriteCommon(Variable<T> &variable, const T *values) { - m_H5File.CheckWriteGroup(); - // here comes your magic at Writing now variable.m_UserValues has the data - // passed by the user - // set variable variable.m_AppValues = values; m_WrittenVariables.insert(variable.m_Name); - - int dimSize = std::max(variable.m_Shape.size(), variable.m_Count.size()); - - if (dimSize == 0) - { - // scalar - hid_t filespaceID = H5Screate(H5S_SCALAR); - hid_t dsetID = - H5Dcreate(m_H5File.m_GroupId, variable.m_Name.c_str(), h5Type, - filespaceID, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - herr_t status = - H5Dwrite(dsetID, h5Type, H5S_ALL, H5S_ALL, H5P_DEFAULT, values); - - H5Sclose(filespaceID); - H5Dclose(dsetID); - - return; - } - - std::vector<hsize_t> dimsf, count, offset; - - for (int i = 0; i < dimSize; i++) - { - if (variable.m_Shape.size() == dimSize) - { - dimsf.push_back(variable.m_Shape[i]); - } - else - { - dimsf.push_back(variable.m_Count[i]); - } - - if (variable.m_Count.size() == dimSize) - { - count.push_back(variable.m_Count[i]); - if (variable.m_Start.size() == dimSize) - { - offset.push_back(variable.m_Start[i]); - } - else - { - offset.push_back(0); - } - } - else - { - count.push_back(variable.m_Shape[i]); - offset.push_back(0); - } - } - - hid_t fileSpace = H5Screate_simple(dimSize, dimsf.data(), NULL); - - hid_t dsetID = - H5Dcreate(m_H5File.m_GroupId, variable.m_Name.c_str(), h5Type, - fileSpace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - // H5Sclose(fileSpace); - - hid_t memSpace = H5Screate_simple(dimSize, count.data(), NULL); - - // Select hyperslab - fileSpace = H5Dget_space(dsetID); - H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, offset.data(), NULL, - count.data(), NULL); - - // Create property list for collective dataset write. - - hid_t plistID = H5Pcreate(H5P_DATASET_XFER); -#ifdef ADIOS2_HAVE_MPI - H5Pset_dxpl_mpio(plistID, H5FD_MPIO_COLLECTIVE); -#endif - herr_t status; - - status = H5Dwrite(dsetID, h5Type, memSpace, fileSpace, plistID, values); - - if (status < 0) - { - // error - std::cerr << " Write failed. " << std::endl; - } - - H5Dclose(dsetID); - H5Sclose(fileSpace); - H5Sclose(memSpace); - H5Pclose(plistID); + m_H5File.Write(variable, values); } } // end namespace adios diff --git a/source/adios2/engine/hdf5/HDF5WriterP.h b/source/adios2/engine/hdf5/HDF5WriterP.h index 22a1b8f57ef079c04f87680c57bb52fa340f74a0..84c3e182fdf633edf92b5434149b7f5215f0d476 100644 --- a/source/adios2/engine/hdf5/HDF5WriterP.h +++ b/source/adios2/engine/hdf5/HDF5WriterP.h @@ -1,4 +1,3 @@ - /* * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. @@ -12,19 +11,18 @@ #ifndef ADIOS2_ENGINE_HDF5_HDF5WRITERP_H__ #define ADIOS2_ENGINE_HDF5_HDF5WRITERP_H__ -#include "HDF5Common.h" +#include <hdf5.h> #include "adios2/ADIOSConfig.h" #include "adios2/ADIOSMPICommOnly.h" -#include "adios2/capsule/heap/STLVector.h" #include "adios2/core/Engine.h" - -#include <hdf5.h> +#include "adios2/core/IO.h" +#include "adios2/toolkit/interop/hdf5/HDF5Common.h" namespace adios { -class HDF5Writer : public Engine +class HDF5WriterP : public Engine { public: @@ -35,71 +33,27 @@ public: * @param mpiComm * @param method */ - HDF5Writer(ADIOS &adios, const std::string name, - const std::string accessMode, MPI_Comm mpiComm, - const Method &method); - - virtual ~HDF5Writer(); - - 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(Variable<std::complex<float>> &variable, - const std::complex<float> *values); - void Write(Variable<std::complex<double>> &variable, - const std::complex<double> *values); - void Write(Variable<std::complex<long double>> &variable, - const std::complex<long double> *values); + HDF5WriterP(IO &io, const std::string &name, const OpenMode openMode, + MPI_Comm mpiComm); - 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 Write(const std::string &variableName, - const std::complex<float> *values); - void Write(const std::string &variableName, - const std::complex<double> *values); - void Write(const std::string &variableName, - const std::complex<long double> *values); + ~HDF5WriterP(); - void Advance(float timeoutSec = 0.0); + void Advance(const float timeoutSeconds = 0.0) final; - void Close(const int transportIndex = -1); + void Close(const int transportIndex = -1) final; private: - ///< heap capsule, contains data and metadata buffers - // capsule::STLVector m_Buffer; + interop::HDF5Common m_H5File; void Init(); - HDF5Common m_H5File; +#define declare_type(T) \ + void DoWrite(Variable<T> &variable, const T *values) final; + ADIOS2_FOREACH_TYPE_1ARG(declare_type) +#undef declare_type template <class T> - void UseHDFWrite(Variable<T> &variable, const T *values, hid_t h5Type); + void DoWriteCommon(Variable<T> &variable, const T *values); }; } // end namespace adios diff --git a/source/adios2/helper/adiosFunctions.h b/source/adios2/helper/adiosFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..af3e98f18f93c75e745c2903ce5f7ab4e98c662f --- /dev/null +++ b/source/adios2/helper/adiosFunctions.h @@ -0,0 +1,22 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosFunctions.h helper functions used by ADIOS class. This is the only + * required "public" header. + * + * Created on: Oct 10, 2016 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSFUNCTIONS_H_ +#define ADIOS2_HELPER_ADIOSFUNCTIONS_H_ + +#include "adios2/helper/adiosMath.h" //math functions (cmath, algorithm) +#include "adios2/helper/adiosMemory.h" //memcpy, std::copy, insert, resize +#include "adios2/helper/adiosString.h" //std::string manipulation +#include "adios2/helper/adiosSystem.h" //OS functionality, POSIX, filesystem +#include "adios2/helper/adiosType.h" //Type casting, conversion, checks, etc. +#include "adios2/helper/adiosXML.h" //XML parsing + +#endif /* ADIOS2_HELPER_ADIOSFUNCTIONS_H_ */ diff --git a/source/adios2/helper/adiosMath.cpp b/source/adios2/helper/adiosMath.cpp new file mode 100644 index 0000000000000000000000000000000000000000..91f27372d296fd98427db2bf243b02b08c850b78 --- /dev/null +++ b/source/adios2/helper/adiosMath.cpp @@ -0,0 +1,39 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosMath.cpp + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "adiosMath.h" + +namespace adios +{ + +size_t GetTotalSize(const Dims &dimensions) noexcept +{ + size_t product = 1; + + for (const auto dimension : dimensions) + { + product *= dimension; + } + + return product; +} + +bool CheckIndexRange(const int index, const int upperLimit, + const int lowerLimit) noexcept +{ + bool inRange = false; + if (index <= upperLimit && index >= lowerLimit) + { + inRange = true; + } + return inRange; +} + +} // end namespace adios diff --git a/source/adios2/helper/adiosMath.h b/source/adios2/helper/adiosMath.h new file mode 100644 index 0000000000000000000000000000000000000000..69d941b2d502f409ae1c4bfc9bfb3d96ece1c981 --- /dev/null +++ b/source/adios2/helper/adiosMath.h @@ -0,0 +1,95 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosMath.h math functions used in the ADIOS framework + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSMATH_H_ +#define ADIOS2_HELPER_ADIOSMATH_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <vector> +/// \endcond + +#include "adios2/ADIOSTypes.h" + +namespace adios +{ +/** + * Loops through a vector containing dimensions and returns the product of all + * elements + * @param dimensions input containing size on each dimension {Nx, Ny, Nz} + * @return product of all dimensions Nx * Ny * Nz + */ +size_t GetTotalSize(const Dims &dimensions) noexcept; + +/** + * Gets the min and max from a values array of primitive types (not including + * complex) + * @param values input array + * @param size of values array + * @param min of values + * @param max of values + */ +template <class T> +void GetMinMax(const T *values, const size_t size, T &min, T &max) noexcept; + +/** + * Version for complex types of GetMinMax, gets the "doughnut" range between min + * and max modulus. Needed a different function as thread can't resolve the + * overload of a GetMinMax with complex types + * @param values array of complex numbers + * @param size of the values array + * @param min modulus from values + * @param max modulus from values + */ +template <class T> +void GetMinMaxComplex(const std::complex<T> *values, const size_t size, T &min, + T &max) noexcept; + +/** + * Threaded version of GetMinMax. + * Gets the min and max from a values array of primitive types (not including + * complex) using threads + * @param values input array of complex + * @param size of values array + * @param min of values + * @param max of values + * @param threads used for parallel computation + */ +template <class T> +void GetMinMaxThreads(const T *values, const size_t size, T &min, T &max, + const unsigned int threads = 1) noexcept; + +/** + * Overloaded version of GetMinMaxThreads for complex types + * @param values input array of complex + * @param size of values array + * @param min of values + * @param max of values + * @param threads used for parallel computation + */ +template <class T> +void GetMinMaxThreads(const std::complex<T> *values, const size_t size, T &min, + T &max, const unsigned int threads = 1) noexcept; + +/** + * Check if index is within (inclusive) limits + * lowerLimit <= index <= upperLimit + * @param index input to be checked + * @param upperLimit + * @param lowerLimit + * @return true index is within limits + */ +bool CheckIndexRange(const int index, const int upperLimit, + const int lowerLimit = 0) noexcept; + +} // end namespace adios + +#include "adiosMath.inl" + +#endif /* ADIOS2_HELPER_ADIOSMATH_H_ */ diff --git a/source/adios2/helper/adiosMath.inl b/source/adios2/helper/adiosMath.inl new file mode 100644 index 0000000000000000000000000000000000000000..b6d7dce9e8187a9802f1f947f2bd11878370064c --- /dev/null +++ b/source/adios2/helper/adiosMath.inl @@ -0,0 +1,161 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosMath.inl + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSMATH_INL_ +#define ADIOS2_HELPER_ADIOSMATH_INL_ +#ifndef ADIOS2_HELPER_ADIOSMATH_H_ +#error "Inline file should only be included from it's header, never on it's own" +#endif + +#include <algorithm> //std::minmax_element, std::min_element, std::max_element +#include <thread> + +namespace adios +{ + +template <class T> +void GetMinMax(const T *values, const size_t size, T &min, T &max) noexcept +{ + auto bounds = std::minmax_element(values, values + size); + min = *bounds.first; + max = *bounds.second; +} + +template <class T> +void GetMinMaxComplex(const std::complex<T> *values, const size_t size, T &min, + T &max) noexcept +{ + + min = std::norm(values[0]); + max = min; + + for (size_t i = 1; i < size; ++i) + { + T norm = std::norm(values[i]); + + if (norm < min) + { + min = norm; + continue; + } + + if (norm > max) + { + max = norm; + } + } + + min = std::sqrt(min); + max = std::sqrt(max); +} + +template <class T> +void GetMinMaxThreads(const T *values, const size_t size, T &min, T &max, + const unsigned int threads) noexcept +{ + if (threads == 1) + { + GetMinMax(values, size, min, max); + return; + } + + const size_t stride = size / threads; // elements per thread + const size_t remainder = size % threads; // remainder if not aligned + const size_t last = stride + remainder; + + std::vector<T> mins(threads); // zero init + std::vector<T> maxs(threads); // zero init + + std::vector<std::thread> getMinMaxThreads; + getMinMaxThreads.reserve(threads); + + for (unsigned int t = 0; t < threads; ++t) + { + const size_t position = stride * t; + + if (t == threads - 1) + { + getMinMaxThreads.push_back( + std::thread(adios::GetMinMax<T>, &values[position], last, + std::ref(mins[t]), std::ref(maxs[t]))); + } + else + { + getMinMaxThreads.push_back( + std::thread(adios::GetMinMax<T>, &values[position], stride, + std::ref(mins[t]), std::ref(maxs[t]))); + } + } + + for (auto &getMinMaxThread : getMinMaxThreads) + { + getMinMaxThread.join(); + } + + auto itMin = std::min_element(mins.begin(), mins.end()); + min = *itMin; + + auto itMax = std::max_element(maxs.begin(), maxs.end()); + max = *itMax; +} + +template <class T> +void GetMinMaxThreads(const std::complex<T> *values, const size_t size, T &min, + T &max, const unsigned int threads) noexcept +{ + if (threads == 1) + { + GetMinMaxComplex(values, size, min, max); + return; + } + + const size_t stride = size / threads; // elements per thread + const size_t remainder = size % threads; // remainder if not aligned + const size_t last = stride + remainder; + + std::vector<T> mins(threads); // zero init + std::vector<T> maxs(threads); // zero init + + std::vector<std::thread> getMinMaxThreads; + getMinMaxThreads.reserve(threads); + + for (unsigned int t = 0; t < threads; ++t) + { + const size_t position = stride * t; + + if (t == threads - 1) + { + getMinMaxThreads.push_back( + std::thread(GetMinMaxComplex<T>, &values[position], last, + std::ref(mins[t]), std::ref(maxs[t]))); + } + else + { + getMinMaxThreads.push_back( + std::thread(GetMinMaxComplex<T>, &values[position], stride, + std::ref(mins[t]), std::ref(maxs[t]))); + } + } + + for (auto &getMinMaxThread : getMinMaxThreads) + { + getMinMaxThread.join(); + } + + auto itMin = std::min_element(mins.begin(), mins.end()); + min = *itMin; + + auto itMax = std::max_element(maxs.begin(), maxs.end()); + max = *itMax; +} + +} // end namespace adios + +#endif /* ADIOS2_HELPER_ADIOSMATH_INL_ */ diff --git a/source/adios2/helper/adiosMemory.cpp b/source/adios2/helper/adiosMemory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5420b698d975b72c13105b86d54d5aa77eb5fa50 --- /dev/null +++ b/source/adios2/helper/adiosMemory.cpp @@ -0,0 +1,49 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosMemory.cpp + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "adiosMemory.h" + +namespace adios +{ + +int GrowBuffer(const size_t incomingDataSize, const float growthFactor, + std::vector<char> &buffer, const size_t position) +{ + const size_t currentCapacity = buffer.capacity(); + const size_t availableSpace = currentCapacity - position; + const double gf = static_cast<double>(growthFactor); + + if (incomingDataSize < availableSpace) + { + return 0; + } + + const size_t neededCapacity = incomingDataSize + position; + const double numerator = std::log(static_cast<double>(neededCapacity) / + static_cast<double>(currentCapacity)); + const double denominator = std::log(gf); + + const double n = std::ceil(numerator / denominator); + const size_t newSize = + static_cast<size_t>(std::ceil(std::pow(gf, n) * currentCapacity)); + + try + { + buffer.resize(newSize); + } + catch (std::bad_alloc &e) + { + return -1; + } + + return 1; +} + +} // end namespace adios diff --git a/source/adios2/helper/adiosMemory.h b/source/adios2/helper/adiosMemory.h new file mode 100644 index 0000000000000000000000000000000000000000..aa2c6f785a95ecebae1f31db80936ffc6401cd86 --- /dev/null +++ b/source/adios2/helper/adiosMemory.h @@ -0,0 +1,103 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosMemory.h : Memory copy operations functions using std::copy std::insert + * and std::memcpy + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSMEMORY_H_ +#define ADIOS2_HELPER_ADIOSMEMORY_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <vector> +/// \endcond + +#include "adios2/ADIOSTypes.h" + +namespace adios +{ + +/** + * Inserts source at the end of a buffer updating buffer.size() + * @param buffer data destination calls insert() + * @param source pointer to source data + * @param elements number of elements of source type + */ +template <class T> +void InsertToBuffer(std::vector<char> &buffer, const T *source, + const size_t elements = 1) noexcept; + +/** + * Copies data to a specific location in the buffer updating position + * Does not update vec.size(). + * @param buffer data destination used in std::copy + * @param position starting position in buffer (in terms of T not bytes) + * @param source pointer to source data + * @param elements number of elements of source type + */ +template <class T> +void CopyToBuffer(std::vector<char> &buffer, size_t &position, const T *source, + const size_t elements = 1) noexcept; + +/** + * Copies data to a specific location in the buffer updating position using + * threads. + * Does not update vec.size(). + * @param buffer data destination used in std::copy + * @param position starting position in buffer (in terms of T not bytes) + * @param source pointer to source data + * @param elements number of elements of source type + * @param threads number of threads sharing the copy load + */ +template <class T> +void CopyToBufferThreads(std::vector<char> &buffer, size_t &position, + const T *source, const size_t elements = 1, + const unsigned int threads = 1) noexcept; + +/** + * Memcpy data to a specific location in the buffer updating position + * Does not update vec.size(). + * @param buffer data destination used in memcpy + * @param position starting position in buffer (in terms of T not bytes) + * @param source pointer to source data + * @param size number of bytes from source + */ +template <class T> +void MemcpyToBuffer(std::vector<char> &buffer, size_t &position, + const T *source, size_t size) noexcept; + +/** + * Threaded version of MemcpyToBuffer + * @param buffer data destination used in memcpy + * @param position starting position in buffer (in terms of T not bytes) + * @param source pointer to source data + * @param size number of bytes from source + * @param threads number of threads sharing the memcpy load + */ +template <class T> +void MemcpyToBufferThreads(std::vector<char> &buffer, size_t &position, + const T *source, size_t size, + const unsigned int threads = 1); + +/** + * Grows a buffer by a factor of n . growthFactor . currentCapacity to + * accommodate for incomingDataSize + * @param incomingDataSize size of new data required to be stored in buffer + * @param growthFactor buffer grows in multiples of the growth buffer + * @param buffer to be resized + * @param position, current buffer position + * @return -1: failed to allocate (bad_alloc), 0: didn't have to allocate + * (enough space), 1: successful allocation + */ +int GrowBuffer(const size_t incomingDataSize, const float growthFactor, + std::vector<char> &buffer, const size_t position); + +} // end namespace adios + +#include "adiosMemory.inl" + +#endif /* ADIOS2_HELPER_ADIOSMEMORY_H_ */ diff --git a/source/adios2/helper/adiosMemory.inl b/source/adios2/helper/adiosMemory.inl new file mode 100644 index 0000000000000000000000000000000000000000..949c256d54ad95879d764f9ba1fbc76f5a9540ba --- /dev/null +++ b/source/adios2/helper/adiosMemory.inl @@ -0,0 +1,150 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosMemory.inl definition of template functions in adiosMemory.h + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSMEMORY_INL_ +#define ADIOS2_HELPER_ADIOSMEMORY_INL_ +#ifndef ADIOS2_HELPER_ADIOSMEMORY_H_ +#error "Inline file should only be included from it's header, never on it's own" +#endif + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <algorithm> //std::copy +#include <cstring> //std::memcpy +#include <thread> +/// \endcond + +namespace adios +{ + +template <class T> +void InsertToBuffer(std::vector<char> &buffer, const T *source, + const std::size_t elements) noexcept +{ + const char *src = reinterpret_cast<const char *>(source); + buffer.insert(buffer.end(), src, src + elements * sizeof(T)); +} + +template <class T> +void CopyToBuffer(std::vector<char> &buffer, size_t &position, const T *source, + const size_t elements) noexcept +{ + const char *src = reinterpret_cast<const char *>(source); + std::copy(src, src + elements * sizeof(T), buffer.begin() + position); + position += elements * sizeof(T); +} + +template <class T> +void CopyToBufferThreads(std::vector<char> &buffer, size_t &position, + const T *source, const size_t elements, + const unsigned int threads) noexcept +{ + if (threads == 1) + { + CopyToBuffer(buffer, position, source, elements); + return; + } + + const size_t stride = elements / threads; // elements per thread + const size_t remainder = elements % threads; // remainder if not aligned + const size_t last = stride + remainder; + + std::vector<std::thread> copyThreads; + copyThreads.reserve(threads); + + for (unsigned int t = 0; t < threads; ++t) + { + size_t bufferPosition = stride * t * sizeof(T); + const size_t sourcePosition = stride * t; + + if (t == threads - 1) // last thread takes stride + remainder + { + copyThreads.push_back(std::thread(CopyToBuffer<T>, std::ref(buffer), + std::ref(bufferPosition), + &source[sourcePosition], last)); + position = bufferPosition; // last position + } + else + { + copyThreads.push_back(std::thread(CopyToBuffer<T>, std::ref(buffer), + std::ref(bufferPosition), + &source[sourcePosition], stride)); + } + } + + for (auto ©Thread : copyThreads) + { + copyThread.join(); + } +} + +template <class T> +void CopyFromBuffer(T *destination, size_t elements, + const std::vector<char> &buffer, size_t &position) noexcept +{ + std::copy(buffer.begin() + position, + buffer.begin() + position + sizeof(T) * elements, + reinterpret_cast<char *>(destination)); + position += elements * sizeof(T); +} + +template <class T> +void MemcpyToBuffer(std::vector<char> &buffer, size_t &position, + const T *source, size_t size) noexcept +{ + std::memcpy(&buffer[position], source, size); + position += size; +} + +template <class T> +void MemcpyToBufferThreads(std::vector<char> &buffer, size_t &position, + const T *source, size_t size, + const unsigned int threads) +{ + if (threads == 1) + { + std::memcpy(&buffer[position], source, size); + return; + } + + const size_t stride = size / threads; + const size_t remainder = size % threads; + const size_t last = stride + remainder; + + std::vector<std::thread> memcpyThreads; + memcpyThreads.reserve(threads); + + for (unsigned int t = 0; t < threads; ++t) + { + const size_t initialDestination = position + stride * t; + const size_t initialSource = stride * t / sizeof(T); + + if (t == threads - 1) + { + memcpyThreads.push_back(std::thread(std::memcpy, + &buffer[initialDestination], + &source[initialSource], last)); + } + else + { + memcpyThreads.push_back( + std::thread(std::memcpy, &buffer[initialDestination], + &source[initialSource], stride)); + } + } + + for (auto &thread : memcpyThreads) + { + thread.join(); + } +} + +} // end namespace + +#endif /* ADIOS2_HELPER_ADIOSMEMORY_INL_ */ diff --git a/source/adios2/helper/adiosString.cpp b/source/adios2/helper/adiosString.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69d34efd7e2d87447a3f64f0594bde7876e46c70 --- /dev/null +++ b/source/adios2/helper/adiosString.cpp @@ -0,0 +1,134 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosString.cpp + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "adiosString.h" + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <fstream> +#include <ios> //std::ios_base::failure +#include <sstream> +#include <stdexcept> // std::invalid_argument +/// \endcond + +namespace adios +{ + +std::string FileToString(const std::string &fileName) +{ + std::ifstream fileStream(fileName); + + if (!fileStream.good()) + { + throw std::ios_base::failure( + "ERROR: file " + fileName + + " could not be opened. Check permissions or existence\n"); + } + + std::ostringstream fileSS; + fileSS << fileStream.rdbuf(); + fileStream.close(); + return fileSS.str(); +} + +Params BuildParametersMap(const std::vector<std::string> ¶meters, + const bool debugMode) +{ + auto lf_GetFieldValue = [](const std::string parameter, std::string &field, + std::string &value, const bool debugMode) { + auto equalPosition = parameter.find("="); + + if (debugMode) + { + if (equalPosition == parameter.npos) + { + throw std::invalid_argument( + "ERROR: wrong format for parameter " + parameter + + ", format must be field=value \n"); + } + + if (equalPosition == parameter.size() - 1) + { + throw std::invalid_argument("ERROR: empty value in parameter " + + parameter + + ", format must be field=value \n"); + } + } + + field = parameter.substr(0, equalPosition); + value = parameter.substr(equalPosition + 1); // need to test + }; + + // BODY OF FUNCTION STARTS HERE + Params parametersOutput; + + for (const auto parameter : parameters) + { + std::string field, value; + lf_GetFieldValue(parameter, field, value, debugMode); + + if (debugMode) + { + if (parametersOutput.count(field) == 1) + { + throw std::invalid_argument( + "ERROR: parameter " + field + + " already exists, must be unique\n"); + } + } + + parametersOutput[field] = value; + } + + return parametersOutput; +} + +std::string AddExtension(const std::string &name, + const std::string extension) noexcept +{ + std::string result(name); + if (name.find(extension) != name.size() - 3) + { + result += extension; + } + return result; +} + +std::vector<std::string> +GetParametersValues(const std::string &key, + const std::vector<Params> ¶metersVector) noexcept +{ + std::vector<std::string> values; + values.reserve(parametersVector.size()); + + for (const auto ¶meters : parametersVector) + { + auto itKey = parameters.find(key); + std::string value; + if (itKey != parameters.end()) + { + value = itKey->second; + } + values.push_back(value); + } + + return values; +} + +void SetParameterValue(const std::string key, const Params ¶meters, + std::string &value) noexcept +{ + auto itKey = parameters.find(key); + if (itKey != parameters.end()) + { + value = itKey->second; + } +} + +} // end namespace adios diff --git a/source/adios2/helper/adiosString.h b/source/adios2/helper/adiosString.h new file mode 100644 index 0000000000000000000000000000000000000000..64f851c52e0652982bb856292cdbeaa4e36d2824 --- /dev/null +++ b/source/adios2/helper/adiosString.h @@ -0,0 +1,72 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosString.h string manipulation functionality + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSSTRING_H_ +#define ADIOS2_HELPER_ADIOSSTRING_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <map> +#include <string> +#include <vector> +/// \endcond + +#include "adios2/ADIOSTypes.h" + +namespace adios +{ + +/** + * Opens and checks for file and dumps content to a single string. + * @param fileName of text file + * @return file contents in a string + */ +std::string FileToString(const std::string &fileName); + +/** + * Transforms a vector to a map of parameters + * @param parameters vector of parameters with format "field=value" + * @param debugMode true=check parameters format, false=no checks + * @return a map with unique key=field, value=corresponding value + */ +Params BuildParametersMap(const std::vector<std::string> ¶meters, + const bool debugMode); + +/** + * Add name extension if not existing at the end of name + * @param name input + * @param extension .ext .bp + * @return if name already has extension returns name (name.bp), otherwise + * returns name.extension (name.bp) + */ +std::string AddExtension(const std::string &name, + const std::string extension) noexcept; + +/** + * Get values for each param entry of a certain key in a vector. + * If key not found then string in vector is empty. + * @param key parameter to be extracted + * @param parametersVector + * @return vector of values, from key,value in parametersVector + */ +std::vector<std::string> +GetParametersValues(const std::string &key, + const std::vector<Params> ¶metersVector) noexcept; + +/** + * Searches key and assign value from parameters map + * @param field input to look for in parameters + * @param parameters map with key: field, value: value + * @param value if found it's modified to value in parameters + */ +void SetParameterValue(const std::string key, const Params ¶meters, + std::string &value) noexcept; +} + +#endif /* ADIOS2_HELPER_ADIOSSTRING_H_ */ diff --git a/source/adios2/helper/adiosSystem.cpp b/source/adios2/helper/adiosSystem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9836130796bb035d886d0d8c60bd334c20748ac5 --- /dev/null +++ b/source/adios2/helper/adiosSystem.cpp @@ -0,0 +1,80 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosSystem.cpp implementation of adiosSystem.h functions + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ +#include "adiosSystem.h" + +#include <sys/stat.h> //stat, mkdir +#include <sys/types.h> //CreateDirectory +#include <unistd.h> //CreateDirectory + +#include <chrono> //system_clock, now +#include <ctime> //std::ctime + +#include "adios2/ADIOSTypes.h" + +namespace adios +{ + +bool CreateDirectory(const std::string &fullPath) noexcept +{ + auto lf_Mkdir = [](const std::string directory, struct stat &st) -> bool { + if (stat(directory.c_str(), &st) == -1) // doesn't exist + { + mkdir(directory.c_str(), 0777); + if (stat(directory.c_str(), &st) == -1) // doesn't exist + { + return false; + } + } + return true; + }; + + bool directoryExists = false; + auto directoryPosition = fullPath.find("/"); + + if (fullPath[0] == '/' || fullPath[0] == '.') + { // find the second '/' + directoryPosition = fullPath.find("/", directoryPosition + 1); + } + + struct stat st = {0}; + if (directoryPosition == fullPath.npos) // no subdirectories + { + directoryExists = lf_Mkdir(fullPath.c_str(), st); + } + else + { + std::string directory(fullPath.substr(0, directoryPosition)); + lf_Mkdir(directory.c_str(), st); + + while (directoryPosition != fullPath.npos) + { + directoryPosition = fullPath.find("/", directoryPosition + 1); + directory = fullPath.substr(0, directoryPosition); + directoryExists = lf_Mkdir(directory.c_str(), st); + } + } + return directoryExists; +} + +bool IsLittleEndian() noexcept +{ + uint16_t hexa = 0x1234; + return *reinterpret_cast<uint8_t *>(&hexa) != 0x12; // NOLINT +} + +std::string LocalTimeDate() noexcept +{ + std::time_t now = + std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + + return std::string(std::ctime(&now)); +} + +} // end namespace adios diff --git a/source/adios2/helper/adiosSystem.h b/source/adios2/helper/adiosSystem.h new file mode 100644 index 0000000000000000000000000000000000000000..9374d160370839377b6c4897f3b489fbb850216e --- /dev/null +++ b/source/adios2/helper/adiosSystem.h @@ -0,0 +1,46 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosSystem.h system related functions using std or POSIX, + * we might wait for C++17 filesystem + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSSYSTEM_H_ +#define ADIOS2_HELPER_ADIOSSYSTEM_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <string> +#include <vector> +/// \endcond + +namespace adios +{ + +/** + * Creates a chain of directories using POSIX systems calls (stat, mkdir), + * Verifies if directory exists before creating a new one. Permissions are 777 + * for now + * @param fullPath /full/path/for/directory + * @return true: directory exists, false: failed to create or access directory + */ +bool CreateDirectory(const std::string &fullPath) noexcept; + +/** + * Check if system is little endian + * @return true: little endian, false: big endian + */ +bool IsLittleEndian() noexcept; + +/** + * returns a string with current local time and date information from std::ctime + * @return string from char* std::ctime + */ +std::string LocalTimeDate() noexcept; + +} // end namespace adios + +#endif /* ADIOS2_HELPER_ADIOSSYSTEM_H_ */ diff --git a/source/adios2/helper/adiosType.cpp b/source/adios2/helper/adiosType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f5d3e3430fa5d03d943c85cd0d44f30b1581f1e8 --- /dev/null +++ b/source/adios2/helper/adiosType.cpp @@ -0,0 +1,215 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosType.cpp + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "adiosType.h" +#include "adiosType.inl" + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <algorithm> //std::transform, std::count +#include <sstream> +/// \endcond + +namespace adios +{ + +std::string DimsToCSV(const Dims &dimensions) noexcept +{ + std::string dimsCSV; + + for (const auto dimension : dimensions) + { + dimsCSV += std::to_string(dimension) + ","; + } + + if (!dimsCSV.empty()) + { + dimsCSV.pop_back(); // remove last comma + } + + return dimsCSV; +} + +std::vector<int> CSVToVectorInt(const std::string csv) noexcept +{ + std::vector<int> numbers; + if (csv.empty()) + { + return numbers; + } + + if (csv.find(",") == csv.npos) // if no commas, one int + { + numbers.push_back(std::stoi(csv)); // might need to be checked + } + else + { + int count = std::count(csv.begin(), csv.end(), ','); + numbers.reserve(count); + + std::istringstream csvSS(csv); + std::string value; + while (std::getline(csvSS, value, ',')) + { + numbers.push_back(std::stoi(csv)); + } + } + + return numbers; +} + +void ConvertUint64VectorToSizetVector(const std::vector<uint64_t> &in, + std::vector<size_t> &out) noexcept +{ + out.resize(in.size()); + std::transform(in.begin(), in.end(), out.begin(), + [](uint64_t value) { return static_cast<size_t>(value); }); +} + +void Uint64ArrayToSizetVector(const size_t nElements, const uint64_t *in, + std::vector<size_t> &out) noexcept +{ + out.resize(nElements); + for (size_t i = 0; i < nElements; i++) + { + out[i] = static_cast<size_t>(in[i]); + } +} + +std::vector<std::size_t> Uint64ArrayToSizetVector(const size_t nElements, + const uint64_t *in) noexcept +{ + std::vector<size_t> out(nElements); + for (size_t i = 0; i < nElements; i++) + { + out[i] = static_cast<size_t>(in[i]); + } + return out; +} + +std::vector<std::size_t> +Uint64VectorToSizetVector(const std::vector<uint64_t> &in) noexcept +{ + std::vector<size_t> out(in.size()); + out.resize(in.size()); + std::transform(in.begin(), in.end(), out.begin(), + [](uint64_t value) { return static_cast<size_t>(value); }); + + return out; +} + +TimeUnit StringToTimeUnit(const std::string timeUnitString, + const bool debugMode) +{ + TimeUnit timeUnit = TimeUnit::Microseconds; // default + + if (timeUnitString == "Microseconds") + { + timeUnit = TimeUnit::Microseconds; + } + else if (timeUnitString == "Milliseconds") + { + timeUnit = TimeUnit::Milliseconds; + } + else if (timeUnitString == "Seconds") + { + timeUnit = TimeUnit::Seconds; + } + else if (timeUnitString == "Minutes") + { + timeUnit = TimeUnit::Minutes; + } + else if (timeUnitString == "Hours") + { + timeUnit = TimeUnit::Hours; + } + else + { + if (debugMode) + { + throw std::invalid_argument("ERROR: profile_units=value " + " must be Microseconds, Milliseconds, " + "Seconds, Minutes or Hours\n"); + } + } + return timeUnit; +} + +size_t BytesFactor(const std::string units, const bool debugMode) +{ + size_t factor = 1; // bytes + if (units == "Gb") + { + factor = 1024 * 1024 * 1024; + } + else if (units == "Mb") + { + factor = 1024 * 1024; + } + else if (units == "Kb") + { + factor = 1024; + } + else if (units == "b" || units == "bytes") + { + // do nothing + } + else + { + if (debugMode) + { + throw std::invalid_argument("ERROR: units " + units + + " not supported\n"); + } + } + return factor; +} + +std::string OpenModeToString(const OpenMode openMode, + const bool oneLetter) noexcept +{ + std::string openModeString; + + if (openMode == OpenMode::Write) + { + if (oneLetter) + { + openModeString = "w"; + } + else + { + openModeString = "Write"; + } + } + else if (openMode == OpenMode::Append) + { + if (oneLetter) + { + openModeString = "a"; + } + else + { + openModeString = "Append"; + } + } + else if (openMode == OpenMode::Read) + { + if (oneLetter) + { + openModeString = "r"; + } + else + { + openModeString = "Read"; + } + } + return openModeString; +} + +} // end namespace adios diff --git a/source/adios2/helper/adiosType.h b/source/adios2/helper/adiosType.h new file mode 100644 index 0000000000000000000000000000000000000000..d98d9a4f95eff007df21a3e2bbbc6fffb611d4e1 --- /dev/null +++ b/source/adios2/helper/adiosType.h @@ -0,0 +1,114 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosType.h helper functions for types: conversion, mapping, etc. + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSTYPE_H_ +#define ADIOS2_HELPER_ADIOSTYPE_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <map> +#include <set> +#include <string> +#include <vector> +/// \endcond + +#include "adios2/ADIOSTypes.h" + +namespace adios +{ + +/** + * Gets type from template parameter T + * @return string with type + */ +template <class T> +inline std::string GetType() noexcept; + +/** + * Check in types set if "type" is one of the aliases for a certain type, + * (e.g. if type = integer is an accepted alias for "int", returning true) + * @param type input to be compared with an alias + * @param aliases set containing aliases to a certain type, typically + * Support::DatatypesAliases from Support.h + * @return true: is an alias, false: is not + */ +template <class T> +bool IsTypeAlias( + const std::string type, + const std::map<std::string, std::set<std::string>> &aliases) noexcept; + +/** + * Converts a vector of dimensions to a CSV string + * @param dims vector of dimensions + * @return comma separate value (CSV) + */ +std::string DimsToCSV(const Dims &dimensions) noexcept; + +/** + * Converts comma-separated values (csv) to a vector of integers + * @param csv "1,2,3" + * @return vector<int> = { 1, 2, 3 } + */ +std::vector<int> CSVToVectorInt(const std::string csv) noexcept; + +/** + * Convert a vector of uint64_t element into size_t + * @param in uint64_t vector + * @param out size_t vector with contents of in + */ +void ConvertUint64VectorToSizetVector(const std::vector<uint64_t> &in, + std::vector<size_t> &out) noexcept; + +/** Convert a C array of uint64_t elements to a vector of std::size_t elements + * @param number of elements + * @param input array of uint64_t elements + * @param vector of std::size_t elements. It will be resized to nElements. + */ +void Uint64ArrayToSizetVector(const size_t nElements, const uint64_t *in, + std::vector<size_t> &out) noexcept; + +/** Convert a C array of uint64_t elements to a vector of std::size_t elements + * @param number of elements + * @param input array of uint64_t elements + * @return vector of std::size_t elements + */ +std::vector<size_t> Uint64ArrayToSizetVector(const size_t nElements, + const uint64_t *in) noexcept; + +/** + * Converts a recognized time unit string to TimeUnit enum + * @param timeUnit string with acceptable time unit + * @param debugMode true: throw exception if timeUnitString not valid + * @return TimeUnit enum (int) TimeUnit::s, TimeUnit::ms, etc. + */ +TimeUnit StringToTimeUnit(const std::string timeUnitString, + const bool debugMode); + +/** + * Returns the conversion factor from input units Tb, Gb, Mb, Kb, to bytes as a + * factor of 1024 + * @param units input + * @param debugMode true: check if input units are valid + * @return conversion factor to bytes, size_t + */ +size_t BytesFactor(const std::string units, const bool debugMode); + +/** + * Returns open mode as a string + * @param openMode from ADIOSTypes.h + * @param oneLetter if true returns a one letter version ("w", "a" or "r") + * @return string with open mode + */ +std::string OpenModeToString(const OpenMode openMode, + const bool oneLetter = false) noexcept; +} + +#include "adiosType.inl" + +#endif /* ADIOS2_HELPER_ADIOSTYPE_H_ */ diff --git a/source/adios2/helper/adiosType.inl b/source/adios2/helper/adiosType.inl new file mode 100644 index 0000000000000000000000000000000000000000..cb8424259ed3e6e6725932a0a11d7f8e04b3420c --- /dev/null +++ b/source/adios2/helper/adiosType.inl @@ -0,0 +1,132 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosType.inl implementation of template functions in adiosType.h + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSTYPE_INL_ +#define ADIOS2_HELPER_ADIOSTYPE_INL_ +#ifndef ADIOS2_HELPER_ADIOSTYPE_H_ +#error "Inline file should only be included from it's header, never on it's own" +#endif + +namespace adios +{ + +template <class T> +inline std::string GetType() noexcept +{ + return "compound"; +} +template <> +inline std::string GetType<void>() noexcept +{ + return "unknown"; +} +template <> +inline std::string GetType<char>() noexcept +{ + return "char"; +} +template <> +inline std::string GetType<unsigned char>() noexcept +{ + return "unsigned char"; +} +template <> +inline std::string GetType<short>() noexcept +{ + return "short"; +} +template <> +inline std::string GetType<unsigned short>() noexcept +{ + return "unsigned short"; +} +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"; +} +template <> +inline std::string GetType<std::complex<float>>() noexcept +{ + return "float complex"; +} +template <> +inline std::string GetType<std::complex<double>>() noexcept +{ + return "double complex"; +} +template <> +inline std::string GetType<std::complex<long double>>() noexcept +{ + return "long double complex"; +} + +template <class T> +bool IsTypeAlias( + const std::string type, + const std::map<std::string, std::set<std::string>> &aliases) noexcept +{ + if (type == GetType<T>()) // is key itself + { + return true; + } + + bool isAlias = false; + if (aliases.at(GetType<T>()).count(type) == 1) + { + isAlias = true; + } + + return isAlias; +} + +} // end namespace adios + +#endif /* ADIOS2_HELPER_ADIOSTYPE_INL_ */ diff --git a/source/adios2/core/adiosFunctions.cpp b/source/adios2/helper/adiosXML.cpp similarity index 56% rename from source/adios2/core/adiosFunctions.cpp rename to source/adios2/helper/adiosXML.cpp index ad8ed6ca418d9ecace76b1c8ffff325de851f26c..746a436145472b910e58d2dccec7e6adc8b9d363 100644 --- a/source/adios2/core/adiosFunctions.cpp +++ b/source/adios2/helper/adiosXML.cpp @@ -2,61 +2,21 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * adiosFunctions.cpp + * adiosXML.cpp * - * Created on: Oct 10, 2016 - * Author: wfg + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov */ -#include "adiosFunctions.h" -/// \cond EXCLUDE_FROM_DOXYGEN -#include <sys/stat.h> //stat -#include <sys/types.h> //CreateDirectory -#include <unistd.h> //CreateDirectory +#include "adiosXML.h" -#include <algorithm> //std::count -#include <cmath> // std::ceil, std::pow, std::log -#include <cstring> //std::memcpy -#include <fstream> -#include <ios> //std::ios_base::failure -#include <sstream> -#include <stdexcept> -#include <thread> //std::thread +/// \cond EXCLUDE_FROM_DOXYGEN +#include <stdexcept> //std::invalid_argument /// \endcond -#include "adios2/ADIOSMPI.h" -#include "adios2/ADIOSTypes.h" -#include "adios2/core/Support.h" - -#ifdef ADIOS2_HAVE_BZIP2 -#include "adios2/transform/BZip2.h" -#endif - namespace adios { -void DumpFileToString(const std::string fileName, std::string &fileContent) -{ - std::ifstream fileStream(fileName); - - if (fileStream.good() == false) - { // check file - throw std::ios_base::failure( - "ERROR: file " + fileName + - " could not be opened. Check permissions or file existence\n"); - } - - std::ostringstream fileSS; - fileSS << fileStream.rdbuf(); - fileStream.close(); - fileContent = fileSS.str(); // convert to string and check - - if (fileContent.empty()) - { - throw std::invalid_argument("ERROR: file " + fileName + " is empty\n"); - } -} - void GetSubString(const std::string initialTag, const std::string finalTag, const std::string content, std::string &subString, std::string::size_type ¤tPosition) @@ -96,7 +56,7 @@ void GetSubString(const std::string initialTag, const std::string finalTag, // find next bool isValue = true; - while (isValue == true) + while (isValue) { std::string::size_type singleQuotePosition = content.find('\'', currentPosition); @@ -273,13 +233,13 @@ void GetPairsFromTag( // if( pair.first == "host-language" ) // hostLanguage = pair.second; // -// if( debugMode == true ) +// if( debugMode ) // { // if( Support::HostLanguages.count( hostLanguage ) == 0 ) // throw std::invalid_argument("ERROR: host language " + hostLanguage // + " not supported.\n" ); // -// if( hostLanguage.empty() == true ) +// if( hostLanguage.empty() ) // throw std::invalid_argument("ERROR: host language is empty.\n" ); // } // @@ -298,7 +258,7 @@ void GetPairsFromTag( // //get group name // std::string::size_type groupPosition( 0 ); // GetSubString( "<adios-group ", ">", xmlGroup, tag, groupPosition ); -// if( debugMode == true ) +// if( debugMode ) // { // if( tag.size() < 2 ) // throw std::invalid_argument( "ERROR: wrong tag " + tag + " in @@ -315,7 +275,7 @@ void GetPairsFromTag( // groupName = pair.second; // } // -// if( debugMode == true ) +// if( debugMode ) // { // if( groupName.empty() ) // throw std::invalid_argument( "ERROR: group name not found. \n" @@ -341,11 +301,11 @@ void GetPairsFromTag( // const bool debugMode, int& field ) // { // field = 0; -// if( fieldStr.empty() == false ) +// if( !fieldStr.empty()) // { // field = std::stoi( fieldStr ); //throws invalid_argument // -// if( debugMode == true ) +// if( debugMode ) // { // if( field < 0 ) // throw std::invalid_argument("ERROR: " + fieldName + " in @@ -375,7 +335,7 @@ void GetPairsFromTag( // } // // auto itGroup = groups.find( groupName ); -// if( debugMode == true ) +// if( debugMode ) // { // if( itGroup == groups.end() ) //not found // throw std::invalid_argument( "ERROR: in transport " + method + @@ -433,294 +393,4 @@ void GetPairsFromTag( // groups ); //} -std::size_t GetTotalSize(const std::vector<std::size_t> &dimensions) -{ - std::size_t product = 1; - - for (const auto dimension : dimensions) - { - product *= dimension; - } - - return product; -} - -void CreateDirectory(const std::string fullPath) noexcept -{ - auto lf_Mkdir = [](const std::string directory, struct stat &st) { - if (stat(directory.c_str(), &st) == -1) - { - mkdir(directory.c_str(), 0777); - } - }; - - auto directoryPosition = fullPath.find("/"); - - if (fullPath[0] == '/' || fullPath[0] == '.') - { // find the second '/' - directoryPosition = fullPath.find("/", directoryPosition + 1); - } - - struct stat st = {0}; - if (directoryPosition == fullPath.npos) // no subdirectories - { - lf_Mkdir(fullPath.c_str(), st); - return; - } - - std::string directory(fullPath.substr(0, directoryPosition)); - lf_Mkdir(directory.c_str(), st); - - while (directoryPosition != fullPath.npos) - { - directoryPosition = fullPath.find("/", directoryPosition + 1); - directory = fullPath.substr(0, directoryPosition); - lf_Mkdir(directory.c_str(), st); - } -} - -void SetTransformsHelper(const std::vector<std::string> &transformNames, - std::vector<std::shared_ptr<Transform>> &transforms, - const bool debugMode, - std::vector<short> &transformIndices, - std::vector<short> ¶meters) -{ - // function to get a parameter from "method:parameter" - auto lf_GetParameter = [](const std::string transformName, - std::string &transformMethod, - const bool debugMode) -> short { - short parameter = -1; - auto colonPosition = transformName.find(":"); - - if (colonPosition != transformName.npos) - { - if (debugMode == true) - { - if (colonPosition == transformName.size() - 1) - { - throw std::invalid_argument( - "ERROR: wrong format for transform " + transformName + - ", in call to SetTransform\n"); - } - } - - transformMethod = transformName.substr(0, colonPosition); - parameter = std::stoi( - transformName.substr(colonPosition + 1)); // need to test - } - return parameter; - }; - - // Get transform index from transforms, if not found return -1 - auto lf_GetTransformIndex = - [](const std::string transformMethod, - const std::vector<std::shared_ptr<Transform>> &transforms) -> short { - short transformIndex = -1; - for (unsigned int i = 0; i < transforms.size(); ++i) - { - if (transforms[i]->m_Method == transformMethod) - { - transformIndex = i; - break; - } - } - return transformIndex; - }; - - // BODY of FUNCTION STARTS HERE - for (const std::string transformName : transformNames) - { - std::string transformMethod(transformName); - short parameter = - lf_GetParameter(transformName, transformMethod, - debugMode); // from transform = "method:parameter" - short transformIndex = - lf_GetTransformIndex(transformMethod, transforms); - - if (transformIndex == -1) // not found, then create a new transform - { - if (transformMethod == "bzip2") - { -#ifdef ADIOS2_HAVE_BZIP2 - transforms.push_back( - std::make_shared<adios::transform::BZip2>()); -#endif - } - - transformIndex = static_cast<short>(transforms.size() - 1); - } - transformIndices.push_back(transformIndex); - parameters.push_back(parameter); - } -} - -std::map<std::string, std::string> -BuildParametersMap(const std::vector<std::string> ¶meters, - const bool debugMode) -{ - auto lf_GetFieldValue = [](const std::string parameter, std::string &field, - std::string &value, const bool debugMode) { - auto equalPosition = parameter.find("="); - - if (debugMode == true) - { - if (equalPosition == parameter.npos) - { - throw std::invalid_argument( - "ERROR: wrong format for parameter " + parameter + - ", format must be field=value \n"); - } - - if (equalPosition == parameter.size() - 1) - { - throw std::invalid_argument("ERROR: empty value in parameter " + - parameter + - ", format must be field=value \n"); - } - } - - field = parameter.substr(0, equalPosition); - value = parameter.substr(equalPosition + 1); // need to test - }; - - // BODY OF FUNCTION STARTS HERE - std::map<std::string, std::string> parametersOutput; - - for (const auto parameter : parameters) - { - std::string field, value; - lf_GetFieldValue(parameter, field, value, debugMode); - - if (debugMode == true) - { - if (parametersOutput.count(field) == 1) - { - throw std::invalid_argument( - "ERROR: parameter " + field + - " already exists, must be unique\n"); - } - } - - parametersOutput[field] = value; - } - - return parametersOutput; -} - -std::vector<int> CSVToVectorInt(const std::string csv) -{ - std::vector<int> numbers; - if (csv.empty()) - { - return numbers; - } - - if (csv.find(",") == csv.npos) // check if no commas, one int - { - numbers.push_back(std::stoi(csv)); // might need to be checked - } - else - { - int count = std::count(csv.begin(), csv.end(), ','); - numbers.reserve(count); - - std::istringstream csvSS(csv); - std::string value; - while (std::getline(csvSS, value, ',')) // need to test - { - numbers.push_back(std::stoi(csv)); - } - } - - return numbers; -} - -std::string DimsToCSV(const std::vector<std::size_t> &dims) -{ - std::string dimsCSV; - - for (const auto dim : dims) - { - dimsCSV += std::to_string(dim) + ","; - } - - if (dimsCSV.empty() == false) - { - dimsCSV.pop_back(); - } - - return dimsCSV; -} - -void ConvertUint64VectorToSizetVector(const std::vector<std::uint64_t> &in, - std::vector<std::size_t> &out) -{ - out.clear(); - out.reserve(in.size()); - for (const auto inElement : in) - { - out.push_back(static_cast<std::size_t>(inElement)); - } -} - -void Uint64ArrayToSizetVector(const std::size_t nElements, const uint64_t *in, - std::vector<std::size_t> &out) -{ - out.resize(nElements); - for (std::size_t i = 0; i < nElements; i++) - { - out[i] = static_cast<std::size_t>(in[i]); - } -} - -std::vector<std::size_t> Uint64ArrayToSizetVector(const std::size_t nElements, - const uint64_t *in) -{ - std::vector<std::size_t> out(nElements); - for (std::size_t i = 0; i < nElements; i++) - { - out[i] = static_cast<std::size_t>(in[i]); - } - return out; -} - -int GrowBuffer(const size_t incomingDataSize, const float growthFactor, - std::vector<char> &buffer, const size_t position) -{ - const size_t currentCapacity = buffer.capacity(); - const size_t availableSpace = currentCapacity - position; - const double gf = static_cast<double>(growthFactor); - - if (incomingDataSize < availableSpace) - { - return 0; - } - - const size_t neededCapacity = incomingDataSize + position; - const double numerator = std::log(static_cast<double>(neededCapacity) / - static_cast<double>(currentCapacity)); - const double denominator = std::log(gf); - - const double n = std::ceil(numerator / denominator); - const size_t newSize = - static_cast<size_t>(std::ceil(std::pow(gf, n) * currentCapacity)); - - try - { - buffer.resize(newSize); - } - catch (std::bad_alloc &e) - { - return -1; - } - - return 1; -} - -bool IsLittleEndian() noexcept -{ - uint16_t hexa = 0x1234; - return *reinterpret_cast<uint8_t *>(&hexa) != 0x12; // NOLINT -} - -} // namespace adios +} // end namespace adios diff --git a/source/adios2/helper/adiosXML.h b/source/adios2/helper/adiosXML.h new file mode 100644 index 0000000000000000000000000000000000000000..f3df2990549ed646f2f66457e82a3b2ec5ad55f0 --- /dev/null +++ b/source/adios2/helper/adiosXML.h @@ -0,0 +1,106 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * adiosXML.h basic XML parsing functionality for ADIOS config file schema + * + * Created on: May 17, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_HELPER_ADIOSXML_H_ +#define ADIOS2_HELPER_ADIOSXML_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <string> +#include <utility> //std::pair +#include <vector> +/// \endcond + +namespace adios +{ + +/** + * Extracts a substring between two tags from content + * @param initialTag + * @param finalTag + * @param content full string + * @param subString if found return substring between initialTag and finalTag, + * otherwise returns empty + * @param currentPosition to start the search, moved forward to finalTag + * position + */ +void GetSubString(const std::string initialTag, const std::string finalTag, + const std::string content, std::string &subString, + std::string::size_type ¤tPosition); + +/** + * Extracts the value inside quotes in a string currentTag ( Example: currentTag + * --> field1="value1" field2="value2" ) + * @param quote double " or single ' + * @param quotePosition position of the opening quote in currentTag + * @param currentTag initial tag value, modified by cutting the first found " " + * portion, currentTag --> field2="value2" + * @param value value1 in the example above + */ +void GetQuotedValue(const char quote, + const std::string::size_type "ePosition, + std::string ¤tTag, std::string &value); + +/** + * Get attributes field1="value1" field2="value2" by looping through a single + * XML tag + * @param tag field0="value0" field1="value1" in a single string + * @param pairs pairs[0].first=field0 pairs[0].second=value0 + * pairs[1].first=field1 pairs[1].second=value1 + */ +void GetPairs(const std::string tag, + std::vector<std::pair<const std::string, const std::string>> + &pairs) noexcept; + +/** + * Determine tag type and call GetPairs to populate pairs + * @param fileContent file Content in a single string + * @param tag field0="value0" field1="value1" in a single string + * @param pairs pairs[0].first=field0 pairs[0].second=value0 + * pairs[1].first=field1 pairs[1].second=value1 + */ +void GetPairsFromTag( + const std::string &fileContent, const std::string tag, + std::vector<std::pair<const std::string, const std::string>> &pairs); + +/** + * Set members m_Groups and m_HostLanguage from XML file content, called within + * Init functions + * @param fileContent file Content in a single string + * @param mpiComm MPI Communicator passed from application passed to Transport + * method if required + * @param hostLanguage return the host language from fileContent + * @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 ); + +/** + * Called inside the ADIOS XML constructors to get contents from file, broadcast + * and set hostLanguage and groups from ADIOS class + * @param xmlConfigFile xml config file name + * @param mpiComm communicator used from broadcasting + * @param debugMode from ADIOS m_DebugMode passed to CGroup in groups + * @param hostLanguage set from host-language in xml file + * @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 ); +} + +#endif /* ADIOS2_HELPER_ADIOSXML_H_ */ diff --git a/source/adios2/core/Capsule.cpp b/source/adios2/toolkit/capsule/Capsule.cpp similarity index 100% rename from source/adios2/core/Capsule.cpp rename to source/adios2/toolkit/capsule/Capsule.cpp diff --git a/source/adios2/core/Capsule.h b/source/adios2/toolkit/capsule/Capsule.h similarity index 88% rename from source/adios2/core/Capsule.h rename to source/adios2/toolkit/capsule/Capsule.h index 51e7098dc61899e59b65a814f9c0785a877a337f..fc90bd09023e82034b36dec61b3f70843aaebe64 100644 --- a/source/adios2/core/Capsule.h +++ b/source/adios2/toolkit/capsule/Capsule.h @@ -5,17 +5,18 @@ * Capsule.h * * Created on: Dec 7, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#ifndef ADIOS2_CORE_CAPSULE_H_ -#define ADIOS2_CORE_CAPSULE_H_ +#ifndef ADIOS2_TOOLKIT_CAPSULE_CAPSULE_H_ +#define ADIOS2_TOOLKIT_CAPSULE_CAPSULE_H_ /// \cond EXCLUDE_FROM_DOXYGEN #include <string> /// \endcond #include "adios2/ADIOSConfig.h" +#include "adios2/ADIOSTypes.h" namespace adios { @@ -67,4 +68,4 @@ protected: } // end namespace -#endif /* ADIOS2_CORE_CAPSULE_H_ */ +#endif /* ADIOS2_TOOLKIT_CAPSULE_CAPSULE_H_ */ diff --git a/source/adios2/capsule/heap/STLVector.cpp b/source/adios2/toolkit/capsule/heap/STLVector.cpp similarity index 96% rename from source/adios2/capsule/heap/STLVector.cpp rename to source/adios2/toolkit/capsule/heap/STLVector.cpp index 2873f3f0f4d4b9e7e1d2c32414d21239e40d8ee8..b5df6541a1e4e6ca0738b2e5bdab80ca792e20f8 100644 --- a/source/adios2/capsule/heap/STLVector.cpp +++ b/source/adios2/toolkit/capsule/heap/STLVector.cpp @@ -35,7 +35,7 @@ size_t STLVector::GetMetadataSize() const { return m_Metadata.size(); } void STLVector::ResizeData(const size_t size) { - if (m_DebugMode == true) + if (m_DebugMode) { try { @@ -56,7 +56,7 @@ void STLVector::ResizeData(const size_t size) void STLVector::ResizeMetadata(const size_t size) { - if (m_DebugMode == true) + if (m_DebugMode) { try { diff --git a/source/adios2/capsule/heap/STLVector.h b/source/adios2/toolkit/capsule/heap/STLVector.h similarity index 88% rename from source/adios2/capsule/heap/STLVector.h rename to source/adios2/toolkit/capsule/heap/STLVector.h index ae00013690608e90a87597a6a52185ad08a8c0c1..f4c7c4bc165bd6bc9cd855ec54150f7d66750787 100644 --- a/source/adios2/capsule/heap/STLVector.h +++ b/source/adios2/toolkit/capsule/heap/STLVector.h @@ -8,15 +8,15 @@ * Author: wfg */ -#ifndef ADIOS2_CAPSULE_HEAP_STLVECTOR_H_ -#define ADIOS2_CAPSULE_HEAP_STLVECTOR_H_ +#ifndef ADIOS2_TOOLKIT_CAPSULE_HEAP_STLVECTOR_H_ +#define ADIOS2_TOOLKIT_CAPSULE_HEAP_STLVECTOR_H_ /// \cond EXCLUDE_FROM_DOXYGEN #include <vector> /// \endcond #include "adios2/ADIOSConfig.h" -#include "adios2/core/Capsule.h" +#include "adios2/toolkit/capsule/Capsule.h" namespace adios { diff --git a/source/adios2/capsule/shmem/ShmSystemV.cpp b/source/adios2/toolkit/capsule/shmem/ShmSystemV.cpp similarity index 97% rename from source/adios2/capsule/shmem/ShmSystemV.cpp rename to source/adios2/toolkit/capsule/shmem/ShmSystemV.cpp index 4562cbc0e96e62508d42622af4182151129d614c..f746517180fab2dcc1a56ab6aac72976e21d9fb5 100644 --- a/source/adios2/capsule/shmem/ShmSystemV.cpp +++ b/source/adios2/toolkit/capsule/shmem/ShmSystemV.cpp @@ -10,7 +10,7 @@ #include "ShmSystemV.h" -#include <sys/shm.h> +#include <sys/shm.h> //shmget /// \cond EXCLUDE_FROM_DOXYGEN #include <ios> //std::ios_base::failure @@ -29,6 +29,7 @@ ShmSystemV::ShmSystemV(const std::string &pathName, const int rankMPI, // Data Shared memory sector const std::string dataPath(pathName + "/adios.shm.data." + std::to_string(rankMPI)); + // 2nd field must be greater than zero and unique m_DataKey = ftok(dataPath.c_str(), rankMPI + 1); m_DataShmID = shmget(m_DataKey, m_DataSize, IPC_CREAT | 0666); @@ -42,7 +43,7 @@ ShmSystemV::ShmSystemV(const std::string &pathName, const int rankMPI, m_MetadataShmID = shmget(m_MetadataKey, m_MetadataSize, IPC_CREAT | 0666); m_Metadata = static_cast<char *>(shmat(m_MetadataShmID, nullptr, 0)); - if (m_DebugMode == true) + if (m_DebugMode) { CheckShm(); } @@ -56,6 +57,7 @@ size_t ShmSystemV::GetDataSize() const { return m_DataSize; } size_t ShmSystemV::GetMetadataSize() const { return m_MetadataSize; } +// PRIVATE void ShmSystemV::CheckShm() const { if (m_DataShmID < 0) diff --git a/source/adios2/capsule/shmem/ShmSystemV.h b/source/adios2/toolkit/capsule/shmem/ShmSystemV.h similarity index 91% rename from source/adios2/capsule/shmem/ShmSystemV.h rename to source/adios2/toolkit/capsule/shmem/ShmSystemV.h index ca8872bfcb32d073c685c5cd7e44aed7a62064c4..7f9de77cd3398f7cf906f5dacbdf45cce43b0897 100644 --- a/source/adios2/capsule/shmem/ShmSystemV.h +++ b/source/adios2/toolkit/capsule/shmem/ShmSystemV.h @@ -3,14 +3,14 @@ * accompanying file Copyright.txt for details. */ -#ifndef ADIOS2_CAPSULE_SHMEM_SHMSYSTEMV_H_ -#define ADIOS2_CAPSULE_SHMEM_SHMSYSTEMV_H_ +#ifndef ADIOS2_TOOLKIT_CAPSULE_SHMEM_SHMSYSTEMV_H_ +#define ADIOS2_TOOLKIT_CAPSULE_SHMEM_SHMSYSTEMV_H_ #include <sys/ipc.h> #include <sys/types.h> #include "adios2/ADIOSConfig.h" -#include "adios2/core/Capsule.h" +#include "adios2/toolkit/capsule/Capsule.h" namespace adios { @@ -63,4 +63,4 @@ private: } // end namespace adios -#endif /* ADIOS2_CAPSULE_SHMEM_SHMSYSTEMV_H_ */ +#endif /* ADIOS2_TOOLKIT_CAPSULE_SHMEM_SHMSYSTEMV_H_ */ diff --git a/source/adios2/toolkit/format/bp1/BP1.h b/source/adios2/toolkit/format/bp1/BP1.h new file mode 100644 index 0000000000000000000000000000000000000000..d2221030dca686cacc0df648d38617db3b668c08 --- /dev/null +++ b/source/adios2/toolkit/format/bp1/BP1.h @@ -0,0 +1,17 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * BP1.h + * + * Created on: Apr 4, 2017 + * Author: wfg + */ + +#ifndef ADIOS2_TOOLKIT_FORMAT_BP1_BP1_H_ +#define ADIOS2_TOOLKIT_FORMAT_BP1_BP1_H_ + +#include "adios2/toolkit/format/bp1/BP1Writer.h" +/** TODO #include "adios2/toolkit/format/bp1/BP1Reader.h" */ + +#endif /* ADIOS2_TOOLKIT_FORMAT_BP1_BP1_H_ */ diff --git a/source/adios2/utilities/format/bp1/BP1Aggregator.cpp b/source/adios2/toolkit/format/bp1/BP1Aggregator.cpp similarity index 63% rename from source/adios2/utilities/format/bp1/BP1Aggregator.cpp rename to source/adios2/toolkit/format/bp1/BP1Aggregator.cpp index b1e8693c228dcd1fec2f539da43cbb4a25ca431c..255e9ce234b0ff3a961d4db9071513d924717443 100644 --- a/source/adios2/utilities/format/bp1/BP1Aggregator.cpp +++ b/source/adios2/toolkit/format/bp1/BP1Aggregator.cpp @@ -5,14 +5,19 @@ * BP1Aggregator.cpp * * Created on: Mar 21, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "BP1Aggregator.h" +/// \cond EXCLUDE_FROM_DOXYGEN #include <fstream> +#include <ios> #include <stdexcept> #include <vector> +/// \endcond + +#include <iostream> #include "adios2/ADIOSMPI.h" @@ -22,15 +27,16 @@ namespace format { BP1Aggregator::BP1Aggregator(MPI_Comm mpiComm, const bool debugMode) -: m_MPIComm{mpiComm}, m_DebugMode{debugMode} +: m_MPIComm(mpiComm), m_DebugMode(debugMode) { MPI_Comm_rank(m_MPIComm, &m_RankMPI); MPI_Comm_size(m_MPIComm, &m_SizeMPI); } -void BP1Aggregator::WriteProfilingLog(const std::string fileName, - const std::string &rankLog) +std::string BP1Aggregator::GetGlobalProfilingLog(const std::string &rankLog) { + std::string profilingLog; + if (m_RankMPI == 0) { const unsigned int sizeMPI = static_cast<const unsigned int>(m_SizeMPI); @@ -49,7 +55,7 @@ void BP1Aggregator::WriteProfilingLog(const std::string fileName, for (unsigned int i = 1; i < sizeMPI; ++i) { MPI_Wait(&requests[i], &statuses[i]); - if (m_DebugMode == true) + if (m_DebugMode) { if (rankLogsSizes[i - 1] == -1) throw std::runtime_error( @@ -72,30 +78,40 @@ void BP1Aggregator::WriteProfilingLog(const std::string fileName, MPI_Wait(&requests[i], &statuses[i]); } - // write file - std::string logFile("{\n"); - logFile += rankLog + "\n"; + // write global string + // key is to reserve memory first + profilingLog.reserve(rankLog.size() * m_SizeMPI); + + profilingLog += "{\n"; + profilingLog += rankLog + "\n"; for (unsigned int i = 1; i < sizeMPI; ++i) { - if (i == sizeMPI - 1) // last one, eliminate trailing comma + const std::string rankLogStr(rankLogs[i - 1].data(), + rankLogs[i - 1].size()); + profilingLog += rankLogStr + ","; + if (i < sizeMPI - 1) { - const std::string rankLogStr(rankLogs[i - 1].data(), - rankLogs[i - 1].size() - 1); - logFile += rankLogStr + "\n"; - } - else - { - const std::string rankLogStr(rankLogs[i - 1].data(), - rankLogs[i - 1].size()); - logFile += rankLogStr + "\n"; + profilingLog += "\n"; } } - logFile += "}\n"; + profilingLog.pop_back(); // eliminate trailing comma + profilingLog += "\n"; + profilingLog += "}\n"; - // write to file - std::ofstream logStream(fileName); - logStream.write(logFile.c_str(), logFile.size()); - logStream.close(); + // // write to file + // std::ofstream logStream(fileName); + // if (m_DebugMode) + // { + // if (!logStream) + // { + // throw std::ios_base::failure( + // "ERROR: couldn't open profiling file " + fileName + // + "\n"); + // } + // } + // + // logStream.write(logFile.c_str(), logFile.size()); + // logStream.close(); } else { @@ -107,6 +123,8 @@ void BP1Aggregator::WriteProfilingLog(const std::string fileName, MPI_Isend(const_cast<char *>(rankLog.c_str()), rankLogSize, MPI_CHAR, 0, 1, m_MPIComm, &requestRankLog); } + + return profilingLog; } } // end namespace format diff --git a/source/adios2/utilities/format/bp1/BP1Aggregator.h b/source/adios2/toolkit/format/bp1/BP1Aggregator.h similarity index 65% rename from source/adios2/utilities/format/bp1/BP1Aggregator.h rename to source/adios2/toolkit/format/bp1/BP1Aggregator.h index de82b269533cfdc5e5f554d1c59ed102af216ee5..ee8e160c726aa7e32e19699e358760eb53f11b33 100644 --- a/source/adios2/utilities/format/bp1/BP1Aggregator.h +++ b/source/adios2/toolkit/format/bp1/BP1Aggregator.h @@ -5,11 +5,11 @@ * BP1Aggregator.h * * Created on: Mar 1, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#ifndef ADIOS2_UTILITIES_FORMAT_BP1_BP1AGGREGATOR_H_ -#define ADIOS2_UTILITIES_FORMAT_BP1_BP1AGGREGATOR_H_ +#ifndef ADIOS2_TOOLKIT_FORMAT_BP1_BP1AGGREGATOR_H_ +#define ADIOS2_TOOLKIT_FORMAT_BP1_BP1AGGREGATOR_H_ /// \cond EXCLUDE_FROM_DOXYGEN #include <string> @@ -23,16 +23,15 @@ namespace adios namespace format { -/** - * Does all MPI related spatial aggregation tasks - */ +/** Does all MPI aggregation tasks */ class BP1Aggregator { public: - MPI_Comm m_MPIComm; ///< MPI communicator from Engine - int m_RankMPI = 0; ///< current MPI rank process - int m_SizeMPI = 1; ///< current MPI processes size + MPI_Comm m_MPIComm; ///< MPI communicator from Engine + int m_RankMPI = 0; ///< current MPI rank process + int m_SizeMPI = 1; ///< current MPI processes size + int m_Processes = 1; ///< number of aggregated MPI processes /** * Unique constructor @@ -47,8 +46,7 @@ public: * python dictionary format * @param rankLog contain rank profiling info to be aggregated */ - void WriteProfilingLog(const std::string fileName, - const std::string &rankLog); + std::string GetGlobalProfilingLog(const std::string &rankLog); private: const bool m_DebugMode = false; diff --git a/source/adios2/toolkit/format/bp1/BP1Base.cpp b/source/adios2/toolkit/format/bp1/BP1Base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81e71392d7e88b84a59f06cc15931c9fd6ee16ed --- /dev/null +++ b/source/adios2/toolkit/format/bp1/BP1Base.cpp @@ -0,0 +1,343 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * BP1Base.cpp + * + * Created on: Feb 7, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "BP1Base.h" +#include "BP1Base.tcc" + +#include "adios2/helper/adiosFunctions.h" //CreateDirectory, StringToTimeUnit + +namespace adios +{ +namespace format +{ + +BP1Base::BP1Base(MPI_Comm mpiComm, const bool debugMode) +: m_HeapBuffer(debugMode), m_BP1Aggregator(mpiComm, debugMode), + m_DebugMode(debugMode) +{ +} + +void BP1Base::InitParameters(const Params ¶meters) +{ + // flags for defaults that require constructors + bool useDefaultBufferSize = true; + bool useDefaultProfileUnits = true; + + for (const auto &pair : parameters) + { + const std::string key(pair.first); + const std::string value(pair.second); + + if (key == "Profile") + { + InitParameterProfile(value); + } + else if (key == "ProfileUnits") + { + InitParameterProfileUnits(value); + useDefaultProfileUnits = false; + } + else if (key == "BufferGrowth") + { + InitParameterBufferGrowth(value); + } + else if (key == "BufferSize") + { + InitParameterInitBufferSize(value); + useDefaultBufferSize = false; + } + else if (key == "MaxBufferSize") + { + InitParameterMaxBufferSize(value); + } + else if (key == "Verbose") + { + InitParameterVerbose(value); + } + } + + // default timer for buffering + if (m_Profiler.IsActive && useDefaultProfileUnits) + { + m_Profiler.Timers.emplace( + "buffering", + profiling::Timer("buffering", DefaultTimeUnitEnum, m_DebugMode)); + + m_Profiler.Bytes.emplace("buffering", 0); + } + + if (useDefaultBufferSize) + { + m_HeapBuffer.ResizeData(DefaultBufferSize); + } +} + +std::vector<std::string> +BP1Base::GetBPBaseNames(const std::vector<std::string> &names) const noexcept +{ + std::vector<std::string> bpBaseNames; + bpBaseNames.reserve(names.size()); + + for (const auto &name : names) + { + bpBaseNames.push_back(GetBPBaseName(name)); + } + return bpBaseNames; +} + +std::string BP1Base::GetBPBaseName(const std::string &name) const noexcept +{ + return AddExtension(name, ".bp"); +} + +std::vector<std::string> +BP1Base::GetBPNames(const std::vector<std::string> &names) const noexcept +{ + std::vector<std::string> bpNames; + bpNames.reserve(names.size()); + + for (const auto &name : names) + { + bpNames.push_back(GetBPName(name)); + } + return bpNames; +} + +std::string BP1Base::GetBPName(const std::string &name) const noexcept +{ + const std::string baseName = AddExtension(name, ".bp"); + // opens a file transport under name.bp/name.bp.rank + const std::string bpName(baseName + "/" + baseName + "." + + std::to_string(m_BP1Aggregator.m_RankMPI)); + return bpName; +} + +// PROTECTED +void BP1Base::InitParameterProfile(const std::string value) +{ + if (value == "off") + { + m_Profiler.IsActive = false; + } + else if (value == "on") + { + m_Profiler.IsActive = true; // default + } + else + { + if (m_DebugMode) + { + throw std::invalid_argument("ERROR: IO SetParameters profile " + "invalid value, valid: " + "profile=on or " + "profile=off, in call to Open\n"); + } + } +} + +void BP1Base::InitParameterProfileUnits(const std::string value) +{ + TimeUnit timeUnit = StringToTimeUnit(value, m_DebugMode); + + if (m_Profiler.Timers.count("buffering") == 1) + { + m_Profiler.Timers.erase("buffering"); + } + + m_Profiler.Timers.emplace( + "buffering", profiling::Timer("buffering", timeUnit, m_DebugMode)); + + m_Profiler.Bytes.emplace("buffering", 0); +} + +void BP1Base::InitParameterBufferGrowth(const std::string value) +{ + if (m_DebugMode) + { + bool success = true; + try + { + m_GrowthFactor = std::stof(value); + } + catch (std::exception &e) + { + success = false; + } + + if (!success || m_GrowthFactor <= 1.f) + { + throw std::invalid_argument( + "ERROR: IO SetParameter buffer_growth value " + "can't be less or equal than 1 (default = 1.5), or couldn't " + "convert number, in call to Open\n"); + } + } + else + { + m_GrowthFactor = std::stof(value); + } +} + +void BP1Base::InitParameterInitBufferSize(const std::string value) +{ + const std::string errorMessage( + "ERROR: couldn't convert value of init_buffer_size IO " + "SetParameter, valid syntax: init_buffer_size=10Gb, " + "init_buffer_size=1000Mb, init_buffer_size=16Kb (minimum default), " + " in call to Open"); + + if (m_DebugMode) + { + if (value.size() < 2) + { + throw std::invalid_argument(errorMessage); + } + } + + const std::string number(value.substr(0, value.size() - 2)); + const std::string units(value.substr(value.size() - 2)); + const size_t factor = BytesFactor(units, m_DebugMode); + size_t bufferSize = DefaultBufferSize; // from ADIOSTypes.h + + if (m_DebugMode) + { + bool success = true; + try + { + bufferSize = static_cast<size_t>(std::stoul(number) * factor); + } + catch (std::exception &e) + { + success = false; + } + + if (!success || bufferSize < 16 * 1024) // 16384b + { + throw std::invalid_argument(errorMessage); + } + } + else + { + bufferSize = static_cast<size_t>(std::stoul(number) * factor); + } + + m_HeapBuffer.ResizeData(bufferSize); +} + +void BP1Base::InitParameterMaxBufferSize(const std::string value) +{ + const std::string errorMessage( + "ERROR: couldn't convert value of max_buffer_size IO " + "SetParameter, valid syntax: MaxBufferSize=10Gb, " + "MaxBufferSize=1000Mb, MaxBufferSize=16Kb (minimum default), " + " in call to Open"); + + if (m_DebugMode) + { + if (value.size() < 2) + { + throw std::invalid_argument(errorMessage); + } + } + + const std::string number(value.substr(0, value.size() - 2)); + const std::string units(value.substr(value.size() - 2)); + const size_t factor = BytesFactor(units, m_DebugMode); + + if (m_DebugMode) + { + bool success = true; + try + { + m_MaxBufferSize = static_cast<size_t>(std::stoul(number) * factor); + } + catch (std::exception &e) + { + success = false; + } + + if (!success || m_MaxBufferSize < 16 * 1024) // 16384b + { + throw std::invalid_argument(errorMessage); + } + } + else + { + m_MaxBufferSize = static_cast<size_t>(std::stoul(number) * factor); + } +} + +void BP1Base::InitParameterVerbose(const std::string value) +{ + if (m_DebugMode) + { + bool success = true; + try + { + m_Verbosity = static_cast<unsigned int>(std::stoi(value)); + } + catch (std::exception &e) + { + success = false; + } + + if (!success || m_Verbosity < 0 || m_Verbosity > 5) + { + throw std::invalid_argument( + "ERROR: value in Verbose=value in IO SetParameters must be " + "an integer in the range [0,5], in call to Open\n"); + } + } + else + { + m_Verbosity = static_cast<unsigned int>(std::stoi(value)); + } +} + +std::vector<uint8_t> +BP1Base::GetTransportIDs(const std::vector<std::string> &transportsTypes) const + noexcept +{ + auto lf_GetTransportID = [](const std::string method) -> uint8_t { + + int id = METHOD_UNKNOWN; + if (method == "NULL") + { + id = METHOD_NULL; + } + else if (method == "FileDescriptor") + { + id = METHOD_POSIX; + } + else if (method == "FileStream") + { + id = METHOD_FSTREAM; + } + else if (method == "FilePointer") + { + id = METHOD_FILE; + } + + return static_cast<uint8_t>(id); + }; + + std::vector<uint8_t> transportsIDs; + transportsIDs.reserve(transportsTypes.size()); + + for (const auto transportType : transportsTypes) + { + transportsIDs.push_back(lf_GetTransportID(transportType)); + } + + return transportsIDs; +} + +} // end namespace format +} // end namespace adios diff --git a/source/adios2/utilities/format/bp1/BP1Base.h b/source/adios2/toolkit/format/bp1/BP1Base.h similarity index 65% rename from source/adios2/utilities/format/bp1/BP1Base.h rename to source/adios2/toolkit/format/bp1/BP1Base.h index 2308c3498ea68a9a659e78d34665b6c3324443b4..d2e9024fcd3b529d4b261b77faa36e6819d3e3cd 100644 --- a/source/adios2/utilities/format/bp1/BP1Base.h +++ b/source/adios2/toolkit/format/bp1/BP1Base.h @@ -2,28 +2,28 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * BP1.h + * BP1Base.h base class for BP1Writer and BP1Reader * * Created on: Feb 2, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#ifndef ADIOS2_UTILITIES_FORMAT_BP1_BP1BASE_H_ -#define ADIOS2_UTILITIES_FORMAT_BP1_BP1BASE_H_ +#ifndef ADIOS2_TOOLKIT_FORMAT_BP1_BP1BASE_H_ +#define ADIOS2_TOOLKIT_FORMAT_BP1_BP1BASE_H_ /// \cond EXCLUDE_FROM_DOXYGEN #include <memory> //std::shared_ptr -#include <unordered_map> #include <vector> /// \endcond -#include "BP1Aggregator.h" -#include "BP1Structs.h" #include "adios2/ADIOSConfig.h" #include "adios2/ADIOSMPICommOnly.h" +#include "adios2/ADIOSMacros.h" #include "adios2/ADIOSTypes.h" -#include "adios2/capsule/heap/STLVector.h" -#include "adios2/core/Transport.h" +#include "adios2/toolkit/capsule/heap/STLVector.h" +#include "adios2/toolkit/format/bp1/BP1Aggregator.h" +#include "adios2/toolkit/format/bp1/BP1Structs.h" +#include "adios2/toolkit/profiling/iochrono/IOChrono.h" namespace adios { @@ -41,20 +41,27 @@ public: unsigned int m_Verbosity = 0; /** contains data buffer and position */ - capsule::STLVector m_Heap = capsule::STLVector(true); + capsule::STLVector m_HeapBuffer; - /** memory growth factor */ + /** memory growth factor,s set by the user */ float m_GrowthFactor = 1.5; - /** max buffer size */ + /** max buffer size, set by the user */ size_t m_MaxBufferSize = 0; - /** contains bp1 format metadata */ + /** contains bp1 format metadata indices*/ BP1MetadataSet m_MetadataSet; - /** aggregation tasks */ + /** object that takes care of all MPI aggregation tasks */ BP1Aggregator m_BP1Aggregator; + /** true: Close was called, Engine will call this many times for different + * transports */ + bool m_IsClosed = false; + + /** buffering and MPI aggregation profiling info, set by user */ + profiling::IOChrono m_Profiler; + /** * Unique constructor * @param mpiComm for m_BP1Aggregator @@ -64,23 +71,39 @@ public: virtual ~BP1Base() = default; + void InitParameters(const Params ¶meters); + /** - * Checks if input name has .bp extension and returns a .bp directory name + * Vector version of BPBaseName + * @param names + * @return vector of base (name.bp) names + */ + std::vector<std::string> + GetBPBaseNames(const std::vector<std::string> &names) const noexcept; + + /** + * Checks if input name has .bp extension and returns a .bp directory + * name * @param name input (might or not have .bp) - * @return either name.bp (name has no .bp) or name (name has .bp extension) + * @return either name.bp (name has no .bp) or name (name has .bp + * extension) + */ + std::string GetBPBaseName(const std::string &name) const noexcept; + + /** + * Vector version of GetBPName + * @param names + * @return */ - std::string GetDirectoryName(const std::string name) const noexcept; + std::vector<std::string> + GetBPNames(const std::vector<std::string> &names) const noexcept; /** - * Opens rank files in the following format: - * if transport.m_MPIComm different from MPI_Comm_SELF --> - * name.bp.dir/name.bp.rank - * @param name might contain .bp or not, if not .bp will be added - * @param accessMode "write" "w", "r" "read", "append" "a" - * @param transport file I/O transport + * Gets the name for bp buffer based on rank + * @param name + * @return name.bp/name.bp.rank */ - void OpenRankFiles(const std::string name, const std::string accessMode, - Transport &file) const; + std::string GetBPName(const std::string &name) const noexcept; /** * Return type of the CheckAllocation function. @@ -96,6 +119,7 @@ public: protected: /** might be used in large payload copies to buffer */ unsigned int m_Threads = 1; + const bool m_DebugMode = false; /** method type for file I/O */ enum IO_METHOD @@ -165,10 +189,11 @@ protected: type_double = 6, //!< type_double type_long_double = 7, //!< type_long_double - type_string = 9, //!< type_string - type_complex = 10, //!< type_complex - type_double_complex = 11, //!< type_double_complex - type_string_array = 12 //!< type_string_array + type_string = 9, //!< type_string + type_complex = 10, //!< type_complex + type_double_complex = 11, //!< type_double_complex + type_string_array = 12, //!< type_string_array + type_long_double_complex = 13 //!< type_double_complex }; /** @@ -219,87 +244,40 @@ protected: // bool finite?? }; + /** profile=on (default) generate profiling.log + * profile=off */ + void InitParameterProfile(const std::string value); + + /** profile_units=s (default) (mus, ms, s,m,h) from ADIOSTypes.h TimeUnit */ + void InitParameterProfileUnits(const std::string value); + + /** growth_factor=1.5 (default), must be > 1.0 */ + void InitParameterBufferGrowth(const std::string value); + + /** set initial buffer size */ + void InitParameterInitBufferSize(const std::string value); + + /** unlimited (default), set max buffer size in Gb or Mb + * max_buffer_size=100Mb or max_buffer_size=1Gb */ + void InitParameterMaxBufferSize(const std::string value); + + /** verbose file level=0 (default) */ + void InitParameterVerbose(const std::string value); + /** * Returns data type index from enum Datatypes * @param variable input variable * @return data type */ template <class T> - inline int8_t GetDataType() const noexcept - { - return type_unknown; - } + int8_t GetDataType() const noexcept; - std::vector<uint8_t> GetMethodIDs( - const std::vector<std::shared_ptr<Transport>> &transports) const + std::vector<uint8_t> + GetTransportIDs(const std::vector<std::string> &transportsTypes) const noexcept; }; -// Moving template BP1Writer::GetDataType template specializations outside of -// the class -template <> -inline int8_t BP1Base::GetDataType<char>() const noexcept -{ - return type_byte; -} - -template <> -inline int8_t BP1Base::GetDataType<short>() const noexcept -{ - return type_short; -} - -template <> -inline int8_t BP1Base::GetDataType<int>() const noexcept -{ - return type_integer; -} -template <> -inline int8_t BP1Base::GetDataType<long int>() const noexcept -{ - return type_long; -} - -template <> -inline int8_t BP1Base::GetDataType<unsigned char>() const noexcept -{ - return type_unsigned_byte; -} -template <> -inline int8_t BP1Base::GetDataType<unsigned short>() const noexcept -{ - return type_unsigned_short; -} -template <> -inline int8_t BP1Base::GetDataType<unsigned int>() const noexcept -{ - return type_unsigned_integer; -} -template <> -inline int8_t BP1Base::GetDataType<unsigned long int>() const noexcept -{ - return type_unsigned_long; -} - -template <> -inline int8_t BP1Base::GetDataType<float>() const noexcept -{ - return type_real; -} - -template <> -inline int8_t BP1Base::GetDataType<double>() const noexcept -{ - return type_double; -} - -template <> -inline int8_t BP1Base::GetDataType<long double>() const noexcept -{ - return type_long_double; -} - } // end namespace format } // end namespace adios -#endif /* ADIOS2_UTILITIES_FORMAT_BP1_BP1BASE_H_ */ +#endif /* ADIOS2_TOOLKIT_FORMAT_BP1_BP1BASE_H_ */ diff --git a/source/adios2/toolkit/format/bp1/BP1Base.tcc b/source/adios2/toolkit/format/bp1/BP1Base.tcc new file mode 100644 index 0000000000000000000000000000000000000000..dfd39f6363985ac63b4055464065111c1d84d9bc --- /dev/null +++ b/source/adios2/toolkit/format/bp1/BP1Base.tcc @@ -0,0 +1,118 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * BP1Base.tcc + * + * Created on: May 19, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_FORMAT_BP1_BP1BASE_TCC_ +#define ADIOS2_TOOLKIT_FORMAT_BP1_BP1BASE_TCC_ + +#include "BP1Base.h" + +namespace adios +{ +namespace format +{ + +template <> +int8_t BP1Base::GetDataType<char>() const noexcept +{ + return type_byte; +} + +template <> +int8_t BP1Base::GetDataType<short>() const noexcept +{ + return type_short; +} + +template <> +int8_t BP1Base::GetDataType<int>() const noexcept +{ + return type_integer; +} + +template <> +int8_t BP1Base::GetDataType<long int>() const noexcept +{ + return type_long; +} + +template <> +int8_t BP1Base::GetDataType<long long int>() const noexcept +{ + return type_long; +} + +template <> +int8_t BP1Base::GetDataType<unsigned char>() const noexcept +{ + return type_unsigned_byte; +} +template <> +int8_t BP1Base::GetDataType<unsigned short>() const noexcept +{ + return type_unsigned_short; +} +template <> +int8_t BP1Base::GetDataType<unsigned int>() const noexcept +{ + return type_unsigned_integer; +} + +template <> +int8_t BP1Base::GetDataType<unsigned long int>() const noexcept +{ + return type_unsigned_long; +} + +template <> +int8_t BP1Base::GetDataType<unsigned long long int>() const noexcept +{ + return type_unsigned_long; +} + +template <> +int8_t BP1Base::GetDataType<float>() const noexcept +{ + return type_real; +} + +template <> +int8_t BP1Base::GetDataType<double>() const noexcept +{ + return type_double; +} + +template <> +int8_t BP1Base::GetDataType<long double>() const noexcept +{ + return type_long_double; +} + +template <> +int8_t BP1Base::GetDataType<cfloat>() const noexcept +{ + return type_complex; +} + +template <> +int8_t BP1Base::GetDataType<cdouble>() const noexcept +{ + return type_double_complex; +} + +template <> +int8_t BP1Base::GetDataType<cldouble>() const noexcept +{ + return type_long_double_complex; +} + +} // end namespace format +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_FORMAT_BP1_BP1BASE_TCC_ */ diff --git a/source/adios2/utilities/format/bp1/BP1Structs.h b/source/adios2/toolkit/format/bp1/BP1Structs.h similarity index 88% rename from source/adios2/utilities/format/bp1/BP1Structs.h rename to source/adios2/toolkit/format/bp1/BP1Structs.h index 825a446fbcde647c36f682c18808fa92b3128cf0..19e9c5ed19f5dce3ca61b94b16661027178cd41c 100644 --- a/source/adios2/utilities/format/bp1/BP1Structs.h +++ b/source/adios2/toolkit/format/bp1/BP1Structs.h @@ -5,22 +5,23 @@ * BP1Structs.h * * Created on: Apr 3, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#ifndef ADIOS2_UTILITIES_FORMAT_BP1_BP1STRUCTS_H_ -#define ADIOS2_UTILITIES_FORMAT_BP1_BP1STRUCTS_H_ +#ifndef ADIOS2_TOOLKIT_FORMAT_BP1_BP1STRUCTS_H_ +#define ADIOS2_TOOLKIT_FORMAT_BP1_BP1STRUCTS_H_ /// \cond EXCLUDE_FROM_DOXYGEN #include <cstdint> #include <string> #include <unordered_map> #include <vector> + /// \endcond #include "adios2/ADIOSConfig.h" #include "adios2/ADIOSTypes.h" -#include "adios2/core/IOChrono.h" +#include "adios2/toolkit/profiling/iochrono/IOChrono.h" namespace adios { @@ -81,11 +82,9 @@ struct BP1MetadataSet /** true: currently writing to a pg, false: no current pg */ bool DataPGIsOpen = false; - - profiling::IOChrono Log; ///< object that takes buffering profiling info }; } // end namespace format } // end namespace adios -#endif /* ADIOS2_UTILITIES_FORMAT_BP1_BP1STRUCTS_H_ */ +#endif /* ADIOS2_TOOLKIT_FORMAT_BP1_BP1STRUCTS_H_ */ diff --git a/source/adios2/utilities/format/bp1/BP1Writer.cpp b/source/adios2/toolkit/format/bp1/BP1Writer.cpp similarity index 72% rename from source/adios2/utilities/format/bp1/BP1Writer.cpp rename to source/adios2/toolkit/format/bp1/BP1Writer.cpp index 666a3e6edd755087feceee18adb3b9ae202a2c06..34639d7fb59eff38671c7d433feec5d72c24d2ef 100644 --- a/source/adios2/utilities/format/bp1/BP1Writer.cpp +++ b/source/adios2/toolkit/format/bp1/BP1Writer.cpp @@ -5,7 +5,7 @@ * BP1Writer.cpp * * Created on: Feb 1, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "BP1Writer.h" @@ -24,23 +24,31 @@ BP1Writer::BP1Writer(MPI_Comm mpiComm, const bool debugMode) { } -std::size_t BP1Writer::GetProcessGroupIndexSize( - const std::string name, const std::string timeStepName, - const std::size_t numberOfTransports) const noexcept +size_t BP1Writer::GetProcessGroupIndexSize(const std::string name, + const std::string timeStepName, + const size_t transportsSize) const + noexcept { // pgIndex + list of methods (transports) - return (name.length() + timeStepName.length() + 23) + - (3 + numberOfTransports); + size_t pgSize = + (name.length() + timeStepName.length() + 23) + (3 + transportsSize); + + return pgSize; } void BP1Writer::WriteProcessGroupIndex( - const bool isFortran, const std::string name, const uint32_t processID, - const std::vector<std::shared_ptr<Transport>> &transports) noexcept + const std::string hostLanguage, + const std::vector<std::string> &transportsTypes) noexcept { + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Resume(); + } + std::vector<char> &metadataBuffer = m_MetadataSet.PGIndex.Buffer; - std::vector<char> &dataBuffer = m_Heap.m_Data; - size_t &dataPosition = m_Heap.m_DataPosition; + std::vector<char> &dataBuffer = m_HeapBuffer.m_Data; + size_t &dataPosition = m_HeapBuffer.m_DataPosition; m_MetadataSet.DataPGLengthPosition = dataPosition; dataPosition += 8; // skip pg length (8) @@ -49,15 +57,18 @@ void BP1Writer::WriteProcessGroupIndex( metadataBuffer.insert(metadataBuffer.end(), 2, 0); // skip pg length (2) // write name to metadata + const std::string name(std::to_string(m_BP1Aggregator.m_RankMPI)); + WriteNameRecord(name, metadataBuffer); // write if host language Fortran in metadata and data - const char hostFortran = (isFortran) ? 'y' : 'n'; + const char hostFortran = (hostLanguage == "Fortran") ? 'y' : 'n'; InsertToBuffer(metadataBuffer, &hostFortran); CopyToBuffer(dataBuffer, dataPosition, &hostFortran); // write name in data WriteNameRecord(name, dataBuffer, dataPosition); // processID in metadata, + const uint32_t processID = static_cast<uint32_t>(m_BP1Aggregator.m_RankMPI); InsertToBuffer(metadataBuffer, &processID); // skip coordination var in data ....what is coordination var? dataPosition += 4; @@ -73,7 +84,7 @@ void BP1Writer::WriteProcessGroupIndex( // offset to pg in data in metadata which is the current absolute position InsertToBuffer(metadataBuffer, reinterpret_cast<uint64_t *>( - &m_Heap.m_DataAbsolutePosition)); + &m_HeapBuffer.m_DataAbsolutePosition)); // Back to writing metadata pg index length (length of group) const uint16_t metadataPGIndexLength = @@ -83,7 +94,7 @@ void BP1Writer::WriteProcessGroupIndex( // DONE With metadataBuffer // here write method in data - const std::vector<uint8_t> methodIDs = GetMethodIDs(transports); + const std::vector<uint8_t> methodIDs = GetTransportIDs(transportsTypes); const uint8_t methodsCount = methodIDs.size(); CopyToBuffer(dataBuffer, dataPosition, &methodsCount); // count // methodID (1) + method params length(2), no parameters for now @@ -98,80 +109,120 @@ void BP1Writer::WriteProcessGroupIndex( } // update absolute position - m_Heap.m_DataAbsolutePosition += + m_HeapBuffer.m_DataAbsolutePosition += dataPosition - m_MetadataSet.DataPGLengthPosition; // pg vars count and position m_MetadataSet.DataPGVarsCount = 0; m_MetadataSet.DataPGVarsCountPosition = dataPosition; // add vars count and length dataPosition += 12; - m_Heap.m_DataAbsolutePosition += 12; // add vars count and length + m_HeapBuffer.m_DataAbsolutePosition += 12; // add vars count and length ++m_MetadataSet.DataPGCount; m_MetadataSet.DataPGIsOpen = true; + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Pause(); + } } -void BP1Writer::Advance() { FlattenData(); } +void BP1Writer::Advance() +{ + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Resume(); + } -void BP1Writer::Close(Transport &transport, bool &isFirstClose, - const bool doAggregation) noexcept + FlattenData(); + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Pause(); + } +} + +void BP1Writer::Close() noexcept { - if (m_MetadataSet.Log.IsActive == true) + if (m_Profiler.IsActive) { - m_MetadataSet.Log.Timers[0].SetInitialTime(); + m_Profiler.Timers.at("buffering").Resume(); } - if (isFirstClose == true) + if (!m_IsClosed) { - if (m_MetadataSet.DataPGIsOpen == true) + if (m_MetadataSet.DataPGIsOpen) { FlattenData(); } FlattenMetadata(); + m_IsClosed = true; + } + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Pause(); + } +} - if (m_MetadataSet.Log.IsActive == true) +std::string BP1Writer::GetRankProfilingLog( + const std::vector<std::string> &transportsTypes, + const std::vector<profiling::IOChrono *> &transportsProfilers) noexcept +{ + auto lf_WriterTimer = [](std::string &rankLog, + const profiling::Timer &timer) { + rankLog += "'" + timer.m_Process + "_" + timer.GetShortUnits() + "': " + + std::to_string(timer.m_ProcessTime) + ", "; + }; + + // prepare string dictionary per rank + std::string rankLog("'rank_" + std::to_string(m_BP1Aggregator.m_RankMPI) + + "': { "); + + auto &profiler = m_Profiler; + rankLog += + "'bytes': " + std::to_string(profiler.Bytes.at("buffering")) + ", "; + lf_WriterTimer(rankLog, profiler.Timers.at("buffering")); + + const size_t transportsSize = transportsTypes.size(); + + for (unsigned int t = 0; t < transportsSize; ++t) + { + rankLog += "'transport_" + std::to_string(t) + "': { "; + rankLog += "'lib': '" + transportsTypes[t] + "', "; + + for (const auto &transportTimerPair : transportsProfilers[t]->Timers) { - m_MetadataSet.Log.Timers[0].SetInitialTime(); + lf_WriterTimer(rankLog, transportTimerPair.second); + rankLog += ", "; } + // replace last comma with space + rankLog.pop_back(); + rankLog.pop_back(); + rankLog += " "; - // N-to-M where 1 <= M <= N-1, might need a new - // Log metadataSet.Log.m_Timers just for aggregation - if (doAggregation == true) + if (t == transportsSize - 1) // last element { - // here call aggregator + rankLog += "}"; + } + else + { + rankLog += "},"; } - isFirstClose = false; - } - - if (doAggregation == true) // N-to-M where 1 <= M <= N-1 - { - // here call aggregator to select transports for Write and Close - } - else // N-to-N - { - // single write - transport.Write(m_Heap.m_Data.data(), m_Heap.m_Data.size()); - transport.Close(); } -} + rankLog += " }"; -void BP1Writer::WriteProfilingLogFile( - const std::string &name, const unsigned int rank, - const std::vector<std::shared_ptr<Transport>> &transports) noexcept -{ - const std::string fileName(GetDirectoryName(name) + "/profiling.log"); - const std::string rankLog(GetRankProfilingLog(rank, transports)); - m_BP1Aggregator.WriteProfilingLog(fileName, rankLog); + return rankLog; } // PRIVATE FUNCTIONS -void BP1Writer::WriteDimensionsRecord( - const std::vector<size_t> &localDimensions, - const std::vector<size_t> &globalDimensions, - const std::vector<size_t> &offsets, std::vector<char> &buffer) noexcept +void BP1Writer::WriteDimensionsRecord(const Dims localDimensions, + const Dims globalDimensions, + const Dims offsets, + std::vector<char> &buffer) noexcept { - if (offsets.empty() == true) + if (offsets.empty()) { for (const auto &localDimension : localDimensions) { @@ -194,11 +245,12 @@ void BP1Writer::WriteDimensionsRecord( } } -void BP1Writer::WriteDimensionsRecord( - const std::vector<size_t> &localDimensions, - const std::vector<size_t> &globalDimensions, - const std::vector<size_t> &offsets, const unsigned int skip, - std::vector<char> &buffer, size_t &position) noexcept +void BP1Writer::WriteDimensionsRecord(const Dims localDimensions, + const Dims globalDimensions, + const Dims offsets, + const unsigned int skip, + std::vector<char> &buffer, + size_t &position) noexcept { auto lf_WriteFlaggedDim = [](std::vector<char> &buffer, size_t &position, const size_t dimension) { @@ -209,7 +261,7 @@ void BP1Writer::WriteDimensionsRecord( }; // BODY Starts here - if (offsets.empty() == true) + if (offsets.empty()) { for (const auto &localDimension : localDimensions) { @@ -264,8 +316,8 @@ BP1Writer::GetBP1Index(const std::string name, void BP1Writer::FlattenData() noexcept { - auto &buffer = m_Heap.m_Data; - auto &position = m_Heap.m_DataPosition; + auto &buffer = m_HeapBuffer.m_Data; + auto &position = m_HeapBuffer.m_DataPosition; // vars count and Length (only for PG) CopyToBuffer(buffer, m_MetadataSet.DataPGVarsCountPosition, @@ -278,7 +330,7 @@ void BP1Writer::FlattenData() noexcept // attributes (empty for now) count (4) and length (8) are zero by moving // positions in time step zero position += 12; - m_Heap.m_DataAbsolutePosition += 12; + m_HeapBuffer.m_DataAbsolutePosition += 12; // Finish writing pg group length // without record itself, 12 due to empty attributes @@ -344,12 +396,13 @@ void BP1Writer::FlattenMetadata() noexcept (attributesLength + 12) + m_MetadataSet.MiniFooterSize; - auto &buffer = m_Heap.m_Data; - auto &position = m_Heap.m_DataPosition; + auto &buffer = m_HeapBuffer.m_Data; + auto &position = m_HeapBuffer.m_DataPosition; // reserve data to fit metadata, - buffer.resize(position + footerSize); - // must replace with growth buffer strategy? + // must replace with growth buffer strategy + m_HeapBuffer.ResizeData(position + footerSize); + // buffer.resize(position + footerSize); // write pg index CopyToBuffer(buffer, position, &pgCount); @@ -365,7 +418,7 @@ void BP1Writer::FlattenMetadata() noexcept m_MetadataSet.AttributesIndices, buffer, position); // getting absolute offsets, minifooter is 28 bytes for now - const uint64_t offsetPGIndex = m_Heap.m_DataAbsolutePosition; + const uint64_t offsetPGIndex = m_HeapBuffer.m_DataAbsolutePosition; const uint64_t offsetVarsIndex = offsetPGIndex + (pgLength + 16); const uint64_t offsetAttributeIndex = offsetVarsIndex + (varsLength + 12); @@ -385,64 +438,15 @@ void BP1Writer::FlattenMetadata() noexcept { } - m_Heap.m_DataAbsolutePosition += footerSize; + m_HeapBuffer.m_DataAbsolutePosition += footerSize; - if (m_MetadataSet.Log.IsActive == true) + if (m_Profiler.IsActive) { - m_MetadataSet.Log.TotalBytes.push_back(m_Heap.m_DataAbsolutePosition); + m_Profiler.Bytes.emplace("buffering", + m_HeapBuffer.m_DataAbsolutePosition); } } -std::string BP1Writer::GetRankProfilingLog( - const unsigned int rank, - const std::vector<std::shared_ptr<Transport>> &transports) noexcept -{ - auto lf_WriterTimer = [](std::string &rankLog, - const profiling::Timer &timer) { - rankLog += "'" + timer.m_Process + "_" + timer.GetUnits() + "': " + - std::to_string(timer.m_ProcessTime); - }; - - // prepare string dictionary per rank - std::string rankLog("'rank_" + std::to_string(rank) + "': { "); - - auto &profiler = m_MetadataSet.Log; - rankLog += "'bytes': " + std::to_string(profiler.TotalBytes[0]) + ", "; - lf_WriterTimer(rankLog, profiler.Timers[0]); - rankLog += ", "; - - for (unsigned int t = 0; t < transports.size(); ++t) - { - rankLog += "'transport_" + std::to_string(t) + "': { "; - rankLog += "'lib': '" + transports[t]->m_Type + "', "; - - for (unsigned int i = 0; i < 3; ++i) - { - lf_WriterTimer(rankLog, transports[t]->m_Profiler.Timers[i]); - if (i < 2) - { - rankLog += ", "; - } - else - { - rankLog += " "; - } - } - - if (t == transports.size() - 1) // last element - { - rankLog += "}"; - } - else - { - rankLog += "},"; - } - } - rankLog += " },"; - - return rankLog; -} - //------------------------------------------------------------------------------ // Explicit instantiation of only public templates @@ -450,13 +454,13 @@ std::string BP1Writer::GetRankProfilingLog( template BP1Writer::ResizeResult BP1Writer::ResizeBuffer( \ const Variable<T> &variable); \ \ - template void BP1Writer::WriteVariablePayload( \ + template void BP1Writer::WriteVariableMetadata( \ const Variable<T> &variable) noexcept; \ \ - template void BP1Writer::WriteVariableMetadata( \ + template void BP1Writer::WriteVariablePayload( \ const Variable<T> &variable) noexcept; -ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation) +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) #undef declare_template_instantiation //------------------------------------------------------------------------------ diff --git a/source/adios2/utilities/format/bp1/BP1Writer.h b/source/adios2/toolkit/format/bp1/BP1Writer.h similarity index 75% rename from source/adios2/utilities/format/bp1/BP1Writer.h rename to source/adios2/toolkit/format/bp1/BP1Writer.h index b3bd946fc6aa38a2483c26ebc5c131d7fa5bc811..d3caf67f36b9970e38c7221f3e5df7451aa21d5c 100644 --- a/source/adios2/utilities/format/bp1/BP1Writer.h +++ b/source/adios2/toolkit/format/bp1/BP1Writer.h @@ -2,14 +2,14 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * BP1.h + * BP1Writer.h * * Created on: Jan 24, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#ifndef ADIOS2_UTILITIES_FORMAT_BP1_BP1WRITER_H_ -#define ADIOS2_UTILITIES_FORMAT_BP1_BP1WRITER_H_ +#ifndef ADIOS2_TOOLKIT_FORMAT_BP1_BP1WRITER_H_ +#define ADIOS2_TOOLKIT_FORMAT_BP1_BP1WRITER_H_ /// \cond EXCLUDE_FROM_DOXYGEN #include <algorithm> //std::count, std::copy, std::for_each @@ -20,12 +20,10 @@ #include "adios2/ADIOSConfig.h" #include "adios2/ADIOSMacros.h" #include "adios2/ADIOSTypes.h" -#include "adios2/capsule/heap/STLVector.h" #include "adios2/core/Variable.h" -#include "adios2/core/adiosFunctions.h" -#include "adios2/core/adiosTemplates.h" -#include "adios2/utilities/format/bp1/BP1Base.h" -#include "adios2/utilities/format/bp1/BP1Structs.h" +#include "adios2/toolkit/capsule/heap/STLVector.h" +#include "adios2/toolkit/format/bp1/BP1Base.h" +#include "adios2/toolkit/format/bp1/BP1Structs.h" namespace adios { @@ -48,14 +46,12 @@ public: /** * Writes a process group index PGIndex and list of methods (from * transports). Done at Open or Advance. - * @param isFortran - * @param name group name, taking the rank - * @param processID - * @param transports + * @param hostLanguage from ADIOS class passed to IO + * @param transportsTypes passed to get list of transport "bp methods" */ void WriteProcessGroupIndex( - const bool isFortran, const std::string name, const uint32_t processID, - const std::vector<std::shared_ptr<Transport>> &transports) noexcept; + const std::string hostLanguage, + const std::vector<std::string> &transportsTypes) noexcept; /** * @@ -88,37 +84,35 @@ public: void Advance(); /** - * Function that sets metadata (if first close) and writes to a single - * transport - * @param metadataSet current rank metadata set - * @param heap contains data buffer - * @param transport does a write after data and metadata is setup - * @param isFirstClose true: metadata has been set and aggregated - * @param doAggregation true: for N-to-M, false: for N-to-N + * @param isFirstClose true: first time close, false: already closed buffer */ - void Close(Transport &transport, bool &isFirstClose, - const bool doAggregation) noexcept; + void Close() noexcept; - void WriteProfilingLogFile( - const std::string &name, const unsigned int rank, - const std::vector<std::shared_ptr<Transport>> &transports) noexcept; + /** + * Get a string with profiling information for this rank + * @param name stream name + * @param transportsTypes list of transport types + * @param transportsProfilers list of references to transport profilers + */ + std::string GetRankProfilingLog( + const std::vector<std::string> &transportsTypes, + const std::vector<profiling::IOChrono *> &transportsProfilers) noexcept; private: /** BP format version */ - const std::uint8_t m_Version = 3; + const uint8_t m_Version = 3; /** * 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 + * @param transportsSize * @return size of pg index */ size_t GetProcessGroupIndexSize(const std::string name, const std::string timeStepName, - const size_t numberOfTransports) const - noexcept; + const size_t transportsSize) const noexcept; /** * Returns the estimated variable index size @@ -185,15 +179,13 @@ private: * data * characteristic */ - void WriteDimensionsRecord(const std::vector<size_t> &localDimensions, - const std::vector<size_t> &globalDimensions, - const std::vector<size_t> &offsets, + void WriteDimensionsRecord(const Dims localDimensions, + const Dims globalDimensions, const Dims offsets, std::vector<char> &buffer) noexcept; /** Overloaded version for data buffer */ - void WriteDimensionsRecord(const std::vector<size_t> &localDimensions, - const std::vector<size_t> &globalDimensions, - const std::vector<size_t> &offsets, + void WriteDimensionsRecord(const Dims localDimensions, + const Dims globalDimensions, const Dims offsets, const unsigned int skip, std::vector<char> &buffer, size_t &position) noexcept; @@ -206,7 +198,7 @@ private: /** Overloaded version for data buffer */ template <class T> - void WriteBoundsRecord(const bool isScalar, const Stats<T> &stats, + void WriteBoundsRecord(const bool singleValue, const Stats<T> &stats, uint8_t &characteristicsCounter, std::vector<char> &buffer, size_t &position) noexcept; @@ -260,19 +252,6 @@ private: * @param buffer */ void FlattenMetadata() noexcept; - - /** - * Writes the ADIOS log information (buffering, open, write and close) for a - * rank process - * @param rank current rank - * @param metadataSet contains Profile info for buffering - * @param transports contains Profile info for transport open, writes and - * close - * @return string for this rank that will be aggregated into profiling.log - */ - std::string GetRankProfilingLog( - const unsigned int rank, - const std::vector<std::shared_ptr<Transport>> &transports) noexcept; }; #define declare_template_instantiation(T) \ @@ -285,7 +264,7 @@ private: extern template void BP1Writer::WriteVariableMetadata( \ const Variable<T> &variable) noexcept; -ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation) +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) #undef declare_template_instantiation } // end namespace format diff --git a/source/adios2/utilities/format/bp1/BP1Writer.tcc b/source/adios2/toolkit/format/bp1/BP1Writer.tcc similarity index 88% rename from source/adios2/utilities/format/bp1/BP1Writer.tcc rename to source/adios2/toolkit/format/bp1/BP1Writer.tcc index 79315b10eb67a0d42f47172c885391c130c3cd51..31eac673a05c903ac5b71193d846aafad31cadac 100644 --- a/source/adios2/utilities/format/bp1/BP1Writer.tcc +++ b/source/adios2/toolkit/format/bp1/BP1Writer.tcc @@ -5,13 +5,15 @@ * BP1Writer.tcc * * Created on: Apr 11, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#ifndef ADIOS2_UTILITIES_FORMAT_BP1_BP1WRITER_TCC_ -#define ADIOS2_UTILITIES_FORMAT_BP1_BP1WRITER_TCC_ +#ifndef ADIOS2_TOOLKIT_FORMAT_BP1_BP1WRITER_TCC_ +#define ADIOS2_TOOLKIT_FORMAT_BP1_BP1WRITER_TCC_ #include "BP1Writer.h" +#include "adios2/helper/adiosFunctions.h" + namespace adios { namespace format @@ -23,13 +25,13 @@ BP1Writer::ResizeResult BP1Writer::ResizeBuffer(const Variable<T> &variable) { size_t variableData = GetVariableIndexSize(variable) + variable.PayLoadSize(); - size_t requiredCapacity = variableData + m_Heap.m_DataPosition; + size_t requiredCapacity = variableData + m_HeapBuffer.m_DataPosition; if (requiredCapacity > m_MaxBufferSize && m_MaxBufferSize > 0) // is set { - if (m_Heap.GetDataSize() < m_MaxBufferSize) + if (m_HeapBuffer.GetDataSize() < m_MaxBufferSize) { - m_Heap.ResizeData(m_MaxBufferSize); + m_HeapBuffer.ResizeData(m_MaxBufferSize); return ResizeResult::FLUSH; } } @@ -40,6 +42,11 @@ BP1Writer::ResizeResult BP1Writer::ResizeBuffer(const Variable<T> &variable) template <class T> void BP1Writer::WriteVariableMetadata(const Variable<T> &variable) noexcept { + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Resume(); + } + Stats<typename TypeInfo<T>::ValueType> stats = GetStats(variable); stats.TimeIndex = m_MetadataSet.TimeStep; @@ -50,23 +57,37 @@ void BP1Writer::WriteVariableMetadata(const Variable<T> &variable) noexcept stats.MemberID = variableIndex.MemberID; // write metadata header in data and extract offsets - stats.Offset = m_Heap.m_DataAbsolutePosition; + stats.Offset = m_HeapBuffer.m_DataAbsolutePosition; WriteVariableMetadataInData(variable, stats); - stats.PayloadOffset = m_Heap.m_DataAbsolutePosition; + stats.PayloadOffset = m_HeapBuffer.m_DataAbsolutePosition; // write to metadata index WriteVariableMetadataInIndex(variable, stats, isNew, variableIndex); ++m_MetadataSet.DataPGVarsCount; + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Pause(); + } } template <class T> void BP1Writer::WriteVariablePayload(const Variable<T> &variable) noexcept { - // EXPENSIVE part, might want to use threads if large, serial for now - CopyToBufferThreads(m_Heap.m_Data, m_Heap.m_DataPosition, + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Resume(); + } + + CopyToBufferThreads(m_HeapBuffer.m_Data, m_HeapBuffer.m_DataPosition, variable.m_AppValues, variable.TotalSize(), m_Threads); - m_Heap.m_DataAbsolutePosition += variable.PayLoadSize(); + m_HeapBuffer.m_DataAbsolutePosition += variable.PayLoadSize(); + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("buffering").Pause(); + } } // PRIVATE @@ -80,7 +101,7 @@ size_t BP1Writer::GetVariableIndexSize(const Variable<T> &variable) const indexSize += variable.m_Name.size(); // characteristics 3 and 4, check variable number of dimensions - const size_t dimensions = variable.DimensionsSize(); + const size_t dimensions = variable.m_Count.size(); indexSize += 28 * dimensions; // 28 bytes per dimension indexSize += 1; // id @@ -127,8 +148,8 @@ void BP1Writer::WriteVariableMetadataInData( const Variable<T> &variable, const Stats<typename TypeInfo<T>::ValueType> &stats) noexcept { - auto &buffer = m_Heap.m_Data; - auto &position = m_Heap.m_DataPosition; + auto &buffer = m_HeapBuffer.m_Data; + auto &position = m_HeapBuffer.m_DataPosition; // for writing length at the end const size_t varLengthPosition = position; @@ -168,7 +189,7 @@ void BP1Writer::WriteVariableMetadataInData( size_t backPosition = varLengthPosition; CopyToBuffer(buffer, backPosition, &varLength); - m_Heap.m_DataAbsolutePosition += position - varLengthPosition; + m_HeapBuffer.m_DataAbsolutePosition += position - varLengthPosition; } template <class T> @@ -179,8 +200,8 @@ void BP1Writer::WriteVariableMetadataInIndex( { auto &buffer = index.Buffer; - if (isNew == true) // write variable header (might be shared with - // attributes index) + if (isNew) // write variable header (might be shared with + // attributes index) { buffer.insert(buffer.end(), 4, 0); // skip var length (4) InsertToBuffer(buffer, &stats.MemberID); @@ -213,7 +234,7 @@ void BP1Writer::WriteBoundsRecord(const bool isScalar, const Stats<T> &stats, std::uint8_t &characteristicsCounter, std::vector<char> &buffer) noexcept { - if (isScalar == true) + if (isScalar) { // stats.min = stats.max = value, need to test WriteCharacteristicRecord(characteristic_value, characteristicsCounter, @@ -233,12 +254,12 @@ void BP1Writer::WriteBoundsRecord(const bool isScalar, const Stats<T> &stats, } template <class T> -void BP1Writer::WriteBoundsRecord(const bool isScalar, const Stats<T> &stats, +void BP1Writer::WriteBoundsRecord(const bool singleValue, const Stats<T> &stats, std::uint8_t &characteristicsCounter, std::vector<char> &buffer, size_t &position) noexcept { - if (isScalar == true) + if (singleValue) { // stats.min = stats.max = value, need to test WriteCharacteristicRecord(characteristic_value, characteristicsCounter, @@ -311,7 +332,7 @@ void BP1Writer::WriteVariableCharacteristics( buffer); ++characteristicsCounter; - WriteBoundsRecord(variable.m_IsScalar, stats, characteristicsCounter, + WriteBoundsRecord(variable.m_SingleValue, stats, characteristicsCounter, buffer); WriteCharacteristicRecord(characteristic_time_index, characteristicsCounter, @@ -365,7 +386,7 @@ void BP1Writer::WriteVariableCharacteristics( ++characteristicsCounter; // VALUE for SCALAR or STAT min, max for ARRAY - WriteBoundsRecord(variable.m_IsScalar, stats, characteristicsCounter, + WriteBoundsRecord(variable.m_SingleValue, stats, characteristicsCounter, buffer, position); // TIME INDEX WriteCharacteristicRecord(characteristic_time_index, characteristicsCounter, diff --git a/source/adios2/toolkit/interop/adios1/ADIOS1Common.cpp b/source/adios2/toolkit/interop/adios1/ADIOS1Common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2f981e94c22d67b2595ca17e9bdc403a23803ed4 --- /dev/null +++ b/source/adios2/toolkit/interop/adios1/ADIOS1Common.cpp @@ -0,0 +1,212 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * ADIOS1Common.cpp + * + * Created on: Jun 1, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov + */ + +#include "ADIOS1Common.h" +#include "ADIOS1Common.tcc" + +#include "adios2/ADIOSMPI.h" +#include "adios2/helper/adiosFunctions.h" //OpenModeToString, GetType + +extern int adios_verbose_level; +extern int adios_errno; + +namespace adios +{ +namespace interop +{ + +ADIOS1Common::ADIOS1Common(const std::string &groupName, + const std::string &fileName, MPI_Comm mpiComm, + const bool debugMode) +: m_GroupName(groupName), m_FileName(fileName), m_MPIComm(mpiComm), + m_DebugMode(debugMode) +{ + Init(); +} + +ADIOS1Common::~ADIOS1Common() { Close(); } + +void ADIOS1Common::Advance() { Close(); } + +void ADIOS1Common::Close() +{ + if (m_IsFileOpen) + { + adios_close(m_ADIOSFile); + m_IsFileOpen = false; + } +} + +// PRIVATE +void ADIOS1Common::Init() +{ + if (!m_IsInitialized) + { + adios_init_noxml(m_MPIComm); + m_IsInitialized = true; + } + adios_declare_group(&m_ADIOSGroup, m_GroupName.c_str(), "", + adios_stat_default); +} + +void ADIOS1Common::InitParameters(const Params ¶meters) +{ + auto itMaxBufferSize = parameters.find("max_size_MB"); + if (itMaxBufferSize != parameters.end()) + { + adios_set_max_buffer_size(std::stoul(itMaxBufferSize->second)); + } + + auto itVerbosity = parameters.find("verbose"); + if (itVerbosity != parameters.end()) + { + int verbosity = std::stoi(itVerbosity->second); + if (m_DebugMode) + { + if (verbosity < 0 || verbosity > 5) + throw std::invalid_argument( + "ERROR: Method verbose argument must be an " + "integer in the range [0,5], in call to " + "Open or Engine constructor\n"); + } + adios_verbose_level = verbosity; + } +} + +void ADIOS1Common::InitTransports( + const std::vector<Params> &transportsParameters) +{ + for (const auto ¶meters : transportsParameters) + { + auto itTransport = parameters.find("transport"); + + if (itTransport->second == "file" || itTransport->second == "File") + { + auto itLibrary = parameters.find("library"); + if (itLibrary == parameters.end() || + itLibrary->second == "POSIX") // use default POSIX + { + adios_select_method(m_ADIOSGroup, "POSIX", "", ""); + } + else if (itLibrary->second == "MPI_File" || + itLibrary->second == "MPI-IO" || + itLibrary->second == "MPI") + { + adios_select_method(m_ADIOSGroup, "MPI", "", ""); + } + else + { + if (m_DebugMode) + { + throw std::invalid_argument( + "ERROR: file transport library " + itLibrary->second + + " for file " + m_FileName + + " not supported, in ADIOS1 " + ", in call to Open\n"); + } + } + } + else + { + if (m_DebugMode) + throw std::invalid_argument("ERROR: invalid transport " + + itTransport->second + + ", only transports of type " + "file supported in ADIOS1, in call " + "to Open\n"); + } + } +} + +bool ADIOS1Common::Open(const OpenMode openMode) +{ + adios_open(&m_ADIOSFile, m_GroupName.c_str(), m_FileName.c_str(), + OpenModeToString(openMode, true).c_str(), m_MPIComm); + if (adios_errno == err_no_error) + { + m_IsFileOpen = true; + } + return m_IsFileOpen; +} + +bool ADIOS1Common::ReOpenAsNeeded() +{ + if (!m_IsFileOpen) + { + // Re-open in APPEND mode + adios_open(&m_ADIOSFile, m_GroupName.c_str(), m_FileName.c_str(), "a", + m_MPIComm); + if (adios_errno == err_no_error) + { + m_IsFileOpen = true; + adios_delete_vardefs(m_ADIOSGroup); + } + } + return m_IsFileOpen; +} + +void ADIOS1Common::DefineVariable(const std::string &name, + const ShapeID shapeID, + enum ADIOS_DATATYPES vartype, + const std::string ldims, + const std::string gdims, + const std::string offsets) +{ + switch (shapeID) + { + case ShapeID::GlobalValue: + adios_define_var(m_ADIOSGroup, name.c_str(), "", vartype, "", "", ""); + break; + case ShapeID::LocalValue: + adios_define_var(m_ADIOSGroup, name.c_str(), "", vartype, "", "", ""); + adios_define_attribute(m_ADIOSGroup, "ReadAsArray", name.c_str(), + adios_byte, "1", nullptr); + break; + case ShapeID::GlobalArray: + case ShapeID::LocalArray: + case ShapeID::JoinedArray: + adios_define_var(m_ADIOSGroup, name.c_str(), "", vartype, ldims.c_str(), + gdims.c_str(), offsets.c_str()); + break; + } +} + +std::string ADIOS1Common::DimsToCSVLocalAware(const Dims &dims) +{ + std::string dimsCSV; + bool localVariable = false; + + for (const auto dim : dims) + { + dimsCSV += std::to_string(dim) + ","; + if (dim == JoinedDim || dim == IrregularDim) + { + localVariable = true; + } + } + + if (!dimsCSV.empty()) + { + dimsCSV.pop_back(); + } + + return dimsCSV; +} + +// Explicit declaration of the public template methods +#define declare_template_instantiation(T) \ + template void ADIOS1Common::WriteVariable<T>( \ + const std::string &name, const ShapeID shapeID, const Dims ldims, \ + const Dims gdims, const Dims offsets, const T *values); +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation + +} // end namespace interop +} // end namespace adios diff --git a/source/adios2/toolkit/interop/adios1/ADIOS1Common.h b/source/adios2/toolkit/interop/adios1/ADIOS1Common.h new file mode 100644 index 0000000000000000000000000000000000000000..6e821fe768055ba45b45d145d751ab2d610b418c --- /dev/null +++ b/source/adios2/toolkit/interop/adios1/ADIOS1Common.h @@ -0,0 +1,102 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * ADIOS1Common.h + * + * Created on: Jun 1, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMON_H_ +#define ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMON_H_ + +// Fake out the include guard from ADIOS1's mpidummy.h to prevent it from +// getting included +#ifdef _NOMPI +#define __MPI_DUMMY_H__ +#define MPI_Comm int +#endif +#include <adios.h> +#ifdef _NOMPI +#undef MPI_Comm +#undef __MPI_DUMMY_H__ +#endif + +#include "adios2/ADIOSMPICommOnly.h" +#include "adios2/ADIOSMacros.h" +#include "adios2/ADIOSTypes.h" + +namespace adios +{ +namespace interop +{ + +class ADIOS1Common +{ +public: + /** ADIOS1 unique group name created from IO class object name */ + const std::string m_GroupName; + + /**Save file name from constructor for Advance when re-open in ADIOS1 */ + const std::string m_FileName; + + const std::string m_OpenModeString; + + bool m_IsInitialized = false; ///< set to true after calling adios_init() + int64_t m_ADIOSFile = 0; ///< ADIOS1 file handler returned by adios_open() + int64_t m_ADIOSGroup = 0; ///< ADIOS1 group pointer that holds the ADIOS1 + /// variable definitions + bool m_IsFileOpen = false; + + int m_VerboseLevel = 0; + ADIOS_ERRCODES m_ErrorNumber = static_cast<ADIOS_ERRCODES>(-1); + + ADIOS1Common(const std::string &groupName, const std::string &fileName, + MPI_Comm mpiComm, const bool debugMode); + + ~ADIOS1Common(); + + void InitParameters(const Params ¶meters); + void InitTransports(const std::vector<Params> &transportsParameters); + bool Open(const OpenMode openMode); // return true if file is opened + bool ReOpenAsNeeded(); // return true if file is open or reopened + + template <class T> + void WriteVariable(const std::string &name, const ShapeID shapeID, + const Dims ldims, const Dims gdims, const Dims offsets, + const T *values); + + void Advance(); + + void Close(); + +private: + MPI_Comm m_MPIComm; + const bool m_DebugMode = false; + + void Init(); + + void DefineVariable(const std::string &name, const ShapeID shapeID, + enum ADIOS_DATATYPES vartype, const std::string ldims, + const std::string gdims, const std::string offsets); + + template <class T> + enum ADIOS_DATATYPES GetADIOS1Type() const; + + std::string DimsToCSVLocalAware(const Dims &dims); +}; + +// Explicit declaration of the public template methods +#define declare_template_instantiation(T) \ + extern template void ADIOS1Common::WriteVariable<T>( \ + const std::string &name, const ShapeID shapeID, const Dims ldims, \ + const Dims gdims, const Dims offsets, const T *values); +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation + +} // end namespace interop +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMON_H_ */ diff --git a/source/adios2/toolkit/interop/adios1/ADIOS1Common.tcc b/source/adios2/toolkit/interop/adios1/ADIOS1Common.tcc new file mode 100644 index 0000000000000000000000000000000000000000..877805bbb044c24d0b662d36b17969504dd89790 --- /dev/null +++ b/source/adios2/toolkit/interop/adios1/ADIOS1Common.tcc @@ -0,0 +1,131 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * ADIOS1Common.tcc + * + * Created on: Jun 1, 2017 + * Author: Norbert Podhorszki pnorbert@ornl.gov + * William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMON_TCC_ +#define ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMON_TCC_ + +#include "ADIOS1Common.h" + +#include "adios2/helper/adiosFunctions.h" //GetType + +namespace adios +{ +namespace interop +{ + +template <class T> +void ADIOS1Common::WriteVariable(const std::string &name, const ShapeID shapeID, + const Dims ldims, const Dims gdims, + const Dims offsets, const T *values) +{ + if (ReOpenAsNeeded()) + { + if (GetADIOS1Type<T>() != adios_unknown) + { + DefineVariable( + name, shapeID, GetADIOS1Type<T>(), DimsToCSVLocalAware(ldims), + DimsToCSVLocalAware(gdims), DimsToCSVLocalAware(offsets)); + adios_write(m_ADIOSFile, name.c_str(), values); + } + else + { + throw std::invalid_argument("ERROR: ADIOS1 doesn't support type " + + GetType<T>() + ", in call to Write\n"); + } + } +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<char>() const { + return adios_byte; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<unsigned char>() const { + return adios_unsigned_byte; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<short>() const { + return adios_short; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<unsigned short>() const { + return adios_unsigned_short; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<int>() const { + return adios_integer; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<unsigned int>() const { + return adios_unsigned_integer; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<long int>() const { + return adios_long; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<unsigned long int>() const { + return adios_unsigned_long; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<long long int>() const { + + return adios_long; +} + +template <> +enum ADIOS_DATATYPES +ADIOS1Common::GetADIOS1Type<unsigned long long int>() const { + return adios_unsigned_long; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<float>() const { + return adios_real; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<double>() const { + return adios_double; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<long double>() const { + return adios_unknown; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<cfloat>() const { + return adios_complex; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<cdouble>() const { + return adios_double_complex; +} + +template <> +enum ADIOS_DATATYPES ADIOS1Common::GetADIOS1Type<cldouble>() const { + return adios_unknown; +} + +} // end namespace interop +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMON_TCC_ */ diff --git a/source/adios2/toolkit/interop/hdf5/HDF5Common.cpp b/source/adios2/toolkit/interop/hdf5/HDF5Common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9edf3a4cee97fe92cdc3f1061eb6520da53f037a --- /dev/null +++ b/source/adios2/toolkit/interop/hdf5/HDF5Common.cpp @@ -0,0 +1,242 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * HDF5Common.cpp + * + * Created on: April 20, 2017 + * Author: Junmin + */ + +#include "HDF5Common.h" +#include "HDF5Common.tcc" + +#include <complex> +#include <ios> +#include <iostream> +#include <stdexcept> + +#include "adios2/ADIOSMPI.h" + +namespace adios +{ +namespace interop +{ + +HDF5Common::HDF5Common(const bool debugMode) : m_DebugMode(debugMode) +{ + m_DefH5TypeComplexFloat = + H5Tcreate(H5T_COMPOUND, sizeof(std::complex<float>)); + H5Tinsert(m_DefH5TypeComplexFloat, "freal", 0, H5T_NATIVE_FLOAT); + H5Tinsert(m_DefH5TypeComplexFloat, "fimg", H5Tget_size(H5T_NATIVE_FLOAT), + H5T_NATIVE_FLOAT); + + m_DefH5TypeComplexDouble = + H5Tcreate(H5T_COMPOUND, sizeof(std::complex<double>)); + H5Tinsert(m_DefH5TypeComplexDouble, "dreal", 0, H5T_NATIVE_DOUBLE); + H5Tinsert(m_DefH5TypeComplexDouble, "dimg", H5Tget_size(H5T_NATIVE_DOUBLE), + H5T_NATIVE_DOUBLE); + + m_DefH5TypeComplexLongDouble = + H5Tcreate(H5T_COMPOUND, sizeof(std::complex<long double>)); + H5Tinsert(m_DefH5TypeComplexLongDouble, "ldouble real", 0, + H5T_NATIVE_LDOUBLE); + H5Tinsert(m_DefH5TypeComplexLongDouble, "ldouble img", + H5Tget_size(H5T_NATIVE_LDOUBLE), H5T_NATIVE_LDOUBLE); +} + +void HDF5Common::Init(const std::string &name, MPI_Comm comm, bool toWrite) +{ + m_WriteMode = toWrite; + m_PropertyListId = H5Pcreate(H5P_FILE_ACCESS); + +#ifdef ADIOS2_HAVE_MPI + H5Pset_fapl_mpio(m_PropertyListId, comm, MPI_INFO_NULL); +#endif + + std::string ts0 = "/TimeStep0"; + + if (toWrite) + { + /* + * Create a new file collectively and release property list identifier. + */ + m_FileId = H5Fcreate(name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, + m_PropertyListId); + if (m_FileId >= 0) + { + m_GroupId = H5Gcreate2(m_FileId, ts0.c_str(), H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + + if (m_DebugMode) + { + if (m_GroupId < 0) + { + throw std::ios_base::failure( + "ERROR: Unable to create HDF5 group " + ts0 + + " in call to Open\n"); + } + } + } + } + else + { + // read a file collectively + m_FileId = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); + if (m_FileId >= 0) + { + m_GroupId = H5Gopen(m_FileId, ts0.c_str(), H5P_DEFAULT); + } + } + + H5Pclose(m_PropertyListId); +} + +void HDF5Common::WriteTimeSteps() +{ + if (m_FileId < 0) + { + if (m_DebugMode) + { + throw std::invalid_argument("ERROR: invalid HDF5 file to record " + "timestep to, in call to Write\n"); + } + } + + if (!m_WriteMode) + { + return; + } + + hid_t s = H5Screate(H5S_SCALAR); + + hid_t attr = H5Acreate(m_FileId, "NumTimeSteps", H5T_NATIVE_UINT, s, + H5P_DEFAULT, H5P_DEFAULT); + uint totalTimeSteps = m_CurrentTimeStep + 1; + + if (m_GroupId < 0) + { + totalTimeSteps = m_CurrentTimeStep; + } + + H5Awrite(attr, H5T_NATIVE_UINT, &totalTimeSteps); + + H5Sclose(s); + H5Aclose(attr); +} + +unsigned int HDF5Common::GetNumTimeSteps() +{ + if (m_WriteMode) + { + return -1; + } + + if (m_FileId < 0) + { + if (m_DebugMode) + { + throw std::invalid_argument( + "ERROR: invalid HDF5 file to read timestep attribute.\n"); + } + } + + if (m_NumTimeSteps <= 0) + { + hid_t attr = H5Aopen(m_FileId, "NumTimeSteps", H5P_DEFAULT); + + H5Aread(attr, H5T_NATIVE_UINT, &m_NumTimeSteps); + H5Aclose(attr); + } + + return m_NumTimeSteps; +} + +void HDF5Common::Close() +{ + if (m_FileId < 0) + { + return; + } + + WriteTimeSteps(); + + if (m_GroupId >= 0) + { + H5Gclose(m_GroupId); + } + + H5Fclose(m_FileId); + m_FileId = -1; + m_GroupId = -1; +} + +void HDF5Common::Advance() +{ + if (m_GroupId >= 0) + { + H5Gclose(m_GroupId); + m_GroupId = -1; + } + + if (m_WriteMode) + { + // m_GroupId = H5Gcreate2(m_FileId, tsname.c_str(), H5P_DEFAULT, + // H5P_DEFAULT, H5P_DEFAULT); + } + else + { + if (m_NumTimeSteps == 0) + { + GetNumTimeSteps(); + } + if (m_CurrentTimeStep + 1 >= m_NumTimeSteps) + { + return; + } + + std::string timeStepName = + "/TimeStep" + std::to_string(m_CurrentTimeStep + 1); + m_GroupId = H5Gopen(m_FileId, timeStepName.c_str(), H5P_DEFAULT); + if (m_GroupId < 0) + { + throw std::ios_base::failure("ERROR: unable to open HDF5 group " + + timeStepName + ", in call to Open\n"); + } + } + ++m_CurrentTimeStep; +} + +void HDF5Common::CheckWriteGroup() +{ + if (!m_WriteMode) + { + return; + } + if (m_GroupId >= 0) + { + return; + } + + std::string timeStepName = "/TimeStep" + std::to_string(m_CurrentTimeStep); + m_GroupId = H5Gcreate2(m_FileId, timeStepName.c_str(), H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + + if (m_DebugMode) + { + if (m_GroupId < 0) + { + throw std::ios_base::failure( + "ERROR: HDF5: Unable to create group " + timeStepName); + } + } +} + +#define declare_template_instantiation(T) \ + template void HDF5Common::Write(Variable<T> &variable, const T *value); + +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation + +} // end namespace interop +} // end namespace adios diff --git a/source/adios2/toolkit/interop/hdf5/HDF5Common.h b/source/adios2/toolkit/interop/hdf5/HDF5Common.h new file mode 100644 index 0000000000000000000000000000000000000000..84151a2ec9d569f7bf5d3b474dd173cceb4b5907 --- /dev/null +++ b/source/adios2/toolkit/interop/hdf5/HDF5Common.h @@ -0,0 +1,81 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * HDF5CommonP.h + * + * Created on: March 20, 2017 + * Author: Junmin + */ + +#ifndef ADIOS2_TOOLKIT_INTEROP_HDF5_HDF5COMMON_H_ +#define ADIOS2_TOOLKIT_INTEROP_HDF5_HDF5COMMON_H_ + +#include <hdf5.h> + +#include <string> + +#include "adios2/ADIOSMPICommOnly.h" +#include "adios2/ADIOSMacros.h" +#include "adios2/ADIOSTypes.h" +#include "adios2/core/Variable.h" + +namespace adios +{ +namespace interop +{ + +class HDF5Common +{ + +public: + /** + * Unique constructor for HDF5 file + * @param debugMode true: extra exception checks + */ + HDF5Common(const bool debugMode); + + void Init(const std::string &name, MPI_Comm comm, bool toWrite); + + template <class T> + void Write(Variable<T> &variable, const T *values); + + void Close(); + void Advance(); + + unsigned int GetNumTimeSteps(); + void WriteTimeSteps(); + + hid_t m_PropertyListId = -1; + hid_t m_FileId = -1; + hid_t m_GroupId = -1; + + hid_t m_DefH5TypeComplexDouble; + hid_t m_DefH5TypeComplexFloat; + hid_t m_DefH5TypeComplexLongDouble; + + unsigned int m_CurrentTimeStep = 0; + + void CheckWriteGroup(); + + template <class T> + hid_t GetHDF5Type(); // should this be public? + +private: + const bool m_DebugMode; + bool m_WriteMode = false; + unsigned int m_NumTimeSteps = 0; +}; + +// Explicit declaration of the public template methods +#define declare_template_instantiation(T) \ + extern template void HDF5Common::Write(Variable<T> &variable, \ + const T *value); + +ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation) +#undef declare_template_instantiation + +} // end namespace interop +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_INTEROP_HDF5_HDF5COMMON_H_ */ diff --git a/source/adios2/toolkit/interop/hdf5/HDF5Common.tcc b/source/adios2/toolkit/interop/hdf5/HDF5Common.tcc new file mode 100644 index 0000000000000000000000000000000000000000..0a8c9ecd1ef76d040cf3776fac0ce229c9c4f170 --- /dev/null +++ b/source/adios2/toolkit/interop/hdf5/HDF5Common.tcc @@ -0,0 +1,184 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * HDF5Common.tcc + * + * Created on: Jun 1, 2017 + * Author: Junmin + */ + +#ifndef ADIOS2_TOOLKIT_INTEROP_HDF5_HDF5COMMON_TCC_ +#define ADIOS2_TOOLKIT_INTEROP_HDF5_HDF5COMMON_TCC_ + +#include "HDF5Common.h" + +#include <vector> + +namespace adios +{ +namespace interop +{ + +template <class T> +void HDF5Common::Write(Variable<T> &variable, const T *values) +{ + CheckWriteGroup(); + int dimSize = std::max(variable.m_Shape.size(), variable.m_Count.size()); + + std::vector<hsize_t> dimsf, count, offset; + + for (int i = 0; i < dimSize; ++i) + { + if (variable.m_Shape.size() == dimSize) + { + dimsf.push_back(variable.m_Shape[i]); + } + else + { + dimsf.push_back(variable.m_Count[i]); + } + + if (variable.m_Count.size() == dimSize) + { + count.push_back(variable.m_Count[i]); + if (variable.m_Start.size() == dimSize) + { + offset.push_back(variable.m_Start[i]); + } + else + { + offset.push_back(0); + } + } + else + { + count.push_back(variable.m_Shape[i]); + offset.push_back(0); + } + } + + hid_t fileSpace = H5Screate_simple(dimSize, dimsf.data(), NULL); + + hid_t h5Type = GetHDF5Type<T>(); + hid_t dsetID = H5Dcreate(m_GroupId, variable.m_Name.c_str(), h5Type, + fileSpace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + // H5Sclose(fileSpace); + + hid_t memSpace = H5Screate_simple(dimSize, count.data(), NULL); + + // Select hyperslab + fileSpace = H5Dget_space(dsetID); + H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, offset.data(), NULL, + count.data(), NULL); + + // Create property list for collective dataset write. + + hid_t plistID = H5Pcreate(H5P_DATASET_XFER); +#ifdef ADIOS2_HAVE_MPI + H5Pset_dxpl_mpio(plistID, H5FD_MPIO_COLLECTIVE); +#endif + herr_t status; + + status = H5Dwrite(dsetID, h5Type, memSpace, fileSpace, plistID, values); + + if (status < 0) + { + if (m_DebugMode) + { + throw std::ios_base::failure( + "ERROR: HDF5 file Write failed, in call to Write\n"); + } + } + + H5Dclose(dsetID); + H5Sclose(fileSpace); + H5Sclose(memSpace); + H5Pclose(plistID); +} + +template <> +hid_t HDF5Common::GetHDF5Type<char>() +{ + return H5T_NATIVE_CHAR; +} +template <> +hid_t HDF5Common::GetHDF5Type<unsigned char>() +{ + return H5T_NATIVE_UCHAR; +} +template <> +hid_t HDF5Common::GetHDF5Type<short>() +{ + return H5T_NATIVE_SHORT; +} +template <> +hid_t HDF5Common::GetHDF5Type<unsigned short>() +{ + return H5T_NATIVE_USHORT; +} +template <> +hid_t HDF5Common::GetHDF5Type<int>() +{ + return H5T_NATIVE_INT; +} +template <> +hid_t HDF5Common::GetHDF5Type<unsigned int>() +{ + return H5T_NATIVE_UINT; +} +template <> +hid_t HDF5Common::GetHDF5Type<long int>() +{ + return H5T_NATIVE_LONG; +} +template <> +hid_t HDF5Common::GetHDF5Type<unsigned long int>() +{ + return H5T_NATIVE_ULONG; +} +template <> +hid_t HDF5Common::GetHDF5Type<long long int>() +{ + return H5T_NATIVE_LLONG; +} +template <> +hid_t HDF5Common::GetHDF5Type<unsigned long long int>() +{ + return H5T_NATIVE_ULLONG; +} +template <> +hid_t HDF5Common::GetHDF5Type<float>() +{ + return H5T_NATIVE_FLOAT; +} +template <> +hid_t HDF5Common::GetHDF5Type<double>() +{ + return H5T_NATIVE_DOUBLE; +} +template <> +hid_t HDF5Common::GetHDF5Type<long double>() +{ + return H5T_NATIVE_LDOUBLE; +} +template <> +hid_t HDF5Common::GetHDF5Type<std::complex<float>>() +{ + return m_DefH5TypeComplexFloat; +} +template <> +hid_t HDF5Common::GetHDF5Type<std::complex<double>>() +{ + return m_DefH5TypeComplexDouble; +} +template <> +hid_t HDF5Common::GetHDF5Type<std::complex<long double>>() +{ + return m_DefH5TypeComplexLongDouble; +} + +} // end namespace interop +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_INTEROP_HDF5_HDF5COMMON_H_ */ diff --git a/source/adios2/toolkit/profiling/iochrono/IOChrono.h b/source/adios2/toolkit/profiling/iochrono/IOChrono.h new file mode 100644 index 0000000000000000000000000000000000000000..7898dd829c36dd6ba9230ba5daeac51f03772b9e --- /dev/null +++ b/source/adios2/toolkit/profiling/iochrono/IOChrono.h @@ -0,0 +1,53 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * IOChrono.h + * + * Created on: Mar 9, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_PROFILING_IOCHRONO_IOCHRONO_H_ +#define ADIOS2_TOOLKIT_PROFILING_IOCHRONO_IOCHRONO_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <unordered_map> +#include <vector> +/// \endcond + +#include "adios2/ADIOSConfig.h" +#include "adios2/toolkit/profiling/iochrono/Timer.h" + +namespace adios +{ +namespace profiling +{ + +/** + * Struct used to track + */ +struct IOChrono +{ + + /** + * Create timers for each process + * <pre> + * Key: process name + * Value: see Timer class public API, use to track process time as a + * chronometer with Resume() and Pause() functions + * </pre> + */ + std::unordered_map<std::string, Timer> Timers; + + /** Create byte tracking counter for each process*/ + std::unordered_map<std::string, size_t> Bytes; + + /** flag to determine if IOChrono object is used */ + bool IsActive = true; +}; + +} // end namespace profiling +} // end namespace adios + +#endif /* ADIOS2_CORE_IOCHRONO_H_ */ diff --git a/source/adios2/toolkit/profiling/iochrono/Timer.cpp b/source/adios2/toolkit/profiling/iochrono/Timer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..627842fa8b6709383beafc9c5ba1d5b872f33b89 --- /dev/null +++ b/source/adios2/toolkit/profiling/iochrono/Timer.cpp @@ -0,0 +1,115 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Timer.cpp + * + * Created on: Apr 4, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "Timer.h" + +#include "adios2/helper/adiosFunctions.h" //LocalTimeDate + +namespace adios +{ +namespace profiling +{ + +Timer::Timer(const std::string process, const TimeUnit timeUnit, + const bool debug) +: m_Process(process), m_TimeUnit(timeUnit), m_LocalTimeDate(LocalTimeDate()), + m_DebugMode(debug) +{ +} + +void Timer::Resume() noexcept +{ + m_InitialTime = std::chrono::high_resolution_clock::now(); + m_InitialTimeSet = true; +} + +void Timer::Pause() noexcept +{ + m_ElapsedTime = std::chrono::high_resolution_clock::now(); + m_ProcessTime += GetElapsedTime(); +} + +std::string Timer::GetShortUnits() const noexcept +{ + std::string units; + switch (m_TimeUnit) + { + case TimeUnit::Microseconds: + units = "mus"; + break; + case TimeUnit::Milliseconds: + units = "ms"; + break; + case TimeUnit::Seconds: + units = "s"; + break; + case TimeUnit::Minutes: + units = "m"; + break; + case TimeUnit::Hours: + units = "h"; + break; + } + return units; +} + +// PRIVATE +int64_t Timer::GetElapsedTime() +{ + if (m_DebugMode) + { + if (!m_InitialTimeSet) + { + throw std::invalid_argument("ERROR: Resume() in process " + + m_Process + " not called\n"); + } + } + + int64_t time = -1; + + switch (m_TimeUnit) + { + + case TimeUnit::Microseconds: + time = std::chrono::duration_cast<std::chrono::microseconds>( + m_ElapsedTime - m_InitialTime) + .count(); + break; + + case TimeUnit::Milliseconds: + time = std::chrono::duration_cast<std::chrono::milliseconds>( + m_ElapsedTime - m_InitialTime) + .count(); + break; + + case TimeUnit::Seconds: + time = std::chrono::duration_cast<std::chrono::seconds>(m_ElapsedTime - + m_InitialTime) + .count(); + break; + + case TimeUnit::Minutes: + time = std::chrono::duration_cast<std::chrono::minutes>(m_ElapsedTime - + m_InitialTime) + .count(); + break; + + case TimeUnit::Hours: + time = std::chrono::duration_cast<std::chrono::hours>(m_ElapsedTime - + m_InitialTime) + .count(); + break; + } + + return time; +} + +} // end namespace +} // end namespace diff --git a/source/adios2/toolkit/profiling/iochrono/Timer.h b/source/adios2/toolkit/profiling/iochrono/Timer.h new file mode 100644 index 0000000000000000000000000000000000000000..88ea9671391796b33de6d9634eab2a1ac4c36700 --- /dev/null +++ b/source/adios2/toolkit/profiling/iochrono/Timer.h @@ -0,0 +1,79 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Timer.h + * + * Created on: Apr 4, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_PROFILING_IOCHRONO_TIMER_H_ +#define ADIOS2_TOOLKIT_PROFILING_IOCHRONO_TIMER_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <chrono> +#include <string> +/// \endcond + +#include "adios2/ADIOSConfig.h" +#include "adios2/ADIOSTypes.h" + +namespace adios +{ +namespace profiling +{ + +class Timer +{ + +public: + /** process name */ + const std::string m_Process; + + /** process elapsed time */ + int64_t m_ProcessTime = 0; + + /** time unit for elapsed time from ADIOSTypes.h */ + const TimeUnit m_TimeUnit; + + /** creation timedate from std::ctime */ + std::string m_LocalTimeDate; + + /** + * Timer object constructor using std::chrono class + * @param process name of process to be measured + * @param timeUnit (mus, ms, s, etc.) from ADIOSTypes.h TimeUnit + * @param debugMode true: additional exception checks (recommended) + */ + Timer(const std::string process, const TimeUnit timeUnit, + const bool debugMode = false); + + ~Timer() = default; + + /** sets timer active to start counting */ + void Resume() noexcept; + + /** pauses timer (set to inactive) */ + void Pause() noexcept; + + /** Returns TimeUnit as a short std::string */ + std::string GetShortUnits() const noexcept; + +private: + /** true: extra exceptions */ + const bool m_DebugMode = false; + /** Set at Resume */ + std::chrono::time_point<std::chrono::high_resolution_clock> m_InitialTime; + /** Set at Pause */ + std::chrono::time_point<std::chrono::high_resolution_clock> m_ElapsedTime; + /** Checks if m_InitialTime is set, timer is running */ + bool m_InitialTimeSet = false; + /** called by Pause to get time between Pause and Resume */ + int64_t GetElapsedTime(); +}; + +} // end namespace profiling +} // end namespace adios + +#endif /* ADIOS2_CORE_TIMER_H_ */ diff --git a/source/adios2/toolkit/transport/Transport.cpp b/source/adios2/toolkit/transport/Transport.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0320a0ccaa32ebce752367b4176eb5c64f9b505d --- /dev/null +++ b/source/adios2/toolkit/transport/Transport.cpp @@ -0,0 +1,68 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Transport.cpp + * + * Created on: Dec 5, 2016 + * Author: wfg + */ + +#include "Transport.h" + +#include "adios2/ADIOSMPI.h" + +namespace adios +{ + +Transport::Transport(const std::string type, const std::string library, + MPI_Comm mpiComm, const bool debugMode) +: m_Type(type), m_Library(library), m_MPIComm(mpiComm), m_DebugMode(debugMode) +{ + MPI_Comm_rank(m_MPIComm, &m_RankMPI); + MPI_Comm_size(m_MPIComm, &m_SizeMPI); +} + +void Transport::InitProfiler(const OpenMode openMode, const TimeUnit timeUnit) +{ + m_Profiler.Timers.emplace(std::make_pair( + "open", profiling::Timer("open", TimeUnit::Microseconds, m_DebugMode))); + + if (openMode == OpenMode::Write) + { + m_Profiler.Timers.emplace( + "write", profiling::Timer("write", timeUnit, m_DebugMode)); + + m_Profiler.Bytes.emplace("write", 0); + } + else if (openMode == OpenMode::Append) + { + m_Profiler.Timers.emplace( + "append", profiling::Timer("append", timeUnit, m_DebugMode)); + m_Profiler.Bytes.emplace("append", 0); + } + else if (openMode == OpenMode::Read) + { + m_Profiler.Timers.emplace( + "read", profiling::Timer("read", timeUnit, m_DebugMode)); + m_Profiler.Bytes.emplace("read", 0); + } + + m_Profiler.Timers.emplace( + "close", + profiling::Timer("close", TimeUnit::Microseconds, m_DebugMode)); + + m_Profiler.IsActive = true; +} + +void Transport::SetBuffer(char * /*buffer*/, size_t /*size*/) +{ + if (m_DebugMode) + { + std::invalid_argument("ERROR: " + m_Name + " transport type " + m_Type + + " using library " + m_Library + + " doesn't implement the SetBuffer function\n"); + } +} + +} // end namespace adios diff --git a/source/adios2/toolkit/transport/Transport.h b/source/adios2/toolkit/transport/Transport.h new file mode 100644 index 0000000000000000000000000000000000000000..ac7a2c89426d5629dac4556a3f8d840461e88df4 --- /dev/null +++ b/source/adios2/toolkit/transport/Transport.h @@ -0,0 +1,88 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * Transport.h defines Transport abstract base class + * + * Created on: Oct 6, 2016 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_TRANSPORT_TRANSPORT_H_ +#define ADIOS2_TOOLKIT_TRANSPORT_TRANSPORT_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <string> +#include <vector> +/// \endcond + +#include "adios2/ADIOSConfig.h" +#include "adios2/ADIOSMPICommOnly.h" +#include "adios2/ADIOSTypes.h" +#include "adios2/toolkit/profiling/iochrono/IOChrono.h" + +namespace adios +{ +/** Abstract Base class for transports */ +class Transport +{ + +public: + const std::string m_Type; ///< transport type from derived class + const std::string m_Library; ///< library implementation (POSIX, Mdtm, etc.) + std::string m_Name; ///< from Open, unique identifier (e.g. filename) + OpenMode m_OpenMode = OpenMode::Undefined; ///< at Open from ADIOSTypes.h + bool m_IsOpen = false; ///< true: open for communication, false: unreachable + MPI_Comm m_MPIComm; ///< current MPI communicator + int m_RankMPI = 0; ///< from MPI_Comm_Rank + int m_SizeMPI = 1; ///< from MPI_Comm_Size + profiling::IOChrono m_Profiler; ///< profiles Open, Write/Read, Close + + /** + * Base constructor that all derived classes pass + * @param type from derived class + * @param mpiComm passed to m_MPIComm + * @param debugMode passed to m_DebugMode + */ + Transport(const std::string type, const std::string library, + MPI_Comm mpiComm, const bool debugMode); + + virtual ~Transport() = default; + + void InitProfiler(const OpenMode openMode, const TimeUnit timeUnit); + + /** + * Opens transport, required before SetBuffer, Write, Read, Flush, Close + * @param name + * @param openMode + */ + virtual void Open(const std::string &name, const OpenMode openMode) = 0; + + /** + * If OS buffered (FILE* or fstream), sets the buffer size + * @param buffer address for OS buffering + * @param size of OS buffer + */ + virtual void SetBuffer(char *buffer, size_t size); + + /** + * Writes to file stream + * @param buffer raw data to be written to file stream + * @param size number of bytes to be written to file stream + */ + virtual void Write(const char *buffer, size_t size) = 0; + + /** flushes current contents to physical medium without closing */ + virtual void Flush() = 0; + + /** closes current file, after this file becomes unreachable */ + virtual void Close() = 0; + +protected: + /** true: turn on exceptions */ + const bool m_DebugMode = false; +}; + +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_TRANSPORT_TRANSPORT_H_ */ diff --git a/source/adios2/transport/file/FileDescriptor.cpp b/source/adios2/toolkit/transport/file/FileDescriptor.cpp similarity index 52% rename from source/adios2/transport/file/FileDescriptor.cpp rename to source/adios2/toolkit/transport/file/FileDescriptor.cpp index c64d6a4cfcdddcdd1b4de723f12c25c93046b495..1829d9c37c150a2d22d1e747141327cb80fc8b2b 100644 --- a/source/adios2/transport/file/FileDescriptor.cpp +++ b/source/adios2/toolkit/transport/file/FileDescriptor.cpp @@ -2,28 +2,31 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * FileDescriptor.cpp file descriptor + * FileDescriptor.cpp file I/O using POSIX I/O library * * Created on: Oct 6, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "FileDescriptor.h" #include <fcntl.h> // open -#include <ios> // std::ios_base::failure #include <stddef.h> // write output #include <sys/stat.h> // open #include <sys/types.h> // open #include <unistd.h> // write, close +/// \cond EXCLUDE_FROM_DOXYGEN +#include <ios> //std::ios_base::failure +/// \endcond + namespace adios { namespace transport { FileDescriptor::FileDescriptor(MPI_Comm mpiComm, const bool debugMode) -: Transport("POSIX_IO", mpiComm, debugMode) +: Transport("File", "POSIX", mpiComm, debugMode) { } @@ -35,90 +38,93 @@ FileDescriptor::~FileDescriptor() } } -void FileDescriptor::Open(const std::string &name, const std::string accessMode) +void FileDescriptor::Open(const std::string &name, const OpenMode openMode) { m_Name = name; - m_AccessMode = accessMode; + m_OpenMode = openMode; - if (accessMode == "w" || accessMode == "write") + if (openMode == OpenMode::Write) { - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[0].SetInitialTime(); + m_Profiler.Timers.at("open").Resume(); } m_FileDescriptor = open(m_Name.c_str(), O_WRONLY | O_CREAT, 0777); - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[0].SetTime(); + m_Profiler.Timers.at("open").Pause(); } } - else if (accessMode == "a" || accessMode == "append") + else if (openMode == OpenMode::Append) { - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[0].SetInitialTime(); + m_Profiler.Timers.at("open").Resume(); } - m_FileDescriptor = open(m_Name.c_str(), - O_WRONLY | O_APPEND); // we need to change this + // TODO we need to change this to read/write + m_FileDescriptor = open(m_Name.c_str(), O_WRONLY | O_APPEND); - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[0].SetTime(); + m_Profiler.Timers.at("open").Pause(); } } - else if (accessMode == "r" || accessMode == "read") + else if (openMode == OpenMode::Read) { - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[0].SetInitialTime(); + m_Profiler.Timers.at("open").Resume(); } m_FileDescriptor = open(m_Name.c_str(), O_RDONLY); - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[0].SetTime(); + m_Profiler.Timers.at("open").Pause(); } } - if (m_DebugMode == true) + if (m_DebugMode) { if (m_FileDescriptor == -1) { throw std::ios_base::failure( "ERROR: couldn't open file " + m_Name + - ", from call to Open in FD transport using " + ", from call to Open in FileDescriptor transport using " "POSIX open. Does file exists?\n"); } } + + m_IsOpen = true; } void FileDescriptor::Write(const char *buffer, std::size_t size) { - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[1].SetInitialTime(); + m_Profiler.Timers.at("write").Resume(); } auto writtenSize = write(m_FileDescriptor, buffer, size); - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[1].SetTime(); + m_Profiler.Timers.at("write").Pause(); } - if (m_DebugMode == true) + if (m_DebugMode) { if (writtenSize == -1) { - throw std::ios_base::failure("ERROR: couldn't write to file " + - m_Name + ", in call to POSIX write\n"); + throw std::ios_base::failure( + "ERROR: couldn't write to file " + m_Name + + ", in call to POSIX FileDescriptor write\n"); } - if (static_cast<std::size_t>(writtenSize) != size) + if (static_cast<size_t>(writtenSize) != size) { throw std::ios_base::failure( "ERROR: written size + " + std::to_string(writtenSize) + @@ -128,21 +134,23 @@ void FileDescriptor::Write(const char *buffer, std::size_t size) } } +void FileDescriptor::Flush() {} + void FileDescriptor::Close() { - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[2].SetInitialTime(); + m_Profiler.Timers.at("close").Resume(); } int status = close(m_FileDescriptor); - if (m_Profiler.IsActive == true) + if (m_Profiler.IsActive) { - m_Profiler.Timers[2].SetTime(); + m_Profiler.Timers.at("close").Pause(); } - if (m_DebugMode == true) + if (m_DebugMode) { if (status == -1) { diff --git a/source/adios2/toolkit/transport/file/FileDescriptor.h b/source/adios2/toolkit/transport/file/FileDescriptor.h new file mode 100644 index 0000000000000000000000000000000000000000..065b2301ad2f2d5b6d1e5e445dec616b9b04e103 --- /dev/null +++ b/source/adios2/toolkit/transport/file/FileDescriptor.h @@ -0,0 +1,47 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * FileDescriptor.h wrapper of POSIX library functions for file I/O + * + * Created on: Oct 6, 2016 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_TRANSPORT_FILE_FILEDESCRIPTOR_H_ +#define ADIOS2_TOOLKIT_TRANSPORT_FILE_FILEDESCRIPTOR_H_ + +#include "adios2/ADIOSConfig.h" +#include "adios2/toolkit/transport/Transport.h" + +namespace adios +{ +namespace transport +{ + +/** File descriptor transport using the POSIX library */ +class FileDescriptor : public Transport +{ + +public: + FileDescriptor(MPI_Comm mpiComm, const bool debugMode); + + ~FileDescriptor(); + + void Open(const std::string &name, const OpenMode openMode) final; + + void Write(const char *buffer, size_t size) final; + + /** Does nothing, each write is supposed to flush */ + void Flush() final; + + void Close() final; + +private: + /** POSIX file handle returned by Open */ + int m_FileDescriptor = -1; +}; + +} // end namespace transport +} // end namespace +#endif /* ADIOS2_TRANSPORT_FILE_FILEDESCRIPTOR_H_ */ diff --git a/source/adios2/transport/file/FilePointer.cpp b/source/adios2/toolkit/transport/file/FilePointer.cpp similarity index 58% rename from source/adios2/transport/file/FilePointer.cpp rename to source/adios2/toolkit/transport/file/FilePointer.cpp index 3e889420b7d7a36f8b0bb99dde1d73f8254203ab..e637693ca8cacad55fa498748bb384bcce7ec742 100644 --- a/source/adios2/transport/file/FilePointer.cpp +++ b/source/adios2/toolkit/transport/file/FilePointer.cpp @@ -2,15 +2,17 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * FP.cpp + * FilePointer.cpp * * Created on: Jan 6, 2017 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "FilePointer.h" +/// \cond EXCLUDE_FROM_DOXYGEN #include <ios> //std::ios_base::failure +/// \endcond namespace adios { @@ -18,53 +20,54 @@ namespace transport { FilePointer::FilePointer(MPI_Comm mpiComm, const bool debugMode) -: Transport("FILE*", mpiComm, debugMode) +: Transport("File", "C stdio.h", mpiComm, debugMode) { } FilePointer::~FilePointer() { - if (m_File != nullptr) + if (m_File) { fclose(m_File); } } -void FilePointer::Open(const std::string &name, const std::string accessMode) +void FilePointer::Open(const std::string &name, const OpenMode openMode) { m_Name = name; - m_AccessMode = accessMode; + m_OpenMode = openMode; - if (accessMode == "w" || accessMode == "write") + if (m_OpenMode == OpenMode::Write) { m_File = fopen(name.c_str(), "w"); } - else if (accessMode == "a" || accessMode == "append") + else if (m_OpenMode == OpenMode::Append) { - m_File = fopen(name.c_str(), "a"); + m_File = fopen(name.c_str(), "a"); // need to change } - else if (accessMode == "r" || accessMode == "read") + else if (m_OpenMode == OpenMode::Read) { m_File = fopen(name.c_str(), "r"); } - if (m_DebugMode == true) + if (m_DebugMode) { if (m_File == nullptr) { throw std::ios_base::failure( "ERROR: couldn't open file " + name + ", " - "in call to Open from File* transport\n"); + "in call to Open from stdio.h FilePointer* transport\n"); } } + m_IsOpen = true; } -void FilePointer::SetBuffer(char *buffer, std::size_t size) +void FilePointer::SetBuffer(char *buffer, size_t size) { int status = setvbuf(m_File, buffer, _IOFBF, size); - if (m_DebugMode == true) + if (m_DebugMode) { if (status == 1) { @@ -75,16 +78,17 @@ void FilePointer::SetBuffer(char *buffer, std::size_t size) } } -void FilePointer::Write(const char *buffer, std::size_t size) +void FilePointer::Write(const char *buffer, size_t size) { fwrite(buffer, sizeof(char), size, m_File); - if (m_DebugMode == true) + if (m_DebugMode) { if (ferror(m_File)) { - throw std::ios_base::failure("ERROR: couldn't write to file " + - m_Name + ", in call to File* write\n"); + throw std::ios_base::failure( + "ERROR: couldn't write to file " + m_Name + + ", in call to FilePointer* transport write\n"); } } } diff --git a/source/adios2/toolkit/transport/file/FilePointer.h b/source/adios2/toolkit/transport/file/FilePointer.h new file mode 100644 index 0000000000000000000000000000000000000000..414a1a71897ce845577bb4c554caaffa1e23eaae --- /dev/null +++ b/source/adios2/toolkit/transport/file/FilePointer.h @@ -0,0 +1,55 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * FilePointer.h wrapper of C/C++ stdio.h for file I/O + * + * Created on: Jan 6, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_TRANSPORT_FILE_FILEPOINTER_H_ +#define ADIOS2_TOOLKIT_TRANSPORT_FILE_FILEPOINTER_H_ + +#include <stdio.h> // FILE* + +#include "adios2/ADIOSConfig.h" +#include "adios2/toolkit/transport/Transport.h" + +namespace adios +{ +namespace transport +{ + +/** + * Class that defines a transport method using C file pointer (FP) to + * streams + * FILE* + */ +class FilePointer : public Transport +{ + +public: + FilePointer(MPI_Comm mpiComm, const bool debugMode); + + ~FilePointer(); + + void Open(const std::string &name, const OpenMode openMode) final; + + void SetBuffer(char *buffer, size_t size) final; + + void Write(const char *buffer, size_t size) final; + + void Flush(); + + void Close(); + +private: + /** C File pointer */ + FILE *m_File = nullptr; // NULL or nullptr? +}; + +} // end namespace transport +} // end namespace + +#endif /* ADIOS2_TOOLKIT_TRANSPORT_FILE_FILEPOINTER_H_ */ diff --git a/source/adios2/toolkit/transport/file/FileStream.cpp b/source/adios2/toolkit/transport/file/FileStream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e8adce2bc1dcbfbac509ffb76cdaaa14314777be --- /dev/null +++ b/source/adios2/toolkit/transport/file/FileStream.cpp @@ -0,0 +1,116 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * FileStream.cpp + * + * Created on: Oct 24, 2016 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "FileStream.h" + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <ios> // std::ios_base::failure +/// \endcond + +namespace adios +{ +namespace transport +{ + +FileStream::FileStream(MPI_Comm mpiComm, const bool debugMode) +: Transport("File", "fstream", mpiComm, debugMode) +{ +} + +void FileStream::Open(const std::string &name, const OpenMode openMode) +{ + m_Name = name; + m_OpenMode = openMode; + + if (m_OpenMode == OpenMode::Write) + { + m_FileStream.open(name, std::fstream::out); + } + else if (m_OpenMode == OpenMode::Append) + { + // to be changed to rw? + m_FileStream.open(name, std::fstream::out | std::fstream::app); + } + else if (m_OpenMode == OpenMode::Read) + { + m_FileStream.open(name, std::fstream::in); + } + + if (m_DebugMode) + { + if (!m_FileStream) + { + throw std::ios_base::failure("ERROR: couldn't open file " + name + + ", in call to FileStream Open\n"); + } + } + m_IsOpen = true; +} + +void FileStream::SetBuffer(char *buffer, size_t size) +{ + m_FileStream.rdbuf()->pubsetbuf(buffer, size); + if (m_DebugMode) + { + if (!m_FileStream) + { + throw std::ios_base::failure("ERROR: couldn't SetBuffer to file " + + m_Name + + ", in call to FileStream SetBuffer\n"); + } + } +} + +void FileStream::Write(const char *buffer, size_t size) +{ + m_FileStream.write(buffer, size); + + if (m_DebugMode) + { + if (!m_FileStream) + { + throw std::ios_base::failure("ERROR: couldn't write to file " + + m_Name + + ", in call to FileStream write\n"); + } + } +} + +void FileStream::Flush() +{ + m_FileStream.flush(); + if (m_DebugMode) + { + if (!m_FileStream) + { + throw std::ios_base::failure("ERROR: couldn't flush to file " + + m_Name + + ", in call to FileStream Flush\n"); + } + } +} + +void FileStream::Close() +{ + m_FileStream.close(); + if (m_DebugMode) + { + if (!m_FileStream) + { + throw std::ios_base::failure("ERROR: couldn't close file " + + m_Name + + ", in call to FileStream Close\n"); + } + } + m_IsOpen = false; +} + +} // end namespace transport +} // end namespace adios diff --git a/source/adios2/toolkit/transport/file/FileStream.h b/source/adios2/toolkit/transport/file/FileStream.h new file mode 100644 index 0000000000000000000000000000000000000000..5708292b20d5b48d683cf51dbd2894bdabd4ad22 --- /dev/null +++ b/source/adios2/toolkit/transport/file/FileStream.h @@ -0,0 +1,51 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * FileStream.h wrapper of C++ fstream for file I/O + * + * Created on: Oct 18, 2016 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_TRANSPORT_FILE_FILESTREAM_H_ +#define ADIOS2_TOOLKIT_TRANSPORT_FILE_FILESTREAM_H_ + +#include <fstream> + +#include "adios2/ADIOSConfig.h" +#include "adios2/toolkit/transport/Transport.h" + +namespace adios +{ +namespace transport +{ + +/** File stream transport using C++ fstream */ +class FileStream : public Transport +{ + +public: + FileStream(MPI_Comm mpiComm, const bool debugMode); + + ~FileStream() = default; + + void Open(const std::string &name, const OpenMode openMode) final; + + void SetBuffer(char *buffer, size_t size) final; + + void Write(const char *buffer, size_t size) final; + + void Flush() final; + + void Close() final; + +private: + /** file stream using fstream library */ + std::fstream m_FileStream; +}; + +} // end namespace transport +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_TRANSPORT_FILE_FILEPOINTER_H_ */ diff --git a/source/adios2/toolkit/transport/wan/WANZmq.cpp b/source/adios2/toolkit/transport/wan/WANZmq.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb72e8c9fbdf91c12e99e592499c3aedd2348bf6 --- /dev/null +++ b/source/adios2/toolkit/transport/wan/WANZmq.cpp @@ -0,0 +1,144 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * WANZmq.cpp + * + * Created on: May 26, 2017 + * Author: Jason Wang wangr1@ornl.gov + */ + +#include "WANZmq.h" + +#include <zmq.h> + +namespace adios +{ +namespace transport +{ + +WANZmq::WANZmq(const std::string ipAddress, const std::string port, + MPI_Comm mpiComm, const bool debugMode) +: Transport("wan", "zmq", mpiComm, debugMode), m_IPAddress(ipAddress), + m_Port(port) +{ + + if (m_DebugMode) + { + // TODO verify port is unsigned int + } +} + +WANZmq::~WANZmq() +{ + if (m_Socket) + { + zmq_close(m_Socket); + } +} + +void WANZmq::Open(const std::string &name, const OpenMode openMode) +{ + m_Name = name; + m_OpenMode = openMode; + + if (m_OpenMode == OpenMode::Write || m_OpenMode == OpenMode::w) + { + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("open").Resume(); + } + + m_Socket = zmq_socket(m_Context, ZMQ_REQ); + const std::string fullIP("tcp://" + m_IPAddress + ":" + m_Port); + zmq_connect(m_Socket, fullIP.c_str()); + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("open").Pause(); + } + } + else if (m_OpenMode == OpenMode::Append || m_OpenMode == OpenMode::a) + { + if (m_DebugMode) + { + throw std::invalid_argument( + "ERROR: WAN transport " + m_Name + + " only supports " + "OpenMode:w (write/sender) and " + "OpenMode:r (read/receiver), in call to Open\n"); + } + } + else if (m_OpenMode == OpenMode::Read || m_OpenMode == OpenMode::r) + { + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("open").Resume(); + } + + m_Socket = zmq_socket(m_Context, ZMQ_REP); + const std::string fullIP("tcp://" + m_IPAddress + ":" + m_Port); + zmq_bind(m_Socket, fullIP.c_str()); + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("open").Pause(); + } + } + + if (m_DebugMode) + { + if (m_Socket == NULL) // something goes wrong + { + throw std::ios_base::failure( + "ERROR: couldn't open socket for address " + m_Name + + ", in call to WANZmq Open\n"); + } + } + m_IsOpen = true; +} + +void WANZmq::SetBuffer(char *buffer, size_t size) {} + +void WANZmq::Write(const char *buffer, size_t size) +{ + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("write").Resume(); + } + + int status = zmq_send(m_Socket, buffer, size, 0); + char ret[10]; + zmq_recv(m_Socket, ret, 10, 0); + + if (m_Profiler.IsActive) + { + m_Profiler.Timers.at("write").Pause(); + } + + if (m_DebugMode) + { + const std::string retString(ret); + + if (status == -1 || retString != "OK") // TODO : verify this + { + throw std::ios_base::failure("ERROR: couldn't send message " + + m_Name + + ", in call to WANZmq write\n"); + } + } +} + +void WANZmq::Flush() {} + +void WANZmq::Close() +{ + if (m_Socket) + { + zmq_close(m_Socket); + } +} + +} // end namespace transport +} // end namespace adios diff --git a/source/adios2/toolkit/transport/wan/WANZmq.h b/source/adios2/toolkit/transport/wan/WANZmq.h new file mode 100644 index 0000000000000000000000000000000000000000..aacbcaeb5c36969783cd56247cbc021de13ebbf2 --- /dev/null +++ b/source/adios2/toolkit/transport/wan/WANZmq.h @@ -0,0 +1,63 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * WANZmq.h + * + * Created on: May 26, 2017 + * Author: Jason Wang wangr1@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_TRANSPORT_WAN_WANZMQ_H_ +#define ADIOS2_TOOLKIT_TRANSPORT_WAN_WANZMQ_H_ + +#include "adios2/toolkit/transport/Transport.h" + +namespace adios +{ +namespace transport +{ + +class WANZmq : public Transport +{ + +public: + /** + * + * @param ipAddress + * @param port + * @param mpiComm + * @param debugMode + */ + WANZmq(const std::string ipAddress, const std::string port, + MPI_Comm mpiComm, const bool debugMode); + + ~WANZmq(); + + void Open(const std::string &name, const OpenMode openMode) final; + + void SetBuffer(char *buffer, size_t size) final; + + void Write(const char *buffer, size_t size) final; + + void Flush() final; + + void Close() final; + + void SetAddress(const std::string address); + +private: + const std::string m_IPAddress; + std::string m_Port; + + /** TODO: find out if is provided externally */ + void *m_Context = NULL; + + /** handler created by zmq */ + void *m_Socket = NULL; +}; + +} // end namespace transport +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_TRANSPORT_WAN_WANZMQ_H_ */ diff --git a/source/adios2/toolkit/transportman/TransportMan.cpp b/source/adios2/toolkit/transportman/TransportMan.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49a45a71e37d8f5892152986289241eeccf1d8ca --- /dev/null +++ b/source/adios2/toolkit/transportman/TransportMan.cpp @@ -0,0 +1,240 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * TransportMan.cpp + * + * Created on: May 23, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include "TransportMan.h" + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <set> +/// \endcond + +#include "adios2/helper/adiosFunctions.h" //CreateDirectory +#include "adios2/toolkit/transport/file/FileDescriptor.h" +#include "adios2/toolkit/transport/file/FilePointer.h" +#include "adios2/toolkit/transport/file/FileStream.h" + +namespace adios +{ +namespace transportman +{ + +TransportMan::TransportMan(MPI_Comm mpiComm, const bool debugMode) +: m_MPIComm(mpiComm), m_DebugMode(debugMode) +{ +} + +void TransportMan::OpenFiles(const std::vector<std::string> &baseNames, + const std::vector<std::string> &names, + const OpenMode openMode, + const std::vector<Params> ¶metersVector, + const bool profile) +{ + const unsigned int size = baseNames.size(); + + for (unsigned int i = 0; i < size; ++i) + { + const Params ¶meters = parametersVector[i]; + const std::string type(parameters.at("transport")); + + if (type == "File" || type == "file") // need to create directory + { + CreateDirectory(baseNames[i]); + OpenFileTransport(names[i], openMode, parameters, profile); + } + } +} + +std::vector<std::string> TransportMan::GetFilesBaseNames( + const std::string &baseName, + const std::vector<Params> ¶metersVector) const +{ + if (parametersVector.size() <= 1) + { + return {baseName}; + } + + std::map<std::string, std::set<std::string>> typeTransportNames; + std::vector<std::string> baseNames; + baseNames.reserve(parametersVector.size()); + + for (const auto ¶meters : parametersVector) + { + // Get transport name from user + std::string name(baseName); + SetParameterValue("Name", parameters, name); // if found in map + + const std::string type(parameters.at("Transport")); + auto itType = typeTransportNames.find(type); + + if (m_DebugMode) + { + // check if name exists for this transport type + if (itType->second.count(name) == 1) + { + throw std::invalid_argument( + "ERROR: two IO AddTransport of the same type can't " + "have the same name : " + + name + ", use Name=value parameter, in " + "call to Open"); + } + } + itType->second.insert(name); + baseNames.push_back(name); + } + return baseNames; +} + +bool TransportMan::CheckTransportIndex(const int index) const noexcept +{ + const int upperLimit = static_cast<int>(m_Transports.size()); + const int lowerLimit = -1; + return CheckIndexRange(index, upperLimit, lowerLimit); +} + +std::vector<std::string> TransportMan::GetTransportsTypes() noexcept +{ + std::vector<std::string> types; + types.reserve(m_Transports.size()); + + for (const auto &transport : m_Transports) + { + types.push_back(transport->m_Type); + } + return types; +} + +std::vector<profiling::IOChrono *> +TransportMan::GetTransportsProfilers() noexcept +{ + std::vector<profiling::IOChrono *> profilers; + profilers.reserve(m_Transports.size()); + + for (const auto &transport : m_Transports) + { + profilers.push_back(&transport->m_Profiler); + } + return profilers; +} + +void TransportMan::CloseFiles(const int transportIndex, const char *buffer, + const size_t size) noexcept +{ + if (transportIndex == -1) + { + for (auto &transport : m_Transports) + { + if (transport->m_Type == "File") + { + // make this truly asynch? + transport->Write(buffer, size); + transport->Close(); + } + } + } + else + { + if (m_DebugMode) + { + if (m_Transports[transportIndex]->m_Type != "File") + { + throw std::invalid_argument( + "ERROR: index " + std::to_string(transportIndex) + + " doesn't come from a file transport in IO AddTransport, " + "in call to Close\n"); + } + } + + m_Transports[transportIndex]->Write(buffer, size); + m_Transports[transportIndex]->Close(); + } +} + +bool TransportMan::AllTransportsClosed() const noexcept +{ + bool allClose = true; + for (const auto &transport : m_Transports) + { + if (transport->m_IsOpen) + { + allClose = false; + break; + } + } + return allClose; +} + +// PRIVATE +void TransportMan::OpenFileTransport(const std::string &fileName, + const OpenMode openMode, + const Params ¶meters, + const bool profile) +{ + auto lf_SetFileTransport = [&](const std::string library, + std::shared_ptr<Transport> &transport) { + if (library == "POSIX") + { + transport = std::make_shared<transport::FileDescriptor>( + m_MPIComm, m_DebugMode); + } + else if (library == "stdio") + { + transport = std::make_shared<transport::FilePointer>(m_MPIComm, + m_DebugMode); + } + else if (library == "fstream") + { + transport = + std::make_shared<transport::FileStream>(m_MPIComm, m_DebugMode); + } + else + { + if (m_DebugMode) + { + throw std::invalid_argument( + "ERROR: invalid IO AddTransport library " + library + + ", only POSIX, stdio, fstream are supported\n"); + } + } + }; + + auto lf_GetLibrary = [](const std::string defaultLibrary, + const Params ¶meters) -> std::string { + + std::string library(defaultLibrary); + SetParameterValue("Library", parameters, library); + return library; + }; + + auto lf_GetTimeUnits = [&](const std::string defaultTimeUnit, + const Params ¶meters) -> TimeUnit { + + std::string profileUnits(defaultTimeUnit); + SetParameterValue("ProfileUnits", parameters, profileUnits); + return StringToTimeUnit(profileUnits, m_DebugMode); + }; + + // BODY OF FUNCTION starts here + std::shared_ptr<Transport> transport; + lf_SetFileTransport(lf_GetLibrary(DefaultFileLibrary, parameters), + transport); + + // Default or user ProfileUnits in parameters + if (profile) + { + transport->InitProfiler(openMode, + lf_GetTimeUnits(DefaultTimeUnit, parameters)); + } + + // open and move transport to container + transport->Open(fileName, openMode); + m_Transports.push_back(std::move(transport)); // is move needed? +} + +} // end namespace transport +} // end namespace adios diff --git a/source/adios2/toolkit/transportman/TransportMan.h b/source/adios2/toolkit/transportman/TransportMan.h new file mode 100644 index 0000000000000000000000000000000000000000..23c728b14513420afb6dfbd4076871d3a34b5d23 --- /dev/null +++ b/source/adios2/toolkit/transportman/TransportMan.h @@ -0,0 +1,114 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * TransportMan.h : manages a vector of transports + * + * Created on: May 23, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_TRANSPORT_TRANSPORTMANAGER_H_ +#define ADIOS2_TOOLKIT_TRANSPORT_TRANSPORTMANAGER_H_ + +/// \cond EXCLUDE_FROM_DOXYGEN +#include <memory> //std::shared_ptr +#include <string> +#include <unordered_map> +#include <vector> +/// \endcond + +#include "adios2/ADIOSMPICommOnly.h" +#include "adios2/toolkit/transport/Transport.h" + +namespace adios +{ +namespace transportman +{ + +class TransportMan +{ + +public: + /** contains all transports from IO AddTransport + * <pre> + * key : unique id from IO AddTransport + * value : obejct derived from Transport.h class + * </pre> + */ + std::vector<std::shared_ptr<Transport>> m_Transports; + + /** + * Unique base constructor + * @param mpiComm + * @param debugMode + */ + TransportMan(MPI_Comm mpiComm, const bool debugMode); + + virtual ~TransportMan() = default; + + /** + * + * @param baseNames passed from Open( name ) + * @param names actual filenames (from BP) + * @param openMode + * @param parametersVector from IO + * @param profile + */ + void OpenFiles(const std::vector<std::string> &baseNames, + const std::vector<std::string> &names, + const OpenMode openMode, + const std::vector<Params> ¶metersVector, + const bool profile); + + /** + * Gets each transport base name from either baseName at Open or name key in + * parameters + * Checks if transport name rules IO AddTransport have unique names for + * every type (for now) + * @param baseName from Open + * @param parameters from IO TransportsParameters (from AddTransport + * function) + * @return transport base names + */ + std::vector<std::string> + GetFilesBaseNames(const std::string &baseName, + const std::vector<Params> ¶metersVector) const; + + /** + * Checks if index is in range + * @param index input to be checked against m_Transports range or it's -1 + * @param true: in range, false: out of range + */ + bool CheckTransportIndex(const int index) const noexcept; + + /** + * m_Type from m_Transports based on derived classes of Transport + * @return m_Type for each transport in m_Transports (e.g. + * {FileDescriptor, + * FilePointer} ) + */ + std::vector<std::string> GetTransportsTypes() noexcept; + + /** Returns a vector of pointer references (not owning the memory) to + * m_Transports.m_Profiler */ + std::vector<profiling::IOChrono *> GetTransportsProfilers() noexcept; + + void CloseFiles(const int transportIndex, const char *buffer, + const size_t size) noexcept; + + /** Checks if all transports are closed */ + bool AllTransportsClosed() const noexcept; + +protected: + MPI_Comm m_MPIComm; + const bool m_DebugMode = false; + + void OpenFileTransport(const std::string &fileName, const OpenMode openMode, + const Params ¶meters, const bool profile); +}; + +} // end namespace transport +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_TRANSPORT_TRANSPORTMANAGER_H_ */ diff --git a/source/adios2/toolkit/transportman/dataman/DataMan.cpp b/source/adios2/toolkit/transportman/dataman/DataMan.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cd2774bbdbb9adfedb23bc92ba85c13d8995f1fe --- /dev/null +++ b/source/adios2/toolkit/transportman/dataman/DataMan.cpp @@ -0,0 +1,110 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * DataMan.cpp + * + * Created on: Jun 1, 2017 + * Author: Jason Wang wangr1@ornl.gov + */ + +#include "DataMan.h" + +namespace adios +{ +namespace transportman +{ + +DataMan::DataMan(MPI_Comm mpiComm, const bool debugMode) +: TransportMan(mpiComm, debugMode) +{ +} + +void DataMan::OpenWANTransports(const std::string &name, + const OpenMode openMode, + const std::vector<Params> ¶metersVector, + const bool profile) +{ + auto lf_GetParameter = [](const std::string key, const Params ¶ms, + const bool isMandatory, + const bool debugMode) -> std::string { + + std::string value; + auto itParameter = params.find(key); + if (itParameter == params.end()) + { + if (debugMode && isMandatory) + { + throw std::invalid_argument( + "ERROR: wan transport doesn't have mandatory parameter " + + key + + ", provide one in IO AddTransport, in call to Open\n"); + } + } + else + { + value = itParameter->second; + } + return value; + }; + + for (const auto ¶meters : parametersVector) + { + std::shared_ptr<Transport> wanTransport; + + const std::string type( + lf_GetParameter("transport", parameters, true, m_DebugMode)); + + const std::string lib( + lf_GetParameter("lib", parameters, true, m_DebugMode)); + + const std::string ipAddress( + lf_GetParameter("ipaddress", parameters, true, m_DebugMode)); + + const std::string port( + lf_GetParameter("port", parameters, false, m_DebugMode)); + + if (port.empty()) + { + port = m_DefaultPort; + } + + const std::string messageName( + lf_GetParameter("name", parameters, false, m_DebugMode)); + + if (messageName.empty()) + { + messageName = name; + } + + if (type == "wan") // need to create directory + { + if (lib == "zmq") + { +#ifdef ADIOS_HAVE_ZMQ + wanTransport = std::make_shared<transport::WANZmq>( + ipAddress, port, m_MPIComm, m_DebugMode); +#else + throw std::invalid_argument( + "ERROR: this version of ADIOS2 didn't compile with " + "ZMQ library, in call to Open\n"); +#endif + } + else + { + if (m_DebugMode) + { + throw std::invalid_argument("ERROR: wan library " + lib + + " not supported or not " + "provided in IO AddTransport, " + "in call to Open\n"); + } + } + } + wanTransport->Open(messageName, openMode); + m_Transports.push_back(std::move(wanTransport)); + } +} + +} // end namespace transportman +} // end namespace adios diff --git a/source/adios2/toolkit/transportman/dataman/DataMan.h b/source/adios2/toolkit/transportman/dataman/DataMan.h new file mode 100644 index 0000000000000000000000000000000000000000..0954fb0c42d37c0e66da15492faf097f475314c5 --- /dev/null +++ b/source/adios2/toolkit/transportman/dataman/DataMan.h @@ -0,0 +1,45 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * DataMan.h + * + * Created on: Jun 1, 2017 + * Author: Jason Wang wangr1@ornl.gov + */ + +#ifndef ADIOS2_TOOLKIT_TRANSPORTMAN_DATAMAN_DATAMAN_H_ +#define ADIOS2_TOOLKIT_TRANSPORTMAN_DATAMAN_DATAMAN_H_ + +#include "adios2/toolkit/transportman/TransportMan.h" + +#include <json.hpp> + +namespace adios +{ +namespace transportman +{ + +class DataMan : public TransportMan +{ + +public: + DataMan(MPI_Comm mpiComm, const bool debugMode); + + virtual ~DataMan() = default; + + void OpenWANTransports(const std::string &name, const OpenMode openMode, + const std::vector<Params> ¶metersVector, + const bool profile); + +private: + nlohmann::json m_JMessage; + + /** Pick the appropriate default */ + const std::string m_DefaultPort = "22"; +}; + +} // end namespace transportman +} // end namespace adios + +#endif /* ADIOS2_TOOLKIT_TRANSPORTMAN_DATAMAN_DATAMAN_H_ */ diff --git a/source/adios2/transform/BZip2.cpp b/source/adios2/transform/compression/BZip2.cpp similarity index 92% rename from source/adios2/transform/BZip2.cpp rename to source/adios2/transform/compression/BZip2.cpp index d0991b3a44fc85dad6ba92195d381f427b3c4148..e1d28134eafbb86f6424ef3b10cbf1cc1d124e16 100644 --- a/source/adios2/transform/BZip2.cpp +++ b/source/adios2/transform/compression/BZip2.cpp @@ -5,7 +5,7 @@ * BZIP2.cpp * * Created on: Oct 19, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ #include "BZip2.h" diff --git a/source/adios2/transform/BZip2.h b/source/adios2/transform/compression/BZip2.h similarity index 84% rename from source/adios2/transform/BZip2.h rename to source/adios2/transform/compression/BZip2.h index bf16fa75750c6e102ca920df3056352b9323273d..215f7d398730206486f72293abf01ed231ef0401 100644 --- a/source/adios2/transform/BZip2.h +++ b/source/adios2/transform/compression/BZip2.h @@ -5,11 +5,11 @@ * BZip2.h * * Created on: Oct 17, 2016 - * Author: wfg + * Author: William F Godoy godoywf@ornl.gov */ -#ifndef ADIOS2_TRANSFORM_BZIP2_H_ -#define ADIOS2_TRANSFORM_BZIP2_H_ +#ifndef ADIOS2_TRANSFORM_COMPRESSION_BZIP2_H_ +#define ADIOS2_TRANSFORM_COMPRESSION_BZIP2_H_ #include "adios2/ADIOSConfig.h" #include "adios2/core/Transform.h" diff --git a/source/adios2/transport/file/FStream.cpp b/source/adios2/transport/file/FStream.cpp deleted file mode 100644 index a22f83da196504c55a520d7927920902cc08ff75..0000000000000000000000000000000000000000 --- a/source/adios2/transport/file/FStream.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * CFStream.cpp - * - * Created on: Oct 24, 2016 - * Author: wfg - */ - -#include "FStream.h" - -#include <ios> // std::ios_base::failure -#include <stdexcept> - -namespace adios -{ -namespace transport -{ - -FStream::FStream(MPI_Comm mpiComm, const bool debugMode) -: Transport("fstream", mpiComm, debugMode) -{ -} - -void FStream::Open(const std::string &name, const std::string accessMode) -{ - m_Name = name; - m_AccessMode = accessMode; - - if (accessMode == "w" || accessMode == "write") - { - m_FStream.open(name, std::fstream::out); - } - else if (accessMode == "a" || accessMode == "append") - { - m_FStream.open(name, std::fstream::out | std::fstream::app); - } - else if (accessMode == "r" || accessMode == "read") - { - m_FStream.open(name, std::fstream::in); - } - - if (m_DebugMode == true) - { - if (!m_FStream) - { - throw std::ios_base::failure( - "ERROR: couldn't open file " + name + - ", in call to Open from FStream transport\n"); - } - } -} - -void FStream::SetBuffer(char *buffer, std::size_t size) -{ - m_FStream.rdbuf()->pubsetbuf(buffer, size); -} - -void FStream::Write(const char *buffer, std::size_t size) -{ - m_FStream.write(buffer, size); - - if (m_DebugMode == true) - { - if (!m_FStream) - { - throw std::ios_base::failure("ERROR: couldn't write to file " + - m_Name + - ", in call to FStream write\n"); - } - } -} - -void FStream::Flush() { m_FStream.flush(); } - -void FStream::Close() { m_FStream.close(); } - -} // end namespace transport -} // end namespace adios diff --git a/source/adios2/transport/file/FStream.h b/source/adios2/transport/file/FStream.h deleted file mode 100644 index a0436d788f0dde895d0ad44f08057b0b5d2f9d52..0000000000000000000000000000000000000000 --- a/source/adios2/transport/file/FStream.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * FStream.h - * - * Created on: Oct 18, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_TRANSPORT_FILE_FSTREAM_H_ -#define ADIOS2_TRANSPORT_FILE_FSTREAM_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <fstream> -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/core/Transport.h" - -namespace adios -{ -namespace transport -{ - -/** - * File stream transport using C++ fstream - */ -class FStream : public Transport -{ - -public: - FStream(MPI_Comm mpiComm, const bool debugMode); - - virtual ~FStream() = default; - - void Open(const std::string &name, const std::string accessMode); - - void SetBuffer(char *buffer, std::size_t size); - - void Write(const char *buffer, std::size_t size); - - void Flush(); - - void Close(); - -private: - std::fstream m_FStream; ///< file stream under name.bp.dir/name.bp.rank -}; - -} // end namespace transport -} // end namespace adios - -#endif /* ADIOS2_TRANSPORT_FILE_FSTREAM_H_ */ diff --git a/source/adios2/transport/file/FileDescriptor.h b/source/adios2/transport/file/FileDescriptor.h deleted file mode 100644 index 7b87d13c3c959ffa9feb908e416a89c06aa901fc..0000000000000000000000000000000000000000 --- a/source/adios2/transport/file/FileDescriptor.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * FileDescriptor.h uses POSIX as the underlying library - * - * Created on: Oct 6, 2016 - * Author: wfg - */ - -#ifndef ADIOS2_TRANSPORT_FILE_FILEDESCRIPTOR_H_ -#define ADIOS2_TRANSPORT_FILE_FILEDESCRIPTOR_H_ - -#include "adios2/ADIOSConfig.h" -#include "adios2/core/Transport.h" - -namespace adios -{ -namespace transport -{ - -/** - * File descriptor transport using the POSIX library - */ -class FileDescriptor : public Transport -{ - -public: - FileDescriptor(MPI_Comm mpiComm, const bool debugMode); - - ~FileDescriptor(); - - void Open(const std::string &name, const std::string accessMode); - - void Write(const char *buffer, std::size_t size); - - void Close(); - -private: - int m_FileDescriptor = -1; ///< file descriptor returned by POSIX open -}; - -} // end namespace transport -} // end namespace -#endif /* ADIOS2_TRANSPORT_FILE_FILEDESCRIPTOR_H_ */ diff --git a/source/adios2/transport/file/FilePointer.h b/source/adios2/transport/file/FilePointer.h deleted file mode 100644 index 8761127044dc8114bf2fa93d4080226127f41ff7..0000000000000000000000000000000000000000 --- a/source/adios2/transport/file/FilePointer.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * FilePointer.h - * - * Created on: Jan 6, 2017 - * Author: wfg - */ - -#ifndef ADIOS2_TRANSPORT_FILE_FILEPOINTER_H_ -#define ADIOS2_TRANSPORT_FILE_FILEPOINTER_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <stdio.h> // FILE* -/// \endcond - -#include "adios2/ADIOSConfig.h" -#include "adios2/core/Transport.h" - -namespace adios -{ -namespace transport -{ - -/** - * Class that defines a transport method using C file pointer (FP) to streams - * FILE* - */ -class FilePointer : public Transport -{ - -public: - FilePointer(MPI_Comm mpiComm, const bool debugMode); - - ~FilePointer(); - - void Open(const std::string &name, const std::string accessMode); - - void SetBuffer(char *buffer, std::size_t size); - - void Write(const char *buffer, std::size_t size); - - void Flush(); - - void Close(); - -private: - FILE *m_File = NULL; ///< C file pointer -}; - -} // end namespace transport -} // end namespace - -#endif /* ADIOS2_TRANSPORT_FILE_FILEPOINTER_H_ */ diff --git a/source/adios2/transport/file/MPI_File.h b/source/adios2/transport/file/MPI_File.h deleted file mode 100644 index 255d55983cc75e2ba111d1cc126f9caa3ae02380..0000000000000000000000000000000000000000 --- a/source/adios2/transport/file/MPI_File.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * MPIFile.h - * - * Created on: Jan 5, 2017 - * Author: wfg - */ - -#ifndef ADIOS2_TRANSPORT_FILE_MPI_FILE_H_ -#define ADIOS2_TRANSPORT_FILE_MPI_FILE_H_ - -#include "adios2/ADIOSConfig.h" -#include "adios2/ADIOSMPICommOnly.h" - -namespace adios -{ -namespace transport -{ - -/** - * Class that defines a transport method using C++ file streams - */ -class MPI_File : public Transport -{ - -public: - MPI_File(MPI_Comm mpiComm, const bool debugMode); - - ~MPI_File(); - - void Open(const std::string streamName, const std::string accessMode); - - void SetBuffer(char *buffer, std::size_t size); - - void Write(const char *buffer, std::size_t size); - - void Flush(); - - void Close(); - -private: - MPI_File m_MPIFile; ///< MPI File -}; - -} // end namespace transport -} // end namespace - -#endif /* ADIOS2_TRANSPORT_FILE_MPI_FILE_H_ */ diff --git a/source/adios2/transport/wan/MdtmMan.cpp b/source/adios2/transport/wan/MdtmMan.cpp deleted file mode 100644 index 2394ed008434404ee309a364a780ffe0239032b2..0000000000000000000000000000000000000000 --- a/source/adios2/transport/wan/MdtmMan.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * MdtmMan.cpp - * - * Created on: Jan 22, 2017 - * Author: wfg - */ - -#include "MdtmMan.h" - -namespace adios -{ -namespace transport -{ - -MdtmMan::MdtmMan(const std::string localIP, const std::string remoteIP, - const std::string mode, const std::string prefix, - const int numberOfPipes, const std::vector<int> tolerances, - const std::vector<int> priorities, MPI_Comm mpiComm, - const bool debugMode) -: Transport("File", mpiComm, debugMode), m_LocalIP{localIP}, - m_RemoteIP{remoteIP}, m_Mode{mode}, m_Prefix{prefix}, - m_NumberOfPipes{numberOfPipes}, m_Tolerances{tolerances}, - m_Priorities{priorities} -{ -} - -void MdtmMan::Open(const std::string name, const std::string accessMode) {} - -void MdtmMan::SetBuffer(char *buffer, std::size_t size) {} - -void MdtmMan::Write(const char *buffer, std::size_t size) {} - -void MdtmMan::Flush() {} - -void MdtmMan::Close() { m_NumberOfPipes = -1; } - -// PRIVATE Functions -int MdtmMan::Put(const void *data, const std::string doid, - const std::string variable, const std::string dType, - const std::vector<std::uint64_t> &putShape, - const std::vector<uint64_t> &varShape, - const std::vector<uint64_t> &offset, - const std::uint64_t timestep, const int tolerance, - const int priority) -{ - - return 0; -} - -int MdtmMan::Get(void *data, const std::string doid, const std::string variable, - const std::string dType, - const std::vector<std::uint64_t> &putShape, - const std::vector<uint64_t> &varShape, - const std::vector<uint64_t> &offset, - const std::uint64_t timestep, const int tolerance, - const int priority) -{ - - return 0; -} - -int MdtmMan::Get(void *data, const std::string doid, const std::string variable, - const std::string dType, std::vector<std::uint64_t> &varShape, - const std::uint64_t timestep) -{ - - return 0; -} - -void MdtmMan::OnReceive(nlohmann::json &jData) {} - -} // end namespace transport -} // end namespace diff --git a/source/adios2/transport/wan/MdtmMan.h b/source/adios2/transport/wan/MdtmMan.h deleted file mode 100644 index 887ffae35d4e8936a89f8d9dada6e49152bc44a5..0000000000000000000000000000000000000000 --- a/source/adios2/transport/wan/MdtmMan.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * MdtmMan.h - * - * Created on: Jan 18, 2017 - * Author: wfg - */ - -#ifndef ADIOS2_TRANSPORT_WAN_MDTMMAN_H_ -#define ADIOS2_TRANSPORT_WAN_MDTMMAN_H_ - -#include <json.hpp> - -#include "adios2/ADIOSConfig.h" -#include "adios2/core/Transport.h" - -namespace adios -{ -namespace transport -{ - -class MdtmMan : public Transport -{ - -public: - /** - * - * @param localIP - * @param remoteIP - * @param mode - * @param prefix - * @param numberOfPipes - * @param tolerances - * @param priorities - * @param mpiComm - * @param debugMode - */ - MdtmMan(const std::string localIP, const std::string remoteIP, - const std::string mode, const std::string prefix, - const int numberOfPipes, const std::vector<int> tolerances, - const std::vector<int> priorities, MPI_Comm mpiComm, - const bool debugMode); - - virtual ~MdtmMan() = default; - - void Open(const std::string name, const std::string accessMode); - - void SetBuffer(char *buffer, std::size_t size); - - /** - * We can always overload this function in the base class and accept other - * types of data pointers, e.g. Write( json* ); - * I'm sticking with char* as it's more general (only C++ libraries, e.g. - * boost understand std::std::vector, MPI, POSIX, Infiniband use pointer*) - * @param buffer - * @param size - */ - void Write(const char *buffer, std::size_t size); - - void Flush(); ///< not sure if this one is needed... - - void Close(); - -private: - std::string m_LocalIP; ///< local ip address, can change over time - std::string m_RemoteIP; ///< remote ip address, can change over time - std::string m_Mode; ///< send/write, receive/read - std::string m_Prefix; ///< prefix given to message - int m_NumberOfPipes = -1; ///< should it be unsigned int? - std::vector<int> m_Tolerances; - std::vector<int> m_Priorities; - - /** - * Should we change data to char* ? - * @param data - * @param doid - * @param variable - * @param dType - * @param putShape - * @param varShape - * @param offset - * @param timestep - * @param tolerance - * @param priority - * @return - */ - int Put(const void *data, const std::string doid, - const std::string variable, const std::string dType, - const std::vector<std::uint64_t> &putShape, - const std::vector<uint64_t> &varShape, - const std::vector<uint64_t> &offset, const std::uint64_t timestep, - const int tolerance, const int priority); - - /** - * - * @param data - * @param doid - * @param variable - * @param dType - * @param putShape - * @param varShape - * @param offset - * @param timestep - * @param tolerance - * @param priority - * @return - */ - int Get(void *data, const std::string doid, const std::string variable, - const std::string dType, const std::vector<std::uint64_t> &putShape, - const std::vector<uint64_t> &varShape, - const std::vector<uint64_t> &offset, const std::uint64_t timestep, - const int tolerance, const int priority); - - /** - * - * @param data - * @param doid - * @param variable - * @param dType - * @param varShape - * @param timestep - * @return - */ - int Get(void *data, const std::string doid, const std::string variable, - const std::string dType, std::vector<std::uint64_t> &varShape, - const std::uint64_t timestep); - - /** - * - * @param jData - */ - void OnReceive(nlohmann::json &jData); -}; - -} // end namespace transport -} // end namespace - -#endif /* ADIOS2_TRANSPORT_WAN_MDTMMAN_H_ */ diff --git a/source/adios2/utilities/format/bp1/BP1.h b/source/adios2/utilities/format/bp1/BP1.h deleted file mode 100644 index bc9ffb84acc7d8e098b7b9f6a65d5a3ed1fd59bd..0000000000000000000000000000000000000000 --- a/source/adios2/utilities/format/bp1/BP1.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * BP1.h - * - * Created on: Apr 4, 2017 - * Author: wfg - */ - -#ifndef ADIOS2_UTILITIES_FORMAT_BP1_BP1_H_ -#define ADIOS2_UTILITIES_FORMAT_BP1_BP1_H_ - -#include "adios2/ADIOSConfig.h" -#include "adios2/utilities/format/bp1/BP1Aggregator.h" -#include "adios2/utilities/format/bp1/BP1Structs.h" -#include "adios2/utilities/format/bp1/BP1Writer.h" - -#endif /* ADIOS2_UTILITIES_FORMAT_BP1_BP1_H_ */ diff --git a/source/adios2/utilities/format/bp1/BP1Base.cpp b/source/adios2/utilities/format/bp1/BP1Base.cpp deleted file mode 100644 index 43b1d293b6bbe94b2e36644a5ddf615ea420f8f8..0000000000000000000000000000000000000000 --- a/source/adios2/utilities/format/bp1/BP1Base.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * BP1.cpp - * - * Created on: Feb 7, 2017 - * Author: wfg - */ - -#include "BP1Base.h" - -#include "adios2/core/adiosFunctions.h" //CreateDirectory - -namespace adios -{ -namespace format -{ - -BP1Base::BP1Base(MPI_Comm mpiComm, const bool debugMode) -: m_BP1Aggregator(mpiComm, debugMode) -{ -} - -std::string BP1Base::GetDirectoryName(const std::string name) const noexcept -{ - std::string directory; - - if (name.find(".bp") == name.size() - 3) - { - directory = name; - } - else - { - directory = name + ".bp"; - } - return directory; -} - -// this should go outside -void BP1Base::OpenRankFiles(const std::string name, - const std::string accessMode, Transport &file) const -{ - const std::string directory = GetDirectoryName(name); - // creates a directory and sub-directories recursively - CreateDirectory(directory); - - // opens a file transport under name.bp/name.bp.rank - const std::string fileName(directory + "/" + directory + "." + - std::to_string(file.m_RankMPI)); - file.Open(fileName, accessMode); -} - -std::vector<uint8_t> BP1Base::GetMethodIDs( - const std::vector<std::shared_ptr<Transport>> &transports) const noexcept -{ - auto lf_GetMethodID = [](const std::string method) -> uint8_t { - 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<uint8_t> 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/source/dataman/DataMan.cpp b/source/dataman/DataMan.cpp index d3ba9a83fc147368a1cf0409a54cb2a9970b37d0..2c9ab9d27ac0b0330a3e9b48476ec963670f6526 100644 --- a/source/dataman/DataMan.cpp +++ b/source/dataman/DataMan.cpp @@ -72,11 +72,23 @@ void DataMan::add_stream(json a_jmsg) a_jmsg["num_channels"] = num_channels; } + int local_port = 12306, remote_port = 12307; + + if (a_jmsg["local_port"].is_number()) + { + local_port = a_jmsg["local_port"].get<int>(); + } + + if (a_jmsg["remote_port"].is_number()) + { + local_port = a_jmsg["remote_port"].get<int>(); + } + for (int i = 0; i < num_channels; i++) { a_jmsg["channel_id"] = i; - a_jmsg["local_port"] = a_jmsg["local_port"].get<int>() + 2; - a_jmsg["remote_port"] = a_jmsg["remote_port"].get<int>() + 2; + a_jmsg["local_port"] = local_port + 2; + a_jmsg["remote_port"] = remote_port + 2; auto man = get_man(method); if (man) { diff --git a/source/dataman/MdtmMan.cpp b/source/dataman/MdtmMan.cpp index 2f41d40c669d4f07439a31f437d4a112e4132517..6bfa3af8c5d860f8db16cfe8f9b380aca392bc42 100644 --- a/source/dataman/MdtmMan.cpp +++ b/source/dataman/MdtmMan.cpp @@ -19,6 +19,7 @@ int MdtmMan::init(json a_jmsg) { + std::cout << " 1 MdtmMan::init " << m_channel_id << std::endl; StreamMan::init(a_jmsg); if (a_jmsg["pipe_prefix"].is_string()) @@ -68,16 +69,22 @@ int MdtmMan::init(json a_jmsg) // Make pipes mkdir(m_pipepath.c_str(), 0755); + + std::cout << "making " << m_full_pipename << std::endl; mkfifo(m_full_pipename.c_str(), 0666); + std::cout << "made " << m_full_pipename << std::endl; if (m_stream_mode == "sender") { + std::cout << "opening " << m_full_pipename << std::endl; m_pipe_handler = open(m_full_pipename.c_str(), O_WRONLY); + std::cout << "opened " << m_full_pipename << std::endl; } if (m_stream_mode == "receiver") { m_pipe_handler = open(m_full_pipename.c_str(), O_RDONLY | O_NONBLOCK); } + return 0; } diff --git a/testing/adios2/engine/adios1/TestADIOS1WriteRead.cpp b/testing/adios2/engine/adios1/TestADIOS1WriteRead.cpp index fc27d532375e52f95eee61b4960327fa5a0e8dfc..ae7e964f16636dc51ad6321d2d23e8fac8db30ae 100644 --- a/testing/adios2/engine/adios1/TestADIOS1WriteRead.cpp +++ b/testing/adios2/engine/adios1/TestADIOS1WriteRead.cpp @@ -37,47 +37,53 @@ TEST_F(ADIOS1WriteReadTest, ADIOS2ADIOS1WriteADIOS1Read1D8) { adios_init_noxml(MPI_COMM_WORLD); - adios::ADIOS adios(adios::Verbose::WARN, true); + adios::ADIOS adios(true); + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{8}); - auto &var_i16 = adios.DefineVariable<short>("i16", adios::Dims{8}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{8}); - auto &var_i64 = adios.DefineVariable<long>("i64", adios::Dims{8}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{8}); + auto &var_i16 = + io.DefineVariable<short>("i16", {}, {}, adios::Dims{8}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{8}); + auto &var_i64 = + io.DefineVariable<long>("i64", {}, {}, adios::Dims{8}); auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{8}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{8}); + io.DefineVariable<unsigned char>("u8", {}, {}, adios::Dims{8}); + auto &var_u16 = io.DefineVariable<unsigned short>("u16", {}, {}, + adios::Dims{8}); auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{8}); + io.DefineVariable<unsigned int>("u32", {}, {}, adios::Dims{8}); auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{8}); - auto &var_r32 = adios.DefineVariable<float>("r32", adios::Dims{8}); - auto &var_r64 = adios.DefineVariable<double>("r64", adios::Dims{8}); + io.DefineVariable<unsigned long>("u64", {}, {}, adios::Dims{8}); + auto &var_r32 = + io.DefineVariable<float>("r32", {}, {}, adios::Dims{8}); + auto &var_r64 = + io.DefineVariable<double>("r64", {}, {}, adios::Dims{8}); } // Create the ADIOS 1 Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("ADIOS1Writer"); - method.AddTransport("File"); + io.SetEngine("ADIOS1Writer"); + io.AddTransport("File"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); @@ -260,51 +266,53 @@ TEST_F(ADIOS1WriteReadTest, ADIOS2ADIOS1WriteADIOS1Read2D2x4) { adios_init_noxml(MPI_COMM_WORLD); - adios::ADIOS adios(adios::Verbose::WARN, true); + adios::ADIOS adios(true); + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{2, 4}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{2, 4}); auto &var_i16 = - adios.DefineVariable<short>("i16", adios::Dims{2, 4}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{2, 4}); + io.DefineVariable<short>("i16", {}, {}, adios::Dims{2, 4}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{2, 4}); auto &var_i64 = - adios.DefineVariable<long>("i64", adios::Dims{2, 4}); - auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{2, 4}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{2, 4}); - auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{2, 4}); - auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{2, 4}); + io.DefineVariable<long>("i64", {}, {}, adios::Dims{2, 4}); + auto &var_u8 = io.DefineVariable<unsigned char>("u8", {}, {}, + adios::Dims{2, 4}); + auto &var_u16 = io.DefineVariable<unsigned short>( + "u16", {}, {}, adios::Dims{2, 4}); + auto &var_u32 = io.DefineVariable<unsigned int>("u32", {}, {}, + adios::Dims{2, 4}); + auto &var_u64 = io.DefineVariable<unsigned long>("u64", {}, {}, + adios::Dims{2, 4}); auto &var_r32 = - adios.DefineVariable<float>("r32", adios::Dims{2, 4}); + io.DefineVariable<float>("r32", {}, {}, adios::Dims{2, 4}); auto &var_r64 = - adios.DefineVariable<double>("r64", adios::Dims{2, 4}); + io.DefineVariable<double>("r64", {}, {}, adios::Dims{2, 4}); } // Create the ADIOS 1 Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("ADIOS1Writer"); - method.AddTransport("File"); + io.SetEngine("ADIOS1Writer"); + io.AddTransport("file"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); @@ -497,51 +505,53 @@ TEST_F(ADIOS1WriteReadTest, ADIOS2ADIOS1WriteADIOS1Read2D4x2) { adios_init_noxml(MPI_COMM_WORLD); - adios::ADIOS adios(adios::Verbose::WARN, true); + adios::ADIOS adios(true); + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{4, 2}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{4, 2}); auto &var_i16 = - adios.DefineVariable<short>("i16", adios::Dims{4, 2}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{4, 2}); + io.DefineVariable<short>("i16", {}, {}, adios::Dims{4, 2}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{4, 2}); auto &var_i64 = - adios.DefineVariable<long>("i64", adios::Dims{4, 2}); - auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{4, 2}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{4, 2}); - auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{4, 2}); - auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{4, 2}); + io.DefineVariable<long>("i64", {}, {}, adios::Dims{4, 2}); + auto &var_u8 = io.DefineVariable<unsigned char>("u8", {}, {}, + adios::Dims{4, 2}); + auto &var_u16 = io.DefineVariable<unsigned short>( + "u16", {}, {}, adios::Dims{4, 2}); + auto &var_u32 = io.DefineVariable<unsigned int>("u32", {}, {}, + adios::Dims{4, 2}); + auto &var_u64 = io.DefineVariable<unsigned long>("u64", {}, {}, + adios::Dims{4, 2}); auto &var_r32 = - adios.DefineVariable<float>("r32", adios::Dims{4, 2}); + io.DefineVariable<float>("r32", {}, {}, adios::Dims{4, 2}); auto &var_r64 = - adios.DefineVariable<double>("r64", adios::Dims{4, 2}); + io.DefineVariable<double>("r64", {}, {}, adios::Dims{4, 2}); } // Create the ADIOS 1 Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("ADIOS1Writer"); - method.AddTransport("File"); + io.SetEngine("ADIOS1Writer"); + io.AddTransport("file"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); diff --git a/testing/adios2/engine/bp/TestBPWriteRead.cpp b/testing/adios2/engine/bp/TestBPWriteRead.cpp index 2ca330c48172be05cb69aa2a174fcca5b56aaa52..ab6f328ced033d1c79a672356743de735cb704cf 100644 --- a/testing/adios2/engine/bp/TestBPWriteRead.cpp +++ b/testing/adios2/engine/bp/TestBPWriteRead.cpp @@ -34,47 +34,53 @@ TEST_F(BPWriteReadTest, ADIOS2BPWriteADIOS1Read1D8) // Write test data using ADIOS2 { - adios::ADIOS adios(adios::Verbose::WARN, true); + adios::ADIOS adios(true); + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{8}); - auto &var_i16 = adios.DefineVariable<short>("i16", adios::Dims{8}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{8}); - auto &var_i64 = adios.DefineVariable<long>("i64", adios::Dims{8}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{8}); + auto &var_i16 = + io.DefineVariable<short>("i16", {}, {}, adios::Dims{8}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{8}); + auto &var_i64 = + io.DefineVariable<long>("i64", {}, {}, adios::Dims{8}); auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{8}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{8}); + io.DefineVariable<unsigned char>("u8", {}, {}, adios::Dims{8}); + auto &var_u16 = io.DefineVariable<unsigned short>("u16", {}, {}, + adios::Dims{8}); auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{8}); + io.DefineVariable<unsigned int>("u32", {}, {}, adios::Dims{8}); auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{8}); - auto &var_r32 = adios.DefineVariable<float>("r32", adios::Dims{8}); - auto &var_r64 = adios.DefineVariable<double>("r64", adios::Dims{8}); + io.DefineVariable<unsigned long>("u64", {}, {}, adios::Dims{8}); + auto &var_r32 = + io.DefineVariable<float>("r32", {}, {}, adios::Dims{8}); + auto &var_r64 = + io.DefineVariable<double>("r64", {}, {}, adios::Dims{8}); } // Create the BP Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("BPFileWriter"); - method.AddTransport("File"); + io.SetEngine("BPFileWriter"); + io.AddTransport("File"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); @@ -244,51 +250,53 @@ TEST_F(BPWriteReadTest, ADIOS2BPWriteADIOS1Read2D2x4) // Write test data using ADIOS2 { - adios::ADIOS adios(adios::Verbose::WARN, true); + adios::ADIOS adios(true); + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{2, 4}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{2, 4}); auto &var_i16 = - adios.DefineVariable<short>("i16", adios::Dims{2, 4}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{2, 4}); + io.DefineVariable<short>("i16", {}, {}, adios::Dims{2, 4}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{2, 4}); auto &var_i64 = - adios.DefineVariable<long>("i64", adios::Dims{2, 4}); - auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{2, 4}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{2, 4}); - auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{2, 4}); - auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{2, 4}); + io.DefineVariable<long>("i64", {}, {}, adios::Dims{2, 4}); + auto &var_u8 = io.DefineVariable<unsigned char>("u8", {}, {}, + adios::Dims{2, 4}); + auto &var_u16 = io.DefineVariable<unsigned short>( + "u16", {}, {}, adios::Dims{2, 4}); + auto &var_u32 = io.DefineVariable<unsigned int>("u32", {}, {}, + adios::Dims{2, 4}); + auto &var_u64 = io.DefineVariable<unsigned long>("u64", {}, {}, + adios::Dims{2, 4}); auto &var_r32 = - adios.DefineVariable<float>("r32", adios::Dims{2, 4}); + io.DefineVariable<float>("r32", {}, {}, adios::Dims{2, 4}); auto &var_r64 = - adios.DefineVariable<double>("r64", adios::Dims{2, 4}); + io.DefineVariable<double>("r64", {}, {}, adios::Dims{2, 4}); } // Create the BP Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("BPFileWriter"); - method.AddTransport("File"); + io.SetEngine("BPFileWriter"); + io.AddTransport("file"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); @@ -468,51 +476,53 @@ TEST_F(BPWriteReadTest, ADIOS2BPWriteADIOS1Read2D4x2) // Write test data using ADIOS2 { - adios::ADIOS adios(adios::Verbose::WARN, true); + adios::ADIOS adios(true); + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{4, 2}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{4, 2}); auto &var_i16 = - adios.DefineVariable<short>("i16", adios::Dims{4, 2}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{4, 2}); + io.DefineVariable<short>("i16", {}, {}, adios::Dims{4, 2}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{4, 2}); auto &var_i64 = - adios.DefineVariable<long>("i64", adios::Dims{4, 2}); - auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{4, 2}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{4, 2}); - auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{4, 2}); - auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{4, 2}); + io.DefineVariable<long>("i64", {}, {}, adios::Dims{4, 2}); + auto &var_u8 = io.DefineVariable<unsigned char>("u8", {}, {}, + adios::Dims{4, 2}); + auto &var_u16 = io.DefineVariable<unsigned short>( + "u16", {}, {}, adios::Dims{4, 2}); + auto &var_u32 = io.DefineVariable<unsigned int>("u32", {}, {}, + adios::Dims{4, 2}); + auto &var_u64 = io.DefineVariable<unsigned long>("u64", {}, {}, + adios::Dims{4, 2}); auto &var_r32 = - adios.DefineVariable<float>("r32", adios::Dims{4, 2}); + io.DefineVariable<float>("r32", {}, {}, adios::Dims{4, 2}); auto &var_r64 = - adios.DefineVariable<double>("r64", adios::Dims{4, 2}); + io.DefineVariable<double>("r64", {}, {}, adios::Dims{4, 2}); } // Create the BP Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("BPFileWriter"); - method.AddTransport("File"); + io.SetEngine("BPFileWriter"); + io.AddTransport("file"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); diff --git a/testing/adios2/engine/hdf5/TestHDF5WriteRead.cpp b/testing/adios2/engine/hdf5/TestHDF5WriteRead.cpp index 3f2b6a69f8ab11257cb14674feb1a174bf23d8ef..8789a0829a109935b18da3cd8227d4034aa7afae 100644 --- a/testing/adios2/engine/hdf5/TestHDF5WriteRead.cpp +++ b/testing/adios2/engine/hdf5/TestHDF5WriteRead.cpp @@ -191,46 +191,51 @@ TEST_F(HDF5WriteReadTest, ADIOS2HDF5WriteHDF5Read1D8) // Write test data using ADIOS2 { - adios::ADIOS adios(adios::Verbose::WARN, true); // moved up + adios::ADIOS adios(true); // moved up + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{8}); - auto &var_i16 = adios.DefineVariable<short>("i16", adios::Dims{8}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{8}); - auto &var_i64 = adios.DefineVariable<long>("i64", adios::Dims{8}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{8}); + auto &var_i16 = + io.DefineVariable<short>("i16", {}, {}, adios::Dims{8}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{8}); + auto &var_i64 = + io.DefineVariable<long>("i64", {}, {}, adios::Dims{8}); auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{8}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{8}); + io.DefineVariable<unsigned char>("u8", {}, {}, adios::Dims{8}); + auto &var_u16 = io.DefineVariable<unsigned short>("u16", {}, {}, + adios::Dims{8}); auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{8}); + io.DefineVariable<unsigned int>("u32", {}, {}, adios::Dims{8}); auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{8}); - auto &var_r32 = adios.DefineVariable<float>("r32", adios::Dims{8}); - auto &var_r64 = adios.DefineVariable<double>("r64", adios::Dims{8}); + io.DefineVariable<unsigned long>("u64", {}, {}, adios::Dims{8}); + auto &var_r32 = + io.DefineVariable<float>("r32", {}, {}, adios::Dims{8}); + auto &var_r64 = + io.DefineVariable<double>("r64", {}, {}, adios::Dims{8}); } // Create the HDF5 Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("HDF5Writer"); - method.AddTransport("File"); + io.SetEngine("HDF5Writer"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); @@ -391,51 +396,53 @@ TEST_F(HDF5WriteReadTest, ADIOS2HDF5WriteHDF5Read2D2x4) // Write test data using ADIOS2 { - adios::ADIOS adios(adios::Verbose::WARN, true); + adios::ADIOS adios(true); + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{2, 4}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{2, 4}); auto &var_i16 = - adios.DefineVariable<short>("i16", adios::Dims{2, 4}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{2, 4}); + io.DefineVariable<short>("i16", {}, {}, adios::Dims{2, 4}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{2, 4}); auto &var_i64 = - adios.DefineVariable<long>("i64", adios::Dims{2, 4}); - auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{2, 4}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{2, 4}); - auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{2, 4}); - auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{2, 4}); + io.DefineVariable<long>("i64", {}, {}, adios::Dims{2, 4}); + auto &var_u8 = io.DefineVariable<unsigned char>("u8", {}, {}, + adios::Dims{2, 4}); + auto &var_u16 = io.DefineVariable<unsigned short>( + "u16", {}, {}, adios::Dims{2, 4}); + auto &var_u32 = io.DefineVariable<unsigned int>("u32", {}, {}, + adios::Dims{2, 4}); + auto &var_u64 = io.DefineVariable<unsigned long>("u64", {}, {}, + adios::Dims{2, 4}); auto &var_r32 = - adios.DefineVariable<float>("r32", adios::Dims{2, 4}); + io.DefineVariable<float>("r32", {}, {}, adios::Dims{2, 4}); auto &var_r64 = - adios.DefineVariable<double>("r64", adios::Dims{2, 4}); + io.DefineVariable<double>("r64", {}, {}, adios::Dims{2, 4}); } - // Create the HDF5 Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("HDF5Writer"); - method.AddTransport("File"); + io.SetEngine("HDF5Writer"); + io.AddTransport("file"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + // Create the HDF5 Engine + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); @@ -604,51 +611,53 @@ TEST_F(HDF5WriteReadTest, ADIOS2HDF5WriteHDF5Read2D4x2) // Write test data using ADIOS2 { - adios::ADIOS adios(adios::Verbose::WARN, true); + adios::ADIOS adios(true); + adios::IO &io = adios.DeclareIO("TestIO"); // Declare 1D variables { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{4, 2}); + auto &var_i8 = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{4, 2}); auto &var_i16 = - adios.DefineVariable<short>("i16", adios::Dims{4, 2}); - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{4, 2}); + io.DefineVariable<short>("i16", {}, {}, adios::Dims{4, 2}); + auto &var_i32 = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{4, 2}); auto &var_i64 = - adios.DefineVariable<long>("i64", adios::Dims{4, 2}); - auto &var_u8 = - adios.DefineVariable<unsigned char>("u8", adios::Dims{4, 2}); - auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{4, 2}); - auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{4, 2}); - auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{4, 2}); + io.DefineVariable<long>("i64", {}, {}, adios::Dims{4, 2}); + auto &var_u8 = io.DefineVariable<unsigned char>("u8", {}, {}, + adios::Dims{4, 2}); + auto &var_u16 = io.DefineVariable<unsigned short>( + "u16", {}, {}, adios::Dims{4, 2}); + auto &var_u32 = io.DefineVariable<unsigned int>("u32", {}, {}, + adios::Dims{4, 2}); + auto &var_u64 = io.DefineVariable<unsigned long>("u64", {}, {}, + adios::Dims{4, 2}); auto &var_r32 = - adios.DefineVariable<float>("r32", adios::Dims{4, 2}); + io.DefineVariable<float>("r32", {}, {}, adios::Dims{4, 2}); auto &var_r64 = - adios.DefineVariable<double>("r64", adios::Dims{4, 2}); + io.DefineVariable<double>("r64", {}, {}, adios::Dims{4, 2}); } // Create the HDF5 Engine - auto method = adios.DeclareMethod("TestMethod"); - method.SetEngine("HDF5Writer"); - method.AddTransport("File"); + io.SetEngine("HDF5Writer"); + io.AddTransport("file"); - auto engine = adios.Open(fname, "w", method); - ASSERT_NE(engine, nullptr); + auto engine = io.Open(fname, adios::OpenMode::Write); + ASSERT_NE(engine.get(), nullptr); for (size_t step = 0; step < 3; ++step) { // Retrieve the variables that previously went out of scope - auto &var_i8 = adios.GetVariable<char>("i8"); - auto &var_i16 = adios.GetVariable<short>("i16"); - auto &var_i32 = adios.GetVariable<int>("i32"); - auto &var_i64 = adios.GetVariable<long>("i64"); - auto &var_u8 = adios.GetVariable<unsigned char>("u8"); - auto &var_u16 = adios.GetVariable<unsigned short>("u16"); - auto &var_u32 = adios.GetVariable<unsigned int>("u32"); - auto &var_u64 = adios.GetVariable<unsigned long>("u64"); - auto &var_r32 = adios.GetVariable<float>("r32"); - auto &var_r64 = adios.GetVariable<double>("r64"); + auto &var_i8 = io.GetVariable<char>("i8"); + auto &var_i16 = io.GetVariable<short>("i16"); + auto &var_i32 = io.GetVariable<int>("i32"); + auto &var_i64 = io.GetVariable<long>("i64"); + auto &var_u8 = io.GetVariable<unsigned char>("u8"); + auto &var_u16 = io.GetVariable<unsigned short>("u16"); + auto &var_u32 = io.GetVariable<unsigned int>("u32"); + auto &var_u64 = io.GetVariable<unsigned long>("u64"); + auto &var_r32 = io.GetVariable<float>("r32"); + auto &var_r64 = io.GetVariable<double>("r64"); // Write each one engine->Write(var_i8, m_TestData.I8.data() + step); diff --git a/testing/adios2/interface/TestADIOSInterfaceWrite.cpp b/testing/adios2/interface/TestADIOSInterfaceWrite.cpp index ece198e126594b365855ce3ba118f8fcc9bbe5fb..c315a166db76cc0633b3d92003b60d700ac546d5 100644 --- a/testing/adios2/interface/TestADIOSInterfaceWrite.cpp +++ b/testing/adios2/interface/TestADIOSInterfaceWrite.cpp @@ -10,7 +10,7 @@ class ADIOSInterfaceWriteTest : public ::testing::Test { public: - ADIOSInterfaceWriteTest() : adios(adios::Verbose::WARN, true) {} + ADIOSInterfaceWriteTest() : adios(true), io(adios.DeclareIO("TestIO")) {} protected: // virtual void SetUp() { } @@ -18,25 +18,27 @@ protected: // virtual void TearDown() { } adios::ADIOS adios; + adios::IO &io; }; TEST_F(ADIOSInterfaceWriteTest, DefineVarChar1x10) { // Define ADIOS variables for each type - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{10}); + auto &var_i8 = io.DefineVariable<char>("i8", {}, {}, adios::Dims{10}); // Verify the return type is as expected ::testing::StaticAssertTypeEq<decltype(var_i8), adios::Variable<char> &>(); // Verify exceptions are thrown upon duplicate variable names - EXPECT_THROW(auto &foo = adios.DefineVariable<char>("i8", adios::Dims{10}), + EXPECT_THROW(auto &foo = + io.DefineVariable<char>("i8", {}, {}, adios::Dims{10}), std::invalid_argument); // Verify the dimensions, name, and type are correct - ASSERT_EQ(var_i8.m_Shape.size(), 1); - EXPECT_EQ(var_i8.m_Shape[0], 10); - EXPECT_EQ(var_i8.m_Count.size(), 0); + ASSERT_EQ(var_i8.m_Shape.size(), 0); EXPECT_EQ(var_i8.m_Start.size(), 0); + EXPECT_EQ(var_i8.m_Count.size(), 1); + EXPECT_EQ(var_i8.m_Count[0], 10); EXPECT_EQ(var_i8.m_Name, "i8"); EXPECT_EQ(var_i8.m_Type, "char"); } @@ -44,60 +46,63 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarChar1x10) // Rinse and repeat for remaining types TEST_F(ADIOSInterfaceWriteTest, DefineVarShort1x10) { - auto &var_i16 = adios.DefineVariable<short>("i16", adios::Dims{10}); + auto &var_i16 = io.DefineVariable<short>("i16", {}, {}, adios::Dims{10}); ::testing::StaticAssertTypeEq<decltype(var_i16), adios::Variable<short> &>(); EXPECT_THROW(auto &foo = - adios.DefineVariable<short>("i16", adios::Dims{10}), + io.DefineVariable<short>("i16", {}, {}, adios::Dims{10}), std::invalid_argument); - ASSERT_EQ(var_i16.m_Shape.size(), 1); - EXPECT_EQ(var_i16.m_Shape[0], 10); - EXPECT_EQ(var_i16.m_Count.size(), 0); + ASSERT_EQ(var_i16.m_Shape.size(), 0); EXPECT_EQ(var_i16.m_Start.size(), 0); + EXPECT_EQ(var_i16.m_Count.size(), 1); + EXPECT_EQ(var_i16.m_Count[0], 10); EXPECT_EQ(var_i16.m_Name, "i16"); EXPECT_EQ(var_i16.m_Type, "short"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarInt1x10) { - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{10}); + auto &var_i32 = io.DefineVariable<int>("i32", {}, {}, adios::Dims{10}); ::testing::StaticAssertTypeEq<decltype(var_i32), adios::Variable<int> &>(); - EXPECT_THROW(auto &foo = adios.DefineVariable<int>("i32", adios::Dims{10}), + EXPECT_THROW(auto &foo = + io.DefineVariable<int>("i32", {}, {}, adios::Dims{10}), std::invalid_argument); - ASSERT_EQ(var_i32.m_Shape.size(), 1); - EXPECT_EQ(var_i32.m_Shape[0], 10); - EXPECT_EQ(var_i32.m_Count.size(), 0); + ASSERT_EQ(var_i32.m_Shape.size(), 0); EXPECT_EQ(var_i32.m_Start.size(), 0); + EXPECT_EQ(var_i32.m_Count.size(), 1); + EXPECT_EQ(var_i32.m_Count[0], 10); EXPECT_EQ(var_i32.m_Name, "i32"); EXPECT_EQ(var_i32.m_Type, "int"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarLong1x10) { - auto &var_i64 = adios.DefineVariable<long>("i64", adios::Dims{10}); - ::testing::StaticAssertTypeEq<decltype(var_i64), adios::Variable<long> &>(); - EXPECT_THROW(auto &foo = adios.DefineVariable<long>("i64", adios::Dims{10}), + auto &var_u16 = io.DefineVariable<long>("u16", {}, {}, adios::Dims{10}); + ::testing::StaticAssertTypeEq<decltype(var_u16), adios::Variable<long> &>(); + EXPECT_THROW(auto &foo = + io.DefineVariable<long>("u16", {}, {}, adios::Dims{10}), std::invalid_argument); - ASSERT_EQ(var_i64.m_Shape.size(), 1); - EXPECT_EQ(var_i64.m_Shape[0], 10); - EXPECT_EQ(var_i64.m_Count.size(), 0); - EXPECT_EQ(var_i64.m_Start.size(), 0); - EXPECT_EQ(var_i64.m_Name, "i64"); - EXPECT_EQ(var_i64.m_Type, "long int"); + ASSERT_EQ(var_u16.m_Shape.size(), 0); + EXPECT_EQ(var_u16.m_Start.size(), 0); + EXPECT_EQ(var_u16.m_Count.size(), 1); + EXPECT_EQ(var_u16.m_Count[0], 10); + EXPECT_EQ(var_u16.m_Name, "u16"); + EXPECT_EQ(var_u16.m_Type, "long int"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarUChar1x10) { - auto &var_u8 = adios.DefineVariable<unsigned char>("u8", adios::Dims{10}); + auto &var_u8 = + io.DefineVariable<unsigned char>("u8", {}, {}, adios::Dims{10}); ::testing::StaticAssertTypeEq<decltype(var_u8), adios::Variable<unsigned char> &>(); - EXPECT_THROW(auto &foo = - adios.DefineVariable<unsigned char>("u8", adios::Dims{10}), + EXPECT_THROW(auto &foo = io.DefineVariable<unsigned char>("u8", {}, {}, + adios::Dims{10}), std::invalid_argument); - ASSERT_EQ(var_u8.m_Shape.size(), 1); - EXPECT_EQ(var_u8.m_Shape[0], 10); - EXPECT_EQ(var_u8.m_Count.size(), 0); + ASSERT_EQ(var_u8.m_Shape.size(), 0); EXPECT_EQ(var_u8.m_Start.size(), 0); + EXPECT_EQ(var_u8.m_Count.size(), 1); + EXPECT_EQ(var_u8.m_Count[0], 10); EXPECT_EQ(var_u8.m_Name, "u8"); EXPECT_EQ(var_u8.m_Type, "unsigned char"); } @@ -105,162 +110,165 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUChar1x10) TEST_F(ADIOSInterfaceWriteTest, DefineVarUShort1x10) { auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{10}); + io.DefineVariable<unsigned short>("u16", {}, {}, adios::Dims{10}); ::testing::StaticAssertTypeEq<decltype(var_u16), adios::Variable<unsigned short> &>(); - EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned short>( - "u16", adios::Dims{10}), + EXPECT_THROW(auto &foo = io.DefineVariable<unsigned short>("u16", {}, {}, + adios::Dims{10}), std::invalid_argument); - ASSERT_EQ(var_u16.m_Shape.size(), 1); - EXPECT_EQ(var_u16.m_Shape[0], 10); - EXPECT_EQ(var_u16.m_Count.size(), 0); + ASSERT_EQ(var_u16.m_Shape.size(), 0); EXPECT_EQ(var_u16.m_Start.size(), 0); + EXPECT_EQ(var_u16.m_Count.size(), 1); + EXPECT_EQ(var_u16.m_Count[0], 10); EXPECT_EQ(var_u16.m_Name, "u16"); EXPECT_EQ(var_u16.m_Type, "unsigned short"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarUInt1x10) { - auto &var_u32 = adios.DefineVariable<unsigned int>("u32", adios::Dims{10}); + auto &var_u32 = + io.DefineVariable<unsigned int>("u32", {}, {}, adios::Dims{10}); ::testing::StaticAssertTypeEq<decltype(var_u32), adios::Variable<unsigned int> &>(); - EXPECT_THROW(auto &foo = - adios.DefineVariable<unsigned int>("u32", adios::Dims{10}), + EXPECT_THROW(auto &foo = io.DefineVariable<unsigned int>("u32", {}, {}, + adios::Dims{10}), std::invalid_argument); - ASSERT_EQ(var_u32.m_Shape.size(), 1); - EXPECT_EQ(var_u32.m_Shape[0], 10); - EXPECT_EQ(var_u32.m_Count.size(), 0); + ASSERT_EQ(var_u32.m_Shape.size(), 0); EXPECT_EQ(var_u32.m_Start.size(), 0); + EXPECT_EQ(var_u32.m_Count.size(), 1); + EXPECT_EQ(var_u32.m_Count[0], 10); EXPECT_EQ(var_u32.m_Name, "u32"); EXPECT_EQ(var_u32.m_Type, "unsigned int"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarULong1x10) { - auto &var_u64 = adios.DefineVariable<unsigned long>("u64", adios::Dims{10}); + auto &var_u64 = + io.DefineVariable<unsigned long>("u64", {}, {}, adios::Dims{10}); ::testing::StaticAssertTypeEq<decltype(var_u64), adios::Variable<unsigned long> &>(); - EXPECT_THROW( - auto &foo = adios.DefineVariable<unsigned long>("u64", adios::Dims{10}), - std::invalid_argument); - ASSERT_EQ(var_u64.m_Shape.size(), 1); - EXPECT_EQ(var_u64.m_Shape[0], 10); - EXPECT_EQ(var_u64.m_Count.size(), 0); + EXPECT_THROW(auto &foo = io.DefineVariable<unsigned long>("u64", {}, {}, + adios::Dims{10}), + std::invalid_argument); + ASSERT_EQ(var_u64.m_Shape.size(), 0); EXPECT_EQ(var_u64.m_Start.size(), 0); + EXPECT_EQ(var_u64.m_Count.size(), 1); + EXPECT_EQ(var_u64.m_Count[0], 10); EXPECT_EQ(var_u64.m_Name, "u64"); EXPECT_EQ(var_u64.m_Type, "unsigned long int"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarFloat1x10) { - auto &var_r32 = adios.DefineVariable<float>("r32", adios::Dims{10}); + auto &var_r32 = io.DefineVariable<float>("r32", {}, {}, adios::Dims{10}); ::testing::StaticAssertTypeEq<decltype(var_r32), adios::Variable<float> &>(); EXPECT_THROW(auto &foo = - adios.DefineVariable<float>("r32", adios::Dims{10}), + io.DefineVariable<float>("r32", {}, {}, adios::Dims{10}), std::invalid_argument); - ASSERT_EQ(var_r32.m_Shape.size(), 1); - EXPECT_EQ(var_r32.m_Shape[0], 10); - EXPECT_EQ(var_r32.m_Count.size(), 0); + ASSERT_EQ(var_r32.m_Shape.size(), 0); EXPECT_EQ(var_r32.m_Start.size(), 0); + EXPECT_EQ(var_r32.m_Count.size(), 1); + EXPECT_EQ(var_r32.m_Count[0], 10); EXPECT_EQ(var_r32.m_Name, "r32"); EXPECT_EQ(var_r32.m_Type, "float"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarDouble1x10) { - auto &var_r64 = adios.DefineVariable<double>("r64", adios::Dims{10}); + auto &var_r64 = io.DefineVariable<double>("r64", {}, {}, adios::Dims{10}); ::testing::StaticAssertTypeEq<decltype(var_r64), adios::Variable<double> &>(); EXPECT_THROW(auto &foo = - adios.DefineVariable<double>("r64", adios::Dims{10}), + io.DefineVariable<double>("r64", {}, {}, adios::Dims{10}), std::invalid_argument); - ASSERT_EQ(var_r64.m_Shape.size(), 1); - EXPECT_EQ(var_r64.m_Shape[0], 10); - EXPECT_EQ(var_r64.m_Count.size(), 0); + ASSERT_EQ(var_r64.m_Shape.size(), 0); EXPECT_EQ(var_r64.m_Start.size(), 0); + EXPECT_EQ(var_r64.m_Count.size(), 1); + EXPECT_EQ(var_r64.m_Count[0], 10); EXPECT_EQ(var_r64.m_Name, "r64"); EXPECT_EQ(var_r64.m_Type, "double"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarChar2x5) { - auto &var_i8 = adios.DefineVariable<char>("i8", adios::Dims{2, 5}); + auto &var_i8 = io.DefineVariable<char>("i8", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_i8), adios::Variable<char> &>(); EXPECT_THROW(auto &foo = - adios.DefineVariable<char>("i8", adios::Dims{2, 5}), + io.DefineVariable<char>("i8", {}, {}, adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_i8.m_Shape.size(), 2); - EXPECT_EQ(var_i8.m_Shape[0], 2); - EXPECT_EQ(var_i8.m_Shape[1], 5); - EXPECT_EQ(var_i8.m_Count.size(), 0); + ASSERT_EQ(var_i8.m_Shape.size(), 0); EXPECT_EQ(var_i8.m_Start.size(), 0); + EXPECT_EQ(var_i8.m_Count.size(), 2); + EXPECT_EQ(var_i8.m_Count[0], 2); + EXPECT_EQ(var_i8.m_Count[1], 5); EXPECT_EQ(var_i8.m_Name, "i8"); EXPECT_EQ(var_i8.m_Type, "char"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarShort2x5) { - auto &var_i16 = adios.DefineVariable<short>("i16", adios::Dims{2, 5}); + auto &var_i16 = io.DefineVariable<short>("i16", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_i16), adios::Variable<short> &>(); EXPECT_THROW(auto &foo = - adios.DefineVariable<short>("i16", adios::Dims{2, 5}), + io.DefineVariable<short>("i16", {}, {}, adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_i16.m_Shape.size(), 2); - EXPECT_EQ(var_i16.m_Shape[0], 2); - EXPECT_EQ(var_i16.m_Shape[1], 5); - EXPECT_EQ(var_i16.m_Count.size(), 0); + ASSERT_EQ(var_i16.m_Shape.size(), 0); EXPECT_EQ(var_i16.m_Start.size(), 0); + EXPECT_EQ(var_i16.m_Count.size(), 2); + EXPECT_EQ(var_i16.m_Count[0], 2); + EXPECT_EQ(var_i16.m_Count[1], 5); EXPECT_EQ(var_i16.m_Name, "i16"); EXPECT_EQ(var_i16.m_Type, "short"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarInt2x5) { - auto &var_i32 = adios.DefineVariable<int>("i32", adios::Dims{2, 5}); + auto &var_i32 = io.DefineVariable<int>("i32", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_i32), adios::Variable<int> &>(); EXPECT_THROW(auto &foo = - adios.DefineVariable<int>("i32", adios::Dims{2, 5}), + io.DefineVariable<int>("i32", {}, {}, adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_i32.m_Shape.size(), 2); - EXPECT_EQ(var_i32.m_Shape[0], 2); - EXPECT_EQ(var_i32.m_Shape[1], 5); - EXPECT_EQ(var_i32.m_Count.size(), 0); + ASSERT_EQ(var_i32.m_Shape.size(), 0); EXPECT_EQ(var_i32.m_Start.size(), 0); + EXPECT_EQ(var_i32.m_Count.size(), 2); + EXPECT_EQ(var_i32.m_Count[0], 2); + EXPECT_EQ(var_i32.m_Count[1], 5); EXPECT_EQ(var_i32.m_Name, "i32"); EXPECT_EQ(var_i32.m_Type, "int"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarLong2x5) { - auto &var_i64 = adios.DefineVariable<long>("i64", adios::Dims{2, 5}); - ::testing::StaticAssertTypeEq<decltype(var_i64), adios::Variable<long> &>(); + auto &var_u16 = io.DefineVariable<long>("u16", {}, {}, adios::Dims{2, 5}); + ::testing::StaticAssertTypeEq<decltype(var_u16), adios::Variable<long> &>(); EXPECT_THROW(auto &foo = - adios.DefineVariable<long>("i64", adios::Dims{2, 5}), + io.DefineVariable<long>("u16", {}, {}, adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_i64.m_Shape.size(), 2); - EXPECT_EQ(var_i64.m_Shape[0], 2); - EXPECT_EQ(var_i64.m_Shape[1], 5); - EXPECT_EQ(var_i64.m_Count.size(), 0); - EXPECT_EQ(var_i64.m_Start.size(), 0); - EXPECT_EQ(var_i64.m_Name, "i64"); - EXPECT_EQ(var_i64.m_Type, "long int"); + ASSERT_EQ(var_u16.m_Shape.size(), 0); + EXPECT_EQ(var_u16.m_Start.size(), 0); + EXPECT_EQ(var_u16.m_Count.size(), 2); + EXPECT_EQ(var_u16.m_Count[0], 2); + EXPECT_EQ(var_u16.m_Count[1], 5); + EXPECT_EQ(var_u16.m_Name, "u16"); + EXPECT_EQ(var_u16.m_Type, "long int"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarUChar2x5) { - auto &var_u8 = adios.DefineVariable<unsigned char>("u8", adios::Dims{2, 5}); + auto &var_u8 = + io.DefineVariable<unsigned char>("u8", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_u8), adios::Variable<unsigned char> &>(); - EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned char>( - "u8", adios::Dims{2, 5}), + EXPECT_THROW(auto &foo = io.DefineVariable<unsigned char>( + "u8", {}, {}, adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_u8.m_Shape.size(), 2); - EXPECT_EQ(var_u8.m_Shape[0], 2); - EXPECT_EQ(var_u8.m_Shape[1], 5); - EXPECT_EQ(var_u8.m_Count.size(), 0); + ASSERT_EQ(var_u8.m_Shape.size(), 0); EXPECT_EQ(var_u8.m_Start.size(), 0); + EXPECT_EQ(var_u8.m_Count.size(), 2); + EXPECT_EQ(var_u8.m_Count[0], 2); + EXPECT_EQ(var_u8.m_Count[1], 5); EXPECT_EQ(var_u8.m_Name, "u8"); EXPECT_EQ(var_u8.m_Type, "unsigned char"); } @@ -268,17 +276,17 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUChar2x5) TEST_F(ADIOSInterfaceWriteTest, DefineVarUShort2x5) { auto &var_u16 = - adios.DefineVariable<unsigned short>("u16", adios::Dims{2, 5}); + io.DefineVariable<unsigned short>("u16", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_u16), adios::Variable<unsigned short> &>(); - EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned short>( - "u16", adios::Dims{2, 5}), + EXPECT_THROW(auto &foo = io.DefineVariable<unsigned short>( + "u16", {}, {}, adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_u16.m_Shape.size(), 2); - EXPECT_EQ(var_u16.m_Shape[0], 2); - EXPECT_EQ(var_u16.m_Shape[1], 5); - EXPECT_EQ(var_u16.m_Count.size(), 0); + ASSERT_EQ(var_u16.m_Shape.size(), 0); EXPECT_EQ(var_u16.m_Start.size(), 0); + EXPECT_EQ(var_u16.m_Count.size(), 2); + EXPECT_EQ(var_u16.m_Count[0], 2); + EXPECT_EQ(var_u16.m_Count[1], 5); EXPECT_EQ(var_u16.m_Name, "u16"); EXPECT_EQ(var_u16.m_Type, "unsigned short"); } @@ -286,17 +294,17 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUShort2x5) TEST_F(ADIOSInterfaceWriteTest, DefineVarUInt2x5) { auto &var_u32 = - adios.DefineVariable<unsigned int>("u32", adios::Dims{2, 5}); + io.DefineVariable<unsigned int>("u32", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_u32), adios::Variable<unsigned int> &>(); - EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned int>( - "u32", adios::Dims{2, 5}), + EXPECT_THROW(auto &foo = io.DefineVariable<unsigned int>("u32", {}, {}, + adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_u32.m_Shape.size(), 2); - EXPECT_EQ(var_u32.m_Shape[0], 2); - EXPECT_EQ(var_u32.m_Shape[1], 5); - EXPECT_EQ(var_u32.m_Count.size(), 0); + ASSERT_EQ(var_u32.m_Shape.size(), 0); EXPECT_EQ(var_u32.m_Start.size(), 0); + EXPECT_EQ(var_u32.m_Count.size(), 2); + EXPECT_EQ(var_u32.m_Count[0], 2); + EXPECT_EQ(var_u32.m_Count[1], 5); EXPECT_EQ(var_u32.m_Name, "u32"); EXPECT_EQ(var_u32.m_Type, "unsigned int"); } @@ -304,51 +312,51 @@ TEST_F(ADIOSInterfaceWriteTest, DefineVarUInt2x5) TEST_F(ADIOSInterfaceWriteTest, DefineVarULong2x5) { auto &var_u64 = - adios.DefineVariable<unsigned long>("u64", adios::Dims{2, 5}); + io.DefineVariable<unsigned long>("u64", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_u64), adios::Variable<unsigned long> &>(); - EXPECT_THROW(auto &foo = adios.DefineVariable<unsigned long>( - "u64", adios::Dims{2, 5}), + EXPECT_THROW(auto &foo = io.DefineVariable<unsigned long>( + "u64", {}, {}, adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_u64.m_Shape.size(), 2); - EXPECT_EQ(var_u64.m_Shape[0], 2); - EXPECT_EQ(var_u64.m_Shape[1], 5); - EXPECT_EQ(var_u64.m_Count.size(), 0); + ASSERT_EQ(var_u64.m_Shape.size(), 0); EXPECT_EQ(var_u64.m_Start.size(), 0); + EXPECT_EQ(var_u64.m_Count.size(), 2); + EXPECT_EQ(var_u64.m_Count[0], 2); + EXPECT_EQ(var_u64.m_Count[1], 5); EXPECT_EQ(var_u64.m_Name, "u64"); EXPECT_EQ(var_u64.m_Type, "unsigned long int"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarFloat2x5) { - auto &var_r32 = adios.DefineVariable<float>("r32", adios::Dims{2, 5}); + auto &var_r32 = io.DefineVariable<float>("r32", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_r32), adios::Variable<float> &>(); EXPECT_THROW(auto &foo = - adios.DefineVariable<float>("r32", adios::Dims{2, 5}), + io.DefineVariable<float>("r32", {}, {}, adios::Dims{2, 5}), std::invalid_argument); - ASSERT_EQ(var_r32.m_Shape.size(), 2); - EXPECT_EQ(var_r32.m_Shape[0], 2); - EXPECT_EQ(var_r32.m_Shape[1], 5); - EXPECT_EQ(var_r32.m_Count.size(), 0); + ASSERT_EQ(var_r32.m_Shape.size(), 0); EXPECT_EQ(var_r32.m_Start.size(), 0); + EXPECT_EQ(var_r32.m_Count.size(), 2); + EXPECT_EQ(var_r32.m_Count[0], 2); + EXPECT_EQ(var_r32.m_Count[1], 5); EXPECT_EQ(var_r32.m_Name, "r32"); EXPECT_EQ(var_r32.m_Type, "float"); } TEST_F(ADIOSInterfaceWriteTest, DefineVarDouble2x5) { - auto &var_r64 = adios.DefineVariable<double>("r64", adios::Dims{2, 5}); + auto &var_r64 = io.DefineVariable<double>("r64", {}, {}, adios::Dims{2, 5}); ::testing::StaticAssertTypeEq<decltype(var_r64), adios::Variable<double> &>(); - EXPECT_THROW(auto &foo = - adios.DefineVariable<double>("r64", adios::Dims{2, 5}), - std::invalid_argument); - ASSERT_EQ(var_r64.m_Shape.size(), 2); - EXPECT_EQ(var_r64.m_Shape[0], 2); - EXPECT_EQ(var_r64.m_Shape[1], 5); - EXPECT_EQ(var_r64.m_Count.size(), 0); + EXPECT_THROW( + auto &foo = io.DefineVariable<double>("r64", {}, {}, adios::Dims{2, 5}), + std::invalid_argument); + ASSERT_EQ(var_r64.m_Shape.size(), 0); EXPECT_EQ(var_r64.m_Start.size(), 0); + EXPECT_EQ(var_r64.m_Count.size(), 2); + EXPECT_EQ(var_r64.m_Count[0], 2); + EXPECT_EQ(var_r64.m_Count[1], 5); EXPECT_EQ(var_r64.m_Name, "r64"); EXPECT_EQ(var_r64.m_Type, "double"); }