From 1eac128e972363bd3e1d69481e8a6be0e31595cc Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Mon, 9 Oct 2023 16:18:16 -0400 Subject: [PATCH 01/16] Add query.rst --- docs/user_guide/source/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/user_guide/source/index.rst b/docs/user_guide/source/index.rst index 6fd178f524..867f184184 100644 --- a/docs/user_guide/source/index.rst +++ b/docs/user_guide/source/index.rst @@ -37,6 +37,7 @@ Funded by the `Exascale Computing Project (ECP) Date: Mon, 9 Oct 2023 16:18:58 -0400 Subject: [PATCH 02/16] Add dataspaces.rst in the list of engines --- docs/user_guide/source/engines/engines.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/user_guide/source/engines/engines.rst b/docs/user_guide/source/engines/engines.rst index a6591322c0..948143453b 100644 --- a/docs/user_guide/source/engines/engines.rst +++ b/docs/user_guide/source/engines/engines.rst @@ -23,6 +23,7 @@ Parameters are passed at: .. include:: sst.rst .. include:: ssc.rst .. include:: dataman.rst +.. include:: dataspaces.rst .. include:: inline.rst .. include:: null.rst .. include:: plugin.rst From 1879ae0148a46244aa4bdb517e8e9882025717b8 Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Mon, 9 Oct 2023 16:24:29 -0400 Subject: [PATCH 03/16] Fix formatting warnings --- .../source/advanced/ecp_hardware.rst | 34 ++++++++------- docs/user_guide/source/advanced/gpu_aware.rst | 6 +-- docs/user_guide/source/advanced/query.rst | 8 ++-- docs/user_guide/source/components/engine.rst | 2 +- .../user_guide/source/components/variable.rst | 9 ++-- .../user_guide/source/ecosystem/h5vol/vol.rst | 33 +++++++-------- docs/user_guide/source/engines/bp3.rst | 4 +- docs/user_guide/source/engines/dataspaces.rst | 4 +- docs/user_guide/source/engines/hdf5.rst | 17 ++++---- docs/user_guide/source/engines/sst.rst | 42 +++++++++---------- .../user_guide/source/operators/operators.rst | 2 +- 11 files changed, 80 insertions(+), 81 deletions(-) diff --git a/docs/user_guide/source/advanced/ecp_hardware.rst b/docs/user_guide/source/advanced/ecp_hardware.rst index 5f79efb49b..37e410fa2f 100644 --- a/docs/user_guide/source/advanced/ecp_hardware.rst +++ b/docs/user_guide/source/advanced/ecp_hardware.rst @@ -33,27 +33,29 @@ your tests. Examples of launching ADIOS2 SST unit tests using MPI DP: .. code-block:: bash - # We omit some of the srun (SLURM) arguments which are specific of the project - # you are working on. Note that you could avoid calling srun directly by - # setting the CMAKE variable `MPIEXEC_EXECUTABLE`. - # Launch simple writer test instance - srun {PROJFLAGS }-N 1 /gpfs/alpine/proj-shared/csc331/vbolea/ADIOS2-build/bin/TestCommonWrite SST mpi_dp_test CPCommPattern=Min,MarshalMethod=BP5' + # We omit some of the srun (SLURM) arguments which are specific of the project + # you are working on. Note that you could avoid calling srun directly by + # setting the CMAKE variable `MPIEXEC_EXECUTABLE`. - # On another terminal launch multiple instances of the Reader test - srun {PROJFLAGS} -N 2 /gpfs/alpine/proj-shared/csc331/vbolea/ADIOS2-build/bin/TestCommonRead SST mpi_dp_test + # Launch simple writer test instance + srun {PROJFLAGS } -N 1 /gpfs/alpine/proj-shared/csc331/vbolea/ADIOS2-build/bin/TestCommonWrite SST mpi_dp_test CPCommPattern=Min,MarshalMethod=BP5 + + # On another terminal launch multiple instances of the Reader test + srun {PROJFLAGS} -N 2 /gpfs/alpine/proj-shared/csc331/vbolea/ADIOS2-build/bin/TestCommonRead SST mpi_dp_test Alternatively, you can configure your CMake build to use srun directly: .. code-block:: bash - cmake . -DMPIEXEC_EXECUTABLE:FILEPATH="/usr/bin/srun" \ - -DMPIEXEC_EXTRA_FLAGS:STRING="-A{YourProject} -pbatch -t10" \ - -DMPIEXEC_NUMPROC_FLAG:STRING="-N" \ - -DMPIEXEC_MAX_NUMPROCS:STRING="-8" \ - -DADIOS2_RUN_MPI_MPMD_TESTS=OFF - cmake --build . - ctest + cmake . -DMPIEXEC_EXECUTABLE:FILEPATH="/usr/bin/srun" \ + -DMPIEXEC_EXTRA_FLAGS:STRING="-A{YourProject} -pbatch -t10" \ + -DMPIEXEC_NUMPROC_FLAG:STRING="-N" \ + -DMPIEXEC_MAX_NUMPROCS:STRING="-8" \ + -DADIOS2_RUN_MPI_MPMD_TESTS=OFF + + cmake --build . + ctest - # monitor your jobs - watch -n1 squeue -l -u $USER + # monitor your jobs + watch -n1 squeue -l -u $USER diff --git a/docs/user_guide/source/advanced/gpu_aware.rst b/docs/user_guide/source/advanced/gpu_aware.rst index ee4c600180..0cf34a893d 100644 --- a/docs/user_guide/source/advanced/gpu_aware.rst +++ b/docs/user_guide/source/advanced/gpu_aware.rst @@ -35,7 +35,7 @@ If there is no CUDA toolkit installed, cmake will turn CUDA off automatically. A When building ADIOS2 with CUDA enabled, the user is responsible with setting the correct ``CMAKE_CUDA_ARCHITECTURES`` (e.g. for Summit the ``CMAKE_CUDA_ARCHITECTURES`` needs to be set to 70 to match the NVIDIA Volta V100). Building with Kokkos enabled --------------------------- +---------------------------- The Kokkos library can be used to enable GPU within ADIOS2. Based on how Kokkos is build, either the CUDA, HIP or SYCL backend will be enabled. Building with Kokkos requires ``-DADIOS2_USE_Kokkos=ON``. The ``CMAKE_CUDA_ARCHITECTURES`` is set automanically to point to the same architecture used when configuring the Kokkos library. @@ -43,9 +43,9 @@ The Kokkos library can be used to enable GPU within ADIOS2. Based on how Kokkos Kokkos version >= 3.7 is required to enable the GPU backend in ADIOS2 -************* +**************** Writing GPU code -************* +**************** The following is a simple example of writing data to storage directly from a GPU buffer allocated with CUDA relying on the automatic detection of device pointers in ADIOS2. The ADIOS2 API is identical to codes using Host buffers for both the read and write logic. diff --git a/docs/user_guide/source/advanced/query.rst b/docs/user_guide/source/advanced/query.rst index 852e0e52dc..e1a967cdfb 100644 --- a/docs/user_guide/source/advanced/query.rst +++ b/docs/user_guide/source/advanced/query.rst @@ -3,7 +3,7 @@ ADIOS2 query API ################# The query API in ADIOS2 allows a client to pass a query in XML or json format, -and get back a list of blocks or subblocks that contains hits. +and get back a list of blocks or sub-blocks that contains hits. Both BP4 and BP5 engines are supported. @@ -21,14 +21,14 @@ to construct a query and evaluate using the engine. // configFile has query, can be either xml or json QueryWorker(const std::string &configFile, adios2::Engine &engine); - // touched_blocks is a list of regions specified by (start, count), - // that contains data that satisfies the query file + // touched_blocks is a list of regions specified by (start, count), + // that contains data that satisfies the query file void GetResultCoverage(std::vector> &touched_blocks); ... } A Sample Compound Query ----------------------- +----------------------- This query targets a 1D variable "doubleV", data of interest is (x > 6.6) or (x < -0.17) or (2.8 < x < 2.9) In addition, this query also specied an output region [start=5,count=80]. diff --git a/docs/user_guide/source/components/engine.rst b/docs/user_guide/source/components/engine.rst index 2dc0babf48..1c03e3286d 100644 --- a/docs/user_guide/source/components/engine.rst +++ b/docs/user_guide/source/components/engine.rst @@ -323,7 +323,7 @@ PerformsPuts PerformsDataWrite ------------- +----------------- If supported by the engine, moves data from prior ``Put`` calls to disk diff --git a/docs/user_guide/source/components/variable.rst b/docs/user_guide/source/components/variable.rst index c3a27545d8..baf071defb 100644 --- a/docs/user_guide/source/components/variable.rst +++ b/docs/user_guide/source/components/variable.rst @@ -142,9 +142,10 @@ Dims value. For example, the definition below defines a 2-D Joined array where the first dimension is the one along which blocks will be joined and the 2nd dimension is 5. Here this rank is contributing two rows to this array. - .. code-block:: c++ - auto var = outIO.DefineVariable("table", {adios2::JoinedDim, 5}, - {}, {2, 5}); + +.. code-block:: c++ + + auto var = outIO.DefineVariable("table", {adios2::JoinedDim, 5}, {}, {2, 5}); If each of N writer ranks were to declare a variable like this and do a single Put() in a timestep, the reader-side GlobalArray would have @@ -152,8 +153,6 @@ shape {2*N, 5} and all normal reader-side GlobalArray operations would be applicable to it. - - .. note:: JoinedArrays are currently only supported by BP4 and BP5 engines, diff --git a/docs/user_guide/source/ecosystem/h5vol/vol.rst b/docs/user_guide/source/ecosystem/h5vol/vol.rst index 6315e1dc62..c8f7b87026 100644 --- a/docs/user_guide/source/ecosystem/h5vol/vol.rst +++ b/docs/user_guide/source/ecosystem/h5vol/vol.rst @@ -1,11 +1,12 @@ -*********** +********** Disclaimer -*********** +********** + .. note:: -The Virtual Object Layer (VOL) is a feature introduced in recent release of HDF5 1.12 (https://hdf5.wiki/index.php/New_Features_in_HDF5_Release_1.12). + The Virtual Object Layer (VOL) is a feature introduced in recent release of HDF5 1.12 (https://hdf5.wiki/index.php/New_Features_in_HDF5_Release_1.12). -So please do make sure your HDF5 version supports the latest VOL. + So please do make sure your HDF5 version supports the latest VOL. Once the ADIOS VOL is compiled, There are two ways to apply it: @@ -20,8 +21,8 @@ External .. code-block:: c++ - HDF5_VOL_CONNECTOR=ADIOS2_VOL - HDF5_PLUGIN_PATH=/replace/with/your/adios2_vol/lib/path/ + HDF5_VOL_CONNECTOR=ADIOS2_VOL + HDF5_PLUGIN_PATH=/replace/with/your/adios2_vol/lib/path/ Without code change, ADIOS2 VOL will be loaded at runtime by HDF5, to access ADIOS files without changing user code. @@ -36,26 +37,22 @@ Internal .. code-block:: c++ - // other includes - #include // ADD THIS LINE TO INCLUDE ADIOS VOL - - hid_t pid = H5Pcreate(H5P_FILE_ACCESS); - // other declarations - hid_t fid = H5Fopen(filename, mode, pid); - - H5VL_ADIOS2_set(pid); // ADD THIS LINE TO USE ADIOS VOL + // other includes + #include // ADD THIS LINE TO INCLUDE ADIOS VOL - H5Fclose(fid); + hid_t pid = H5Pcreate(H5P_FILE_ACCESS); + // other declarations + hid_t fid = H5Fopen(filename, mode, pid); - H5VL_ADIOS2_unset(); // ADD THIS LINE TO EXIT ADIOS VOL + H5VL_ADIOS2_set(pid); // ADD THIS LINE TO USE ADIOS VOL + H5Fclose(fid); + H5VL_ADIOS2_unset(); // ADD THIS LINE TO EXIT ADIOS VOL .. To choose what ADIOS2 Engine to use, set env variable: ADIOS2_ENGINE (default is BP5) - - **Note:** The following features are not supported in this VOL: * hyperslab support diff --git a/docs/user_guide/source/engines/bp3.rst b/docs/user_guide/source/engines/bp3.rst index 4f46c7b44e..b9a18a71bd 100644 --- a/docs/user_guide/source/engines/bp3.rst +++ b/docs/user_guide/source/engines/bp3.rst @@ -1,6 +1,6 @@ -**** +*** BP3 -**** +*** The BP3 Engine writes and reads files in ADIOS2 native binary-pack (bp) format. BP files are backwards compatible with ADIOS1.x and have the following structure given a "name" string passed as the first argument of ``IO::Open``: diff --git a/docs/user_guide/source/engines/dataspaces.rst b/docs/user_guide/source/engines/dataspaces.rst index a9627a833b..6f88a55704 100644 --- a/docs/user_guide/source/engines/dataspaces.rst +++ b/docs/user_guide/source/engines/dataspaces.rst @@ -1,6 +1,6 @@ -********************************* +********** DataSpaces -********************************* +********** The DataSpaces engine for ADIOS2 is experimental. DataSpaces is an asynchronous I/O transfer method within ADIOS that enables low-overhead, high-throughput data extraction from a running simulation. diff --git a/docs/user_guide/source/engines/hdf5.rst b/docs/user_guide/source/engines/hdf5.rst index c785c32e8f..a3ece47766 100644 --- a/docs/user_guide/source/engines/hdf5.rst +++ b/docs/user_guide/source/engines/hdf5.rst @@ -9,9 +9,9 @@ or, set it in client code. For example, here is how to create a hdf5 reader: .. code-block:: c++ - adios2::IO h5IO = adios.DeclareIO("SomeName"); - h5IO.SetEngine("HDF5"); - adios2::Engine h5Reader = h5IO.Open(filename, adios2::Mode::Read); + adios2::IO h5IO = adios.DeclareIO("SomeName"); + h5IO.SetEngine("HDF5"); + adios2::Engine h5Reader = h5IO.Open(filename, adios2::Mode::Read); To read back the h5 files generated with VDS to ADIOS2, one can use the HDF5 engine. Please make sure you are using the HDF5 library that has version greater than or equal to 1.11 in ADIOS2. @@ -33,10 +33,11 @@ After the subfile feature is introduced in HDF5 version 1.14, the ADIOS2 HDF5 e To use the subfile feature, client needs to support MPI_Init_thread with MPI_THREAD_MULTIPLE. -Useful parameters from the HDF lirbary to tune subfiles are: +Useful parameters from the HDF library to tune subfiles are: + .. code-block:: xml -H5FD_SUBFILING_IOC_PER_NODE (num of subfiles per node) - set H5FD_SUBFILING_IOC_PER_NODE to 0 if the regular h5 file is prefered, before using ADIOS2 HDF5 engine. -H5FD_SUBFILING_STRIPE_SIZE -H5FD_IOC_THREAD_POOL_SIZE + H5FD_SUBFILING_IOC_PER_NODE (num of subfiles per node) + set H5FD_SUBFILING_IOC_PER_NODE to 0 if the regular h5 file is preferred, before using ADIOS2 HDF5 engine. + H5FD_SUBFILING_STRIPE_SIZE + H5FD_IOC_THREAD_POOL_SIZE diff --git a/docs/user_guide/source/engines/sst.rst b/docs/user_guide/source/engines/sst.rst index 61a2e0aa87..83adf8d85e 100644 --- a/docs/user_guide/source/engines/sst.rst +++ b/docs/user_guide/source/engines/sst.rst @@ -280,24 +280,24 @@ single reader, but only upon request (with a request being initiated by the reader doing BeginStep()). Normal reader-side rules (like BeginStep timeouts) and writer-side rules (like queue limit behavior) apply. -============================= ===================== ==================================================== - **Key** **Value Format** **Default** and Examples -============================= ===================== ==================================================== - RendezvousReaderCount integer **1** - RegistrationMethod string **File**, Screen - QueueLimit integer **0** (no queue limits) - QueueFullPolicy string **Block**, Discard - ReserveQueueLimit integer **0** (no queue limits) - DataTransport string **default varies by platform**, UCX, MPI, RDMA, WAN - WANDataTransport string **sockets**, enet, ib - ControlTransport string **TCP**, Scalable - MarshalMethod string **BP5**, BP, FFS - NetworkInterface string **NULL** - ControlInterface string **NULL** - DataInterface string **NULL** - FirstTimestepPrecious boolean **FALSE**, true, no, yes - AlwaysProvideLatestTimestep boolean **FALSE**, true, no, yes - OpenTimeoutSecs integer **60** - SpeculativePreloadMode string **AUTO**, ON, OFF - SpecAutoNodeThreshold integer **1** -============================= ===================== ===================================================== ++-----------------------------+---------------------+----------------------------------------------------+ +| **Key** | **Value Format** | **Default** and Examples | ++-----------------------------+---------------------+----------------------------------------------------+ +| RendezvousReaderCount | integer | **1** | +| RegistrationMethod | string | **File**, Screen | +| QueueLimit | integer | **0** (no queue limits) | +| QueueFullPolicy | string | **Block**, Discard | +| ReserveQueueLimit | integer | **0** (no queue limits) | +| DataTransport | string | **default varies by platform**, UCX, MPI, RDMA, WAN| +| WANDataTransport | string | **sockets**, enet, ib | +| ControlTransport | string | **TCP**, Scalable | +| MarshalMethod | string | **BP5**, BP, FFS | +| NetworkInterface | string | **NULL** | +| ControlInterface | string | **NULL** | +| DataInterface | string | **NULL** | +| FirstTimestepPrecious | boolean | **FALSE**, true, no, yes | +| AlwaysProvideLatestTimestep | boolean | **FALSE**, true, no, yes | +| OpenTimeoutSecs | integer | **60** | +| SpeculativePreloadMode | string | **AUTO**, ON, OFF | +| SpecAutoNodeThreshold | integer | **1** | ++-----------------------------+---------------------+----------------------------------------------------+ diff --git a/docs/user_guide/source/operators/operators.rst b/docs/user_guide/source/operators/operators.rst index 1543bd009c..0deb69d833 100644 --- a/docs/user_guide/source/operators/operators.rst +++ b/docs/user_guide/source/operators/operators.rst @@ -8,7 +8,7 @@ object. Current supported operations are: 1. Data compression/decompression, lossy and lossless. -This section provides a description of the :ref:`Available Operators` in ADIOS2 +This section provides a description of the supported operators in ADIOS2 and their specific parameters to allow extra-control from the user. Parameters are passed in key-value pairs for: From d98dfda87b4234a9704e8de978e3bb24457e1e82 Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Tue, 31 Oct 2023 11:27:31 -0400 Subject: [PATCH 04/16] Fix names of functions in engine --- docs/user_guide/source/components/engine.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/user_guide/source/components/engine.rst b/docs/user_guide/source/components/engine.rst index 1c03e3286d..f20b854589 100644 --- a/docs/user_guide/source/components/engine.rst +++ b/docs/user_guide/source/components/engine.rst @@ -309,8 +309,8 @@ The ``data`` fed to the ``Put`` function is assumed to be allocated on the Host Only the BP4 and BP5 engines are capable of receiving device allocated buffers. -PerformsPuts ------------- +PerformPuts +----------- Executes all pending ``Put`` calls in deferred mode and collects span data. Specifically this call copies Put(Deferred) data into @@ -322,8 +322,8 @@ PerformsPuts impact performance on some engines. -PerformsDataWrite ------------------ +PerformDataWrite +---------------- If supported by the engine, moves data from prior ``Put`` calls to disk @@ -452,8 +452,8 @@ Only use it if absolutely necessary (*e.g.* memory bound application or out of s ``Get`` doesn't support returning spans. -PerformsGets ------------- +PerformGets +----------- Executes all pending ``Get`` calls in deferred mode. From b25fe536a263bd2f8d7b1d4056ce1e642f9506f0 Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Tue, 31 Oct 2023 11:45:18 -0400 Subject: [PATCH 05/16] Close file after reading for hello-world.py --- examples/hello/helloWorld/hello-world.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/hello/helloWorld/hello-world.py b/examples/hello/helloWorld/hello-world.py index e2b3bd7f8d..685d648597 100644 --- a/examples/hello/helloWorld/hello-world.py +++ b/examples/hello/helloWorld/hello-world.py @@ -39,6 +39,7 @@ def reader(ad): var_greeting = io.InquireVariable("Greeting") message = r.Get(var_greeting) r.EndStep() + r.Close() return message From 284dfc319cc235f6fbc9d470a6d6d94eef48f3f1 Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Tue, 31 Oct 2023 11:36:38 -0400 Subject: [PATCH 06/16] Improve bpWriter/bpReader examples Improve variable names, and remove the non-mpi versions, and keep only one with ifdefs. --- examples/hello/bpReader/CMakeLists.txt | 2 +- examples/hello/bpReader/bpReader.cpp | 42 +++++++--- examples/hello/bpReader/bpReader_nompi.cpp | 96 ---------------------- examples/hello/bpWriter/bpWriter.cpp | 16 ++-- examples/hello/bpWriter/bpWriter_nompi.py | 30 ------- 5 files changed, 38 insertions(+), 148 deletions(-) delete mode 100644 examples/hello/bpReader/bpReader_nompi.cpp delete mode 100644 examples/hello/bpWriter/bpWriter_nompi.py diff --git a/examples/hello/bpReader/CMakeLists.txt b/examples/hello/bpReader/CMakeLists.txt index 95be573537..47a5140944 100644 --- a/examples/hello/bpReader/CMakeLists.txt +++ b/examples/hello/bpReader/CMakeLists.txt @@ -30,7 +30,7 @@ if(NOT TARGET adios2::cxx11) find_package(ADIOS2 REQUIRED COMPONENTS ${_components}) endif() -add_executable(adios2_hello_bpReader bpReader_nompi.cpp) +add_executable(adios2_hello_bpReader bpReader.cpp) target_link_libraries(adios2_hello_bpReader adios2::cxx11) install(TARGETS adios2_hello_bpReader RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/examples/hello/bpReader/bpReader.cpp b/examples/hello/bpReader/bpReader.cpp index 1b57561fd0..a987faeba8 100644 --- a/examples/hello/bpReader/bpReader.cpp +++ b/examples/hello/bpReader/bpReader.cpp @@ -5,15 +5,14 @@ * bpReader.cpp: Simple self-descriptive example of how to read a variable * from a BP File. * - * Try running like this from the build directory: - * mpirun -np 3 ./bin/hello_bpReader - * * Created on: Feb 16, 2017 * Author: William F Godoy godoywf@ornl.gov */ #include //std::ios_base::failure #include //std::cout +#if ADIOS2_USE_MPI #include +#endif #include //std::invalid_argument std::exception #include @@ -21,25 +20,34 @@ int main(int argc, char *argv[]) { - int provided; + int rank, size; +#if ADIOS2_USE_MPI + int provided; // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); - int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); - std::string filename = "myVector_cpp.bp"; +#else + rank = 0; + size = 1; +#endif + std::cout << "rank " << rank << " size " << size << "\n"; try { +#if ADIOS2_USE_MPI /** ADIOS class factory of IO class objects */ adios2::ADIOS adios(MPI_COMM_WORLD); +#else + adios2::ADIOS adios; +#endif /*** IO class object: settings and factory of Settings: Variables, * Parameters, Transports, and Execution: Engines */ - adios2::IO bpIO = adios.DeclareIO("ReadBP"); + adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); /** Engine derived class, spawned to start IO operations */ - adios2::Engine bpReader = bpIO.Open(filename, adios2::Mode::Read); + adios2::Engine bpReader = bpIO.Open("myVector_cpp.bp", adios2::Mode::Read); bpReader.BeginStep(); const std::map variables = bpIO.AvailableVariables(); @@ -66,7 +74,7 @@ int main(int argc, char *argv[]) // read only the chunk corresponding to our rank bpFloats.SetSelection({{Nx * rank}, {Nx}}); // myFloats.data is pre-allocated - bpReader.Get(bpFloats, myFloats, adios2::Mode::Sync); + bpReader.Get(bpFloats, myFloats, adios2::Mode::Sync); if (rank == 0) { @@ -85,7 +93,7 @@ int main(int argc, char *argv[]) // read only the chunk corresponding to our rank bpInts.SetSelection({{Nx * rank}, {Nx}}); - bpReader.Get(bpInts, myInts, adios2::Mode::Sync); + bpReader.Get(bpInts, myInts, adios2::Mode::Sync); if (rank == 0) { @@ -109,7 +117,9 @@ int main(int argc, char *argv[]) std::cerr << "Invalid argument exception, STOPPING PROGRAM from rank " << rank << "\n"; std::cerr << e.what() << "\n"; } +#if ADIOS2_USE_MPI MPI_Abort(MPI_COMM_WORLD, 1); +#endif } catch (std::ios_base::failure &e) { @@ -119,12 +129,14 @@ int main(int argc, char *argv[]) "from rank " << rank << "\n"; std::cerr << e.what() << "\n"; - std::cerr << "The file " << filename << " does not exist." - << " Presumably this is because hello_bpWriter has not " + std::cerr << "The file myVector_cpp.bp does not exist." + << " Presumably this is because adios2_hello_bpWriter has not " "been run." - << " Run ./hello_bpWriter before running this program.\n"; + << " Run ./adios2_hello_bpWriter before running this program.\n"; } +#if ADIOS2_USE_MPI MPI_Abort(MPI_COMM_WORLD, 1); +#endif } catch (std::exception &e) { @@ -133,10 +145,14 @@ int main(int argc, char *argv[]) std::cerr << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; std::cerr << e.what() << "\n"; } +#if ADIOS2_USE_MPI MPI_Abort(MPI_COMM_WORLD, 1); +#endif } +#if ADIOS2_USE_MPI MPI_Finalize(); +#endif return 0; } diff --git a/examples/hello/bpReader/bpReader_nompi.cpp b/examples/hello/bpReader/bpReader_nompi.cpp deleted file mode 100644 index 6f36aa3c63..0000000000 --- a/examples/hello/bpReader/bpReader_nompi.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * bpReader_nompi.cpp: Simple self-descriptive example of how to read a variable - * from a BP File. - * - * Created on: Feb 16, 2017 - * Author: William F Godoy godoywf@ornl.gov - */ - -#include //std::ios_base::failure -#include //std::cout -#include //std::invalid_argument std::exception -#include - -#include - -int main(int argc, char *argv[]) -{ - std::string filename = "myVector_cpp.bp"; - - try - { - /** ADIOS class factory of IO class objects */ - adios2::ADIOS adios; - - /*** IO class object: settings and factory of Settings: Variables, - * Parameters, Transports, and Execution: Engines */ - adios2::IO bpIO = adios.DeclareIO("ReadBP"); - - /** Engine derived class, spawned to start IO operations */ - adios2::Engine bpReader = bpIO.Open(filename, adios2::Mode::Read); - bpReader.BeginStep(); - - const std::map variables = bpIO.AvailableVariables(true); - - std::cout << "List of variables:"; - for (const auto &variablePair : variables) - { - std::cout << " " << variablePair.first; - } - std::cout << std::endl; - - /** Write variable for buffering */ - adios2::Variable bpFloats = bpIO.InquireVariable("bpFloats"); - - adios2::Variable bpInts = bpIO.InquireVariable("bpInts"); - - if (bpFloats) - { - std::vector myFloats; - bpReader.Get(bpFloats, myFloats, adios2::Mode::Sync); - std::cout << "Float vector inside " << filename << ": {"; - for (auto &x : myFloats) - { - std::cout << x << ", "; - } - std::cout << "}\n"; - } - - if (bpInts) - { - std::vector myInts; - bpReader.Get(bpInts, myInts, adios2::Mode::Sync); - } - else - { - std::cout << "There are no integer datasets in " << filename << ".\n"; - } - bpReader.EndStep(); - - /** Close bp file, engine becomes unreachable after this*/ - bpReader.Close(); - } - catch (std::invalid_argument &e) - { - std::cerr << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cerr << e.what() << "\n"; - } - catch (std::ios_base::failure &e) - { - std::cerr << "IO System base failure exception, STOPPING PROGRAM\n"; - std::cerr << e.what() << "\n"; - std::cerr << "The file " << filename << " does not exist." - << " Presumably this is because hello_bpWriter has not been " - "run. Run ./hello_bpWriter before running this program.\n"; - } - catch (std::exception &e) - { - std::cerr << "Exception, STOPPING PROGRAM\n"; - std::cerr << e.what() << "\n"; - } - - return 0; -} diff --git a/examples/hello/bpWriter/bpWriter.cpp b/examples/hello/bpWriter/bpWriter.cpp index 6afd440791..112feb21f5 100644 --- a/examples/hello/bpWriter/bpWriter.cpp +++ b/examples/hello/bpWriter/bpWriter.cpp @@ -69,22 +69,22 @@ int main(int argc, char *argv[]) std::string filename = "myVector_cpp.bp"; /** Engine derived class, spawned to start IO operations */ - adios2::Engine bpFileWriter = bpIO.Open(filename, adios2::Mode::Write); + adios2::Engine bpWriter = bpIO.Open(filename, adios2::Mode::Write); - bpFileWriter.BeginStep(); + bpWriter.BeginStep(); /** Put variables for buffering, template type is optional */ - bpFileWriter.Put(bpFloats, myFloats.data()); - bpFileWriter.Put(bpInts, myInts.data()); - // bpFileWriter.Put(bpString, myString); - bpFileWriter.EndStep(); + bpWriter.Put(bpFloats, myFloats.data()); + bpWriter.Put(bpInts, myInts.data()); + // bpWriter.Put(bpString, myString); + bpWriter.EndStep(); /** Create bp file, engine becomes unreachable after this*/ - bpFileWriter.Close(); + bpWriter.Close(); if (rank == 0) { std::cout << "Wrote file " << filename << " to disk. It can now be read by running " - "./bin/hello_bpReader.\n"; + "./bin/adios2_hello_bpReader.\n"; } } catch (std::invalid_argument &e) diff --git a/examples/hello/bpWriter/bpWriter_nompi.py b/examples/hello/bpWriter/bpWriter_nompi.py deleted file mode 100644 index 1de8ce4dd6..0000000000 --- a/examples/hello/bpWriter/bpWriter_nompi.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# Distributed under the OSI-approved Apache License, Version 2.0. See -# accompanying file Copyright.txt for details. -# -# bpWriter_nonmpi.py : only works with non MPI version -# Created on: Feb 2, 2017 -# Author: William F Godoy godoywf@ornl.gov - -import numpy -import adios2 - -# User data -myArray = numpy.array([0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) -Nx = myArray.size - -# adios -adios = adios2.ADIOS() - -# ADIOS IO -bpIO = adios.DeclareIO("BPFile_N2N") - -# ADIOS Variable name, shape, start, offset, constant dims -ioArray = bpIO.DefineVariable("bpArray", myArray, [], [], [Nx], adios2.ConstantDims) - -# ADIOS Engine -bpFileWriter = bpIO.Open("npArray.bp", adios2.Mode.Write) -bpFileWriter.BeginStep() -bpFileWriter.Put(ioArray, myArray, adios2.Mode.Sync) -bpFileWriter.EndStep() -bpFileWriter.Close() From 49ffba23a0336da1a5decd8f79377070998b936a Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Tue, 24 Oct 2023 13:47:38 -0400 Subject: [PATCH 07/16] Convert bpAttributeWriter to bpAttributeWriteRead --- examples/hello/CMakeLists.txt | 2 +- examples/hello/ReadMe.md | 2 +- .../CMakeLists.txt | 15 +- .../bpAttributeWriteRead.cpp | 188 ++++++++++++++++++ .../bpAttributeWriter/bpAttributeWriter.cpp | 112 ----------- .../bpAttributeWriter_nompi.cpp | 78 -------- 6 files changed, 197 insertions(+), 200 deletions(-) rename examples/hello/{bpAttributeWriter => bpAttributeWriteRead}/CMakeLists.txt (55%) create mode 100644 examples/hello/bpAttributeWriteRead/bpAttributeWriteRead.cpp delete mode 100644 examples/hello/bpAttributeWriter/bpAttributeWriter.cpp delete mode 100644 examples/hello/bpAttributeWriter/bpAttributeWriter_nompi.cpp diff --git a/examples/hello/CMakeLists.txt b/examples/hello/CMakeLists.txt index 297ed51882..077f42b07c 100644 --- a/examples/hello/CMakeLists.txt +++ b/examples/hello/CMakeLists.txt @@ -3,7 +3,7 @@ # accompanying file Copyright.txt for details. #------------------------------------------------------------------------------# -add_subdirectory(bpAttributeWriter) +add_subdirectory(bpAttributeWriteRead) add_subdirectory(bpFlushWriter) if(ADIOS2_HAVE_MPI) diff --git a/examples/hello/ReadMe.md b/examples/hello/ReadMe.md index 90341a3957..ff236f5658 100644 --- a/examples/hello/ReadMe.md +++ b/examples/hello/ReadMe.md @@ -17,7 +17,7 @@ They can be found in the following subdirectories, and they should be explored i 5. [bpTimeWriter](bpTimeWriter): The _bpTimeWriter_ example demonstrates how to write two Variables (one is timestep) using time aggregation using ADIOS2's BP engine. * Languages: C++, Python -6. [bpAttributeWriter](bpAttributeWriter): The _bpAttributeWriter_ example demonstrates how to write attributes using +6. [bpAttributeWriterReader](bpAttributeWriter): The _bpAttributeWriterReader_ example demonstrates how to write/read attributes using ADIOS2's BP engine. * Languages: C++ 7. [bpFlushWriter](bpFlushWriter): The _bpFlushWriter_ example demonstrates how to flush a variable using ADIOS2's BP diff --git a/examples/hello/bpAttributeWriter/CMakeLists.txt b/examples/hello/bpAttributeWriteRead/CMakeLists.txt similarity index 55% rename from examples/hello/bpAttributeWriter/CMakeLists.txt rename to examples/hello/bpAttributeWriteRead/CMakeLists.txt index c5eaf598e3..cfc777fef2 100644 --- a/examples/hello/bpAttributeWriter/CMakeLists.txt +++ b/examples/hello/bpAttributeWriteRead/CMakeLists.txt @@ -4,7 +4,7 @@ #------------------------------------------------------------------------------# cmake_minimum_required(VERSION 3.12) -project(ADIOS2HelloBPAttributeWriterExample) +project(ADIOS2HelloBPAttributeWriteReadExample) if(NOT TARGET adios2_core) set(_components CXX) @@ -20,13 +20,12 @@ if(NOT TARGET adios2_core) find_package(ADIOS2 REQUIRED COMPONENTS ${_components}) endif() -add_executable(adios2_hello_bpAttributeWriter bpAttributeWriter_nompi.cpp) -target_link_libraries(adios2_hello_bpAttributeWriter adios2::cxx11) -install(TARGETS adios2_hello_bpAttributeWriter RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +add_executable(adios2_hello_bpAttributeWriteRead bpAttributeWriteRead.cpp) +target_link_libraries(adios2_hello_bpAttributeWriteRead adios2::cxx11) +install(TARGETS adios2_hello_bpAttributeWriteRead RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) if(ADIOS2_HAVE_MPI) - add_executable(adios2_hello_bpAttributeWriter_mpi bpAttributeWriter.cpp) - target_link_libraries(adios2_hello_bpAttributeWriter_mpi adios2::cxx11_mpi MPI::MPI_C) - install(TARGETS adios2_hello_bpAttributeWriter_mpi RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + add_executable(adios2_hello_bpAttributeWriteRead_mpi bpAttributeWriteRead.cpp) + target_link_libraries(adios2_hello_bpAttributeWriteRead_mpi adios2::cxx11_mpi MPI::MPI_C) + install(TARGETS adios2_hello_bpAttributeWriteRead_mpi RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() - diff --git a/examples/hello/bpAttributeWriteRead/bpAttributeWriteRead.cpp b/examples/hello/bpAttributeWriteRead/bpAttributeWriteRead.cpp new file mode 100644 index 0000000000..0d55e703e8 --- /dev/null +++ b/examples/hello/bpAttributeWriteRead/bpAttributeWriteRead.cpp @@ -0,0 +1,188 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpAttributeWriteRead.cpp: Simple self-descriptive example of how to write/read attributes and + * a variable to a BP File that lives in several MPI processes. + * + * Created on: Feb 16, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include //std::ios_base::failure +#include //std::cout +#if ADIOS2_USE_MPI +#include +#endif +#include //std::invalid_argument std::exception +#include +#include + +#include + +void writer(adios2::ADIOS &adios, int rank, int size, std::vector &myFloats) +{ + /*** IO class object: settings and factory of Settings: Variables, + * Parameters, Transports, and Execution: Engines */ + adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); + + const std::size_t Nx = myFloats.size(); + + /** global array : name, { shape (total) }, { start (local) }, { count + * (local) }, all are constant dimensions */ + adios2::Variable bpFloats = bpIO.DefineVariable( + "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios2::ConstantDims); + + bpIO.DefineAttribute("Single_String", "File generated with ADIOS2"); + + std::vector myStrings = {"one", "two", "three"}; + bpIO.DefineAttribute("Array_of_Strings", myStrings.data(), myStrings.size()); + + bpIO.DefineAttribute("Attr_Double", 0.f); + std::vector myDoubles = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + bpIO.DefineAttribute("Array_of_Doubles", myDoubles.data(), myDoubles.size()); + + /** Engine derived class, spawned to start IO operations */ + adios2::Engine bpWriter = bpIO.Open("fileAttributes.bp", adios2::Mode::Write); + + bpWriter.BeginStep(); + + /** Write variable for buffering */ + bpWriter.Put(bpFloats, myFloats.data()); + + bpWriter.EndStep(); + + /** Create bp file, engine becomes unreachable after this*/ + bpWriter.Close(); +} + +void reader(adios2::ADIOS &adios, int rank, int /*size*/) +{ + adios2::IO bpIO = adios.DeclareIO("BPReader"); + + adios2::Engine bpReader = bpIO.Open("fileAttributes.bp", adios2::Mode::Read); + + bpReader.BeginStep(); + const auto attributesInfo = bpIO.AvailableAttributes(); + + for (const auto &attributeInfoPair : attributesInfo) + { + std::cout << "Attribute: " << attributeInfoPair.first; + for (const auto &attributePair : attributeInfoPair.second) + { + std::cout << "\tKey: " << attributePair.first << "\tValue: " << attributePair.second + << "\n"; + } + std::cout << "\n"; + } + + adios2::Attribute singleString = bpIO.InquireAttribute("Single_String"); + if (singleString) + { + std::cout << singleString.Name() << ": " << singleString.Data()[0] << "\n"; + } + adios2::Attribute arrayOfStrings = + bpIO.InquireAttribute("Array_of_Strings"); + if (arrayOfStrings) + { + std::cout << arrayOfStrings.Name() << ": "; + for (const auto &value : arrayOfStrings.Data()) + { + std::cout << value << " "; + } + std::cout << "\n"; + } + adios2::Attribute attrDouble = bpIO.InquireAttribute("Attr_Double"); + if (attrDouble) + { + std::cout << attrDouble.Name() << ": " << attrDouble.Data()[0] << "\n"; + } + adios2::Attribute arrayOfDoubles = bpIO.InquireAttribute("Array_of_Doubles"); + if (arrayOfDoubles) + { + std::cout << arrayOfDoubles.Name() << ": "; + for (const auto &value : arrayOfDoubles.Data()) + { + std::cout << value << " "; + } + std::cout << "\n"; + } + + adios2::Variable bpFloats = bpIO.InquireVariable("bpFloats"); + const std::size_t Nx = 10; + std::vector myFloats(Nx); + if (bpFloats) + { + bpFloats.SetSelection({{Nx * rank}, {Nx}}); + bpReader.Get(bpFloats, myFloats.data()); + } + + bpReader.EndStep(); + + bpReader.Close(); +} + +int main(int argc, char *argv[]) +{ + int rank, size; +#if ADIOS2_USE_MPI + int provided; + + // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); +#else + rank = 0; + size = 1; +#endif + + /** Application variable */ + std::vector myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + try + { + /** ADIOS class factory of IO class objects */ +#if ADIOS2_USE_MPI + adios2::ADIOS adios(MPI_COMM_WORLD); +#else + adios2::ADIOS adios; +#endif + + writer(adios, rank, size, myFloats); + reader(adios, rank, size); + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; +#if ADIOS2_USE_MPI + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); +#endif + } + catch (std::ios_base::failure &e) + { + std::cout << "IO System base failure exception, STOPPING PROGRAM from rank " << rank + << "\n"; + std::cout << e.what() << "\n"; +#if ADIOS2_USE_MPI + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); +#endif + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; +#if ADIOS2_USE_MPI + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); +#endif + } + +#if ADIOS2_USE_MPI + MPI_Finalize(); +#endif + + return 0; +} diff --git a/examples/hello/bpAttributeWriter/bpAttributeWriter.cpp b/examples/hello/bpAttributeWriter/bpAttributeWriter.cpp deleted file mode 100644 index 1ef46f2e87..0000000000 --- a/examples/hello/bpAttributeWriter/bpAttributeWriter.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * bpAttributeWriter.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: William F Godoy godoywf@ornl.gov - */ - -#include //std::ios_base::failure -#include //std::cout -#include -#include //std::invalid_argument std::exception -#include -#include - -#include - -int main(int argc, char *argv[]) -{ - int provided; - - // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP - MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); - int rank, size; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - - /** Application variable */ - std::vector 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 */ - adios2::ADIOS adios(MPI_COMM_WORLD); - - /*** IO class object: settings and factory of Settings: Variables, - * Parameters, Transports, and Execution: Engines */ - adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); - - /** global array : name, { shape (total) }, { start (local) }, { count - * (local) }, all are constant dimensions */ - adios2::Variable bpFloats = bpIO.DefineVariable( - "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios2::ConstantDims); - - bpIO.DefineAttribute("Single_String", "File generated with ADIOS2"); - - std::vector myStrings = {"one", "two", "three"}; - bpIO.DefineAttribute("Array_of_Strings", myStrings.data(), myStrings.size()); - - bpIO.DefineAttribute("Attr_Double", 0.f); - std::vector myDoubles = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - bpIO.DefineAttribute("Array_of_Doubles", myDoubles.data(), myDoubles.size()); - - /** Engine derived class, spawned to start IO operations */ - adios2::Engine bpWriter = bpIO.Open("fileAttributes.bp", adios2::Mode::Write); - - bpWriter.BeginStep(); - - /** Write variable for buffering */ - bpWriter.Put(bpFloats, myFloats.data()); - - bpWriter.EndStep(); - - /** Create bp file, engine becomes unreachable after this*/ - bpWriter.Close(); - - adios2::IO bpReader = adios.DeclareIO("BPReader"); - - adios2::Engine bpReaderEngine = bpReader.Open("fileAttributes.bp", adios2::Mode::Read); - - bpReaderEngine.BeginStep(); - const auto attributesInfo = bpReader.AvailableAttributes(); - - for (const auto &attributeInfoPair : attributesInfo) - { - std::cout << "Attribute: " << attributeInfoPair.first; - for (const auto &attributePair : attributeInfoPair.second) - { - std::cout << "\tKey: " << attributePair.first << "\tValue: " << attributePair.second - << "\n"; - } - std::cout << "\n"; - } - bpReaderEngine.EndStep(); - - bpReaderEngine.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/bpAttributeWriter/bpAttributeWriter_nompi.cpp b/examples/hello/bpAttributeWriter/bpAttributeWriter_nompi.cpp deleted file mode 100644 index bb8aeab6fd..0000000000 --- a/examples/hello/bpAttributeWriter/bpAttributeWriter_nompi.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * bpAttributeWriter_nompi.cpp sequential non-mpi version of bpAttributeWriter - * - * Created on: Jan 9, 2017 - * Author: William F Godoy godoywf@ornl.gov - */ - -#include //std::ios_base::failure -#include //std::cout -#include //std::invalid_argument std::exception -#include -#include - -#include - -int main(int argc, char *argv[]) -{ - /** Application variable */ - std::vector 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 */ - adios2::ADIOS adios; - - /*** IO class object: settings and factory of Settings: Variables, - * Parameters, Transports, and Execution: Engines */ - adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); - - /** global array: name, { shape (total dimensions) }, { start (local) }, - * { count (local) }, all are constant dimensions */ - adios2::Variable bpFloats = - bpIO.DefineVariable("bpFloats", {}, {}, {Nx}, adios2::ConstantDims); - - bpIO.DefineAttribute("Single_String", "File generated with ADIOS2"); - - std::vector myStrings = {"one", "two", "three"}; - bpIO.DefineAttribute("Array_of_Strings", myStrings.data(), myStrings.size()); - - bpIO.DefineAttribute("Attr_Double", 0.f); - std::vector myDoubles = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - bpIO.DefineAttribute("Array_of_Doubles", myDoubles.data(), myDoubles.size()); - - /** Engine derived class, spawned to start IO operations */ - adios2::Engine bpWriter = bpIO.Open("myVector.bp", adios2::Mode::Write); - - bpWriter.BeginStep(); - - /** Write variable for buffering */ - bpWriter.Put(bpFloats, myFloats.data()); - - bpWriter.EndStep(); - - /** Create bp file, engine becomes unreachable after this*/ - 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; -} From fb738ca9faf299e72b0fdb2e20f4d8f17d406151 Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Mon, 30 Oct 2023 10:50:41 -0400 Subject: [PATCH 08/16] Rename bpSZ to bpOperatorSZWriter --- examples/hello/CMakeLists.txt | 4 ++ examples/hello/ReadMe.md | 55 ++++++++++--------- .../hello/bpOperatorSZWriter/CMakeLists.txt | 36 ++++++++++++ .../bpOperatorSZWriter.cpp} | 41 ++++++++------ examples/hello/bpWriter/CMakeLists.txt | 14 ----- 5 files changed, 92 insertions(+), 58 deletions(-) create mode 100644 examples/hello/bpOperatorSZWriter/CMakeLists.txt rename examples/hello/{bpWriter/bpSZ.cpp => bpOperatorSZWriter/bpOperatorSZWriter.cpp} (79%) diff --git a/examples/hello/CMakeLists.txt b/examples/hello/CMakeLists.txt index 077f42b07c..f1d9707e32 100644 --- a/examples/hello/CMakeLists.txt +++ b/examples/hello/CMakeLists.txt @@ -10,6 +10,10 @@ if(ADIOS2_HAVE_MPI) add_subdirectory(bpFWriteCRead) endif() +if(ADIOS2_HAVE_SZ) + add_subdirectory(bpOperatorSZWriter) +endif() + add_subdirectory(bpReader) add_subdirectory(bpThreadWrite) add_subdirectory(bpTimeWriter) diff --git a/examples/hello/ReadMe.md b/examples/hello/ReadMe.md index ff236f5658..44858ccb6d 100644 --- a/examples/hello/ReadMe.md +++ b/examples/hello/ReadMe.md @@ -11,59 +11,62 @@ They can be found in the following subdirectories, and they should be explored i * Languages: C++, C, Fortran, Python 3. [bpReader](bpReader): The _bpReader_ examples demonstrate how to read a 1D/2D/3D variable using ADIOS2's BP engine. * Languages: C++, Fortran, Python -4. [bpFWriteCRead](bpFWriteCRead): The _bpFWriteCRead_ example demonstrates how to write a 2D variable with Fortran and - read a subset of it with C++, and vice versa using ADIOS2's BP engine. - * Languages: C++, Fortran -5. [bpTimeWriter](bpTimeWriter): The _bpTimeWriter_ example demonstrates how to write two Variables (one is timestep) - using time aggregation using ADIOS2's BP engine. - * Languages: C++, Python -6. [bpAttributeWriterReader](bpAttributeWriter): The _bpAttributeWriterReader_ example demonstrates how to write/read attributes using - ADIOS2's BP engine. +4. [bpAttributeWriterReader](bpAttributeWriterReader): The _bpAttributeWriterReader_ example demonstrates how to + write/read attributes using ADIOS2's BP engine. * Languages: C++ -7. [bpFlushWriter](bpFlushWriter): The _bpFlushWriter_ example demonstrates how to flush a variable using ADIOS2's BP - engine. +5. [bpOperatorSZWriter](bpOperatorSZWriter): The _bpOperatorSZWriter_ example demonstrates how to write variables with + the SZ operator using ADIOS2's BP engine. * Languages: C++ -8. [bpWriteReadCuda](bpWriteReadCuda): The _bpWriteReadCuda_ example demonstrates how to write and read a variable with +6. [bpTimeWriter](bpTimeWriter): The _bpTimeWriter_ example demonstrates how to write two Variables (one is timestep) + using time aggregation using ADIOS2's BP engine. + * Languages: C++, Python +7. [bpWriteReadCuda](bpWriteReadCuda): The _bpWriteReadCuda_ example demonstrates how to write and read a variable with multiple time steps using ADIOS2's BP engine and leveraging CUDA. * Languages: C++ -9. [bpWriteReadHip](bpWriteReadHip): The _bpWriteReadHip_ example demonstrates how to write and read a variable with +8. [bpWriteReadHip](bpWriteReadHip): The _bpWriteReadHip_ example demonstrates how to write and read a variable with multiple time steps using ADIOS2's BP engine and leveraging HIP. * Languages: C++ -10. [bpWriteReadKokkos](bpWriteReadKokkos): The _bpWriteReadOmp_ example demonstrates how to write and read a variable +9. [bpWriteReadKokkos](bpWriteReadKokkos): The _bpWriteReadOmp_ example demonstrates how to write and read a variable with multiple time steps using ADIOS2's BP engine and leveraging Kokkos. * Languages: C++ -11. [datamanReader](datamanReader): The _datamanReader_ example demonstrates how to read variables in real-time WAN +10. [bpFlushWriter](bpFlushWriter): The _bpFlushWriter_ example demonstrates how to flush a variable using ADIOS2's BP + engine. + * Languages: C++ +11. [bpFWriteCRead](bpFWriteCRead): The _bpFWriteCRead_ example demonstrates how to write a 2D variable with + Fortran and read a subset of it with C++, and vice versa using ADIOS2's BP engine. + * Languages: C++, Fortran +12. [datamanReader](datamanReader): The _datamanReader_ example demonstrates how to read variables in real-time WAN streams using ADIOS's DataMan engine. * Languages: C++, Python -12. [datamanWriter](datamanWriter): The _datamanWriter_ example demonstrates how to write variables in real-time WAN +13. [datamanWriter](datamanWriter): The _datamanWriter_ example demonstrates how to write variables in real-time WAN streams using ADIOS's DataMan engine. * Languages: C++, Python -13. [dataspacesReader](dataspacesReader): The _dataspacesReader_ example demonstrates how to read a variable using +14. [dataspacesReader](dataspacesReader): The _dataspacesReader_ example demonstrates how to read a variable using ADIOS2's DATASPACES engine. * Languages: C++ -14. [dataspacesWriter](dataspacesWriter): The _dataspacesWriter_ example demonstrates how to write a variable using +15. [dataspacesWriter](dataspacesWriter): The _dataspacesWriter_ example demonstrates how to write a variable using ADIOS2's DATASPACES engine. * Languages: C++ -15. [hdf5Reader](hdf5Reader): The _hdf5Reader_ example demonstrates how to read variables using ADIOS2's HDF5 engine. +16. [hdf5Reader](hdf5Reader): The _hdf5Reader_ example demonstrates how to read variables using ADIOS2's HDF5 engine. * Languages: C++ -16. [hdf5Writer](hdf5Writer): The _hdf5Writer_ example demonstrates how to write variables using ADIOS2's HDF5 engine. +17. [hdf5Writer](hdf5Writer): The _hdf5Writer_ example demonstrates how to write variables using ADIOS2's HDF5 engine. * Languages: C++ -17. [hdf5SubFile](hdf5SubFile): The _hdf5SubFile_ example demonstrates how to write variables using ADIOS2's parallel +18. [hdf5SubFile](hdf5SubFile): The _hdf5SubFile_ example demonstrates how to write variables using ADIOS2's parallel HDF5 engine leveraging the subfile feature. * Languages: C++ -18. [inlineMWE](inlineMWE): The _inlineMWE_ example demonstrates how to write and read a variable using ADIOS2's inline +19. [inlineMWE](inlineMWE): The _inlineMWE_ example demonstrates how to write and read a variable using ADIOS2's inline engine. * Languages: C++ -19. [inlineFWriteCppRead](inlineFWriteCppRead): The _inlineFWriteCppRead_ example demonstrates how to write a 2D +20. [inlineFWriteCppRead](inlineFWriteCppRead): The _inlineFWriteCppRead_ example demonstrates how to write a 2D variable with Fortran and read it back a subset of it with C++ using ADIOS2's inline engine. * Languages: C++, Fortran -20. [inlineReaderWriter](inlineReaderWriter): The _inlineReaderWriter_ example demonstrates how to write two Variables +21. [inlineReaderWriter](inlineReaderWriter): The _inlineReaderWriter_ example demonstrates how to write two Variables (one is timestep) using time aggregation and ADIOS2's inline engine. * Languages: C++ -21. [sstReader](sstReader): The _sstReader_ example demonstrates how to read a variable using ADIOS2's SST engine. +22. [sstReader](sstReader): The _sstReader_ example demonstrates how to read a variable using ADIOS2's SST engine. * Languages: C++ -22. [sstWriter](sstWriter): The _sstWriter_ example demonstrates how to write a variable using ADIOS2's SST engine. +23. [sstWriter](sstWriter): The _sstWriter_ example demonstrates how to write a variable using ADIOS2's SST engine. * Languages: C++ -23. [skeleton](skeleton): The _skeleton_ example demonstrates how to write and read a variable using an ADIOS2 skeleton +24. [skeleton](skeleton): The _skeleton_ example demonstrates how to write and read a variable using an ADIOS2 skeleton engine. * Languages: C++ diff --git a/examples/hello/bpOperatorSZWriter/CMakeLists.txt b/examples/hello/bpOperatorSZWriter/CMakeLists.txt new file mode 100644 index 0000000000..c54aadf81e --- /dev/null +++ b/examples/hello/bpOperatorSZWriter/CMakeLists.txt @@ -0,0 +1,36 @@ +#------------------------------------------------------------------------------# +# Distributed under the OSI-approved Apache License, Version 2.0. See +# accompanying file Copyright.txt for details. +#------------------------------------------------------------------------------# + +cmake_minimum_required(VERSION 3.12) +project(ADIOS2HelloBPOperatorSZWriterExample) + +if(NOT TARGET adios2_core) + set(_components C) + + find_package(MPI COMPONENTS ${_components}) + if(MPI_FOUND) + # Workaround for various MPI implementations forcing the link of C++ bindings + add_definitions(-DOMPI_SKIP_MPICXX -DMPICH_SKIP_MPICXX) + + list(APPEND _components MPI) + endif() + list(APPEND _components CXX) + + find_package(SZ QUIET) + + find_package(ADIOS2 REQUIRED COMPONENTS ${_components}) +endif() + +if(ADIOS2_HAVE_SZ) + add_executable(adios2_hello_bpOperatorSZWriter bpOperatorSZWriter.cpp) + target_link_libraries(adios2_hello_bpOperatorSZWriter adios2::cxx11) + install(TARGETS adios2_hello_bpOperatorSZWriter RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + + if (ADIOS2_HAVE_MPI) + add_executable(adios2_hello_bpOperatorSZWriter_mpi bpOperatorSZWriter.cpp) + target_link_libraries(adios2_hello_bpOperatorSZWriter_mpi adios2::cxx11_mpi MPI::MPI_C) + install(TARGETS adios2_hello_bpOperatorSZWriter_mpi RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif () +endif() diff --git a/examples/hello/bpWriter/bpSZ.cpp b/examples/hello/bpOperatorSZWriter/bpOperatorSZWriter.cpp similarity index 79% rename from examples/hello/bpWriter/bpSZ.cpp rename to examples/hello/bpOperatorSZWriter/bpOperatorSZWriter.cpp index 357f42f829..2fb96876a1 100644 --- a/examples/hello/bpWriter/bpSZ.cpp +++ b/examples/hello/bpOperatorSZWriter/bpOperatorSZWriter.cpp @@ -2,19 +2,20 @@ * Distributed under the OSI-approved Apache License, Version 2.0. See * accompanying file Copyright.txt for details. * - * bpSZ.cpp : example passing runtime compression arguments + * bpOperatorSZWriter.cpp : example using operator by passing compression arguments * * Created on: Aug 3, 2018 * Author: William F Godoy godoywf@ornl.gov */ +#include //std::transform #include //std::ios_base::failure #include //std::cout #include //std::iota #include //std::invalid_argument std::exception #include -#include +#include "adios2.h" #if ADIOS2_USE_MPI #include #endif @@ -23,7 +24,7 @@ void Usage() { std::cout << "\n"; std::cout << "USAGE:\n"; - std::cout << "./helloBPSZ Nx sz_accuracy\n"; + std::cout << "./adios2_hello_bpOperatorSZWriter Nx sz_accuracy\n"; std::cout << "\t Nx: size of float and double arrays to be compressed\n"; std::cout << "\t sz_accuracy: absolute accuracy e.g. 0.1, 0.001, to skip " "compression: -1\n\n"; @@ -31,8 +32,13 @@ void Usage() int main(int argc, char *argv[]) { - int rank, size; + if (argc != 3) + { + Usage(); + return EXIT_SUCCESS; + } + int rank, size; #if ADIOS2_USE_MPI int provided; @@ -47,12 +53,6 @@ int main(int argc, char *argv[]) try { - if (argc != 3) - { - throw std::invalid_argument("ERROR: need sz accuracy e.g. 0.01, 0.1 as " - "2nd parameter in argv\n"); - } - const std::size_t Nx = static_cast(std::stoull(argv[1])); const double accuracy = std::stod(argv[2]); @@ -92,21 +92,26 @@ int main(int argc, char *argv[]) (void)attribute; /** Engine derived class, spawned to start IO operations */ - adios2::Engine bpFileWriter = bpIO.Open("SZexample.bp", adios2::Mode::Write); + adios2::Engine bpWriter = bpIO.Open("SZexample.bp", adios2::Mode::Write); - for (unsigned int t = 0; t < 3; ++t) + for (unsigned int step = 0; step < 3; ++step) { - bpFileWriter.BeginStep(); + bpWriter.BeginStep(); - // here you can modify myFloats, myDoubles per step + bpWriter.Put(varFloats, myFloats.data()); + bpWriter.Put(varDoubles, myDoubles.data()); - bpFileWriter.Put(varFloats, myFloats.data()); - bpFileWriter.Put(varDoubles, myDoubles.data()); - bpFileWriter.EndStep(); + bpWriter.EndStep(); + + // here you can modify myFloats, myDoubles per step + std::transform(myFloats.begin(), myFloats.end(), myFloats.begin(), + [&](float v) -> float { return 2 * v; }); + std::transform(myDoubles.begin(), myDoubles.end(), myDoubles.begin(), + [&](double v) -> double { return 3 * v; }); } /** Create bp file, engine becomes unreachable after this*/ - bpFileWriter.Close(); + bpWriter.Close(); } catch (std::invalid_argument &e) { diff --git a/examples/hello/bpWriter/CMakeLists.txt b/examples/hello/bpWriter/CMakeLists.txt index 0e48312f8c..9eb0fbf91a 100644 --- a/examples/hello/bpWriter/CMakeLists.txt +++ b/examples/hello/bpWriter/CMakeLists.txt @@ -27,8 +27,6 @@ if(NOT TARGET adios2_core) endif() list(APPEND _components CXX) - find_package(SZ QUIET) - find_package(ADIOS2 REQUIRED COMPONENTS ${_components}) endif() @@ -48,12 +46,6 @@ add_executable(adios2_hello_bpSubStreams bpSubStreams.cpp) target_link_libraries(adios2_hello_bpSubStreams adios2::cxx11) install(TARGETS adios2_hello_bpSubStreams RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -if(ADIOS2_HAVE_SZ) - add_executable(adios2_hello_bpSZ bpSZ.cpp) - target_link_libraries(adios2_hello_bpSZ adios2::cxx11) - install(TARGETS adios2_hello_bpSZ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -endif() - if(ADIOS2_HAVE_Fortran) add_executable(adios2_hello_bpWriter_f bpWriter.F90) target_link_libraries(adios2_hello_bpWriter_f adios2::fortran) @@ -77,12 +69,6 @@ if(ADIOS2_HAVE_MPI) target_link_libraries(adios2_hello_bpSubStreams_mpi adios2::cxx11_mpi MPI::MPI_C) install(TARGETS adios2_hello_bpSubStreams_mpi RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - if(ADIOS2_HAVE_SZ) - add_executable(adios2_hello_bpSZ_mpi bpSZ.cpp) - target_link_libraries(adios2_hello_bpSZ_mpi adios2::cxx11_mpi MPI::MPI_C) - install(TARGETS adios2_hello_bpSZ_mpi RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - endif() - if(ADIOS2_HAVE_Fortran) add_executable(adios2_hello_bpWriter_f_mpi bpWriter.F90) target_link_libraries(adios2_hello_bpWriter_f_mpi adios2::fortran_mpi MPI::MPI_Fortran) From e20d489e17d9833299159dda5a216141930cb5cc Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Mon, 30 Oct 2023 12:11:07 -0400 Subject: [PATCH 09/16] Improve bpStepsWriteRead* examples Make all of their code similar. The bpStepsWriteRead example will be used for a tutorial. --- examples/hello/CMakeLists.txt | 15 +- examples/hello/ReadMe.md | 20 +- .../CMakeLists.txt | 14 +- .../bpStepsWriteRead/bpStepsWriteRead.cpp | 154 +++++++++++++++ .../CMakeLists.txt | 10 +- .../bpStepsWriteReadCuda.cu | 142 ++++++++++++++ .../CMakeLists.txt | 10 +- .../bpStepsWriteReadHip.cpp | 161 ++++++++++++++++ .../CMakeLists.txt | 10 +- .../bpStepsWriteReadKokkos.cpp | 146 ++++++++++++++ examples/hello/bpTimeWriter/bpTimeWriter.cpp | 178 ------------------ examples/hello/bpTimeWriter/bpTimeWriter.py | 51 ----- .../hello/bpTimeWriter/bpTimeWriter_nompi.cpp | 76 -------- .../hello/bpWriteReadCuda/bpWriteReadCuda.cu | 113 ----------- .../hello/bpWriteReadHip/bpWriteReadHip.cpp | 135 ------------- .../bpWriteReadKokkos/bpWriteReadKokkos.cpp | 117 ------------ 16 files changed, 642 insertions(+), 710 deletions(-) rename examples/hello/{bpTimeWriter => bpStepsWriteRead}/CMakeLists.txt (57%) create mode 100644 examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp rename examples/hello/{bpWriteReadCuda => bpStepsWriteReadCuda}/CMakeLists.txt (58%) create mode 100644 examples/hello/bpStepsWriteReadCuda/bpStepsWriteReadCuda.cu rename examples/hello/{bpWriteReadHip => bpStepsWriteReadHip}/CMakeLists.txt (59%) create mode 100644 examples/hello/bpStepsWriteReadHip/bpStepsWriteReadHip.cpp rename examples/hello/{bpWriteReadKokkos => bpStepsWriteReadKokkos}/CMakeLists.txt (68%) create mode 100644 examples/hello/bpStepsWriteReadKokkos/bpStepsWriteReadKokkos.cpp delete mode 100644 examples/hello/bpTimeWriter/bpTimeWriter.cpp delete mode 100644 examples/hello/bpTimeWriter/bpTimeWriter.py delete mode 100644 examples/hello/bpTimeWriter/bpTimeWriter_nompi.cpp delete mode 100644 examples/hello/bpWriteReadCuda/bpWriteReadCuda.cu delete mode 100644 examples/hello/bpWriteReadHip/bpWriteReadHip.cpp delete mode 100644 examples/hello/bpWriteReadKokkos/bpWriteReadKokkos.cpp diff --git a/examples/hello/CMakeLists.txt b/examples/hello/CMakeLists.txt index f1d9707e32..a3841fdd27 100644 --- a/examples/hello/CMakeLists.txt +++ b/examples/hello/CMakeLists.txt @@ -15,23 +15,22 @@ if(ADIOS2_HAVE_SZ) endif() add_subdirectory(bpReader) -add_subdirectory(bpThreadWrite) -add_subdirectory(bpTimeWriter) -add_subdirectory(bpWriter) +add_subdirectory(bpStepsWriteRead) if(ADIOS2_HAVE_CUDA OR ADIOS2_HAVE_Kokkos_CUDA) - add_subdirectory(bpWriteReadCuda) + add_subdirectory(bpStepsWriteReadCuda) endif() - find_package(hip QUIET) if(ADIOS2_HAVE_Kokkos_HIP OR hip_FOUND) - add_subdirectory(bpWriteReadHip) + add_subdirectory(bpStepsWriteReadHip) endif() - if(ADIOS2_HAVE_Kokkos) - add_subdirectory(bpWriteReadKokkos) + add_subdirectory(bpStepsWriteReadKokkos) endif() +add_subdirectory(bpThreadWrite) +add_subdirectory(bpWriter) + if(ADIOS2_HAVE_DataMan) add_subdirectory(datamanReader) add_subdirectory(datamanWriter) diff --git a/examples/hello/ReadMe.md b/examples/hello/ReadMe.md index 44858ccb6d..ed45bec50c 100644 --- a/examples/hello/ReadMe.md +++ b/examples/hello/ReadMe.md @@ -17,18 +17,18 @@ They can be found in the following subdirectories, and they should be explored i 5. [bpOperatorSZWriter](bpOperatorSZWriter): The _bpOperatorSZWriter_ example demonstrates how to write variables with the SZ operator using ADIOS2's BP engine. * Languages: C++ -6. [bpTimeWriter](bpTimeWriter): The _bpTimeWriter_ example demonstrates how to write two Variables (one is timestep) - using time aggregation using ADIOS2's BP engine. - * Languages: C++, Python -7. [bpWriteReadCuda](bpWriteReadCuda): The _bpWriteReadCuda_ example demonstrates how to write and read a variable with - multiple time steps using ADIOS2's BP engine and leveraging CUDA. +6. [bpStepsWriteRead](bpStepsWriteRead): The _bpStepsWriteRead_ example demonstrates how to write and read + multiple steps using ADIOS2's BP engine. + * Languages: C++ +7. [bpStepsWriteReadCuda](bpStepsWriteReadCuda): The _bpStepsWriteReadCuda_ example demonstrates how to write and read a + variable with multiple steps using ADIOS2's BP engine and leveraging CUDA. * Languages: C++ -8. [bpWriteReadHip](bpWriteReadHip): The _bpWriteReadHip_ example demonstrates how to write and read a variable with - multiple time steps using ADIOS2's BP engine and leveraging HIP. +8. [bpStepsWriteReadHip](bpStepsWriteReadHip): The _bpStepsWriteReadHip_ example demonstrates how to write and read a + variable with multiple steps using ADIOS2's BP engine and leveraging HIP. + * Languages: C++ +9. [bpStepsWriteReadKokkos](bpStepsWriteReadKokkos): The _bpStepsWriteReadKokkos_ example demonstrates how to write and + read a variable with multiple steps using ADIOS2's BP engine and leveraging Kokkos. * Languages: C++ -9. [bpWriteReadKokkos](bpWriteReadKokkos): The _bpWriteReadOmp_ example demonstrates how to write and read a variable - with multiple time steps using ADIOS2's BP engine and leveraging Kokkos. - * Languages: C++ 10. [bpFlushWriter](bpFlushWriter): The _bpFlushWriter_ example demonstrates how to flush a variable using ADIOS2's BP engine. * Languages: C++ diff --git a/examples/hello/bpTimeWriter/CMakeLists.txt b/examples/hello/bpStepsWriteRead/CMakeLists.txt similarity index 57% rename from examples/hello/bpTimeWriter/CMakeLists.txt rename to examples/hello/bpStepsWriteRead/CMakeLists.txt index 30a9f1d361..6acf9698dd 100644 --- a/examples/hello/bpTimeWriter/CMakeLists.txt +++ b/examples/hello/bpStepsWriteRead/CMakeLists.txt @@ -4,7 +4,7 @@ #------------------------------------------------------------------------------# cmake_minimum_required(VERSION 3.12) -project(ADIOS2HelloBPTimeWriterExample) +project(ADIOS2HelloBPStepsWriteReadExample) if(NOT TARGET adios2_core) set(_components CXX) @@ -20,12 +20,12 @@ if(NOT TARGET adios2_core) find_package(ADIOS2 REQUIRED COMPONENTS ${_components}) endif() -add_executable(adios2_hello_bpTimeWriter bpTimeWriter_nompi.cpp) -target_link_libraries(adios2_hello_bpTimeWriter adios2::cxx11) -install(TARGETS adios2_hello_bpTimeWriter RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +add_executable(adios2_hello_bpStepsWriteRead bpStepsWriteRead.cpp) +target_link_libraries(adios2_hello_bpStepsWriteRead adios2::cxx11) +install(TARGETS adios2_hello_bpStepsWriteRead RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) if(ADIOS2_HAVE_MPI) - add_executable(adios2_hello_bpTimeWriter_mpi bpTimeWriter.cpp) - target_link_libraries(adios2_hello_bpTimeWriter_mpi adios2::cxx11_mpi MPI::MPI_C) - install(TARGETS adios2_hello_bpTimeWriter_mpi RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + add_executable(adios2_hello_bpStepsWriteRead_mpi bpStepsWriteRead.cpp) + target_link_libraries(adios2_hello_bpStepsWriteRead_mpi adios2::cxx11_mpi MPI::MPI_C) + install(TARGETS adios2_hello_bpStepsWriteRead_mpi RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp b/examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp new file mode 100644 index 0000000000..e06a2e80da --- /dev/null +++ b/examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp @@ -0,0 +1,154 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpStepsWriteRead.cpp Simple example of writing and reading data through ADIOS2 BP engine with + * multiple simulations steps for every IO step. + * + * Created on: Feb 16, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include // std::for_each +#include // std::ios_base::failure +#include // std::cout +#if ADIOS2_USE_MPI +#include +#endif +#include //std::invalid_argument std::exception +#include + +#include + +void update_array(std::vector &array, int val) +{ + std::transform(array.begin(), array.end(), array.begin(), + [val](float v) -> float { return v + static_cast(val); }); +} + +void writer(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int nSteps, int rank, int size) +{ + std::vector simData(Nx, 0); + + adios2::IO bpIO = adios.DeclareIO("WriteIO"); + bpIO.SetEngine(engine); + + const adios2::Dims shape{static_cast(size * Nx)}; + const adios2::Dims start{static_cast(rank * Nx)}; + const adios2::Dims count{Nx}; + auto bpFloats = bpIO.DefineVariable("bpFloats", shape, start, count); + + auto bpStep = bpIO.DefineVariable("bpStep"); + + adios2::Engine bpWriter = bpIO.Open(fname, adios2::Mode::Write); + + for (unsigned int step = 0; step < nSteps; ++step) + { + const adios2::Box sel({0}, {Nx}); + bpFloats.SetSelection(sel); + + bpWriter.BeginStep(); + bpWriter.Put(bpFloats, simData.data()); + bpWriter.Put(bpStep, step); + bpWriter.EndStep(); + + // Update values in the simulation data + update_array(simData, 10); + } + + bpWriter.Close(); +} + +void reader(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int /*nSteps*/, int rank, int /*size*/) +{ + adios2::IO bpIO = adios.DeclareIO("ReadIO"); + bpIO.SetEngine(engine); + + adios2::Engine bpReader = bpIO.Open(fname, adios2::Mode::Read); + + std::vector simData(Nx, 0); + unsigned int inStep = 0; + for (unsigned int step = 0; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) + { + auto bpFloats = bpIO.InquireVariable("bpFloats"); + if (bpFloats) + { + const adios2::Box sel({{Nx * rank}, {Nx}}); + bpFloats.SetSelection(sel); + bpReader.Get(bpFloats, simData.data()); + } + auto bpStep = bpIO.InquireVariable("bpStep"); + if (bpStep) + { + bpReader.Get(bpStep, &inStep); + } + + bpReader.EndStep(); + if (inStep != step) + { + std::cout << "ERROR: step mismatch\n"; + return; + } + } + bpReader.Close(); +} + +int main(int argc, char *argv[]) +{ + int rank, size; + +#if ADIOS2_USE_MPI + int provided; + // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); +#else + rank = 0; + size = 1; +#endif + + const std::string engine = argv[1] ? argv[1] : "BPFile"; + std::cout << "Using engine " << engine << std::endl; + + const std::string filename = engine + "StepsWriteRead.bp"; + const unsigned int nSteps = 10; + const unsigned int Nx = 60000; + try + { + /** ADIOS class factory of IO class objects */ +#if ADIOS2_USE_MPI + adios2::ADIOS adios(MPI_COMM_WORLD); +#else + adios2::ADIOS adios; +#endif + + writer(adios, engine, filename, Nx, nSteps, rank, size); + reader(adios, engine, filename, Nx, nSteps, rank, size); + } + 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"; + } + +#if ADIOS2_USE_MPI + MPI_Finalize(); +#endif + + return 0; +} diff --git a/examples/hello/bpWriteReadCuda/CMakeLists.txt b/examples/hello/bpStepsWriteReadCuda/CMakeLists.txt similarity index 58% rename from examples/hello/bpWriteReadCuda/CMakeLists.txt rename to examples/hello/bpStepsWriteReadCuda/CMakeLists.txt index 453867f0b4..590adb671a 100644 --- a/examples/hello/bpWriteReadCuda/CMakeLists.txt +++ b/examples/hello/bpStepsWriteReadCuda/CMakeLists.txt @@ -4,7 +4,7 @@ #------------------------------------------------------------------------------# cmake_minimum_required(VERSION 3.12) -project(ADIOS2HelloBPWriteReadCudaExample) +project(ADIOS2HelloBPStepsWriteReadCudaExample) if(NOT TARGET adios2_core) set(_components CXX) @@ -18,8 +18,8 @@ if(NOT TARGET adios2_core) endif() if(ADIOS2_HAVE_CUDA OR ADIOS2_HAVE_Kokkos_CUDA) - add_executable(adios2_hello_bpWriteReadCuda bpWriteReadCuda.cu) - target_link_libraries(adios2_hello_bpWriteReadCuda PUBLIC adios2::cxx11 CUDA::cudart) - set_target_properties(adios2_hello_bpWriteReadCuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON) - install(TARGETS adios2_hello_bpWriteReadCuda RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + add_executable(adios2_hello_bpStepsWriteReadCuda bpStepsWriteReadCuda.cu) + target_link_libraries(adios2_hello_bpStepsWriteReadCuda PUBLIC adios2::cxx11 CUDA::cudart) + set_target_properties(adios2_hello_bpStepsWriteReadCuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON) + install(TARGETS adios2_hello_bpStepsWriteReadCuda RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/examples/hello/bpStepsWriteReadCuda/bpStepsWriteReadCuda.cu b/examples/hello/bpStepsWriteReadCuda/bpStepsWriteReadCuda.cu new file mode 100644 index 0000000000..5d911e64cf --- /dev/null +++ b/examples/hello/bpStepsWriteReadCuda/bpStepsWriteReadCuda.cu @@ -0,0 +1,142 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpStepsWriteReadCuda.cu Simple example of writing and reading data through ADIOS2 BP engine with + * multiple simulations steps for every IO step using CUDA + */ + +#include +#include +#include //std::invalid_argument std::exception +#include +#include + +#include + +#include + +__global__ void update_array(float *vect, int val) { vect[blockIdx.x] += val; } + +void writer(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int nSteps) +{ + // Initialize the simulation data + float *gpuSimData; + cudaMalloc(&gpuSimData, Nx * sizeof(float)); + cudaMemset(gpuSimData, 0, Nx); + + // Set up the ADIOS structures + adios2::IO bpIO = adios.DeclareIO("WriteIO"); + bpIO.SetEngine(engine); + + // Declare an array for the ADIOS data of size (NumOfProcesses * Nx) + const adios2::Dims shape{static_cast(Nx)}; + const adios2::Dims start{static_cast(0)}; + const adios2::Dims count{Nx}; + auto bpFloats = bpIO.DefineVariable("bpFloats", shape, start, count); + auto bpStep = bpIO.DefineVariable("bpStep"); + + adios2::Engine bpWriter = bpIO.Open(fname, adios2::Mode::Write); + + // Simulation steps + for (unsigned int step = 0; step < nSteps; ++step) + { + // Make a 1D selection to describe the local dimensions of the + // variable we write and its offsets in the global spaces + const adios2::Box sel({0}, {Nx}); + bpFloats.SetSelection(sel); + + // Start IO step every write step + bpWriter.BeginStep(); + bpFloats.SetMemorySpace(adios2::MemorySpace::GPU); + bpWriter.Put(bpFloats, gpuSimData); + bpWriter.Put(bpStep, step); + bpWriter.EndStep(); + + // Update values in the simulation data + update_array<<>>(gpuSimData, 10); + } + + bpWriter.Close(); +} + +void reader(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int /*nSteps*/) +{ + // Create ADIOS structures + adios2::IO bpIO = adios.DeclareIO("ReadIO"); + bpIO.SetEngine(engine); + + adios2::Engine bpReader = bpIO.Open(fname, adios2::Mode::Read); + + unsigned int inStep = 0; + float *gpuSimData; + cudaMalloc(&gpuSimData, Nx * sizeof(float)); + cudaMemset(gpuSimData, 0, Nx); + for (unsigned int step = 0; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) + { + auto bpFloats = bpIO.InquireVariable("bpFloats"); + if (bpFloats) + { + const adios2::Dims start{0}; + const adios2::Dims count{Nx}; + const adios2::Box sel(start, count); + bpFloats.SetSelection(sel); + + bpFloats.SetMemorySpace(adios2::MemorySpace::GPU); + bpReader.Get(bpFloats, gpuSimData); //, adios2::Mode::Deferred); + } + auto bpStep = bpIO.InquireVariable("bpStep"); + if (bpStep) + { + bpReader.Get(bpStep, &inStep); + } + + bpReader.EndStep(); + if (inStep != step) + { + std::cout << "ERROR: step mismatch\n"; + return; + } + } + bpReader.Close(); +} + +int main(int argc, char **argv) +{ + const int device_id = 1; + cudaSetDevice(device_id); + + const std::string engine = argv[1] ? argv[1] : "BPFile"; + std::cout << "Using engine " << engine << std::endl; + + const std::string filename = engine + "StepsWriteReadCuda.bp"; + const unsigned int nSteps = 10; + const unsigned int Nx = 6000; + try + { + /** ADIOS class factory of IO class objects */ + adios2::ADIOS adios; + + writer(adios, engine, filename, Nx, nSteps); + reader(adios, engine, filename, Nx, nSteps); + } + 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\n"; + std::cout << e.what() << "\n"; + } + + return 0; +} diff --git a/examples/hello/bpWriteReadHip/CMakeLists.txt b/examples/hello/bpStepsWriteReadHip/CMakeLists.txt similarity index 59% rename from examples/hello/bpWriteReadHip/CMakeLists.txt rename to examples/hello/bpStepsWriteReadHip/CMakeLists.txt index bb1b6d3acf..ad7ff0d30d 100644 --- a/examples/hello/bpWriteReadHip/CMakeLists.txt +++ b/examples/hello/bpStepsWriteReadHip/CMakeLists.txt @@ -4,7 +4,7 @@ #------------------------------------------------------------------------------# cmake_minimum_required(VERSION 3.12) -project(ADIOS2HelloBPWriteReadHipExample) +project(ADIOS2HelloBPStepsWriteReadHipExample) if(NOT TARGET adios2_core) set(_components CXX) @@ -18,8 +18,8 @@ if(NOT TARGET adios2_core) endif() if(ADIOS2_HAVE_Kokkos_HIP OR hip_FOUND) - add_executable(adios2_hello_bpWriteReadHip bpWriteReadHip.cpp) - target_link_libraries(adios2_hello_bpWriteReadHip adios2::cxx11 hip::device) - set_source_files_properties(bpWriteReadHip.cpp PROPERTIES LANGUAGE HIP) - install(TARGETS adios2_hello_bpWriteReadHip RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + add_executable(adios2_hello_bpStepsWriteReadHip bpStepsWriteReadHip.cpp) + target_link_libraries(adios2_hello_bpStepsWriteReadHip adios2::cxx11 hip::device) + set_source_files_properties(bpStepsWriteReadHip.cpp PROPERTIES LANGUAGE HIP) + install(TARGETS adios2_hello_bpStepsWriteReadHip RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/examples/hello/bpStepsWriteReadHip/bpStepsWriteReadHip.cpp b/examples/hello/bpStepsWriteReadHip/bpStepsWriteReadHip.cpp new file mode 100644 index 0000000000..12fe720d51 --- /dev/null +++ b/examples/hello/bpStepsWriteReadHip/bpStepsWriteReadHip.cpp @@ -0,0 +1,161 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpStepsWriteReadHip.cpp Simple example of writing and reading bpFloats through ADIOS2 BP engine + * with multiple simulations steps for every IO step using HIP + */ +#include +#include +#include +#include //std::invalid_argument std::exception +#include + +#include + +#include + +__global__ void hip_initialize(float *vec) { vec[hipBlockIdx_x] = hipBlockIdx_x; } + +__global__ void hip_increment(float *vec, float val) { vec[hipBlockIdx_x] += val; } + +void writer(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int nSteps) +{ + hipError_t hipExit; + float *gpuSimData; + hipExit = hipMalloc((void **)&gpuSimData, Nx * sizeof(float)); + if (hipExit != hipSuccess) + { + std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; + return; + } + hipLaunchKernelGGL(hip_initialize, dim3(Nx), dim3(1), 0, 0, gpuSimData); + hipExit = hipDeviceSynchronize(); + if (hipExit != hipSuccess) + { + std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; + return; + } + + adios2::IO bpIO = adios.DeclareIO("WriteIO"); + bpIO.SetEngine(engine); + + const adios2::Dims shape{static_cast(Nx)}; + const adios2::Dims start{static_cast(0)}; + const adios2::Dims count{Nx}; + auto bpFloats = bpIO.DefineVariable("bpFloats", shape, start, count); + auto bpStep = bpIO.DefineVariable("bpStep"); + + adios2::Engine bpWriter = bpIO.Open(fname, adios2::Mode::Write); + + for (unsigned int step = 0; step < nSteps; ++step) + { + const adios2::Box sel({0}, {Nx}); + bpFloats.SetSelection(sel); + + bpWriter.BeginStep(); + bpWriter.Put(bpFloats, gpuSimData); + bpWriter.Put(bpStep, step); + bpWriter.EndStep(); + + hipLaunchKernelGGL(hip_increment, dim3(Nx), dim3(1), 0, 0, gpuSimData, 10); + hipExit = hipDeviceSynchronize(); + if (hipExit != hipSuccess) + { + std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; + return; + } + } + + bpWriter.Close(); +} + +void reader(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int /*nSteps*/) +{ + hipError_t hipExit; + adios2::IO bpIO = adios.DeclareIO("ReadIO"); + bpIO.SetEngine(engine); + + adios2::Engine bpReader = bpIO.Open(fname, adios2::Mode::Read); + + unsigned int inStep = 0; + float *gpuSimData; + hipExit = hipMalloc((void **)&gpuSimData, Nx * sizeof(float)); + if (hipExit != hipSuccess) + { + std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; + return; + } + for (unsigned int step = 0; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) + { + auto bpFloats = bpIO.InquireVariable("bpFloats"); + if (bpFloats) + { + const adios2::Dims start{0}; + const adios2::Dims count{Nx}; + const adios2::Box sel(start, count); + bpFloats.SetSelection(sel); + bpFloats.SetMemorySpace(adios2::MemorySpace::GPU); + bpReader.Get(bpFloats, gpuSimData); + } + auto bpStep = bpIO.InquireVariable("bpStep"); + if (bpStep) + { + bpReader.Get(bpStep, &inStep); + } + + bpReader.EndStep(); + if (inStep != step) + { + std::cout << "ERROR: step mismatch\n"; + return; + } + } + bpReader.Close(); +} + +int main(int argc, char **argv) +{ + hipError_t hipExit; + const int device_id = 0; + hipExit = hipSetDevice(device_id); + if (hipExit != hipSuccess) + { + std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; + return 1; + } + + const std::string engine = argv[1] ? argv[1] : "BPFile"; + std::cout << "Using engine " << engine << std::endl; + + const std::string filename = engine + "StepsWriteReadHip.bp"; + const unsigned int nSteps = 10; + const unsigned int Nx = 6000; + try + { + /** ADIOS class factory of IO class objects */ + adios2::ADIOS adios; + + writer(adios, engine, filename, Nx, nSteps); + reader(adios, engine, filename, Nx, nSteps); + } + 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\n"; + std::cout << e.what() << "\n"; + } + + return 0; +} diff --git a/examples/hello/bpWriteReadKokkos/CMakeLists.txt b/examples/hello/bpStepsWriteReadKokkos/CMakeLists.txt similarity index 68% rename from examples/hello/bpWriteReadKokkos/CMakeLists.txt rename to examples/hello/bpStepsWriteReadKokkos/CMakeLists.txt index a8e810b734..c420e6e762 100644 --- a/examples/hello/bpWriteReadKokkos/CMakeLists.txt +++ b/examples/hello/bpStepsWriteReadKokkos/CMakeLists.txt @@ -4,7 +4,7 @@ #------------------------------------------------------------------------------# cmake_minimum_required(VERSION 3.12) -project(ADIOS2HelloBPWriteReadKokkosExample) +project(ADIOS2HelloBPStepsWriteReadKokkosExample) # CXX Compiler settings only in for this example set(CMAKE_CXX_STANDARD 17) @@ -26,8 +26,8 @@ else() endif() if(ADIOS2_HAVE_Kokkos) - add_executable(adios2_hello_bpWriteReadKokkos bpWriteReadKokkos.cpp) - kokkos_compilation(SOURCE bpWriteReadKokkos.cpp) - target_link_libraries(adios2_hello_bpWriteReadKokkos adios2::cxx11 Kokkos::kokkos) - install(TARGETS adios2_hello_bpWriteReadKokkos RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + add_executable(adios2_hello_bpStepsWriteReadKokkos bpStepsWriteReadKokkos.cpp) + kokkos_compilation(SOURCE bpStepsWriteReadKokkos.cpp) + target_link_libraries(adios2_hello_bpStepsWriteReadKokkos adios2::cxx11 Kokkos::kokkos) + install(TARGETS adios2_hello_bpStepsWriteReadKokkos RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/examples/hello/bpStepsWriteReadKokkos/bpStepsWriteReadKokkos.cpp b/examples/hello/bpStepsWriteReadKokkos/bpStepsWriteReadKokkos.cpp new file mode 100644 index 0000000000..268d75adf3 --- /dev/null +++ b/examples/hello/bpStepsWriteReadKokkos/bpStepsWriteReadKokkos.cpp @@ -0,0 +1,146 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpStepsWriteReadKokkos.cpp Simple example of writing and reading bpFloats through ADIOS2 BP + * engine with multiple simulations steps for every IO step using Kokkos + */ +#include +#include +#include //std::invalid_argument std::exception +#include + +#include + +#include + +void writer(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int nSteps) +{ + // Initialize the simulation bpFloats with the default memory space + using mem_space = Kokkos::DefaultExecutionSpace::memory_space; + Kokkos::View gpuSimData("simBuffer", Nx); + Kokkos::parallel_for( + "initBuffer", Kokkos::RangePolicy(0, Nx), + KOKKOS_LAMBDA(int i) { gpuSimData(i) = static_cast(i); }); + Kokkos::fence(); + + // Set up the ADIOS structures + adios2::IO bpIO = adios.DeclareIO("WriteIO"); + bpIO.SetEngine(engine); + + const adios2::Dims shape{static_cast(Nx)}; + const adios2::Dims start{static_cast(0)}; + const adios2::Dims count{Nx}; + auto bpFloats = bpIO.DefineVariable("bpFloats", shape, start, count); + auto bpStep = bpIO.DefineVariable("bpStep"); + + adios2::Engine bpWriter = bpIO.Open(fname, adios2::Mode::Write); + + // Simulation steps + for (unsigned int step = 0; step < nSteps; ++step) + { + // Make a 1D selection to describe the local dimensions of the + // variable we write and its offsets in the global spaces + adios2::Box sel({0}, {Nx}); + bpFloats.SetSelection(sel); + + // Start IO step every write step + bpWriter.BeginStep(); + bpWriter.Put(bpFloats, gpuSimData.data()); + bpWriter.Put(bpStep, step); + bpWriter.EndStep(); + + // Update values in the simulation bpFloats using the default + // execution space + Kokkos::parallel_for( + "updateBuffer", Kokkos::RangePolicy(0, Nx), + KOKKOS_LAMBDA(int i) { gpuSimData(i) += 10; }); + Kokkos::fence(); + } + + bpWriter.Close(); + Kokkos::DefaultExecutionSpace exe_space; + std::cout << "Done writing on memory space: " << exe_space.name() << std::endl; +} + +void reader(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int /*nSteps*/) +{ + // Create ADIOS structures + adios2::IO bpIO = adios.DeclareIO("ReadIO"); + bpIO.SetEngine(engine); + + Kokkos::DefaultExecutionSpace exe_space; + std::cout << "Read on memory space: " << exe_space.name() << std::endl; + + adios2::Engine bpReader = bpIO.Open(fname, adios2::Mode::Read); + + using mem_space = Kokkos::DefaultExecutionSpace::memory_space; + Kokkos::View gpuSimData("simBuffer", Nx); + unsigned int inStep = 0; + for (unsigned int step = 0; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) + { + auto bpFloats = bpIO.InquireVariable("bpFloats"); + if (bpFloats) + { + const adios2::Dims start{0}; + const adios2::Dims count{Nx}; + const adios2::Box sel(start, count); + bpFloats.SetSelection(sel); + + bpReader.Get(bpFloats, gpuSimData.data()); + } + auto bpStep = bpIO.InquireVariable("bpStep"); + if (bpStep) + { + bpReader.Get(bpStep, &inStep); + } + bpReader.EndStep(); + if (inStep != step) + { + std::cout << "ERROR: step mismatch\n"; + return; + } + } + + bpReader.Close(); +} + +int main(int argc, char **argv) +{ + Kokkos::initialize(argc, argv); + + const std::string engine = argv[1] ? argv[1] : "BPFile"; + std::cout << "Using engine " << engine << std::endl; + + const std::string filename = engine + "StepsWriteReadCuda.bp"; + const unsigned int nSteps = 10; + const unsigned int Nx = 6000; + try + { + /** ADIOS class factory of IO class objects */ + adios2::ADIOS adios; + + writer(adios, engine, filename, Nx, nSteps); + reader(adios, engine, filename, Nx, nSteps); + } + 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\n"; + std::cout << e.what() << "\n"; + } + Kokkos::finalize(); + + return 0; +} diff --git a/examples/hello/bpTimeWriter/bpTimeWriter.cpp b/examples/hello/bpTimeWriter/bpTimeWriter.cpp deleted file mode 100644 index 77e37389cc..0000000000 --- a/examples/hello/bpTimeWriter/bpTimeWriter.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * bpTimeWriter.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 //std::for_each -#include //std::ios_base::failure -#include //std::cout -#include -#include //std::invalid_argument std::exception -#include - -#include - -int main(int argc, char *argv[]) -{ - int provided; - - // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP - MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); - int rank, size; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - - // Application variable - std::vector 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 */ - adios2::ADIOS adios(MPI_COMM_WORLD); - - /// WRITE - { - /*** IO class object: settings and factory of Settings: Variables, - * Parameters, Transports, and Execution: Engines */ - adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); - bpIO.SetParameters({{"Threads", "2"}}); - - /** global array: name, { shape (total dimensions) }, { start - * (local) }, - * { count (local) }, all are constant dimensions */ - const unsigned int variablesSize = 10; - std::vector> bpFloats(variablesSize); - - adios2::Variable bpString = bpIO.DefineVariable("bpString"); - - for (unsigned int v = 0; v < variablesSize; ++v) - { - std::string namev("bpFloats"); - if (v < 10) - { - namev += "00"; - } - else if (v < 100) - { - namev += "0"; - } - namev += std::to_string(v); - - bpFloats[v] = bpIO.DefineVariable(namev, {size * Nx}, {rank * Nx}, {Nx}, - adios2::ConstantDims); - } - - /** global single value variable: name */ - adios2::Variable bpTimeStep = - bpIO.DefineVariable("timeStep"); - - /** Engine derived class, spawned to start IO operations */ - adios2::Engine bpWriter = bpIO.Open("myVector.bp", adios2::Mode::Write); - - for (unsigned int timeStep = 0; timeStep < 3; ++timeStep) - { - bpWriter.BeginStep(); - if (rank == 0) // global single value, only saved by rank 0 - { - bpWriter.Put(bpTimeStep, timeStep); - } - - // template type is optional, but recommended - for (unsigned int v = 0; v < variablesSize; ++v) - { - myFloats[0] = static_cast(v + timeStep); - // Note: Put is deferred, so all variables will see v == 9 - // and myFloats[0] == 9, 10, or 11 - bpWriter.Put(bpFloats[v], myFloats.data()); - } - const std::string myString("Hello from rank: " + std::to_string(rank) + - " and timestep: " + std::to_string(timeStep)); - - if (rank == 0) - { - bpWriter.Put(bpString, myString); - } - - bpWriter.EndStep(); - } - - bpWriter.Close(); - } - // MPI_Barrier(MPI_COMM_WORLD); - - if (false) - { /////////////////////READ - // if (rank == 0) - // { - adios2::IO ioReader = adios.DeclareIO("bpReader"); - - adios2::Engine bpReader = ioReader.Open("myVector.bp", adios2::Mode::Read); - - adios2::Variable bpFloats000 = ioReader.InquireVariable("bpFloats000"); - - adios2::Variable bpString = - ioReader.InquireVariable("bpString"); - - if (bpFloats000) - { - bpFloats000.SetSelection({{rank * Nx}, {Nx}}); - bpFloats000.SetStepSelection({2, 1}); - - std::vector data(bpFloats000.SelectionSize()); - bpReader.Get(bpFloats000, data.data(), adios2::Mode::Sync); - - std::cout << "Data timestep " << bpFloats000.StepsStart() << " from rank " << rank - << ": "; - for (const auto datum : data) - { - std::cout << datum << " "; - } - std::cout << "\n"; - } - else - { - std::cout << "Variable bpFloats000 not found\n"; - } - - if (bpString) - { - bpString.SetStepSelection({3, 1}); - - std::string myString; - bpReader.Get(bpString, myString, adios2::Mode::Sync); - std::cout << myString << "\n"; - } - - bpReader.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/bpTimeWriter.py b/examples/hello/bpTimeWriter/bpTimeWriter.py deleted file mode 100644 index 87afc7f1c1..0000000000 --- a/examples/hello/bpTimeWriter/bpTimeWriter.py +++ /dev/null @@ -1,51 +0,0 @@ -# -# Distributed under the OSI-approved Apache License, Version 2.0. See -# accompanying file Copyright.txt for details. -# -# bpTimeWriter.py -# Created on: Feb 2, 2017 -# Author: William F Godoy godoywf@ornl.gov - -from mpi4py import MPI -import adios2 -import numpy as np - - -# MPI -comm = MPI.COMM_WORLD -rank = comm.Get_rank() -size = comm.Get_size() - -# User data -myArray = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) -nx = myArray.size -time = np.array([0.0]) - -# ADIOS -adios = adios2.ADIOS(comm) - -# IO -bpIO = adios.DeclareIO("BPN2N") - -# Variables -bpArray = bpIO.DefineVariable( - "bpArray", myArray, [size * nx], [rank * nx], [nx], adios2.ConstantDims -) -bpTimeStep = bpIO.DefineVariable("bpTimeStep", time) - -# Engine -bpFileWriter = bpIO.Open("myArray.bp", adios2.Mode.Write) -# Doesn't work: bpFileWriter = bpIO.Open("myArray.bp", adios2.OpenModeWrite) -# Doesn't work: bpFileWriter = bpIO.Open("myArray.bp", adiosOpenModeWrite, -# MPI.COMM_WORLD) - - -for t in range(0, 10): - bpFileWriter.BeginStep() - if rank == 0: - time[0] = t - bpFileWriter.Put(bpTimeStep, time) - bpFileWriter.Put(bpArray, myArray) - bpFileWriter.EndStep() - -bpFileWriter.Close() diff --git a/examples/hello/bpTimeWriter/bpTimeWriter_nompi.cpp b/examples/hello/bpTimeWriter/bpTimeWriter_nompi.cpp deleted file mode 100644 index ddfd113fa4..0000000000 --- a/examples/hello/bpTimeWriter/bpTimeWriter_nompi.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * bpTimeWriter_nompi.cpp no mpi version of bpTimeWriter.cpp - * - * Created on: Feb 16, 2017 - * Author: William F Godoy godoywf@ornl.gov - */ - -#include //std::ios_base::failure -#include //std::cout -#include //std::invalid_argument std::exception -#include - -#include - -int main(int argc, char *argv[]) -{ - // Application variable - std::vector 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 */ - adios2::ADIOS adios; - - /*** IO class object: settings and factory of Settings: Variables, - * Parameters, Transports, and Execution: Engines */ - adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); - - /** name, { shape (total dimensions) }, { start (local) }, { count - * {local} } */ - adios2::Variable bpFloats = - bpIO.DefineVariable("bpFloats", {}, {}, {Nx}, adios2::ConstantDims); - - adios2::Variable bpTimeStep = bpIO.DefineVariable("timeStep"); - - /** Engine derived class, spawned to start IO operations */ - adios2::Engine bpWriter = bpIO.Open("myVector.bp", adios2::Mode::Write); - - for (unsigned int timeStep = 0; timeStep < 10; ++timeStep) - { - bpWriter.BeginStep(); - - // template type is optional but recommended - bpWriter.Put(bpTimeStep, timeStep); - - // modifying data - myFloats[0] = static_cast(timeStep); - bpWriter.Put(bpFloats, myFloats.data(), adios2::Mode::Sync); - - bpWriter.EndStep(); - } - - 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/bpWriteReadCuda/bpWriteReadCuda.cu b/examples/hello/bpWriteReadCuda/bpWriteReadCuda.cu deleted file mode 100644 index 5db837c79d..0000000000 --- a/examples/hello/bpWriteReadCuda/bpWriteReadCuda.cu +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - * - * Simple example of writing and reading data - * through ADIOS2 BP engine with multiple simulations steps - * for every IO step. - */ - -#include -#include -#include -#include - -#include - -#include - -__global__ void update_array(float *vect, int val) { vect[blockIdx.x] += val; } - -std::string engine("BPFile"); - -int BPWrite(const std::string fname, const size_t N, int nSteps, const std::string engine) -{ - // Initialize the simulation data - float *gpuSimData; - cudaMalloc(&gpuSimData, N * sizeof(float)); - cudaMemset(gpuSimData, 0, N); - - // Set up the ADIOS structures - adios2::ADIOS adios; - adios2::IO io = adios.DeclareIO("WriteIO"); - io.SetEngine(engine); - - // Declare an array for the ADIOS data of size (NumOfProcesses * N) - const adios2::Dims shape{static_cast(N)}; - const adios2::Dims start{static_cast(0)}; - const adios2::Dims count{N}; - auto data = io.DefineVariable("data", shape, start, count); - - adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); - - // Simulation steps - for (size_t step = 0; step < nSteps; ++step) - { - // Make a 1D selection to describe the local dimensions of the - // variable we write and its offsets in the global spaces - adios2::Box sel({0}, {N}); - data.SetSelection(sel); - - // Start IO step every write step - bpWriter.BeginStep(); - data.SetMemorySpace(adios2::MemorySpace::GPU); - bpWriter.Put(data, gpuSimData); - bpWriter.EndStep(); - - // Update values in the simulation data - update_array<<>>(gpuSimData, 10); - } - - bpWriter.Close(); - return 0; -} - -int BPRead(const std::string fname, const size_t N, int nSteps, const std::string engine) -{ - // Create ADIOS structures - adios2::ADIOS adios; - adios2::IO io = adios.DeclareIO("ReadIO"); - io.SetEngine(engine); - - adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read); - - unsigned int step = 0; - float *gpuSimData; - cudaMalloc(&gpuSimData, N * sizeof(float)); - cudaMemset(gpuSimData, 0, N); - for (; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) - { - auto data = io.InquireVariable("data"); - std::vector simData(N); - const adios2::Dims start{0}; - const adios2::Dims count{N}; - const adios2::Box sel(start, count); - data.SetSelection(sel); - - data.SetMemorySpace(adios2::MemorySpace::GPU); - bpReader.Get(data, gpuSimData); //, adios2::Mode::Deferred); - bpReader.EndStep(); - cudaMemcpy(simData.data(), gpuSimData, N * sizeof(float), cudaMemcpyDeviceToHost); - std::cout << "Simualation step " << step << " : "; - std::cout << simData.size() << " elements: " << simData[1] << std::endl; - } - bpReader.Close(); - return 0; -} - -int main(int argc, char **argv) -{ - if (argv[1]) - engine = argv[1]; - std::cout << "Using engine " << engine << std::endl; - - const std::string fname("Cuda" + engine + "wr.bp"); - const int device_id = 1; - cudaSetDevice(device_id); - const size_t N = 6000; - int nSteps = 10, ret = 0; - - ret += BPWrite(fname, N, nSteps, engine); - ret += BPRead(fname, N, nSteps, engine); - return ret; -} diff --git a/examples/hello/bpWriteReadHip/bpWriteReadHip.cpp b/examples/hello/bpWriteReadHip/bpWriteReadHip.cpp deleted file mode 100644 index 755bb3f735..0000000000 --- a/examples/hello/bpWriteReadHip/bpWriteReadHip.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - */ -#include -#include -#include -#include - -#include - -#include - -__global__ void hip_initialize(float *vec) { vec[hipBlockIdx_x] = hipBlockIdx_x; } - -__global__ void hip_increment(float *vec, float val) { vec[hipBlockIdx_x] += val; } - -int BPWrite(const std::string fname, const size_t N, int nSteps, const std::string engine) -{ - hipError_t hipExit; - float *gpuSimData; - hipExit = hipMalloc((void **)&gpuSimData, N * sizeof(float)); - if (hipExit != hipSuccess) - { - std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; - return 1; - } - hipLaunchKernelGGL(hip_initialize, dim3(N), dim3(1), 0, 0, gpuSimData); - hipExit = hipDeviceSynchronize(); - if (hipExit != hipSuccess) - { - std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; - return 1; - } - - adios2::ADIOS adios; - adios2::IO io = adios.DeclareIO("WriteIO"); - io.SetEngine(engine); - - const adios2::Dims shape{static_cast(N)}; - const adios2::Dims start{static_cast(0)}; - const adios2::Dims count{N}; - auto data = io.DefineVariable("data", shape, start, count); - - adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); - - for (size_t step = 0; step < nSteps; ++step) - { - adios2::Box sel({0}, {N}); - data.SetSelection(sel); - - bpWriter.BeginStep(); - bpWriter.Put(data, gpuSimData); - bpWriter.EndStep(); - - hipLaunchKernelGGL(hip_increment, dim3(N), dim3(1), 0, 0, gpuSimData, 10); - hipExit = hipDeviceSynchronize(); - if (hipExit != hipSuccess) - { - std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; - return 1; - } - } - - bpWriter.Close(); - return 0; -} - -int BPRead(const std::string fname, const size_t N, int nSteps, const std::string engine) -{ - hipError_t hipExit; - adios2::ADIOS adios; - adios2::IO io = adios.DeclareIO("ReadIO"); - io.SetEngine(engine); - - adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read); - - unsigned int step = 0; - float *gpuSimData; - hipExit = hipMalloc((void **)&gpuSimData, N * sizeof(float)); - if (hipExit != hipSuccess) - { - std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; - return 1; - } - for (; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) - { - auto data = io.InquireVariable("data"); - const adios2::Dims start{0}; - const adios2::Dims count{N}; - const adios2::Box sel(start, count); - data.SetSelection(sel); - - bpReader.Get(data, gpuSimData); - bpReader.EndStep(); - - std::vector cpuData(N); - hipExit = hipMemcpy(cpuData.data(), gpuSimData, N * sizeof(float), hipMemcpyDeviceToHost); - if (hipExit != hipSuccess) - { - std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; - return 1; - } - std::cout << "Simualation step " << step << " : "; - std::cout << cpuData.size() << " elements: " << cpuData[0]; - std::cout << " " << cpuData[1] << " ... "; - std::cout << cpuData[cpuData.size() - 1] << std::endl; - } - bpReader.Close(); - return 0; -} - -int main(int argc, char **argv) -{ - hipError_t hipExit; - const int device_id = 0; - hipExit = hipSetDevice(device_id); - if (hipExit != hipSuccess) - { - std::cout << "[BPWrite] error: " << hipGetErrorString(hipExit) << std::endl; - return 1; - } - const std::vector list_of_engines = {"BPFile"}; - const size_t N = 6000; - int nSteps = 2, ret = 0; - - for (auto engine : list_of_engines) - { - std::cout << "Using engine " << engine << std::endl; - const std::string fname(engine + "_HIP_WR.bp"); - ret += BPWrite(fname, N, nSteps, engine); - ret += BPRead(fname, N, nSteps, engine); - } - return ret; -} diff --git a/examples/hello/bpWriteReadKokkos/bpWriteReadKokkos.cpp b/examples/hello/bpWriteReadKokkos/bpWriteReadKokkos.cpp deleted file mode 100644 index fd972ed9b0..0000000000 --- a/examples/hello/bpWriteReadKokkos/bpWriteReadKokkos.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Distributed under the OSI-approved Apache License, Version 2.0. See - * accompanying file Copyright.txt for details. - */ -#include -#include -#include - -#include - -#include - -int BPWrite(const std::string fname, const size_t N, int nSteps, const std::string engine) -{ - // Initialize the simulation data with the default memory space - using mem_space = Kokkos::DefaultExecutionSpace::memory_space; - Kokkos::View gpuSimData("simBuffer", N); - Kokkos::parallel_for( - "initBuffer", Kokkos::RangePolicy(0, N), - KOKKOS_LAMBDA(int i) { gpuSimData(i) = static_cast(i); }); - Kokkos::fence(); - - // Set up the ADIOS structures - adios2::ADIOS adios; - adios2::IO io = adios.DeclareIO("WriteIO"); - io.SetEngine(engine); - - const adios2::Dims shape{static_cast(N)}; - const adios2::Dims start{static_cast(0)}; - const adios2::Dims count{N}; - auto data = io.DefineVariable("data", shape, start, count); - - adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); - - // Simulation steps - for (int step = 0; step < nSteps; ++step) - { - // Make a 1D selection to describe the local dimensions of the - // variable we write and its offsets in the global spaces - adios2::Box sel({0}, {N}); - data.SetSelection(sel); - - // Start IO step every write step - bpWriter.BeginStep(); - bpWriter.Put(data, gpuSimData.data()); - bpWriter.EndStep(); - - // Update values in the simulation data using the default - // execution space - Kokkos::parallel_for( - "updateBuffer", Kokkos::RangePolicy(0, N), - KOKKOS_LAMBDA(int i) { gpuSimData(i) += 10; }); - Kokkos::fence(); - } - - bpWriter.Close(); - Kokkos::DefaultExecutionSpace exe_space; - std::cout << "Done writing on memory space: " << exe_space.name() << std::endl; - return 0; -} - -int BPRead(const std::string fname, const size_t N, int nSteps, const std::string engine) -{ - // Create ADIOS structures - adios2::ADIOS adios; - adios2::IO io = adios.DeclareIO("ReadIO"); - io.SetEngine(engine); - - Kokkos::DefaultExecutionSpace exe_space; - std::cout << "Read on memory space: " << exe_space.name() << std::endl; - - adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read); - - unsigned int step = 0; - using mem_space = Kokkos::DefaultExecutionSpace::memory_space; - Kokkos::View gpuSimData("simBuffer", N); - for (; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) - { - auto data = io.InquireVariable("data"); - const adios2::Dims start{0}; - const adios2::Dims count{N}; - const adios2::Box sel(start, count); - data.SetSelection(sel); - - bpReader.Get(data, gpuSimData.data()); - bpReader.EndStep(); - - auto cpuData = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, gpuSimData); - std::cout << "Simualation step " << step << " : "; - std::cout << cpuData.size() << " elements: " << cpuData[0]; - std::cout << " " << cpuData[1] << " ... "; - std::cout << cpuData[cpuData.size() - 1] << std::endl; - } - - bpReader.Close(); - return 0; -} - -int main(int argc, char **argv) -{ - const std::vector list_of_engines = {"BPFile"}; - const size_t N = 6000; - int nSteps = 2, ret = 0; - - Kokkos::initialize(argc, argv); - { - for (auto engine : list_of_engines) - { - std::cout << "Using engine " << engine << std::endl; - const std::string fname(engine + "_Kokkos_WR.bp"); - ret += BPWrite(fname, N, nSteps, engine); - ret += BPRead(fname, N, nSteps, engine); - } - } - Kokkos::finalize(); - return ret; -} From 23e3223b47296a7015eb6d1056ee5d3fd031429b Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Tue, 24 Oct 2023 09:58:15 -0400 Subject: [PATCH 10/16] Add Tutorials' Overview section --- docs/user_guide/source/index.rst | 7 ++++++- docs/user_guide/source/tutorials/overview.rst | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 docs/user_guide/source/tutorials/overview.rst diff --git a/docs/user_guide/source/index.rst b/docs/user_guide/source/index.rst index 867f184184..301931fe24 100644 --- a/docs/user_guide/source/index.rst +++ b/docs/user_guide/source/index.rst @@ -40,7 +40,12 @@ Funded by the `Exascale Computing Project (ECP) Date: Tue, 24 Oct 2023 10:06:51 -0400 Subject: [PATCH 11/16] Add Tutorials' Download and Build section --- docs/user_guide/source/index.rst | 1 + .../source/setting_up/source/cmake.rst | 2 + .../source/tutorials/downloadAndBuild.rst | 42 +++++++++++++++++++ docs/user_guide/source/tutorials/overview.rst | 2 + 4 files changed, 47 insertions(+) create mode 100644 docs/user_guide/source/tutorials/downloadAndBuild.rst diff --git a/docs/user_guide/source/index.rst b/docs/user_guide/source/index.rst index 301931fe24..f534a9e870 100644 --- a/docs/user_guide/source/index.rst +++ b/docs/user_guide/source/index.rst @@ -45,6 +45,7 @@ Funded by the `Exascale Computing Project (ECP) `_ for building, testing and installing the library and utilities. + So you need to have CMake installed on your system. + +Then, create a build directory, run CMake, and build ADIOS2: + +.. code-block:: bash + + cd ADIOS2 + mkdir build + cd build + cmake -DADIOS2_USE_MPI=ON .. + cmake --build . + +.. note:: + + If you want to know more about the ADIOS2's CMake options, see section + :ref:`CMake Options `. + +All the tutorials that we will explore are existing ADIOS2 examples located in the ``ADIOS2/examples`` directory. + +To build any of the examples, e.g. the ``helloWorld`` example, you can run the following commands: + +.. code-block:: bash + + cd Path-To-ADIOS2/examples/hello/helloWorld + mkdir build + cd build + cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ .. + cmake --build . diff --git a/docs/user_guide/source/tutorials/overview.rst b/docs/user_guide/source/tutorials/overview.rst index 6bb7aa5970..3eeafd3501 100644 --- a/docs/user_guide/source/tutorials/overview.rst +++ b/docs/user_guide/source/tutorials/overview.rst @@ -4,3 +4,5 @@ Overview In this tutorial we will learn about how to build ADIOS2, and go through several tutorials explaining basic topics. More specifically, we will go through the following examples: + +1. :ref:`Download And Build ` From 3288ed1d34c327c613131fafdbde138273f291be Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Tue, 24 Oct 2023 10:12:05 -0400 Subject: [PATCH 12/16] Add Hello World Tutorial --- docs/user_guide/source/index.rst | 1 + .../source/tutorials/basicTutorials.rst | 6 + .../source/tutorials/helloWorld.rst | 143 ++++++++++++++++++ docs/user_guide/source/tutorials/overview.rst | 3 + .../hello-world_tutorialSkeleton.cpp | 39 +++++ 5 files changed, 192 insertions(+) create mode 100644 docs/user_guide/source/tutorials/basicTutorials.rst create mode 100644 docs/user_guide/source/tutorials/helloWorld.rst create mode 100644 examples/hello/helloWorld/hello-world_tutorialSkeleton.cpp diff --git a/docs/user_guide/source/index.rst b/docs/user_guide/source/index.rst index f534a9e870..c976e6826d 100644 --- a/docs/user_guide/source/index.rst +++ b/docs/user_guide/source/index.rst @@ -46,6 +46,7 @@ Funded by the `Exascale Computing Project (ECP) `_. + + +1. We create an ADIOS instance, and define the greeting message in our main function as follows: + +.. code-block:: c++ + + int main() + { + adios2::ADIOS adios(); + const std::string greeting("Hello World from ADIOS2"); + ... + return 0; + } + +2. Then we create a writer function in which we pass the adios instance, and the greeting message as follows: + +.. code-block:: c++ + + void writer(adios2::ADIOS& adios, const std::string& greeting) + { + ... + } + +3. In this writer function, we define an IO object, a string variable for the message as follows: + +.. code-block:: c++ + + adios2::IO io = adios.DeclareIO("hello-world-writer"); + adios2::Variable varGreeting = io.DefineVariable("Greeting"); + +.. note:: + + Using the IO object, we can define the engine type that we want to utilize using the *io.SetEngine()* function. + If *SetEngine()* is not used, the default engine type is *BPFile* which is an alias for the latest version of the BP + engine of the ADIOS2 library. See :ref:`Available Engines` and :ref:`Supported Engines` for more information. + It's important to note that the file extension of an output file, although it's not a good practice, it can differ + from the engine type, e.g. write a foo.h5 file with the BPFile engine. When reading foo.h5 you should explicitly + specify the engine type as BPFile to read it properly. + +4. Then we open a file with the name "hello-world-cpp.bp" and write the greeting message to it as follows: + +.. code-block:: c++ + + adios2::Engine writer = io.Open("hello-world-cpp.bp", adios2::Mode::Write); + writer.BeginStep(); + writer.Put(varGreeting, greeting); + writer.EndStep(); + writer.Close(); + +.. note:: + + The ``BeginStep`` and ``EndStep`` calls are optional when **writing** one step, but they are required + for multiple steps, so it is a good practice to always use them. + +5. Now we create a reader function in which we pass the adios instance, and get the greeting message back as follows: + +.. code-block:: c++ + + std::string reader(adios2::ADIOS& adios) + { + ... + } + +6. In this reader function, we define an IO object and inquire a string variable for the message as follows: + +.. code-block:: c++ + + adios2::IO io = adios.DeclareIO("hello-world-reader"); + reader.BeginStep(); + adios2::Variable varGreeting = io.InquireVariable("Greeting"); + +7. Then we open the file with the name "hello-world-cpp.bp", read the greeting message from it and return it as follows: + +.. code-block:: c++ + + adios2::Engine reader = io.Open("hello-world-cpp.bp", adios2::Mode::Read); + std::string greeting; + reader.Get(varGreeting, greeting); + reader.EndStep(); + reader.Close(); + return greeting; + +.. note:: + + The ``BeginStep`` and ``EndStep`` calls are required when **reading** one step and multiple steps. We will see in + another tutorial how to read multiple steps. It's important to note that the ``BeginStep`` should be called **before** + all ``Inquire*`` / ``Available*`` function calls. + +8. Finally, we call the writer and reader functions in our main function as follows: + +.. code-block:: c++ + + int main() + { + adios2::ADIOS adios(); + const std::string greeting("Hello World from ADIOS2"); + writer(adios, greeting); + std::string message = reader(adios); + std::cout << message << std::endl; + return 0; + } + +9. The final code should look as follows (excluding try/catch and the optional usage of MPI), and it was derived from + the example `ADIOS2/examples/hello/helloWorld/hello-world.cpp `_. + +.. literalinclude:: ../../../../examples/hello/helloWorld/hello-world.cpp + :language: cpp + +10. You can compile and run it as follows: + +.. code-block:: bash + + cd Path-To-ADIOS2/examples/hello/helloWorld + mkdir build + cd build + cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ .. + cmake --build . + ./adios2_hello_helloWorld + +11. You can check the content of the output file "hello-world-cpp.bp" using *bpls* as follows: + +.. code-block:: bash + + Path-To-ADIOS2/build/bin/bpls ./hello-world-cpp.bp + + string Greeting scalar + +12. The Python version of this tutorial can be found at `ADIOS2/examples/hello/helloWorld/hello-world.py `_. + and it looks as follows: + +.. literalinclude:: ../../../../examples/hello/helloWorld/hello-world.py + :language: python diff --git a/docs/user_guide/source/tutorials/overview.rst b/docs/user_guide/source/tutorials/overview.rst index 3eeafd3501..82e2475b5b 100644 --- a/docs/user_guide/source/tutorials/overview.rst +++ b/docs/user_guide/source/tutorials/overview.rst @@ -6,3 +6,6 @@ In this tutorial we will learn about how to build ADIOS2, and go through several More specifically, we will go through the following examples: 1. :ref:`Download And Build ` +2. Basic tutorials: + + 1. :ref:`Hello World ` diff --git a/examples/hello/helloWorld/hello-world_tutorialSkeleton.cpp b/examples/hello/helloWorld/hello-world_tutorialSkeleton.cpp new file mode 100644 index 0000000000..df89e385e3 --- /dev/null +++ b/examples/hello/helloWorld/hello-world_tutorialSkeleton.cpp @@ -0,0 +1,39 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * hello-world.cpp : adios2 low-level API example to write and read a + * std::string Variable with a greeting + * + * Created on: Nov 14, 2019 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include +#include + +#include + +void writer(adios2::ADIOS &adios, const std::string &greeting) +{ + // Add code +} + +std::string reader(adios2::ADIOS &adios) +{ + // Add code +} + +int main(int argc, char *argv[]) +{ + try + { + // Add code + } + catch (std::exception &e) + { + std::cout << "ERROR: ADIOS2 exception: " << e.what() << "\n"; + } + + return 0; +} From 2a8e2e3399c62998cfbddcd579ee04e4e1b7d8ce Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Tue, 31 Oct 2023 11:37:22 -0400 Subject: [PATCH 13/16] Add Variables Tutorial --- docs/user_guide/source/components/engine.rst | 10 +- .../source/tutorials/basicTutorials.rst | 3 +- docs/user_guide/source/tutorials/overview.rst | 1 + .../user_guide/source/tutorials/variables.rst | 246 ++++++++++++++++++ .../bpReader/bpReader_tutorialSkeleton.cpp | 76 ++++++ .../bpWriter/bpWriter_tutorialSkeleton.cpp | 61 +++++ 6 files changed, 392 insertions(+), 5 deletions(-) create mode 100644 docs/user_guide/source/tutorials/variables.rst create mode 100644 examples/hello/bpReader/bpReader_tutorialSkeleton.cpp create mode 100644 examples/hello/bpWriter/bpWriter_tutorialSkeleton.cpp diff --git a/docs/user_guide/source/components/engine.rst b/docs/user_guide/source/components/engine.rst index f20b854589..4a5377e3c9 100644 --- a/docs/user_guide/source/components/engine.rst +++ b/docs/user_guide/source/components/engine.rst @@ -2,6 +2,8 @@ Engine ****** +.. _sec:basics_interface_components_engine: + The Engine abstraction component serves as the base interface to the actual IO systems executing the heavy-load tasks performed when producing and consuming data. Engine functionality works around two concepts: @@ -361,13 +363,13 @@ The following table summarizes the memory contracts required by ADIOS2 engines b +----------+-------------+-----------------------------------------------+ | Get | Data Memory | Contract | +----------+-------------+-----------------------------------------------+ -| | Pointer | do not modify until PerformPuts/EndStep/Close | +| | Pointer | do not modify until PerformGets/EndStep/Close | | Deferred | | | -| | Contents | populated at Put or PerformPuts/EndStep/Close | +| | Contents | populated at Get or PerformGets/EndStep/Close | +----------+-------------+-----------------------------------------------+ -| | Pointer | modify after Put | +| | Pointer | modify after Get | | Sync | | | -| | Contents | populated at Put | +| | Contents | populated at Get | +----------+-------------+-----------------------------------------------+ diff --git a/docs/user_guide/source/tutorials/basicTutorials.rst b/docs/user_guide/source/tutorials/basicTutorials.rst index cc7f828577..59e082a07e 100644 --- a/docs/user_guide/source/tutorials/basicTutorials.rst +++ b/docs/user_guide/source/tutorials/basicTutorials.rst @@ -3,4 +3,5 @@ Basic Tutorials .. toctree:: - helloWorld \ No newline at end of file + helloWorld + variables diff --git a/docs/user_guide/source/tutorials/overview.rst b/docs/user_guide/source/tutorials/overview.rst index 82e2475b5b..964622079d 100644 --- a/docs/user_guide/source/tutorials/overview.rst +++ b/docs/user_guide/source/tutorials/overview.rst @@ -9,3 +9,4 @@ More specifically, we will go through the following examples: 2. Basic tutorials: 1. :ref:`Hello World ` + 2. :ref:`Variables ` diff --git a/docs/user_guide/source/tutorials/variables.rst b/docs/user_guide/source/tutorials/variables.rst new file mode 100644 index 0000000000..1d05acf8b3 --- /dev/null +++ b/docs/user_guide/source/tutorials/variables.rst @@ -0,0 +1,246 @@ +Variables +========= + +.. _sec:tutorials_basics_variables: + +In the previous tutorial we learned how to define a simple string variable, write it, and read it back. + +In this tutorial we will go two steps further: + +1. We will define variables which include arrays, and we will write them and read them back. +2. We will use MPI to write and read the above variables in parallel. + +Let's start with the writing part. + +Start editing the skeleton file `ADIOS2/examples/hello/bpWriter/bpWriter_tutorialSkeleton.cpp `_. + +1. In an MPI application first we need to always initialize MPI. We do that with the following lines: + +.. code-block:: cpp + + int rank, size; + int provided; + + // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + +2. Now we need to create some application variables which will be used to define ADIOS2 variables. + +.. code-block:: cpp + + // Application variable + std::vector myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + std::vector myInts = {0, -1, -2, -3, -4, -5, -6, -7, -8, -9}; + const std::size_t Nx = myFloats.size(); + const std::string myString("Hello Variable String from rank " + std::to_string(rank)); + +3. Now we need to define an ADIOS2 instance and the ADIOS2 variables. + +.. code-block:: cpp + + adios2::ADIOS adios(MPI_COMM_WORLD); + adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); + + adios2::Variable bpFloats = bpIO.DefineVariable( + "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios2::ConstantDims); + + adios2::Variable bpInts = bpIO.DefineVariable("bpInts", {size * Nx}, {rank * Nx}, + {Nx}, adios2::ConstantDims); + + // For the sake of the tutorial we create an unused variable + adios2::Variable bpString = bpIO.DefineVariable("bpString"); + +.. note:: + + The above int/float variables are global arrays. The 1st argument of the ``DefineVariable`` function is the variable + name, the 2nd are the global dimensions, the 3rd is the start index for a rank, the 4th are the rank/local + dimensions, and the 5th is a boolean variable to indicate if the dimensions are constant or not over multiple steps, + where ``adios2::ConstantDims == true`` We will explore other tutorials that don't use constant dimensions. + +4. Now we need to open the ADIOS2 engine and write the variables. + +.. code-block:: cpp + + adios2::Engine bpWriter = bpIO.Open("myVector_cpp.bp", adios2::Mode::Write); + + bpWriter.BeginStep(); + bpWriter.Put(bpFloats, myFloats.data()); + bpWriter.Put(bpInts, myInts.data()); + // bpWriter.Put(bpString, myString); + bpWriter.EndStep(); + + bpWriter.Close(); + +5. Finally we need to finalize MPI. + +.. code-block:: cpp + + MPI_Finalize(); + +6. The final code should look as follows (excluding try/catch and the optional usage of MPI), and it was derived + from the example `ADIOS2/examples/hello/bpWriter/bpWriter.cpp `_. + +.. literalinclude:: ../../../../examples/hello/bpWriter/bpWriter.cpp + :language: cpp + +7. You can compile and run it as follows: + +.. code-block:: bash + + cd Path-To-ADIOS2/examples/hello/bpWriter + mkdir build + cd build + cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ .. + cmake --build . + mpirun -np 2 ./adios2_hello_bpWriter_mpi + +8. You can check the content of the output file "myVector_cpp.bp" using *bpls* as follows: + +.. code-block:: bash + + Path-To-ADIOS2/build/bin/bpls ./myVector_cpp.bp + + float bpFloats {10} + int32_t bpInts {10} + +Now let's move to the reading part. + +Start editing the skeleton file `ADIOS2/examples/hello/bpReader/bpReader_tutorialSkeleton.cpp `_. + +9. In an MPI application first we need to always initialize MPI. We do that with the following line: + +.. code-block:: cpp + + int rank, size; + int provided; + + // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + +10. Now we need to define an ADIOS2 instance and open the ADIOS2 engine. + +.. code-block:: cpp + + adios2::ADIOS adios(MPI_COMM_WORLD); + + adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); + + adios2::Engine bpReader = bpIO.Open("myVector_cpp.bp", adios2::Mode::Read); + +11. Now we need to read the variables. In this case we know the variables that we need to inquire, so we can use the + ``InquireVariable`` function immediately. But let's explore how to check the available variables in a file first, + and then we will use the ``InquireVariable`` function. + +.. code-block:: cpp + + bpReader.BeginStep(); + const std::map variables = bpIO.AvailableVariables(); + + for (const auto &variablePair : variables) + { + std::cout << "Name: " << variablePair.first; + for (const auto ¶meter : variablePair.second) + { + std::cout << "\t" << parameter.first << ": " << parameter.second << "\n"; + } + } + + adios2::Variable bpFloats = bpIO.InquireVariable("bpFloats"); + adios2::Variable bpInts = bpIO.InquireVariable("bpInts"); + +12. Now we need to read the variables from each rank. We will use the ``SetSelection`` to set the start index and rank + dimensions, then ``Get`` function to read the variables, and print the contents from rank 0. + +.. code-block:: cpp + + const std::size_t Nx = 10; + if (bpFloats) // means found + { + std::vector myFloats; + + // read only the chunk corresponding to our rank + bpFloats.SetSelection({{Nx * rank}, {Nx}}); + bpReader.Get(bpFloats, myFloats, adios2::Mode::Sync); + + if (rank == 0) + { + std::cout << "MyFloats: \n"; + for (const auto number : myFloats) + { + std::cout << number << " "; + } + std::cout << "\n"; + } + } + + if (bpInts) // means not found + { + std::vector myInts; + // read only the chunk corresponding to our rank + bpInts.SetSelection({{Nx * rank}, {Nx}}); + + bpReader.Get(bpInts, myInts, adios2::Mode::Sync); + + if (rank == 0) + { + std::cout << "myInts: \n"; + for (const auto number : myInts) + { + std::cout << number << " "; + } + std::cout << "\n"; + } + } + +.. note:: + + While using the ``Get`` function, we used the third parameter named ``Mode``. The mode parameter can also be used + for the ``Put`` function. + + For the ``Put`` function, there are three modes: ``Deferred`` (default), ``Sync``, and ``Span``. and for the ``Get`` + there are two modes: ``Deferred`` (default) and ``Sync``. + + 1. The ``Deferred`` mode is the default mode, because it is the fastest mode, as it allows ``Put`` / ``Get`` to be + grouped before potential data transport at the first encounter of ``PerformPuts`` / ``PerformGets``, ``EndStep`` + or ``Close``. + + 2. The ``Sync`` mode forces ``Put`` / ``Get`` to be performed immediately so that the data are available immediately. + + 3. The ``Span`` mode is special mode of ``Deferred`` that allows population from non-contiguous memory structures. + + For more information about the ``Mode`` parameter for both ``Put`` and ``Get`` functions, and when you should use + each option see :ref:`Basics: Interface Components: Engine `. + +13. Now we need close the ADIOS2 engine. + +.. code-block:: cpp + + bpReader.EndStep(); + bpReader.Close(); + +14. Finally we need to finalize MPI. + +.. code-block:: cpp + + MPI_Finalize(); + +15. The final code should look as follows (excluding try/catch), and it was derived from the example + `ADIOS2/examples/hello/bpWriter/bpWriter.cpp `_. + +.. literalinclude:: ../../../../examples/hello/bpReader/bpReader.cpp + :language: cpp + +16. You can compile and run it as follows: + +.. code-block:: bash + + cd Path-To-ADIOS2/examples/hello/bpReader + mkdir build + cd build + cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ .. + cmake --build . + mpirun -np 2 ./adios2_hello_bpReader_mpi diff --git a/examples/hello/bpReader/bpReader_tutorialSkeleton.cpp b/examples/hello/bpReader/bpReader_tutorialSkeleton.cpp new file mode 100644 index 0000000000..d0f4713ec3 --- /dev/null +++ b/examples/hello/bpReader/bpReader_tutorialSkeleton.cpp @@ -0,0 +1,76 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpReader.cpp: Simple self-descriptive example of how to read a variable + * from a BP File. + * + * Created on: Feb 16, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ +#include //std::ios_base::failure +#include //std::cout +#include +#include //std::invalid_argument std::exception +#include + +#include + +int main(int argc, char *argv[]) +{ + int rank, size; + int provided; + + // Add code to init MPI + try + { + // Add code to create ADIOS object + + // Add code to create IO object + + // Add code to open file + + // Add code to inquire variables and optionally check all available variables + + // Add code to read variables + + // Add code to close file + } + catch (std::invalid_argument &e) + { + if (rank == 0) + { + std::cerr << "Invalid argument exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cerr << e.what() << "\n"; + } + MPI_Abort(MPI_COMM_WORLD, 1); + } + catch (std::ios_base::failure &e) + { + if (rank == 0) + { + std::cerr << "IO System base failure exception, STOPPING PROGRAM " + "from rank " + << rank << "\n"; + std::cerr << e.what() << "\n"; + std::cerr << "The file myVector_cpp.bp does not exist." + << " Presumably this is because adios2_hello_bpWriter has not " + "been run." + << " Run ./adios2_hello_bpWriter before running this program.\n"; + } + MPI_Abort(MPI_COMM_WORLD, 1); + } + catch (std::exception &e) + { + if (rank == 0) + { + std::cerr << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cerr << e.what() << "\n"; + } + MPI_Abort(MPI_COMM_WORLD, 1); + } + + MPI_Finalize(); + + return 0; +} diff --git a/examples/hello/bpWriter/bpWriter_tutorialSkeleton.cpp b/examples/hello/bpWriter/bpWriter_tutorialSkeleton.cpp new file mode 100644 index 0000000000..d24a7f9bfe --- /dev/null +++ b/examples/hello/bpWriter/bpWriter_tutorialSkeleton.cpp @@ -0,0 +1,61 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpWriter.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: William F Godoy godoywf@ornl.gov + */ + +#include //std::ios_base::failure +#include //std::cout +#include //std::invalid_argument std::exception +#include + +#include +#include + +int main(int argc, char *argv[]) +{ + int rank, size; + int provided; + // Add code to init MPI + + // Add code to create arrays + try + { + // Add code to create ADIOS object + + // Add code to create IO object + + // Add code to create variables + + // Add code to open file + + // Add code to write variables + + // Add code to close file + } + catch (std::invalid_argument &e) + { + std::cerr << "Invalid argument exception: " << e.what() << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); + } + catch (std::ios_base::failure &e) + { + std::cerr << "IO System base failure exception: " << e.what() << "\n"; + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + } + catch (std::exception &e) + { + std::cerr << "Exception: " << e.what() << "\n"; + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); + } + + // Add code to finalize MPI + + return 0; +} From f3e74435cc2f865e24d160791968db1cf1cfe149 Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Tue, 24 Oct 2023 16:02:00 -0400 Subject: [PATCH 14/16] Add Attributes Tutorial --- .../source/tutorials/attributes.rst | 230 ++++++++++++++++++ .../source/tutorials/basicTutorials.rst | 1 + docs/user_guide/source/tutorials/overview.rst | 3 +- .../bpAttributeWriteRead_tutorialSkeleton.cpp | 91 +++++++ 4 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 docs/user_guide/source/tutorials/attributes.rst create mode 100644 examples/hello/bpAttributeWriteRead/bpAttributeWriteRead_tutorialSkeleton.cpp diff --git a/docs/user_guide/source/tutorials/attributes.rst b/docs/user_guide/source/tutorials/attributes.rst new file mode 100644 index 0000000000..802ca924dd --- /dev/null +++ b/docs/user_guide/source/tutorials/attributes.rst @@ -0,0 +1,230 @@ +Attributes +========== + +.. _sec:tutorials_basics_attributes: + +In the previous tutorial, we learned how to write/read variables. + +In this tutorial, we will explore how to write/read attributes. Attributes are metadata related to the whole dataset or +to a specific variable. In this tutorial, we will only focus on attributes related to the whole dataset, but we will +explain how variable's attributes can be used too. + +Start editing the skeleton file `ADIOS2/examples/hello/bpAttributeWriteRead/bpAttributeWriteRead_tutorialSkeleton.cpp `_. + +1. In an MPI application first we need to always initialize MPI. We do that with the following lines: + +.. code-block:: cpp + + int rank, size; + int provided; + + // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + +2. Now we need to create a application variable which will be used to define an ADIOS2 variable. + +.. code-block:: cpp + + std::vector myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + +3. Then, we need to create an ADIOS2 instance. + +.. code-block:: cpp + + adios2::ADIOS adios(MPI_COMM_WORLD); + +4. Then, we create the following writer function: + +.. code-block:: cpp + + void writer(adios2::ADIOS &adios, int rank, int size, std::vector &myFloats) + { + ... + } + +5. In this writer function, we define an IO object, and a float vector variable as follows: + +.. code-block:: cpp + + adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); + + const std::size_t Nx = myFloats.size(); + adios2::Variable bpFloats = bpIO.DefineVariable( + "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios2::ConstantDims); + +6. Now, we will define various types of attributes as follows: + +.. code-block:: cpp + + bpIO.DefineAttribute("Single_String", "File generated with ADIOS2"); + + std::vector myStrings = {"one", "two", "three"}; + bpIO.DefineAttribute("Array_of_Strings", myStrings.data(), myStrings.size()); + + bpIO.DefineAttribute("Attr_Double", 0.f); + std::vector myDoubles = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + bpIO.DefineAttribute("Array_of_Doubles", myDoubles.data(), myDoubles.size()); + +.. note:: + + if we want to define an attribute for a specific variable, we can use one of the following API: + + .. code-block:: cpp + + template + Attribute DefineAttribute(const std::string &name, const T *data, const size_t size, + const std::string &variableName = "", const std::string separator = "/", + const bool allowModification = false); + + template + Attribute DefineAttribute(const std::string &name, const T &value, + const std::string &variableName = "", const std::string separator = "/", + const bool allowModification = false); + + As we can see, by default the attributes don't change over multiple steps, but we can change that by setting + ``allowModification`` to ``true``. + +7. Then, we open a file for writing: + +.. code-block:: cpp + + adios2::Engine bpWriter = bpIO.Open("fileAttributes.bp", adios2::Mode::Write); + +8. Now, we write the data and close the file: + +.. code-block:: cpp + + bpWriter.BeginStep(); + bpWriter.Put(bpFloats, myFloats.data()); + bpWriter.EndStep(); + bpWriter.Close(); + +9. Steps 1-8 are used for writing, we will define a reader function in the rest of the steps: + +.. code-block:: cpp + + void reader(adios2::ADIOS &adios, int rank, int size) + { + ... + } + +10. In this reader function, we define an IO object, and open the file for reading: + +.. code-block:: cpp + + adios2::IO bpIO = adios.DeclareIO("BPFile_N2N"); + adios2::Engine bpReader = bpIO.Open("fileAttributes.bp", adios2::Mode::Read); + +11. Now, we check the available attributes as follows: + +.. code-block:: cpp + + bpReader.BeginStep(); + const auto attributesInfo = bpIO.AvailableAttributes(); + + for (const auto &attributeInfoPair : attributesInfo) + { + std::cout << "Attribute: " << attributeInfoPair.first; + for (const auto &attributePair : attributeInfoPair.second) + { + std::cout << "\tKey: " << attributePair.first << "\tValue: " << attributePair.second + << "\n"; + } + std::cout << "\n"; + } + +12. Now we will inquire and get the attributes as follows: + +.. code-block:: cpp + + adios2::Attribute singleString = bpIO.InquireAttribute("Single_String"); + if (singleString) + { + std::cout << singleString.Name() << ": " << singleString.Data()[0] << "\n"; + } + adios2::Attribute arrayOfStrings = + bpIO.InquireAttribute("Array_of_Strings"); + if (arrayOfStrings) + { + std::cout << arrayOfStrings.Name() << ": "; + for (const auto &value : arrayOfStrings.Data()) + { + std::cout << value << " "; + } + std::cout << "\n"; + } + adios2::Attribute attrDouble = bpIO.InquireAttribute("Attr_Double"); + if (attrDouble) + { + std::cout << attrDouble.Name() << ": " << attrDouble.Data()[0] << "\n"; + } + adios2::Attribute arrayOfDoubles = bpIO.InquireAttribute("Array_of_Doubles"); + if (arrayOfDoubles) + { + std::cout << arrayOfDoubles.Name() << ": "; + for (const auto &value : arrayOfDoubles.Data()) + { + std::cout << value << " "; + } + std::cout << "\n"; + } + +13. Afterward, we will inquire and get the variable as follows: + +.. code-block:: cpp + + adios2::Variable bpFloats = bpIO.InquireVariable("bpFloats"); + const std::size_t Nx = 10; + std::vector myFloats(Nx); + if (bpFloats) + { + bpFloats.SetSelection({{Nx * rank}, {Nx}}); + bpReader.Get(bpFloats, myFloats.data()); + } + bpReader.EndStep(); + +14. Finally, we close the file: + +.. code-block:: cpp + + bpReader.Close(); + +15. In the main function, we call the writer and reader functions as follows: + +.. code-block:: cpp + + writer(adios, rank, size, myFloats); + reader(adios, rank, size); + +16. Finally, we finalize MPI: + +.. code-block:: cpp + + MPI_Finalize(); + +17. The final code should look as follows (excluding try/catch and optional usage MPI), and it was derived from the + example `ADIOS2/examples/hello/bpAttributeWriteRead/bpAttributeWriteRead.cpp `_. + +.. literalinclude:: ../../../../examples/hello/bpAttributeWriteRead/bpAttributeWriteRead.cpp + :language: cpp + +18. You can compile and run it as follows: + +.. code-block:: bash + + cd Path-To-ADIOS2/examples/hello/bpAttributeWriteRead + mkdir build + cd build + cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ .. + cmake --build . + mpirun -np 2 ./adios2_hello_bpAttributeWriteRead_mpi + +19. You can check the content of the output file "fileAttributes.bp" using *bpls* as follows: + +.. code-block:: bash + + Path-To-ADIOS2/build/bin/bpls ./fileAttributes.bp + + float bpFloats {20} diff --git a/docs/user_guide/source/tutorials/basicTutorials.rst b/docs/user_guide/source/tutorials/basicTutorials.rst index 59e082a07e..ca7659408d 100644 --- a/docs/user_guide/source/tutorials/basicTutorials.rst +++ b/docs/user_guide/source/tutorials/basicTutorials.rst @@ -5,3 +5,4 @@ Basic Tutorials helloWorld variables + attributes diff --git a/docs/user_guide/source/tutorials/overview.rst b/docs/user_guide/source/tutorials/overview.rst index 964622079d..a1ad25909a 100644 --- a/docs/user_guide/source/tutorials/overview.rst +++ b/docs/user_guide/source/tutorials/overview.rst @@ -9,4 +9,5 @@ More specifically, we will go through the following examples: 2. Basic tutorials: 1. :ref:`Hello World ` - 2. :ref:`Variables ` + 2. :ref:`Array Variables ` + 3. :ref:`Attributes ` diff --git a/examples/hello/bpAttributeWriteRead/bpAttributeWriteRead_tutorialSkeleton.cpp b/examples/hello/bpAttributeWriteRead/bpAttributeWriteRead_tutorialSkeleton.cpp new file mode 100644 index 0000000000..ef78c5efe0 --- /dev/null +++ b/examples/hello/bpAttributeWriteRead/bpAttributeWriteRead_tutorialSkeleton.cpp @@ -0,0 +1,91 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpAttributeWriteRead.cpp: Simple self-descriptive example of how to write/read attributes and + * a variable to a BP File that lives in several MPI processes. + * + * Created on: Feb 16, 2017 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include //std::ios_base::failure +#include //std::cout +#include +#include //std::invalid_argument std::exception +#include +#include + +#include + +void writer(adios2::ADIOS &adios, int rank, int size, std::vector &myFloats) +{ + // Add code to create IO object + + // Add code to create variable + + // Add code to create attributes + + // Add code to open file + + // Add code to write variables + + // Add code to close file +} + +void reader(adios2::ADIOS &adios, int rank, int /*size*/) +{ + // Add code to create IO object + + // Add code to open file + + // add code to check available attributes + + // Add code to read attributes + + // Add code to read variables + + // Add code to close file +} + +int main(int argc, char *argv[]) +{ + int rank, size; + int provided; + + // Add code to init MPI + + // Add code to create array + try + { + // Add code to create ADIOS object + + // Call writer and reader functions + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); + } + catch (std::ios_base::failure &e) + { + std::cout << "IO System base failure exception, STOPPING PROGRAM from rank " << rank + << "\n"; + std::cout << e.what() << "\n"; + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n"; + std::cout << e.what() << "\n"; + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); + } + + // Add code to finalize MPI + + return 0; +} From c3349547a4c0752a4fe0abce4ee870607accff26 Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Mon, 30 Oct 2023 10:53:03 -0400 Subject: [PATCH 15/16] Add Operators Tutorial --- .../user_guide/source/components/operator.rst | 2 + .../source/tutorials/basicTutorials.rst | 1 + .../user_guide/source/tutorials/operators.rst | 156 ++++++++++++++++++ docs/user_guide/source/tutorials/overview.rst | 1 + .../bpOperatorSZWriter_tutorialSkeleton.cxx | 94 +++++++++++ 5 files changed, 254 insertions(+) create mode 100644 docs/user_guide/source/tutorials/operators.rst create mode 100644 examples/hello/bpOperatorSZWriter/bpOperatorSZWriter_tutorialSkeleton.cxx diff --git a/docs/user_guide/source/components/operator.rst b/docs/user_guide/source/components/operator.rst index 04f30bc686..d1fce6591a 100644 --- a/docs/user_guide/source/components/operator.rst +++ b/docs/user_guide/source/components/operator.rst @@ -2,6 +2,8 @@ Operator ******** +.. _sec:basics_interface_components_operator: + The Operator abstraction allows ADIOS2 to act upon the user application data, either from a ``adios2::Variable`` or a set of Variables in an ``adios2::IO`` object. Current supported operations are: diff --git a/docs/user_guide/source/tutorials/basicTutorials.rst b/docs/user_guide/source/tutorials/basicTutorials.rst index ca7659408d..fcac1ed85a 100644 --- a/docs/user_guide/source/tutorials/basicTutorials.rst +++ b/docs/user_guide/source/tutorials/basicTutorials.rst @@ -6,3 +6,4 @@ Basic Tutorials helloWorld variables attributes + operators diff --git a/docs/user_guide/source/tutorials/operators.rst b/docs/user_guide/source/tutorials/operators.rst new file mode 100644 index 0000000000..8fa400fb53 --- /dev/null +++ b/docs/user_guide/source/tutorials/operators.rst @@ -0,0 +1,156 @@ +Operators +========= + +.. _sec:tutorials_basics_operators: + +In the previous tutorial we learned how to write and read attributes. + +For this example to work, you would need to have the SZ compression library installed, which ADIOS automatically detects. +The easiest way to install SZ is with Spack, and you can do that as follows: + +.. code-block:: bash + + git clone https://github.com/spack/spack.git ~/spack + cd ~/spack + . share/spack/setup-env.sh + spack install sz + spack load sz + +In this tutorial we will learn how to use operators. Operators are used for Data compression/decompression, lossy and +lossless. They act upon the user application data, either from a variable or a set of variables in a IO object. + +Additionally, we will explore how to simply write variables across multiple steps. + +So, let's dig in! + +Start editing the skeleton file `ADIOS2/examples/hello/bpOperatorSZWriter/bpOperatorSZWriter_tutorialSkeleton.cpp `_. + +1. In an MPI application first we need to always initialize MPI. We do that with the following lines: + +.. code-block:: cpp + + + int rank, size; + int rank, size; + int provided; + + // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + +2. This application has command line arguments for the size of the data, and the compression accuracy, + which we can read as follows: + +.. code-block:: cpp + + const std::size_t Nx = static_cast(std::stoull(argv[1])); + const double accuracy = std::stod(argv[2]); + +3. Now we need to create some application variables which will be used to define ADIOS2 variables. + +.. code-block:: cpp + + std::vector myFloats(Nx); + std::vector myDoubles(Nx); + std::iota(myFloats.begin(), myFloats.end(), 0.); + std::iota(myDoubles.begin(), myDoubles.end(), 0.); + +4. Now we need to create an ADIOS2 instance and IO object. + +.. code-block:: cpp + + adios2::ADIOS adios(MPI_COMM_WORLD); + adios2::IO bpIO = adios.DeclareIO("BPFile_SZ"); + +5. Now we need to define the variables we want to write. + +.. code-block:: cpp + + adios2::Variable bpFloats = bpIO.DefineVariable( + "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios2::ConstantDims); + adios2::Variable bpDoubles = bpIO.DefineVariable( + "bpDoubles", {size * Nx}, {rank * Nx}, {Nx}, adios2::ConstantDims); + +6. Now we need to define the compression operator we want to use. In this case we will use the SZ compressor. + +.. code-block:: cpp + + adios2::Operator op = bpIO.DefineOperator("SZCompressor", "sz"); + varFloats.AddOperation(op, {{"accuracy", std::to_string(accuracy)}}); + varDoubles.AddOperation(op, {{"accuracy", std::to_string(accuracy)}}); + +.. note:: + + ``DefineOperator()'`` s second parameter can be either zfp or sz. For more information regarding operators and their + properties you can look at :ref:`Basics: Interface Components: Operator `. + +7. Let's also create an attribute to store the accuracy value. + +.. code-block:: cpp + + adios2::Attribute attribute = bpIO.DefineAttribute("accuracy", accuracy); + +8. Now we need to open the file for writing. + +.. code-block:: cpp + + adios2::Engine bpWriter = bpIO.Open("SZexample.bp", adios2::Mode::Write); + +9. Now we need to write the data. We will write the data for 3 steps, and edit them in between. + +.. code-block:: cpp + + for (unsigned int step = 0; step < 3; ++step) + { + bpWriter.BeginStep(); + + bpWriter.Put(bpDoubles, myDoubles.data()); + bpWriter.Put(bpFloats, myFloats.data()); + + bpWriter.EndStep(); + + // here you can modify myFloats, myDoubles per step + std::transform(myFloats.begin(), myFloats.end(), myFloats.begin(), + [&](float v) -> float { return 2 * v; }); + std::transform(myDoubles.begin(), myDoubles.end(), myDoubles.begin(), + [&](double v) -> double { return 3 * v; }); + } + +10. Now we need to close the file. + +.. code-block:: cpp + + bpWriter.Close(); + +11. Finally we need to finalize MPI. + +.. code-block:: cpp + + MPI_Finalize(); + +12. The final code should look as follows (excluding try/catch and optional usage of MPI), and it was derived from the + example `ADIOS2/examples/hello/bpOperatorSZWriter/bpOperatorSZWriter.cpp `_. + +.. literalinclude:: ../../../../examples/hello/bpOperatorSZWriter/bpOperatorSZWriter.cpp + :language: cpp + +13. You can compile and run it as follows: + +.. code-block:: bash + + cd Path-To-ADIOS2/examples/hello/bpOperatorSZWriter + mkdir build + cd build + cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ .. + cmake --build . + mpirun -np 2 ./adios2_hello_bpOperatorSZWriter_mpi 20 0.000001 + +12. You can check the content of the output file "SZexample.bp" using *bpls* as follows: + +.. code-block:: bash + + Path-To-ADIOS2/build/bin/bpls ./SZexample.bp + + double bpDoubles 3*{40} + float bpFloats 3*{40} diff --git a/docs/user_guide/source/tutorials/overview.rst b/docs/user_guide/source/tutorials/overview.rst index a1ad25909a..fb4725fa75 100644 --- a/docs/user_guide/source/tutorials/overview.rst +++ b/docs/user_guide/source/tutorials/overview.rst @@ -11,3 +11,4 @@ More specifically, we will go through the following examples: 1. :ref:`Hello World ` 2. :ref:`Array Variables ` 3. :ref:`Attributes ` + 4. :ref:`Operators ` diff --git a/examples/hello/bpOperatorSZWriter/bpOperatorSZWriter_tutorialSkeleton.cxx b/examples/hello/bpOperatorSZWriter/bpOperatorSZWriter_tutorialSkeleton.cxx new file mode 100644 index 0000000000..618ea7f50b --- /dev/null +++ b/examples/hello/bpOperatorSZWriter/bpOperatorSZWriter_tutorialSkeleton.cxx @@ -0,0 +1,94 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * bpSZ.cpp : example passing runtime compression arguments + * + * Created on: Aug 3, 2018 + * Author: William F Godoy godoywf@ornl.gov + */ + +#include //std::transform +#include //std::ios_base::failure +#include //std::cout +#include //std::iota +#include //std::invalid_argument std::exception +#include + +#include +#include + +void Usage() +{ + std::cout << "\n"; + std::cout << "USAGE:\n"; + std::cout << "./adios2_hello_bpSZ Nx sz_accuracy\n"; + std::cout << "\t Nx: size of float and double arrays to be compressed\n"; + std::cout << "\t sz_accuracy: absolute accuracy e.g. 0.1, 0.001, to skip " + "compression: -1\n\n"; +} + +int main(int argc, char *argv[]) +{ + if (argc != 3) + { + Usage(); + return EXIT_SUCCESS; + } + + int rank, size; + int provided; + + // Add code to init MPI + + try + { + // Add code to get command line arguments + + // Add code to create arrays + + // Add code to create ADIOS object + + // Add code to create IO object + + // Add code to create variables + + // Add code to add SZ compressor operation + + // Add code to add attribute + + // Add code to open file + + // Add code to write variables for 3 time steps and edit them + + // Add code to close file + } + catch (std::invalid_argument &e) + { + std::cerr << "Invalid argument exception: " << e.what() << "\n"; +#if ADIOS2_USE_MPI + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); +#endif + } + catch (std::ios_base::failure &e) + { + std::cerr << "IO System base failure exception: " << e.what() << "\n"; +#if ADIOS2_USE_MPI + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); +#endif + } + catch (std::exception &e) + { + std::cerr << "Exception: " << e.what() << "\n"; +#if ADIOS2_USE_MPI + std::cerr << "STOPPING PROGRAM from rank " << rank << "\n"; + MPI_Abort(MPI_COMM_WORLD, 1); +#endif + } + + // Add code to finalize MPI + + return 0; +} From 3ffb6c64d3c48600668511daf853eb2d05191cc7 Mon Sep 17 00:00:00 2001 From: Spiros Tsalikis Date: Mon, 30 Oct 2023 15:11:56 -0400 Subject: [PATCH 16/16] Add Steps Tutorial --- .../source/tutorials/basicTutorials.rst | 1 + docs/user_guide/source/tutorials/overview.rst | 1 + docs/user_guide/source/tutorials/steps.rst | 212 ++++++++++++++++++ .../bpStepsWriteRead_tutorialSkeleton.cxx | 98 ++++++++ 4 files changed, 312 insertions(+) create mode 100644 docs/user_guide/source/tutorials/steps.rst create mode 100644 examples/hello/bpStepsWriteRead/bpStepsWriteRead_tutorialSkeleton.cxx diff --git a/docs/user_guide/source/tutorials/basicTutorials.rst b/docs/user_guide/source/tutorials/basicTutorials.rst index fcac1ed85a..c1c7a44de2 100644 --- a/docs/user_guide/source/tutorials/basicTutorials.rst +++ b/docs/user_guide/source/tutorials/basicTutorials.rst @@ -7,3 +7,4 @@ Basic Tutorials variables attributes operators + steps diff --git a/docs/user_guide/source/tutorials/overview.rst b/docs/user_guide/source/tutorials/overview.rst index fb4725fa75..b9cb47a573 100644 --- a/docs/user_guide/source/tutorials/overview.rst +++ b/docs/user_guide/source/tutorials/overview.rst @@ -12,3 +12,4 @@ More specifically, we will go through the following examples: 2. :ref:`Array Variables ` 3. :ref:`Attributes ` 4. :ref:`Operators ` + 5. :ref:`Steps ` diff --git a/docs/user_guide/source/tutorials/steps.rst b/docs/user_guide/source/tutorials/steps.rst new file mode 100644 index 0000000000..d7d6f8cac0 --- /dev/null +++ b/docs/user_guide/source/tutorials/steps.rst @@ -0,0 +1,212 @@ +Steps +===== + +.. _sec:tutorials_basics_steps: + +In the previous tutorial, we introduced the concept of operators, and briefly touched upon the concept of steps. + +In this tutorial, we will explore how to write data for multiple steps, and how to read them back. + +So let's dig in! + +Start editing the skeleton file `ADIOS2/examples/hello/bpStepsWriteRead/bpStepsWriteRead_tutorialSkeleton.cpp `_. + +1. In an MPI application first we need to always initialize MPI. We do that with the following lines: + +.. code-block:: cpp + + int rank, size; + int rank, size; + int provided; + + // MPI_THREAD_MULTIPLE is only required if you enable the SST MPI_DP + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + +2. This application has an optional command line argument for engine being used. If + no argument is provided, the default engine is BPFile. + +.. code-block:: cpp + + const std::string engine = argv[1] ? argv[1] : "BPFile"; + +3. We will define the number of steps and the size of the data that we will create. + +.. code-block:: cpp + + const std::string filename = engine + "StepsWriteRead.bp"; + const unsigned int nSteps = 10; + const unsigned int Nx = 60000; + +4. Now we need to create an ADIOS2 instance. + +.. code-block:: cpp + + adios2::ADIOS adios(MPI_COMM_WORLD); + +5. Now we will populate the writer function with the following signature: + +.. code-block:: + + void writer(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int nSteps, int rank, int size) + { + ... + } + +6. Let's create some simulation data. We will create a 1D array of size Nx, and fill it with 0.block + +.. code-block:: cpp + + std::vector simData(Nx, 0.0); + +7. Now we will create an IO object and set the engine type.block + +.. code-block:: cpp + + adios2::IO bpIO = adios.DeclareIO("SimulationOutput"); + io.SetEngine(engine); + +.. note:: + + The beauty of ADIOS2 is that you write the same code for all engines. The only thing that changes is the engine name. + The underlying engine handles all the intricacies of the engine's format, and the user enjoys the API's simplicity. + +8. Now we will create a variable for the simulation data and the step. + +.. code-block:: cpp + + const adios2::Dims shape{static_cast(size * Nx)}; + const adios2::Dims start{static_cast(rank * Nx)}; + const adios2::Dims count{Nx}; + auto bpFloats = bpIO.DefineVariable("bpFloats", shape, start, count); + + auto bpStep = bpIO.DefineVariable("bpStep"); + +9. Now we will open the file for writing. + +.. code-block:: cpp + + adios2::Engine bpWriter = bpIO.Open(fname, adios2::Mode::Write); + +10. Now we will write the data for each step. + +.. code-block:: cpp + + for (unsigned int step = 0; step < nSteps; ++step) + { + const adios2::Box sel({0}, {Nx}); + bpFloats.SetSelection(sel); + + bpWriter.BeginStep(); + bpWriter.Put(bpFloats, simData.data()); + bpWriter.Put(bpStep, step); + bpWriter.EndStep(); + + // Update values in the simulation data + update_array(simData, 10); + } + +11. Now we will close the file. + +.. code-block:: cpp + + bpWriter.Close(); + +12. Now we will populate the reader function with the following signature: + +.. code-block:: cpp + + void reader(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int /*nSteps*/, int rank, int /*size*/) + { + ... + } + +13. Now we will create an IO object and set the engine type. + +.. code-block:: cpp + + adios2::IO bpIO = adios.DeclareIO("SimulationOutput"); + io.SetEngine(engine); + +14. Now we will open the file for reading. + +.. code-block:: cpp + + adios2::Engine bpReader = bpIO.Open(fname, adios2::Mode::Read); + +15. Now we will create a vector to store simData and a variable for the step. + +.. code-block:: cpp + + std::vector simData(Nx, 0); + unsigned int inStep = 0; + +16. Now we will read the data for each step. + +.. code-block:: cpp + + for (unsigned int step = 0; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) + { + auto bpFloats = bpIO.InquireVariable("bpFloats"); + if (bpFloats) + { + const adios2::Box sel({{Nx * rank}, {Nx}}); + bpFloats.SetSelection(sel); + bpReader.Get(bpFloats, simData.data()); + } + auto bpStep = bpIO.InquireVariable("bpStep"); + if (bpStep) + { + bpReader.Get(bpStep, &inStep); + } + + bpReader.EndStep(); + } + +17. Now we will close the file. + +.. code-block:: cpp + + bpReader.Close(); + +18. Now we will call the writer and reader functions: + +.. code-block:: cpp + + writer(adios, engine, filename, Nx, nSteps, rank, size); + reader(adios, engine, filename, Nx, nSteps, rank, size); + +19. Finally we need to finalize MPI. + +.. code-block:: cpp + + MPI_Finalize(); + +20. The final code should look as follows (excluding try/catch and optional usage of MPI), and it was derived from the + example `ADIOS2/examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp `_. + +.. literalinclude:: ../../../../examples/hello/bpStepsWriteRead/bpStepsWriteRead.cpp + :language: cpp + +21. You can compile and run it as follows: + +.. code-block:: bash + + cd Path-To-ADIOS2/examples/hello/bpStepsWriteRead + mkdir build + cd build + cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ .. + cmake --build . + mpirun -np 2 ./adios2_hello_bpStepsWriteRead_mpi + +22. You can check the content of the output file "BPFileStepsWriteRead.bp" using *bpls* as follows: + +.. code-block:: bash + + Path-To-ADIOS2/build/bin/bpls ./BPFileStepsWriteRead.bp + + float bpFloats 10*{120000} + uint32_t bpStep 10*scalar diff --git a/examples/hello/bpStepsWriteRead/bpStepsWriteRead_tutorialSkeleton.cxx b/examples/hello/bpStepsWriteRead/bpStepsWriteRead_tutorialSkeleton.cxx new file mode 100644 index 0000000000..faceff681d --- /dev/null +++ b/examples/hello/bpStepsWriteRead/bpStepsWriteRead_tutorialSkeleton.cxx @@ -0,0 +1,98 @@ +/* +* Distributed under the OSI-approved Apache License, Version 2.0. See +* accompanying file Copyright.txt for details. +* +* bpStepsWriteRead.cpp Simple example of writing and reading data through ADIOS2 BP engine with +* multiple simulations steps for every IO step. +* +* Created on: Feb 16, 2017 +* Author: William F Godoy godoywf@ornl.gov + */ + +#include //std::for_each +#include //std::ios_base::failure +#include //std::cout +#include +#include //std::invalid_argument std::exception +#include + +#include + +void update_array(std::vector &array, int val) +{ + std::transform(array.begin(), array.end(), array.begin(), + [val](float v) -> float { return v + static_cast(val); }); +} + +void writer(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int nSteps, int rank, int size) +{ + // Add code to create the simulation data + + // Add code to create ADIOS io and set engine type + + // Add code to define sim data variable + + // Add code to define step variable + + // Add code to open file + + // Add code to write data across multiple steps, and update the simulation data + + // Add code to close file +} + +void reader(adios2::ADIOS &adios, const std::string &engine, const std::string &fname, + const size_t Nx, unsigned int /*nSteps*/, int rank, int /*size*/) +{ + // Add code to create ADIOS io and set engine type + + // Add code to open file + + // Add code to create variable for sim data and step + + // Add code to read data across multiple steps + + // Add code to close file +} + +int main(int argc, char *argv[]) +{ + int rank, size; + int provided; + + // Add code to initialize MPI + + const std::string engine = argv[1] ? argv[1] : "BPFile"; + std::cout << "Using engine " << engine << std::endl; + + // Add Code to set filename, nSteps, Nx + try + { + // Add code to create ADIOS object + + // Add code to call writer + // Add code to call reader + } + 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"; + } + + // Add code to finalize MPI + + return 0; +}