├── .clang-format ├── .github └── workflows │ └── build-and-test.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── ReadMe.md ├── cmake └── Functions.cmake ├── docs ├── Makefile ├── README.md ├── make.bat ├── requirements.txt └── source │ ├── concepts │ ├── adiosobjects.rst │ ├── anatomy.rst │ ├── deferredvssync.rst │ ├── mpmd.rst │ └── streamvsfile.rst │ ├── conf.py │ ├── fortran │ ├── fortran.rst │ └── variables.rst │ ├── image │ ├── global_array.png │ ├── global_array_changing_blocksizes.png │ ├── global_array_changing_shape.png │ ├── global_array_multiblock.png │ ├── global_array_overlap.png │ ├── global_array_read_pattern.png │ └── global_array_sparse.png │ ├── index.rst │ ├── introduction │ ├── introduction.rst │ └── manualbuild.rst │ ├── performance │ └── aggregation.rst │ └── variables │ ├── globalarray.rst │ └── introduction.rst ├── make.settings ├── meson.build ├── meson_options.txt ├── scripts ├── ci │ └── user-setup.sh ├── conda │ ├── LICENSE │ ├── build.sh │ └── meta.yaml └── developer │ └── setup.sh └── source ├── CMakeLists.txt ├── c ├── CMakeLists.txt ├── hello-world │ ├── CMakeLists.txt │ ├── hello-world.c │ └── meson.build ├── meson.build └── shapes │ ├── CMakeLists.txt │ ├── decomp.c │ ├── decomp.h │ ├── global-array-fixed-read.c │ ├── global-array-fixed-write.c │ ├── mpivars.c │ └── mpivars.h ├── cpp ├── CMakeLists.txt ├── basics │ ├── CMakeLists.txt │ ├── meson.build │ ├── thread-write.cpp │ ├── variables-shapes-hl.cpp │ └── variables-shapes.cpp ├── gray-scott-struct │ ├── CMakeLists.txt │ ├── README.md │ ├── adios2-inline-plugin.xml │ ├── adios2.xml │ ├── analysis │ │ ├── curvature.cpp │ │ ├── find_blobs.cpp │ │ ├── isosurface.cpp │ │ └── pdf-calc.cpp │ ├── catalyst │ │ ├── gs-fides.json │ │ ├── gs-pipeline.py │ │ └── setup.sh │ ├── cleanup.sh │ ├── common │ │ └── timer.hpp │ ├── img │ │ ├── example1.jpg │ │ ├── example2.jpg │ │ ├── example3.jpg │ │ ├── example4.jpg │ │ └── example5.jpg │ ├── meson.build │ ├── plot │ │ ├── decomp.py │ │ ├── gsplot.py │ │ ├── pdfplot.py │ │ └── render_isosurface.cpp │ ├── simulation │ │ ├── LICENSE │ │ ├── gray-scott.cpp │ │ ├── gray-scott.h │ │ ├── json.hpp │ │ ├── main.cpp │ │ ├── restart.cpp │ │ ├── restart.h │ │ ├── settings-files.json │ │ ├── settings-inline.json │ │ ├── settings-staging.json │ │ ├── settings.cpp │ │ ├── settings.h │ │ ├── writer.cpp │ │ └── writer.h │ ├── test-firstrun.json │ ├── test-restart.json │ ├── visit-bp4.session │ ├── visit-bp4.session.gui │ ├── visit-sst.session │ └── visit-sst.session.gui ├── gray-scott │ ├── CMakeLists.txt │ ├── README.md │ ├── adios2-fides-staging.xml │ ├── adios2-inline-plugin.xml │ ├── adios2.xml │ ├── analysis │ │ ├── curvature.cpp │ │ ├── find_blobs.cpp │ │ ├── isosurface.cpp │ │ └── pdf-calc.cpp │ ├── catalyst │ │ ├── gs-fides.json │ │ ├── gs-pipeline.py │ │ └── setup.sh │ ├── cleanup.sh │ ├── common │ │ └── timer.hpp │ ├── img │ │ ├── example1.jpg │ │ ├── example2.jpg │ │ ├── example3.jpg │ │ ├── example4.jpg │ │ └── example5.jpg │ ├── meson.build │ ├── plot │ │ ├── decomp.py │ │ ├── gsplot.py │ │ ├── pdfplot.py │ │ └── render_isosurface.cpp │ ├── simulation │ │ ├── LICENSE │ │ ├── gray-scott.cpp │ │ ├── gray-scott.h │ │ ├── json.hpp │ │ ├── main.cpp │ │ ├── restart.cpp │ │ ├── restart.h │ │ ├── settings-files.json │ │ ├── settings-inline.json │ │ ├── settings-staging.json │ │ ├── settings.cpp │ │ ├── settings.h │ │ ├── writer.cpp │ │ └── writer.h │ ├── visit-bp4.session │ ├── visit-bp4.session.gui │ ├── visit-sst.session │ └── visit-sst.session.gui ├── hello-world │ ├── CMakeLists.txt │ ├── hello-world-hl.cpp │ ├── hello-world.cpp │ └── meson.build ├── korteweg-de-vries │ ├── CMakeLists.txt │ ├── KdV.cpp │ ├── README.md │ └── graph_solution.py ├── lorenz_ode │ ├── CMakeLists.txt │ ├── README.md │ ├── lorenz.hpp │ ├── lorenz_ode.svg │ ├── lorenz_reader.cpp │ ├── lorenz_writer.cpp │ ├── ode_phase_space.svg │ ├── ode_tuples.svg │ ├── second_derivative.svg │ └── taylor_series.svg └── meson.build ├── fortran ├── CMakeLists.txt ├── adios-module │ ├── CMakeLists.txt │ ├── Makefile │ ├── adiosio.F90 │ ├── main.F90 │ └── mpivars.F90 └── shapes │ ├── CMakeLists.txt │ ├── Makefile │ ├── decomp.F90 │ ├── global-array-changing-shape-write.F90 │ ├── global-array-fixed-read.F90 │ ├── global-array-fixed-write.F90 │ ├── mpivars.F90 │ ├── shapes-read.F90 │ ├── shapes-write.F90 │ ├── shapes.xml │ └── values.F90 ├── gpu ├── CMakeLists.txt ├── basics-cuda │ ├── CMakeLists.txt │ ├── cudaRoutines.cu │ ├── cudaRoutines.h │ └── write-read-cuda.cpp ├── basics-hip │ ├── CMakeLists.txt │ └── write-read-hip.cpp ├── basics-kokkos │ ├── CMakeLists.txt │ └── write-read-kokkos.cpp └── gray-scott-kokkos │ ├── CMakeLists.txt │ ├── README.md │ ├── gray-scott.cpp │ ├── gray-scott.h │ ├── json.hpp │ ├── main.cpp │ ├── restart.cpp │ ├── restart.h │ ├── settings.cpp │ ├── settings.h │ ├── timer.hpp │ ├── writer.cpp │ └── writer.h ├── julia └── GrayScott.jl │ ├── .JuliaFormatter.toml │ ├── Project.toml │ ├── ReadMe.md │ ├── examples │ └── settings-files.json │ ├── gray-scott.jl │ ├── scripts │ ├── config_crusher.sh │ ├── config_summit.sh │ ├── job_crusher.sh │ └── job_summit.sh │ ├── src │ ├── GrayScott.jl │ ├── analysis │ │ └── pdfcalc.jl │ ├── helper │ │ ├── Helper.jl │ │ ├── helperMPI.jl │ │ └── helperString.jl │ └── simulation │ │ ├── IO.jl │ │ ├── Inputs.jl │ │ ├── Simulation.jl │ │ ├── Simulation_AMDGPU.jl │ │ ├── Simulation_CUDA.jl │ │ └── Structs.jl │ └── test │ ├── Project.toml │ ├── functional │ └── functional-GrayScott.jl │ ├── runtests.jl │ └── unit │ ├── analysis │ └── unit-pdfcalc.jl │ ├── helper │ └── unit-helperMPI.jl │ └── simulation │ ├── unit-IO.jl │ ├── unit-Inputs.jl │ ├── unit-Simulation.jl │ └── unit-Simulation_CUDA.jl ├── manual-build ├── Makefile ├── Readme.md ├── example-mpi.F90 ├── example-mpi.c ├── example-mpi.cpp ├── example-serial.F90 ├── example-serial.c └── example-serial.cpp ├── meson.build └── python └── hello-world ├── hello-world-hl.py └── hello-world.py /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: LLVM 3 | BreakBeforeBraces: Custom 4 | ConstructorInitializerIndentWidth: 0 5 | IndentWidth: 4 6 | ContinuationIndentWidth: 4 7 | AccessModifierOffset: -4 8 | AlwaysBreakTemplateDeclarations: true 9 | CompactNamespaces: false 10 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 11 | FixNamespaceComments: false 12 | Standard: Cpp11 13 | ColumnLimit: 80 14 | AllowAllParametersOfDeclarationOnNextLine: true 15 | AlignEscapedNewlines: Right 16 | AlignAfterOpenBracket: Align 17 | SortUsingDeclarations: false 18 | BraceWrapping: 19 | AfterClass: true 20 | AfterControlStatement: true 21 | AfterEnum: true 22 | AfterExternBlock: false 23 | AfterFunction: true 24 | AfterNamespace: true 25 | AfterStruct: true 26 | AfterUnion: true 27 | BeforeCatch: true 28 | BeforeElse: true 29 | SplitEmptyFunction: true 30 | SplitEmptyRecord: true 31 | SplitEmptyNamespace: false 32 | -------------------------------------------------------------------------------- /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | #on: 4 | # push: 5 | # branches: 6 | # - master 7 | # pull_request: 8 | # branches: 9 | # - master 10 | 11 | concurrency: 12 | group: ${{ github.head_ref || github.run_id }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | linux-cmake: 17 | runs-on: ubuntu-latest 18 | container: 19 | image: ornladios/adios2:release_28-ubuntu-bionic 20 | defaults: 21 | run: 22 | shell: bash -l {0} 23 | 24 | steps: 25 | - name: User Setup 26 | shell: sh -e {0} 27 | run: | 28 | sudo chown -R 1000:1000 . 29 | sudo ln -s $PWD/source/scripts/ci/user-setup.sh /etc/profile.d/zzz-adios2-ci.sh 30 | - uses: actions/checkout@v3 31 | with: 32 | ref: ${{ github.event.pull_request.head.sha }} 33 | path: source 34 | - name: Environment 35 | run: env | sort 36 | - name: Configure 37 | run: | 38 | mkdir -p build 39 | cd build 40 | cmake ../source 41 | - name: Build 42 | run: | 43 | cd build 44 | make -j$(grep -c '^processor' /proc/cpuinfo) 45 | - name: Test 46 | run: | 47 | cd build 48 | ctest -VV -j 1 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Vi(m) temporary buffer files 2 | *.sw? 3 | 4 | # Emacs temporary files 5 | *~ 6 | 7 | #Eclipse 8 | .cproject 9 | .project 10 | .settings/ 11 | .pydevproject 12 | 13 | # VS Code 14 | .vscode/ 15 | 16 | #binary, library, or temporary build files 17 | *.o 18 | *.a 19 | *.so 20 | *.tmp 21 | *.exe 22 | *.bp 23 | *.h5 24 | *.out 25 | *.pyc 26 | *.bp 27 | *.bp.dir 28 | build*/ 29 | 30 | # Mac OSX finder-related files 31 | .DS_Store 32 | 33 | # julia 34 | Manifest.toml 35 | 36 | -------------------------------------------------------------------------------- /cmake/Functions.cmake: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | 7 | function(add_mpi_test DIR_NAME BASE LANG) 8 | add_executable(a2e_${DIR_NAME}-${BASE}_${LANG} ${BASE}.${LANG}) 9 | target_link_libraries(a2e_002_basics-variables_cpp adios2::adios2 MPI::MPI_C) 10 | add_test(NAME 002_basics-variables_cpp COMMAND mpirun -np ${NPROCS} $) 11 | install(TARGETS a2e_002_basics-variables_cpp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 12 | end function() 13 | 14 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Documentation for ADIOS2-Examples 2 | 3 | # Generate html with Sphinx 4 | 5 | This guide is hosted in readthedocs: https://adios2-examples.readthedocs.io/en/latest/ 6 | 7 | To generate the guide under docs/build/html format from the Sphinx source files: 8 | 9 | ```bash 10 | $ cd ADIOS2-Examples/docs 11 | docs$ python3 -m venv . 12 | docs$ . bin/activate 13 | docs$ pip3 install -r requirements.txt 14 | docs$ make html 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | alabaster==0.7.12 2 | Babel==2.9.1 3 | blockdiag==2.0.1 4 | breathe==4.18.1 5 | certifi==2022.12.7 6 | chardet==3.0.4 7 | docutils==0.16 8 | funcparserlib==0.3.6 9 | idna==2.9 10 | imagesize==1.2.0 11 | Jinja2==2.11.3 12 | MarkupSafe==1.1.1 13 | packaging==20.1 14 | Pillow==9.3.0 15 | Pygments==2.7.4 16 | pyparsing==2.4.6 17 | pytz==2019.3 18 | requests==2.31.0 19 | six==1.14.0 20 | snowballstemmer==2.0.0 21 | Sphinx==3.0.4 22 | sphinx-rtd-theme==0.4.3 23 | sphinxcontrib-applehelp==1.0.2 24 | sphinxcontrib-blockdiag==2.0.0 25 | sphinxcontrib-devhelp==1.0.2 26 | sphinxcontrib-htmlhelp==1.0.3 27 | sphinxcontrib-jsmath==1.0.1 28 | sphinxcontrib-qthelp==1.0.3 29 | sphinxcontrib-serializinghtml==1.1.4 30 | sphinxcontrib-osexample==0.1.1 31 | urllib3==1.26.5 32 | webcolors==1.11.1 33 | -------------------------------------------------------------------------------- /docs/source/concepts/adiosobjects.rst: -------------------------------------------------------------------------------- 1 | .. _section-objects: 2 | 3 | ############# 4 | ADIOS Objects 5 | ############# 6 | 7 | ADIOS2 has a few objects that need to be created and maintained for performing I/O. Since you have already read the `Components of ADIOS2 `_ in the ADIOS2 documentation, there is nothing to be added here about this topic ;-) 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/source/concepts/deferredvssync.rst: -------------------------------------------------------------------------------- 1 | .. _section-deferred: 2 | 3 | Deferred vs Sync 4 | ################ 5 | 6 | .. warning:: 7 | 8 | This is the most dangerous and controversial concept of ADIOS and you must understand what is going on to avoid writing or reading garbage instead of your precious data. 9 | 10 | Default mode: Deferred 11 | ********************** 12 | 13 | The Put() and Get() functions simply associate an application data pointer to a variable definition. They do not perform actual IO on their own, unless when explicitly asked. 14 | 15 | By default, the list of Put() and Get() calls in a step enumerate the IO requests that need to be performed in the step. The actions are performed in EndStep() and the results are available after EndStep(). 16 | 17 | For an output stream this means, that the data pointer passed in the Put() call must hold the actual data until the end of EndStep(). If you pass temporary data here (because you reuse the same memory to prepare multiple output variables in consecutive Put calls, or pass a Fortran subselection on an array), there will be garbage in the memory by the time EndStep takes care of the output. 18 | 19 | For an input stream this means, that after the Get() call, you must not attempt to use the data pointer yet because the data is not there yet. You can only use the data pointer after the EndStep call. 20 | 21 | So remember, keep the data pointers valid until EndStep and use their content only after EndStep. 22 | 23 | Sync mode 24 | ********* 25 | 26 | Of course, Deferred mode is limiting. Sometimes we want to pass temporary pointers to Put() that will go out of scope right after the Put() call. And sometimes, we need to read in some data to know how to read the rest. ``Sync`` mode flag can be passed to both Put() and Get() to force the engine to take care of that piece of data right away. 27 | 28 | 29 | .. code-block:: c++ 30 | 31 | C++: engine.Get(varF, data, adios2::Mode::Sync); 32 | 33 | .. code-block:: fortran 34 | 35 | F90: call adios2_get(engine, varF, data, adios2_mode_sync, ierr) 36 | 37 | .. code-block:: python 38 | 39 | Python: engine.Get(varF, data, adios2.Mode.Sync) 40 | 41 | Why deferred? 42 | ************* 43 | 44 | We wanted to design an API that enables specialized engines to perform at their best. We did not want to add a single function for multiple purposes and then be stuck with its semantics. An engine may perform better if it knows all the outputs or inputs to perform in a batch instead of performing them one by one. 45 | 46 | A particularly good example is the Inline engine that is used to run an analysis code inside the application. All application data is exposed directly (zero-copy) to the reading code when EndStep is called by the application. If Sync mode is used in a Put(), the engine has no choice but to copy the data into a private buffer to preserve it for the reader. 47 | 48 | PerformPuts/PerformGets 49 | *********************** 50 | 51 | The ADIOS2 API has PerformGets and PerformPuts functions for the 52 | situation when one can Put/Get multiple variables in one batch, then 53 | another set of variables, within one step. These function enfore Sync 54 | mode for all Puts and Gets called before it. However, PerformPuts() 55 | can lower performance in some engines, so it should not be used 56 | unnecessarily. In particular, calling PerformPuts() just prior to 57 | EndStep() is at best unnecessary and may result in lower performance. 58 | 59 | -------------------------------------------------------------------------------- /docs/source/concepts/mpmd.rst: -------------------------------------------------------------------------------- 1 | .. _section-mpmd: 2 | 3 | ############## 4 | Why MPMD mode? 5 | ############## 6 | 7 | Location of examples: ``source/fortran/adios-module/mpivars.F90`` 8 | 9 | MPMD (Multiple Program Multiple Data) mode is when we compose one MPI World from multiple executables. Usually one can launch two executables separately by two MPI launch commands (mpirun, jsrun, aprun, etc.) and each application will have its own world and own ``MPI_COMM_WORLD`` communicator. Sharing the world is beneficial if the two codes know about each other and can use MPI for communicating with each other. The cost of preparing your code for MPMD mode is simply to expect other codes be present and avoid using MPI_COMM_WORLD for in-application operations. 10 | 11 | ADIOS has specialized solutions to use MPI for the data movement in a stream but it requires MPMD mode. If the steps in a stream is "fixed", i.e. the list of variables, their definition and the writing/reading patterns are the same in every step, the SSC engine of ADIOS can use one-sided MPI functions to push the data to the consumer quickly. SSC still works if the content of the steps change but needs to spend considerable amount of time to figure out which process of the consumer gets which portion of the data every step. 12 | 13 | You don't need to use MPMD mode at all to get faster communication. RDMA and TCP based solutions are available to communicate between two or more separate concurrent applications (SST and DataMan engines). However, the effort to prepare your code for MPMD mode is very small, and it may come handy some day on some system to use MPI for ADIOS I/O. 14 | 15 | Split communicator 16 | ****************** 17 | 18 | The only thing required for MPMD mode is that each application has its own communicator that only includes the processes of that application. *MPI_COMM_WORLD* includes all processes created in one launch command. Therefore, the application must first create its own "app" communicator and then completely avoid using MPI_COMM_WORLD in the application code. 19 | 20 | MPI has an operation for this: ``MPI_Comm_split``. Each application must pick a unique ID ("color") to distinguish themselves from other applications. Additionally, every process can pick its new rank in the "app" communicator but the simplest way is to keep the original order of ranks. 21 | 22 | .. code-block:: fortran 23 | 24 | integer:: app_comm, rank, nproc 25 | integer:: wrank, wnproc 26 | integer:: ierr 27 | integer, parameter:: color = 7215 28 | 29 | call MPI_Init(ierr) 30 | ! World comm spans all applications started with the same mpirun command 31 | call MPI_Comm_rank(MPI_COMM_WORLD, wrank, ierr) 32 | call MPI_Comm_size(MPI_COMM_WORLD, wnproc, ierr) 33 | 34 | ! Have to split and create a 'world' communicator for this app only 35 | ! color must be unique for each application 36 | call MPI_Comm_split (MPI_COMM_WORLD, color, wrank, app_comm, ierr) 37 | call MPI_Comm_rank (app_comm, rank, ierr) 38 | call MPI_Comm_size (app_comm, nproc , ierr) 39 | 40 | 41 | .. code-block:: c 42 | 43 | MPI_Init(&argc, &argv); 44 | 45 | int wrank, wnproc; 46 | MPI_Comm_rank(MPI_COMM_WORLD, &wrank); 47 | MPI_Comm_size(MPI_COMM_WORLD, &wnproc); 48 | 49 | const unsigned int color = 18325; 50 | MPI_Comm app_comm; 51 | MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &app_comm); 52 | 53 | int rank, nproc; 54 | MPI_Comm_rank(app_comm, &rank); 55 | MPI_Comm_size(app_comm, &nproc); 56 | 57 | .. code-block:: python 58 | 59 | from mpi4py import MPI 60 | 61 | color = 3231 62 | wrank = MPI.COMM_WORLD.Get_rank() 63 | wnproc = MPI.COMM_WORLD.Get_size() 64 | app_comm = MPI.COMM_WORLD.Split(color, wrank) 65 | nproc = app_comm.Get_size() 66 | rank = app_comm.Get_rank() 67 | -------------------------------------------------------------------------------- /docs/source/concepts/streamvsfile.rst: -------------------------------------------------------------------------------- 1 | .. _section-stream-vs-file: 2 | 3 | ############## 4 | Stream vs File 5 | ############## 6 | 7 | When we start thinking of I/O we first focus on a single application writing an output file to disk, or read an input file from disk. In general, however, that output is going to be read by another application or applications, once or more. That input had been written by another (or the same) application. Thinking further, we may want to read portions of the data written by another application while the first application is still producing more data. And we certainly don't want the file system to be the bottleneck when we do so. 8 | 9 | The file system always is, or is going to be at some point of scaling an application, a bottleneck. It forces us to separate data meant for immediate consumption from data meant for preservation. Why do we store temporary data on the permanent (and slow) storage? Because we don't have better solutions or because it is too complicated to do otherwise. 10 | 11 | Step 12 | **** 13 | 14 | The ADIOS I/O abstraction is designed around the concept of producers and consumers that exchange data, consumed immediately or much later, and around the fact that small pieces of data exchange is inefficient. It forces a producer to output a big chunk of data (called **Step**). Consumers get access to a complete Step and are guaranteed that it is available for consumption until the consumer releases it. A step can consist of anything, composed of n-dimensional distributed arrays, single values, strings, and a new step can be completely different in structure than the previous one. But usually, a repetitive application, like most simulations, produce the same structure of data with updated content. So usually, the content of the Step, the list of variables and attributes, need to be defined once and then publish new content every now and then. But remember, variables can be added, modified (e.g. array sizes), removed in new steps if necessary. 15 | 16 | Checkpoint 17 | ********** 18 | 19 | So what about the checkpoint file which is written once and read never (usually)? It fits the ADIOS abstraction as a single step, written to a file. And later the application may read it from the file as a single step. 20 | 21 | Code coupling at every iteration 22 | ******************************** 23 | 24 | Two separate applications (e.g. for multiphysics multiscale problems solved partially by different code bases) may want to exchange data very frequently (once or multiple times in every iteration). Exhange = two separate input-output streams between two applications. Minimizing the time for data movement is key. The ADIOS interface allows to write this data exchange with two streams. Exchanging data is still possible using files on disk but the cost of I/O will be overwhelming. ADIOS provides other solutions (``Engines``) that can use the local network to move data much faster then through the file system. Using a file-based engine, however, is the best thing one can have while developing these applications and to debug the data content being exchanged. 25 | 26 | But I just want a file 27 | ********************** 28 | 29 | That's all right. There are two extra capabilities in ADIOS that only applies to files on disk. These are random access to steps from a file, and reading multiple steps at once from the file. This is provided by the ``Variable.SetStepSelection`` (C++ method), ``adios2_set_step_selection`` (Fortran/C function). This is a per-variable function, so one can read different variables from different steps from a file. Don't use ``BeginStep``/``EndStep`` functions in the reading code after opening a file and you are good to go. Just remember, if you do so, your code can never connect to a running application to process data on the fly. 30 | 31 | .. note:: 32 | 33 | ``bpls`` is a tool that reads files and you can dump multiple steps at once. Alternatively you can use the ``-t`` parameter to force bpls read step by step (still from a file). 34 | 35 | 36 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | extensions = ['sphinx.ext.autosectionlabel', 18 | 'sphinxcontrib.osexample'] 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = 'ADIOS2-Examples' 23 | copyright = u'2021, Oak Ridge National Laboratory' 24 | author = u'Oak Ridge National Laboratory' 25 | 26 | # The full version, including alpha/beta/rc tags 27 | release = '2.7.0' 28 | 29 | 30 | # -- General configuration --------------------------------------------------- 31 | 32 | # Add any Sphinx extension module names here, as strings. They can be 33 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 34 | # ones. 35 | extensions = [ 36 | ] 37 | 38 | # Add any paths that contain templates here, relative to this directory. 39 | templates_path = ['_templates'] 40 | 41 | # List of patterns, relative to source directory, that match files and 42 | # directories to ignore when looking for source files. 43 | # This pattern also affects html_static_path and html_extra_path. 44 | exclude_patterns = [] 45 | 46 | 47 | # -- Options for HTML output ------------------------------------------------- 48 | 49 | # The theme to use for HTML and HTML Help pages. See the documentation for 50 | # a list of builtin themes. 51 | # 52 | # html_theme = 'alabaster' 53 | html_theme = "sphinx_rtd_theme" 54 | 55 | # Add any paths that contain custom static files (such as style sheets) here, 56 | # relative to this directory. They are copied after the builtin static files, 57 | # so a file named "default.css" will overwrite the builtin "default.css". 58 | html_static_path = ['_static'] 59 | 60 | # The name of the Pygments (syntax highlighting) style to use. 61 | pygments_style = 'sphinx' 62 | -------------------------------------------------------------------------------- /docs/source/fortran/fortran.rst: -------------------------------------------------------------------------------- 1 | .. _section_fortran: 2 | 3 | Fortran examples 4 | ################ 5 | 6 | The ADIOS2 Fortran bindings are documented in ``_. 7 | 8 | When writing Fortran code, it comes handy to look at the `source code of the Fortran bindings `_ directly to find the possible signatures of each function, and especially at the `ADIOS2 constants `_. 9 | 10 | Including ADIOS2 in a Fortran application 11 | ***************************************** 12 | 13 | ADIOS2 is using a Fortran 90 interface, so it cannot be directly used in an F77 code base. Files that include adios calls, should be named \*.F90 (capital F) so that macros are pre-processed by the Fortran compiler. 14 | 15 | Since ADIOS2 is object-oriented and is implemented in C++, there is a need to use global variables in Fortran to initialize an ``adios`` object and to keep it alive ("in scope") as long as it is needed. Usually, the adios object is created after MPI is initialized and destroyed before MPI is finalized. An ``io`` object is used to define all variables, attributes and runtime parameters for an input or output. Finally, an ``engine`` object needed to call the actual operations on the input or output (open, close and read/write-related calls). 16 | 17 | The easiest way to manage the objects is to put them into a new module for ADIOS I/O. The example is in ``source/fortran/adios-module/adiosio.F90`` 18 | 19 | Assuming you have the MPI communicator in another module name *mpivars*, and the communicator is named *app_comm*: 20 | 21 | .. literalinclude:: ../../../source/fortran/adios-module/adiosio.F90 22 | :language: fortran 23 | 24 | .. note:: 25 | 26 | The example above adds an IO and an Engine object to the module, which is not required if you write an output or read an input in a single subroutine and do so only once. However, if you want to refer to them in multiple subroutines, or you want to read/write multiple steps, you need to keep these objects (technically, object references) alive to avoid premature destruction of the C++ objects behind. 27 | 28 | .. note:: 29 | 30 | The example above also closes the engine object in the finalization. This is an example to follow if you want to open an output somewhere else in the code, and output new data (new steps) regularly until the end. This usage is not encouraged here. It is cleaner if you manage the (single) open and (single) close of your outputs and the (multiple) output steps yourself. However, in existing large applications with many optional modules it may be difficult to find the exact spot where the output stream actually ends. This subroutine is the last point where the output must be closed. 31 | 32 | 33 | In the main program, include these snippets of code: 34 | 35 | .. code-block:: fortran 36 | 37 | program adios2_module_example 38 | use mpivars 39 | #ifdef ADIOS2 40 | use adiosio 41 | #endif 42 | implicit none 43 | 44 | ... 45 | 46 | ! After call MPI_Init() 47 | #ifdef ADIOS2 48 | call init_adiosio() 49 | #endif 50 | 51 | ... 52 | 53 | ! Before call MPI_Finalize() 54 | #ifdef ADIOS2 55 | call finalize_adiosio() 56 | #endif 57 | 58 | .. note:: 59 | 60 | We are using the *ADIOS2* macro everywhere to allow for building the application with or without ADIOS2. If you make ADIOS2 a required dependency, there is no need for this macro. 61 | 62 | -------------------------------------------------------------------------------- /docs/source/fortran/variables.rst: -------------------------------------------------------------------------------- 1 | .. _section_fortran_variables: 2 | 3 | Defining, writing and reading variables 4 | ####################################### 5 | 6 | Global Array 7 | ***************************************** 8 | 9 | Global array of fixed shape 10 | --------------------------- 11 | 12 | This is how we define a 1D array of type *real4* and of size *nproc* x *NX* where every process has an array of size *NX*, there are *nproc* processes, and their *rank* runs from 0..*nproc*-1: 13 | 14 | .. code-block:: fortran 15 | :emphasize-lines: 14-17 16 | 17 | use adios2 18 | implicit none 19 | type(adios2_io) :: io 20 | type(adios2_variable) :: var_g 21 | ... 22 | integer*4 :: ndim 23 | integer*8, dimension(1) :: fixed_shape, fixed_start, fixed_count 24 | 25 | ndim = 1 26 | fixed_count = NX 27 | fixed_shape = nproc * NX 28 | fixed_start = rank * NX 29 | 30 | call adios2_define_variable(var_g, io, "GlobalArray", & 31 | adios2_type_real4, ndim, & 32 | fixed_shape, fixed_start, fixed_count, & 33 | adios2_constant_dims, ierr) 34 | 35 | 36 | .. note:: 37 | 38 | The flag ``adios2_constant_dims`` indicates that this definition is fixed, i.e. the block selection and the global array shape cannot be changed. Use ``adios2_variable_dims`` if you intend to change any of these later. 39 | 40 | The example in ``source/fortran/shapes/global-array-fixed-write.F90`` and ``global-array-fixed-read.F90`` is similar but each process holds a (random) size of array between 2 and 5 and the global shape has to be calculated that involves an MPI Allgather operation. 41 | 42 | .. note:: 43 | 44 | For an N-dimensional arrays, the function is the same, just the value of *ndim* is N, and the shape, start and count arrays must have N elements. 45 | 46 | 47 | 48 | Global array that changes 49 | ------------------------- 50 | 51 | If you don't know the size of the local arrays at the point of the definition, you can set this information later (before calling Put). 52 | 53 | .. code-block:: fortran 54 | 55 | ! Change the shape and decomposition information 56 | call adios2_set_shape(var_g, 1, changing_shape, ierr) 57 | call adios2_set_selection(var_g, 1, changing_start, changing_count, ierr); 58 | 59 | .. note:: 60 | 61 | The global shape of the array is a single global piece of information about the array (in one output step), which can only change between steps. Technically, one can call adios2_set_shape multiple times but only the last call before the last adios2_put() call will count. The final shape must be set to the same shape on every process. 62 | 63 | The example in ``source/fortran/shapes/global-array-changing-shape-write.F90`` shows how to write an array whose global size changes over time. 64 | 65 | Multiblock 66 | ---------- 67 | 68 | By multiblock we mean that one process contributes more than one block to the global array. Since only one definition is allowed for a variable, one needs to call ``adios2_set_selection`` and then ``adios2_put()`` for each block once. -------------------------------------------------------------------------------- /docs/source/image/global_array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/docs/source/image/global_array.png -------------------------------------------------------------------------------- /docs/source/image/global_array_changing_blocksizes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/docs/source/image/global_array_changing_blocksizes.png -------------------------------------------------------------------------------- /docs/source/image/global_array_changing_shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/docs/source/image/global_array_changing_shape.png -------------------------------------------------------------------------------- /docs/source/image/global_array_multiblock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/docs/source/image/global_array_multiblock.png -------------------------------------------------------------------------------- /docs/source/image/global_array_overlap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/docs/source/image/global_array_overlap.png -------------------------------------------------------------------------------- /docs/source/image/global_array_read_pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/docs/source/image/global_array_read_pattern.png -------------------------------------------------------------------------------- /docs/source/image/global_array_sparse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/docs/source/image/global_array_sparse.png -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. ADIOS2-Examples documentation master file, created by 2 | sphinx-quickstart on Fri Jan 22 11:14:20 2021. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | ADIOS2 Examples 7 | =============== 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | :caption: Introduction 12 | 13 | introduction/introduction 14 | introduction/manualbuild 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | :caption: Concepts 19 | 20 | concepts/streamvsfile 21 | concepts/mpmd 22 | concepts/adiosobjects 23 | concepts/anatomy 24 | concepts/deferredvssync 25 | 26 | .. toctree:: 27 | :maxdepth: 1 28 | :caption: Variables 29 | 30 | variables/introduction 31 | variables/globalarray 32 | variables/globalvalue 33 | variables/localvalue 34 | variables/localarray 35 | variables/strings 36 | 37 | .. toctree:: 38 | :maxdepth: 1 39 | :caption: Fortran 40 | 41 | fortran/fortran.rst 42 | fortran/variables.rst 43 | 44 | .. toctree:: 45 | :maxdepth: 1 46 | :caption: Python 47 | 48 | .. toctree:: 49 | :maxdepth: 1 50 | :caption: C 51 | 52 | .. toctree:: 53 | :maxdepth: 1 54 | :caption: C++ 55 | 56 | 57 | .. toctree:: 58 | :maxdepth: 1 59 | :caption: Performance 60 | 61 | performance/aggregation 62 | 63 | 64 | .. toctree:: 65 | :maxdepth: 1 66 | :caption: Advanced Examples 67 | 68 | advanced/gray-scott 69 | 70 | 71 | Indices and tables 72 | ================== 73 | 74 | * :ref:`genindex` 75 | * :ref:`modindex` 76 | * :ref:`search` 77 | -------------------------------------------------------------------------------- /docs/source/introduction/introduction.rst: -------------------------------------------------------------------------------- 1 | .. _section_introduction: 2 | 3 | Introduction 4 | ############ 5 | 6 | This documentation contains examples for using the `ADIOS2 `_ I/O framework. Install ADIOS2 first on your system. In this documentation we will assume it is installed in ``/opt/adios2`` and that the binaries are in the path. You need to modify the paths to your commands if it is installed somewhere else. 7 | 8 | If you are interested in the Fortran examples, make sure ADIOS2 is configured and built with a Fortran compiler. Similarly, if you are interested in the Python examples, make sure ``Python 3`` is available (with ``Numpy`` and ``MPI4py`` included) when configuring and building ADIOS2, then add the installed adios2 python library to the ``PYTHONPATH``. 9 | 10 | Downloading the examples 11 | ======================== 12 | 13 | The examples are on `GitHub `_. You can download a `release `_ matching the version of your ADIOS2 version, or clone the repository: 14 | 15 | .. code-block:: bash 16 | 17 | git clone https://github.com/ornladios/ADIOS2-Examples 18 | cd ADIOS2-Examples 19 | 20 | 21 | Building the examples 22 | ===================== 23 | 24 | As explained in the `README `_, you can build all the examples at once using CMake or Meson builders. In this case, all the binaries will be located in the build directory. This approach is mostly useful if you want to see how to incorporate ADIOS2 into your own CMake/Meson project or if you just want to quickly build all examples and run them, or if you are on Windows. 25 | 26 | A more manual approach is preferred if you are interested in particular examples. In this documentation we describe and use the examples in this manual approach but you can find the same binaries in the full build, just in a different place (in the build directory). 27 | 28 | Where to start? 29 | =============== 30 | 31 | First we suggest to read the `Components of ADIOS2 `_ in the ADIOS2 documentation. Next, familiarize yourself with the `tools of ADIOS2 `_, mainly ``bpls`` and ``adios2-config``. 32 | 33 | Then start with the :ref:`section-manual-build` example for your choice of language. Then you will be able to build any of the examples individually. 34 | 35 | Please read the CONCEPTS section carefully. It is important to understand them to get the ADIOS IO right. -------------------------------------------------------------------------------- /docs/source/performance/aggregation.rst: -------------------------------------------------------------------------------- 1 | .. _section-aggregation: 2 | 3 | Aggregation 4 | ############ 5 | 6 | There is one basic knob to turn for improving output performance as we scale up an application. Traditional approaches to write a single file from arbitrary number of processes, or to write one file per process, are not scalable. The ADIOS BP format allows for writing the global arrays from many processes into a few files. The number of files should be tuned to the capability of the underlying file system, not to the number of processes. 7 | 8 | You can see that the *.bp* output is actually a directory. So when we say ADIOS file, we actually mean a directory, which contains one or more data files (data. *NNN*), a metadata file (md.0) and an index table (md.idx). 9 | 10 | The BP engine parameter ``NumAggregators`` is an absolute number to choose the desired number of files (if the number of processes is smaller then this number, then the number of processes will apply). The parameter ``AggregatorRatio`` is an integer value to divide the number of processes. The default ratio is one file per shared-memory-domain (i.e. per compute node), which is a good setting for most large scale supercomputers but may be underperforming at small scale if the file system could deal with more files at once. 11 | 12 | 13 | .. code-block:: fortran 14 | 15 | ! Fortran 16 | call adios2_set_parameter(io, "NumAggregators", "100", ierr) 17 | 18 | 19 | .. code-block:: c 20 | 21 | // C 22 | adios2_set_parameter(io, "NumAggregators", "100"); 23 | 24 | .. code-block:: c++ 25 | 26 | // C++ 27 | io.SetParameter("NumAggregators", "100"); 28 | 29 | 30 | .. code-block:: xml 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /docs/source/variables/introduction.rst: -------------------------------------------------------------------------------- 1 | .. _section-variables: 2 | 3 | Variables 4 | ######### 5 | 6 | Start with reading about Variables here ``_ 7 | 8 | Location of examples: 9 | 10 | * C++: ``source/cpp/basics/variables-shapes.cpp`` 11 | 12 | * Fortran: ``source/fortran/shapes`` 13 | 14 | -------------------------------------------------------------------------------- /make.settings: -------------------------------------------------------------------------------- 1 | # Set the ADIOS2 installation directory 2 | ADIOS2_DIR=/opt/adios2 3 | 4 | # Set the MPI compilers if available 5 | MPICC=mpicc 6 | MPICXX=mpicxx 7 | MPIFC=mpif90 8 | 9 | # Set the serial compilers 10 | CC=gcc 11 | CXX=g++ 12 | FC=gfortran 13 | 14 | ###################################################### 15 | # These settings below should not need to be edited # 16 | ###################################################### 17 | 18 | CXX_MPI_FLAGS=`${ADIOS2_DIR}/bin/adios2-config --cxx-flags -m` 19 | CXX_MPI_LDFLAGS=`${ADIOS2_DIR}/bin/adios2-config --cxx-libs -m` 20 | 21 | CXX_FLAGS=`adios2-config --cxx-flags -s` 22 | CXX_LDFLAGS=`adios2-config --cxx-libs -s` 23 | 24 | C_MPI_FLAGS=`${ADIOS2_DIR}/bin/adios2-config --c-flags -m` 25 | C_MPI_LDFLAGS=`${ADIOS2_DIR}/bin/adios2-config --c-libs -m` 26 | 27 | C_FLAGS=`${ADIOS2_DIR}/bin/adios2-config --c-flags -s` 28 | C_LDFLAGS=`${ADIOS2_DIR}/bin/adios2-config --c-libs -s` 29 | 30 | F90_MPI_FLAGS=`${ADIOS2_DIR}/bin/adios2-config --fortran-flags -m` 31 | F90_MPI_LDFLAGS=`${ADIOS2_DIR}/bin/adios2-config --fortran-libs -m` 32 | 33 | F90_FLAGS=`${ADIOS2_DIR}/bin/adios2-config --fortran-flags -s` 34 | F90_LDFLAGS=`${ADIOS2_DIR}/bin/adios2-config --fortran-libs -s` 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | project('ADIOS2-Examples', 7 | ['cpp', 'c'], 8 | license: 'Apache 2', 9 | version: '2.7.0', 10 | meson_version: '>=0.52.0', 11 | default_options : ['c_std=c99', 'cpp_std=c++17', 'buildtype=release', 12 | 'layout=flat'] 13 | ) 14 | 15 | adios2_dep = dependency('adios2', required: true, version: '>=2.7.0', 16 | cmake_module_path: [get_option('ADIOS2_DIR')], 17 | not_found_message: 'adios2 not found, check -DADIOS2_DIR') 18 | 19 | mpi_dep = dependency('mpi', language: 'cpp', required: false) 20 | 21 | # Needed for MPI tests 22 | mpiexec = find_program('mpiexec') 23 | nprocs = '2' 24 | 25 | subdir('source') 26 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | option('ADIOS2_DIR', type : 'string', value : '/opt', description : 'ADIOS2 location') 7 | 8 | -------------------------------------------------------------------------------- /scripts/ci/user-setup.sh: -------------------------------------------------------------------------------- 1 | source /opt/spack/share/spack/setup-env.sh 2 | module use ${SPACK_ROOT}/share/spack/modules/linux-ubuntu18.04-haswell 3 | source ${SPACK_ROOT}/var/spack/environments/adios2/loads 4 | -------------------------------------------------------------------------------- /scripts/conda/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # builds a special adios2 version for Jupyter Notebooks cling using openmpi 4 | 5 | set -e 6 | set -x 7 | 8 | mkdir build-dir 9 | cd build-dir 10 | 11 | cmake \ 12 | -DCMAKE_INSTALL_PREFIX=$PREFIX \ 13 | -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ 14 | -DCMAKE_BUILD_TYPE=Release \ 15 | .. 16 | 17 | make -j 8 18 | make install 19 | 20 | -------------------------------------------------------------------------------- /scripts/conda/meta.yaml: -------------------------------------------------------------------------------- 1 | package: 2 | name: adios2-examples 3 | version: 2.7.0 4 | 5 | build: 6 | number: 0 7 | string: openmpi 8 | 9 | source: 10 | git_url: https://github.com/ornladios/adios2-examples.git 11 | git_rev: v2.7.0 12 | git_depth: 1 13 | 14 | requirements: 15 | build: 16 | - python 17 | - openmpi 18 | - mpi4py 19 | - numpy=1.15 20 | - cmake 21 | - adios2-openmpi=2.7.0=full 22 | run: 23 | - python 24 | - openmpi 25 | - mpi4py 26 | - numpy=1.15 27 | - adios2-openmpi=2.7.0=full 28 | - matplotlib 29 | 30 | about: 31 | home: https://github.com/ornladios/adios2-examples 32 | license: Apache2 33 | license_file: LICENSE 34 | 35 | # build: conda build -c conda-forge -c williamfgc . 36 | -------------------------------------------------------------------------------- /scripts/developer/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Get github username 5 | read -p "Github username: " github_username 6 | if test -z "${github_username}" 7 | then 8 | echo "Github username can't be empty" 9 | exit 10 | fi 11 | 12 | git remote set-url origin https://github.com/${github_username}/ADIOS2-Examples.git 13 | 14 | echo "Checking SSH Github access" 15 | ssh -o ConnectTimeout=10 -T git@github.com 2>/dev/null 16 | 17 | if [ $? -eq 1 ] 18 | then 19 | echo "SSH Github sucess" 20 | git config remote.origin.pushurl "git@github.com:${github_username}/ADIOS2-Examples.git" 21 | else 22 | echo "SSH Github failed. Using HTTPS." 23 | git config remote.origin.pushurl https://${github_username}@github.com/${github_username}/ADIOS2-Examples.git 24 | fi 25 | 26 | git checkout master 27 | git remote rm upstream 28 | git remote add upstream https://github.com/ornladios/ADIOS2-Examples.git 29 | 30 | echo "Local master branch to use upstream" 31 | git config branch.master.remote upstream 32 | git config branch.master.mergeOptions "--ff-only" 33 | git config merge.log 20 34 | git fetch --all -p 35 | 36 | exit 0 -------------------------------------------------------------------------------- /source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | add_subdirectory(c) 7 | add_subdirectory(cpp) 8 | add_subdirectory(gpu) 9 | 10 | if(CMAKE_Fortran_COMPILER_LOADED) 11 | add_subdirectory(fortran) 12 | endif() 13 | -------------------------------------------------------------------------------- /source/c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | if(MPI_FOUND) 7 | set(common_deps adios2::c_mpi MPI::MPI_C) 8 | else() 9 | set(common_deps adios2::c) 10 | endif() 11 | 12 | add_subdirectory(hello-world) 13 | add_subdirectory(shapes) 14 | -------------------------------------------------------------------------------- /source/c/hello-world/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | add_executable(adios2-hello-world-c hello-world.c) 7 | target_link_libraries(adios2-hello-world-c ${common_deps}) 8 | add_test_helper(adios2-hello-world-c) 9 | install(TARGETS adios2-hello-world-c 10 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 11 | ) 12 | -------------------------------------------------------------------------------- /source/c/hello-world/hello-world.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Distributed under the OSI-approved Apache License, Version 2.0. See 3 | * accompanying file Copyright.txt for details. 4 | * 5 | * hello-world.c : adios2 C API example to write and read a 6 | * char* Variable with a greeting 7 | * 8 | * Created on: Nov 14, 2019 9 | * Author: William F Godoy godoywf@ornl.gov 10 | */ 11 | 12 | #include //printf 13 | #include //malloc, free 14 | 15 | #include 16 | #if ADIOS2_USE_MPI 17 | #include 18 | #endif 19 | 20 | void writer(adios2_adios *adios, const char *greeting) 21 | { 22 | adios2_io *io = adios2_declare_io(adios, "hello-world-writer"); 23 | adios2_variable *var_greeting = 24 | adios2_define_variable(io, "Greeting", adios2_type_string, 0, NULL, 25 | NULL, NULL, adios2_constant_dims_true); 26 | 27 | adios2_engine *engine = 28 | adios2_open(io, "hello-world-c.bp", adios2_mode_write); 29 | adios2_put(engine, var_greeting, greeting, adios2_mode_deferred); 30 | adios2_close(engine); 31 | } 32 | 33 | void reader(adios2_adios *adios, char *greeting) 34 | { 35 | adios2_step_status status; 36 | adios2_io *io = adios2_declare_io(adios, "hello-world-reader"); 37 | adios2_engine *engine = 38 | adios2_open(io, "hello-world-c.bp", adios2_mode_read); 39 | adios2_variable *var_greeting = adios2_inquire_variable(io, "Greeting"); 40 | adios2_begin_step(engine, adios2_step_mode_read, -1., &status); 41 | adios2_get(engine, var_greeting, greeting, adios2_mode_deferred); 42 | adios2_end_step(engine); 43 | adios2_close(engine); 44 | } 45 | 46 | int main(int argc, char *argv[]) 47 | { 48 | #if ADIOS2_USE_MPI 49 | MPI_Init(&argc, &argv); 50 | #endif 51 | 52 | { 53 | #if ADIOS2_USE_MPI 54 | adios2_adios *adios = adios2_init_mpi(MPI_COMM_WORLD); 55 | #else 56 | adios2_adios *adios = adios2_init(); 57 | #endif 58 | 59 | const char greeting[] = "Hello World from ADIOS2"; 60 | writer(adios, greeting); 61 | 62 | char *message = (char *)malloc(24); 63 | reader(adios, message); 64 | printf("%s\n", message); 65 | 66 | free(message); 67 | } 68 | 69 | #if ADIOS2_USE_MPI 70 | MPI_Finalize(); 71 | #endif 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /source/c/hello-world/meson.build: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | hello_world_exe = executable('adios2-hello-world-c', 'hello-world.c', 7 | dependencies : [mpi_dep, adios2_dep], install: true) 8 | 9 | # MPI test 10 | test('hello-world-c', mpiexec, args:['-np', nprocs, hello_world_exe], timeout: 10, 11 | is_parallel: false) 12 | -------------------------------------------------------------------------------- /source/c/meson.build: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | subdir('hello-world') -------------------------------------------------------------------------------- /source/c/shapes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | add_library(mpivars OBJECT mpivars.c) 6 | target_link_libraries(mpivars ${common_deps}) 7 | 8 | add_library(decomp OBJECT decomp.c) 9 | target_link_libraries(decomp ${common_deps}) 10 | 11 | add_executable(adios2-global-array-fixed-write-c 12 | global-array-fixed-write.c) 13 | 14 | target_link_libraries(adios2-global-array-fixed-write-c mpivars decomp ${common_deps}) 15 | 16 | add_executable(adios2-global-array-fixed-read-c 17 | global-array-fixed-read.c) 18 | 19 | target_link_libraries(adios2-global-array-fixed-read-c mpivars decomp ${common_deps}) 20 | -------------------------------------------------------------------------------- /source/c/shapes/decomp.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dmitry Ganyushin ganyushindi@ornl.gov 3 | // 4 | // Helper functions for all examples 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "decomp.h" 10 | #include "mpivars.h" 11 | 12 | /* random integer from {minv, minv+1, ..., maxv} 13 | including minv and maxv */ 14 | long long int get_random(int minv, int maxv) 15 | { 16 | long long int n; 17 | time_t t; 18 | /* Intializes random number generator */ 19 | srand((unsigned) time(&t)); 20 | n = (rand() % (maxv - minv + 1)) + minv; 21 | return n; 22 | } 23 | /* gather the local sizes of arrays and sum them up 24 | so that each process knows the global shape 25 | and its own offset in the global space */ 26 | void gather_decomp_1d( long long int *mysize, long long int *myshape, long long int *myoffset) 27 | { 28 | long long int *sizes; 29 | int i; 30 | sizes = malloc(sizeof(long long int) * nproc); 31 | MPI_Allgather(mysize, 1, MPI_LONG_LONG, sizes, 1, MPI_LONG_LONG, app_comm); 32 | 33 | *myshape = 0; 34 | for (i = 0; i < nproc; i++) 35 | { 36 | *myshape += sizes[i]; 37 | } 38 | *myoffset = 0; 39 | for (i = 0; i < rank; i++) 40 | { 41 | *myoffset += sizes[i]; 42 | } 43 | 44 | free(sizes); 45 | return; 46 | } 47 | 48 | 49 | void decomp_1d(long long int globalsize, long long int *myoffset, 50 | long long int *mysize) 51 | { 52 | long long int rem; 53 | *mysize = globalsize / nproc; 54 | rem = globalsize - (nproc * *mysize); 55 | if (rank < rem) 56 | { 57 | mysize = mysize + 1; 58 | *myoffset = rank * *mysize; 59 | } 60 | else 61 | { 62 | *myoffset = rank * *mysize + rem; 63 | } 64 | return; 65 | } 66 | -------------------------------------------------------------------------------- /source/c/shapes/decomp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dmitry Ganyushin ganyushindi@ornl.gov 3 | // 4 | 5 | #ifndef ADIOS2EXAMPLES_DECOMP_H 6 | #define ADIOS2EXAMPLES_DECOMP_H 7 | 8 | extern long long int get_random(int, int); 9 | extern void gather_decomp_1d(long long int *, long long int *, long long int *); 10 | extern void decomp_1d(long long int, long long int *, long long int *); 11 | #endif // ADIOS2EXAMPLES_DECOMP_H 12 | -------------------------------------------------------------------------------- /source/c/shapes/global-array-fixed-read.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dmitry Ganyushin ganyuhsindi@ornl.gov 3 | // 4 | #include "decomp.h" 5 | #include "mpivars.h" 6 | #include 7 | #include 8 | #include 9 | 10 | void reader(adios2_adios *adios) 11 | { 12 | int step; 13 | float *g; 14 | const char *streamname = "adios2-global-array-fixed-c.bp"; 15 | adios2_step_status err; 16 | 17 | long long int fixed_shape = 0, fixed_start = 0, fixed_count = 0; 18 | 19 | adios2_io *io = adios2_declare_io(adios, "input"); 20 | size_t shape[1]; 21 | shape[0] = fixed_shape; 22 | 23 | size_t start[1]; 24 | start[0] = fixed_start; 25 | 26 | size_t count[1]; 27 | count[0] = fixed_count; 28 | 29 | adios2_engine *engine = adios2_open(io, streamname, adios2_mode_read); 30 | step = 0; 31 | do 32 | { 33 | adios2_begin_step(engine, adios2_step_mode_read, 10.0, &err); 34 | adios2_variable *var_g = adios2_inquire_variable(io, "GlobalArray"); 35 | if (step == 0) 36 | { 37 | /* fixed_shape is allocated in the next call*/ 38 | adios2_variable_shape(shape, var_g); 39 | fixed_shape = shape[0]; 40 | decomp_1d(fixed_shape, &fixed_start, &fixed_count); 41 | g = malloc(fixed_count * sizeof(float)); 42 | 43 | printf("Read plan rank = %d global shape = %lld local count = %lld " 44 | "offset = %lld\n", 45 | rank, fixed_shape, fixed_count, fixed_start); 46 | } 47 | adios2_end_step(engine); 48 | step++; 49 | } while (err != adios2_step_status_end_of_stream); 50 | // Close the output 51 | adios2_close(engine); 52 | free(g); 53 | 54 | if (rank == 0) 55 | { 56 | printf("Try the following: \n"); 57 | printf(" bpls -la adios2-global-array-fixed-c.bp GlobalArray -d -n " 58 | "%lld \n", 59 | fixed_shape); 60 | printf(" bpls -la adios2-global-array-fixed-c.bp GlobalArray -d -t -n " 61 | "%lld \n ", 62 | fixed_shape); 63 | printf(" mpirun -n 2 ./adios2-global-array-fixed-read-c \n"); 64 | } 65 | } 66 | 67 | int main(int argc, char *argv[]) 68 | { 69 | #if ADIOS2_USE_MPI 70 | init_mpi(123, argc, argv); 71 | #endif 72 | 73 | { 74 | #if ADIOS2_USE_MPI 75 | 76 | adios2_adios *adios = adios2_init_mpi(MPI_COMM_WORLD); 77 | #else 78 | adios2_adios *adios = adios2_init(); 79 | #endif 80 | reader(adios); 81 | adios2_finalize(adios); 82 | } 83 | 84 | #if ADIOS2_USE_MPI 85 | finalize_mpi(); 86 | #endif 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /source/c/shapes/global-array-fixed-write.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dmitry Ganyushin ganyushindi@ornl.gov 3 | // 4 | #include "decomp.h" 5 | #include "mpivars.h" 6 | #include 7 | #include 8 | #include 9 | 10 | void writer(adios2_adios *adios) 11 | { 12 | int step, i; 13 | float *g; 14 | const char *ga = "Global Array with fixed shape and decomposition"; 15 | const int mincount = 2; 16 | const int maxcount = 5; 17 | const int numsteps = 5; 18 | adios2_step_status err; 19 | 20 | long long int fixed_shape = 0, fixed_start = 0, fixed_count = 0; 21 | 22 | /* Application variables 23 | g = 1D distributed array, 24 | global shape and per-process size is fixed */ 25 | fixed_count = get_random(mincount, maxcount); 26 | g = malloc(fixed_count * sizeof(float)); 27 | gather_decomp_1d(&fixed_count, &fixed_shape, &fixed_start); 28 | 29 | adios2_io *io = adios2_declare_io(adios, "output"); 30 | size_t shape[1]; 31 | shape[0] = fixed_shape; 32 | 33 | size_t start[1]; 34 | start[0] = fixed_start; 35 | 36 | size_t count[1]; 37 | count[0] = fixed_count; 38 | 39 | adios2_variable *var_g = 40 | adios2_define_variable(io, "GlobalArray", adios2_type_float, 1, shape, 41 | start, count, adios2_constant_dims_true); 42 | 43 | adios2_attribute *attr = 44 | adios2_define_attribute(io, "GlobalArray/info", adios2_type_string, ga); 45 | 46 | adios2_engine *engine = 47 | adios2_open(io, "adios2-global-array-fixed-c.bp", adios2_mode_write); 48 | printf("Decmp rank = %d global shape = %lld local count = %lld offset = " 49 | "%lld\n", 50 | rank, fixed_shape, fixed_count, fixed_start); 51 | for (step = 0; step < numsteps; step++) 52 | { 53 | for (i = 0; i < fixed_count; i++) 54 | { 55 | g[i] = rank + (step + 1) / 100.0; 56 | } 57 | 58 | adios2_begin_step(engine, adios2_step_mode_append, 10.0, &err); 59 | adios2_put(engine, var_g, g, adios2_mode_deferred); 60 | adios2_end_step(engine); 61 | } 62 | // Close the output 63 | adios2_close(engine); 64 | free(g); 65 | 66 | if (rank == 0) 67 | { 68 | printf("Try the following: \n"); 69 | printf(" bpls -la adios2-global-array-fixed-c.bp GlobalArray -d -n " 70 | "%lld \n", 71 | fixed_shape); 72 | printf(" bpls -la adios2-global-array-fixed-c.bp GlobalArray -d -t -n " 73 | "%lld \n ", 74 | fixed_shape); 75 | printf(" mpirun -n 2 ./adios2-global-array-fixed-read-c \n"); 76 | } 77 | } 78 | 79 | int main(int argc, char *argv[]) 80 | { 81 | #if ADIOS2_USE_MPI 82 | init_mpi(123, argc, argv); 83 | #endif 84 | 85 | { 86 | #if ADIOS2_USE_MPI 87 | 88 | adios2_adios *adios = adios2_init_mpi(MPI_COMM_WORLD); 89 | #else 90 | adios2_adios *adios = adios2_init(); 91 | #endif 92 | 93 | writer(adios); 94 | adios2_finalize(adios); 95 | } 96 | 97 | #if ADIOS2_USE_MPI 98 | finalize_mpi(); 99 | #endif 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /source/c/shapes/mpivars.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dmitry Ganyushin ganyushindi@ornl.gov 3 | // 4 | #include "mpivars.h" 5 | #include 6 | 7 | int rank, nproc; 8 | int wrank, wnproc; 9 | MPI_Comm app_comm; 10 | 11 | void init_mpi(int color, int argc, char *argv[]) 12 | { 13 | MPI_Init(&argc, &argv); 14 | /* World comm spans all applications started with the same mpirun command */ 15 | MPI_Comm_rank(MPI_COMM_WORLD, &wrank); 16 | MPI_Comm_size(MPI_COMM_WORLD, &wnproc); 17 | 18 | /* Have to split and create a 'world' communicator for this app only 19 | color must be unique for each application*/ 20 | MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &app_comm); 21 | MPI_Comm_rank(app_comm, &rank); 22 | MPI_Comm_size(app_comm, &nproc); 23 | return; 24 | } 25 | 26 | void finalize_mpi() { MPI_Finalize(); } 27 | -------------------------------------------------------------------------------- /source/c/shapes/mpivars.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Dmitry Ganyushin ganyushindi@ornl.gov 3 | // 4 | 5 | #ifndef ADIOS2EXAMPLES_MPIVARS_H 6 | #define ADIOS2EXAMPLES_MPIVARS_H 7 | #include 8 | extern int rank, nproc; 9 | extern MPI_Comm app_comm; 10 | void init_mpi(int, int, char *argv[]); 11 | void finalize_mpi(); 12 | #endif // ADIOS2EXAMPLES_MPIVARS_H 13 | -------------------------------------------------------------------------------- /source/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | if(MPI_FOUND) 7 | set(common_deps adios2::cxx11_mpi MPI::MPI_C) 8 | else() 9 | set(common_deps adios2::cxx11) 10 | endif() 11 | 12 | add_subdirectory(basics) 13 | 14 | if(MPI_FOUND) 15 | add_subdirectory(gray-scott) 16 | add_subdirectory(gray-scott-struct) 17 | endif() 18 | 19 | add_subdirectory(hello-world) 20 | add_subdirectory(korteweg-de-vries) 21 | 22 | if(CMAKE_CXX_STANDARD GREATER_EQUAL 17) 23 | add_subdirectory(lorenz_ode) 24 | endif() 25 | -------------------------------------------------------------------------------- /source/cpp/basics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | add_executable(adios2-variables-shapes-cpp variables-shapes.cpp) 7 | target_link_libraries(adios2-variables-shapes-cpp ${common_deps}) 8 | add_test_helper(adios2-variables-shapes-cpp) 9 | install(TARGETS adios2-variables-shapes-cpp 10 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 11 | ) 12 | 13 | add_executable(adios2-variables-shapes-hl-cpp variables-shapes-hl.cpp) 14 | target_link_libraries(adios2-variables-shapes-hl-cpp ${common_deps}) 15 | add_test_helper(adios2-variables-shapes-hl-cpp) 16 | install(TARGETS adios2-variables-shapes-hl-cpp 17 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 18 | ) 19 | 20 | if(Threads_FOUND) 21 | add_executable(adios2-thread-write-cpp thread-write.cpp) 22 | target_link_libraries(adios2-thread-write-cpp ${common_deps} Threads::Threads) 23 | add_test_helper(adios2-thread-write-cpp) 24 | install(TARGETS adios2-thread-write-cpp 25 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 26 | ) 27 | endif() 28 | -------------------------------------------------------------------------------- /source/cpp/basics/meson.build: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | names = ['variables-shapes', 'variables-shapes-hl', 'thread-write'] 7 | 8 | # meson is not Turing-complete, so user-defined functions are not possible 9 | # still this is a great workaround 10 | foreach name : names 11 | exe = executable('adios2-'+name+'-cpp', name+'.cpp', 12 | dependencies : [mpi_dep, adios2_dep], install: true) 13 | test(name+'-cpp', mpiexec, args:['-np', nprocs, exe], 14 | timeout: 10, is_parallel: false) 15 | endforeach 16 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | # ------------------------------------------------------------------------------# 5 | 6 | add_executable(adios2-gray-scott-struct 7 | simulation/main.cpp 8 | simulation/gray-scott.cpp 9 | simulation/settings.cpp 10 | simulation/writer.cpp 11 | simulation/restart.cpp 12 | ) 13 | target_link_libraries(adios2-gray-scott-struct adios2::adios2 MPI::MPI_C) 14 | install(TARGETS adios2-gray-scott-struct 15 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 16 | 17 | add_executable(adios2-pdf-calc-struct analysis/pdf-calc.cpp) 18 | target_link_libraries(adios2-pdf-calc-struct adios2::adios2 MPI::MPI_C) 19 | install(TARGETS adios2-pdf-calc-struct 20 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 21 | 22 | install(FILES "adios2.xml" "adios2-inline-plugin.xml" 23 | "visit-bp4.session" "visit-bp4.session.gui" 24 | "visit-sst.session" "visit-sst.session.gui" 25 | "simulation/settings-files.json" 26 | "simulation/settings-staging.json" 27 | "simulation/settings-inline.json" 28 | "plot/decomp.py" "plot/gsplot.py" "plot/pdfplot.py" 29 | "README.md" 30 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/adios2-examples/gray-scott-struct) 31 | 32 | install(DIRECTORY "catalyst" 33 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/adios2-examples/gray-scott-struct) 34 | 35 | install(PROGRAMS "cleanup.sh" 36 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/adios2-examples/gray-scott-struct) 37 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/catalyst/gs-fides.json: -------------------------------------------------------------------------------- 1 | { 2 | "VTK-Cartesian-grid": { 3 | "data_sources": [ 4 | { 5 | "name": "source", 6 | "filename_mode": "input" 7 | } 8 | ], 9 | "step_information": { 10 | "data_source": "source", 11 | "variable": "step" 12 | }, 13 | "coordinate_system" : { 14 | "array" : { 15 | "array_type" : "uniform_point_coordinates", 16 | "dimensions" : { 17 | "source" : "variable_dimensions", 18 | "data_source": "source", 19 | "variable" : "U" 20 | }, 21 | "origin" : { 22 | "source" : "array", 23 | "values" : [0.0, 0.0, 0.0] 24 | }, 25 | "spacing" : { 26 | "source" : "array", 27 | "values" : [0.1, 0.1, 0.1] 28 | } 29 | } 30 | }, 31 | "cell_set": { 32 | "cell_set_type" : "structured", 33 | "dimensions" : { 34 | "source" : "variable_dimensions", 35 | "data_source": "source", 36 | "variable" : "U" 37 | } 38 | }, 39 | "fields": [ 40 | { 41 | "name": "U", 42 | "association": "points", 43 | "array" : { 44 | "array_type" : "basic", 45 | "data_source": "source", 46 | "variable" : "U" 47 | } 48 | }, 49 | { 50 | "name": "V", 51 | "association": "points", 52 | "array" : { 53 | "array_type" : "basic", 54 | "data_source": "source", 55 | "variable" : "V" 56 | } 57 | } 58 | ] 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/catalyst/gs-pipeline.py: -------------------------------------------------------------------------------- 1 | from paraview.simple import * 2 | from paraview import print_info 3 | 4 | # catalyst options 5 | from paraview.catalyst import Options 6 | options = Options() 7 | 8 | # print start marker 9 | print_info("begin '%s'", __name__) 10 | 11 | # directory under which to save all extracts 12 | # generated using Extractors defined in the pipeline 13 | # (optional, but recommended) 14 | options.ExtractsOutputDirectory = '.' 15 | SaveExtractsUsingCatalystOptions(options) 16 | 17 | view = CreateRenderView() 18 | # when using Fides, registrationName is always 'fides' 19 | producer = TrivialProducer(registrationName='fides') 20 | display = Show(producer) 21 | view.ResetCamera() 22 | ColorBy(display, ('POINTS', 'U')) 23 | display.RescaleTransferFunctionToDataRange(True, False) 24 | display.SetScalarBarVisibility(view, True) 25 | transFunc = GetColorTransferFunction('U') 26 | transFunc.RescaleOnVisibilityChange = 1 27 | 28 | display.SetRepresentationType('Surface') 29 | 30 | clip = Clip(registrationName="clip1", Input=producer) 31 | clip.ClipType = 'Plane' 32 | clip.Scalars = ['POINTS', 'U'] 33 | clip.ClipType.Origin = [1.5, 1.5, 1.5] 34 | clip.ClipType.Normal = [0.0, 1.0, 0.0] 35 | clipDisplay = Show(clip, view, 'UnstructuredGridRepresentation') 36 | 37 | Hide(producer, view) 38 | view.ResetCamera() 39 | 40 | camera = GetActiveCamera() 41 | camera.Azimuth(45) 42 | camera.Elevation(45) 43 | 44 | # the extractor will save the view on each time step 45 | extractor = CreateExtractor('PNG', view, registrationName='PNG1') 46 | extractor.Writer.FileName = 'output-{timestep}.png' 47 | extractor.Writer.ImageResolution = [800, 800] 48 | 49 | 50 | def catalyst_execute(info): 51 | print_info("in '%s::catalyst_execute'", __name__) 52 | global producer 53 | producer.UpdatePipeline() 54 | print("updating pipeline and saving image") 55 | 56 | #print("-----------------------------------") 57 | #print("executing (cycle={}, time={})".format(info.cycle, info.time)) 58 | #print("bounds:", producer.GetDataInformation().GetBounds()) 59 | #print("U-range:", producer.PointData['U'].GetRange(0)) 60 | #print("V-range:", producer.PointData['V'].GetRange(0)) 61 | 62 | 63 | # print end marker 64 | print_info("end '%s'", __name__) 65 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/catalyst/setup.sh: -------------------------------------------------------------------------------- 1 | # The ${PARAVIEW_BUILD_PATH}/lib directory should contain `libADIOSInSituPlugin.so`. 2 | export PARAVIEW_BUILD_PATH=/home/adios/Software/paraview/build 3 | # Set the following env variables. 4 | export ADIOS2_PLUGIN_PATH=${PARAVIEW_BUILD_PATH}/lib 5 | export CATALYST_IMPLEMENTATION_NAME=paraview 6 | export CATALYST_IMPLEMENTATION_PATHS=${PARAVIEW_BUILD_PATH}/lib/catalyst 7 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Cmds: help data code all 4 | cmd=${1:-help} 5 | 6 | fail=yes 7 | 8 | if [ "x$cmd" == "xcode" -o "x$cmd" == "xall" ]; then 9 | echo "== cleanup code in build/" 10 | cd build 11 | make clean 12 | cd - 13 | fail=no 14 | fi 15 | if [ "x$cmd" == "xdata" -o "x$cmd" == "xall" ]; then 16 | echo "== cleanup data" 17 | rm -rf *.bp *.bp.dir *.h5 18 | rm -rf *.sst *.ssc *_insitumpi_* 19 | rm -rf *.png *.pnm *.jpg 20 | rm -rf *.log 21 | fail=no 22 | fi 23 | 24 | 25 | if [ "x$cmd" == "xhelp" -o "x$cmd" == "xh" -o "$fail" == "yes" ]; then 26 | echo "./cleanup.sh [ data | code | all ]" 27 | fi 28 | 29 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/common/timer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_HPP__ 2 | #define __TIMER_HPP__ 3 | 4 | #include 5 | 6 | class Timer 7 | { 8 | private: 9 | bool _is_running; 10 | std::chrono::steady_clock::time_point _start; 11 | std::chrono::steady_clock::duration _total; 12 | 13 | double _to_millis(std::chrono::steady_clock::duration duration) const 14 | { 15 | std::chrono::duration duration_ms(duration); 16 | return duration_ms.count(); 17 | } 18 | 19 | public: 20 | Timer() 21 | : _is_running(false), _total(std::chrono::steady_clock::duration::zero()) 22 | { 23 | } 24 | 25 | void start() 26 | { 27 | _is_running = true; 28 | _start = std::chrono::steady_clock::now(); 29 | } 30 | 31 | double stop() 32 | { 33 | _is_running = false; 34 | 35 | const auto elapsed = std::chrono::steady_clock::now() - _start; 36 | 37 | _total += elapsed; 38 | 39 | return _to_millis(elapsed); 40 | } 41 | 42 | void reset() 43 | { 44 | _is_running = false; 45 | _total = std::chrono::steady_clock::duration::zero(); 46 | } 47 | 48 | bool is_running() const { return _is_running; } 49 | 50 | double elapsed() const { return _to_millis(_total); } 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/img/example1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott-struct/img/example1.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/img/example2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott-struct/img/example2.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/img/example3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott-struct/img/example3.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/img/example4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott-struct/img/example4.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/img/example5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott-struct/img/example5.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/meson.build: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | gray_scott_exe = executable('adios2-gray-scott', 7 | ['simulation/main.cpp', 8 | 'simulation/gray-scott.cpp', 9 | 'simulation/settings.cpp', 10 | 'simulation/writer.cpp'], 11 | dependencies : [mpi_dep, adios2_dep], 12 | install: true) 13 | 14 | pdf_calc_exe = executable('adios2-pdf-calc', 'analysis/pdf-calc.cpp', 15 | dependencies : [mpi_dep, adios2_dep], 16 | install: true) 17 | 18 | install_data(['adios2.xml','visit-bp4.session','visit-bp4.session.gui', 19 | 'visit-sst.session','visit-sst.session.gui', 20 | 'simulation/settings-files.json', 21 | 'simulation/settings-staging.json', 22 | 'plot/decomp.py','plot/gsplot.py','plot/pdfplot.py', 23 | 'cleanup.sh', 'README.md'], 24 | install_dir : 'share/adios2-examples/gray-scott') 25 | 26 | install_data(['img/example1.jpg','img/example2.jpg','img/example3.jpg', 27 | 'img/example4.jpg'], 28 | install_dir : 'share/adios2-examples/gray-scott/img') 29 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Keichi Takahashi 2 | Copyright (c) 2018 Hiroshi Watanabe 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/restart.cpp: -------------------------------------------------------------------------------- 1 | #include "restart.h" 2 | 3 | #include 4 | 5 | static bool firstCkpt = true; 6 | 7 | using DataType = std::complex; 8 | 9 | void WriteCkpt(MPI_Comm comm, const int step, const Settings &settings, 10 | const GrayScott &sim, adios2::IO io) 11 | { 12 | int rank, nproc; 13 | MPI_Comm_rank(comm, &rank); 14 | MPI_Comm_size(comm, &nproc); 15 | std::cout << "checkpoint at step " << step << " create file " 16 | << settings.checkpoint_output << std::endl; 17 | adios2::Engine writer = 18 | io.Open(settings.checkpoint_output, adios2::Mode::Write); 19 | if (writer) 20 | { 21 | adios2::Variable var_uv; 22 | adios2::Variable var_step; 23 | 24 | if (firstCkpt) 25 | { 26 | size_t X = sim.size_x + 2; 27 | size_t Y = sim.size_y + 2; 28 | size_t Z = sim.size_z + 2; 29 | size_t R = static_cast(rank); 30 | size_t N = static_cast(nproc); 31 | 32 | var_uv = io.DefineVariable("UV", {N, X, Y, Z}, 33 | {R, 0, 0, 0}, {1, X, Y, Z}); 34 | 35 | var_step = io.DefineVariable("step"); 36 | firstCkpt = false; 37 | } 38 | else 39 | { 40 | var_uv = io.InquireVariable("UV"); 41 | var_step = io.InquireVariable("step"); 42 | } 43 | 44 | writer.Put(var_step, &step); 45 | const DataType *ptr = 46 | reinterpret_cast(sim.d_ghost().data()); 47 | writer.Put(var_uv, ptr); 48 | 49 | writer.Close(); 50 | } 51 | } 52 | 53 | int ReadRestart(MPI_Comm comm, const Settings &settings, GrayScott &sim, 54 | adios2::IO io) 55 | { 56 | int step = 0; 57 | int rank, nproc; 58 | MPI_Comm_rank(comm, &rank); 59 | MPI_Comm_size(comm, &nproc); 60 | if (!rank) 61 | { 62 | std::cout << "restart from file " << settings.restart_input 63 | << std::endl; 64 | } 65 | adios2::Engine reader = 66 | io.Open(settings.restart_input, adios2::Mode::ReadRandomAccess); 67 | if (reader) 68 | { 69 | adios2::Variable var_step = io.InquireVariable("step"); 70 | adios2::Variable var_uv = io.InquireVariable("UV"); 71 | size_t X = sim.size_x + 2; 72 | size_t Y = sim.size_y + 2; 73 | size_t Z = sim.size_z + 2; 74 | size_t R = static_cast(rank); 75 | std::vector uv(X * Y * Z); 76 | 77 | var_uv.SetSelection({{R, 0, 0, 0}, {1, X, Y, Z}}); 78 | reader.Get(var_step, step); 79 | reader.Get(var_uv, reinterpret_cast(uv.data())); 80 | reader.Close(); 81 | 82 | if (!rank) 83 | { 84 | std::cout << "restart from step " << step << std::endl; 85 | } 86 | sim.restart(uv); 87 | } 88 | else 89 | { 90 | std::cout << " failed to open file " << std::endl; 91 | } 92 | return step; 93 | } 94 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/restart.h: -------------------------------------------------------------------------------- 1 | #ifndef __RESTART_H__ 2 | #define __RESTART_H__ 3 | 4 | #include "gray-scott.h" 5 | #include "settings.h" 6 | 7 | #include 8 | #include 9 | 10 | void WriteCkpt(MPI_Comm comm, const int step, const Settings &settings, 11 | const GrayScott &sim, adios2::IO io); 12 | int ReadRestart(MPI_Comm comm, const Settings &settings, GrayScott &sim, 13 | adios2::IO io); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/settings-files.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 64, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.01, 6 | "k": 0.05, 7 | "dt": 2.0, 8 | "plotgap": 10, 9 | "steps": 1000, 10 | "noise": 0.0000001, 11 | "output": "gs.bp", 12 | "checkpoint": true, 13 | "checkpoint_freq": 700, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": false, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": false, 20 | "mesh_type": "image" 21 | } 22 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/settings-inline.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 64, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.02, 6 | "k": 0.048, 7 | "dt": 2.0, 8 | "plotgap": 100, 9 | "steps": 1000, 10 | "noise": 0.0000001, 11 | "output": "gs.bp", 12 | "checkpoint": true, 13 | "checkpoint_freq": 700, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": false, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2-inline-plugin.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": false, 20 | "mesh_type": "image" 21 | } 22 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/settings-staging.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 64, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.01, 6 | "k": 0.05, 7 | "dt": 2.0, 8 | "plotgap": 10, 9 | "steps": 60000, 10 | "noise": 0.0000001, 11 | "output": "gs.bp", 12 | "checkpoint": false, 13 | "checkpoint_freq": 1000, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": false, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": true, 20 | "mesh_type": "image" 21 | } 22 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/settings.cpp: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include 4 | 5 | #include "json.hpp" 6 | 7 | void to_json(nlohmann::json &j, const Settings &s) 8 | { 9 | j = nlohmann::json{{"L", s.L}, 10 | {"steps", s.steps}, 11 | {"plotgap", s.plotgap}, 12 | {"F", s.F}, 13 | {"k", s.k}, 14 | {"dt", s.dt}, 15 | {"Du", s.Du}, 16 | {"Dv", s.Dv}, 17 | {"noise", s.noise}, 18 | {"output", s.output}, 19 | {"checkpoint", s.checkpoint}, 20 | {"checkpoint_freq", s.checkpoint_freq}, 21 | {"checkpoint_output", s.checkpoint_output}, 22 | {"restart", s.restart}, 23 | {"restart_input", s.restart_input}, 24 | {"adios_config", s.adios_config}, 25 | {"adios_span", s.adios_span}, 26 | {"adios_memory_selection", s.adios_memory_selection}, 27 | {"mesh_type", s.mesh_type}}; 28 | } 29 | 30 | void from_json(const nlohmann::json &j, Settings &s) 31 | { 32 | j.at("L").get_to(s.L); 33 | j.at("steps").get_to(s.steps); 34 | j.at("plotgap").get_to(s.plotgap); 35 | j.at("F").get_to(s.F); 36 | j.at("k").get_to(s.k); 37 | j.at("dt").get_to(s.dt); 38 | j.at("Du").get_to(s.Du); 39 | j.at("Dv").get_to(s.Dv); 40 | j.at("noise").get_to(s.noise); 41 | j.at("output").get_to(s.output); 42 | j.at("checkpoint").get_to(s.checkpoint); 43 | j.at("checkpoint_freq").get_to(s.checkpoint_freq); 44 | j.at("checkpoint_output").get_to(s.checkpoint_output); 45 | j.at("restart").get_to(s.restart); 46 | j.at("restart_input").get_to(s.restart_input); 47 | j.at("adios_config").get_to(s.adios_config); 48 | j.at("adios_span").get_to(s.adios_span); 49 | j.at("adios_memory_selection").get_to(s.adios_memory_selection); 50 | j.at("mesh_type").get_to(s.mesh_type); 51 | } 52 | 53 | Settings::Settings() 54 | { 55 | L = 128; 56 | steps = 20000; 57 | plotgap = 200; 58 | F = 0.04; 59 | k = 0.06075; 60 | dt = 0.2; 61 | Du = 0.05; 62 | Dv = 0.1; 63 | noise = 0.0; 64 | output = "foo.bp"; 65 | checkpoint = false; 66 | checkpoint_freq = 2000; 67 | checkpoint_output = "ckpt.bp"; 68 | restart = false; 69 | restart_input = "ckpt.bp"; 70 | adios_config = "adios2.xml"; 71 | adios_span = false; 72 | adios_memory_selection = false; 73 | mesh_type = "image"; 74 | } 75 | 76 | Settings Settings::from_json(const std::string &fname) 77 | { 78 | std::ifstream ifs(fname); 79 | nlohmann::json j; 80 | 81 | ifs >> j; 82 | 83 | return j.get(); 84 | } 85 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/settings.h: -------------------------------------------------------------------------------- 1 | #ifndef __SETTINGS_H__ 2 | #define __SETTINGS_H__ 3 | 4 | #include 5 | 6 | struct Settings 7 | { 8 | size_t L; 9 | int steps; 10 | int plotgap; 11 | double F; 12 | double k; 13 | double dt; 14 | double Du; 15 | double Dv; 16 | double noise; 17 | std::string output; 18 | bool checkpoint; 19 | int checkpoint_freq; 20 | std::string checkpoint_output; 21 | bool restart; 22 | std::string restart_input; 23 | std::string adios_config; 24 | bool adios_span; 25 | bool adios_memory_selection; 26 | std::string mesh_type; 27 | 28 | Settings(); 29 | static Settings from_json(const std::string &fname); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/simulation/writer.h: -------------------------------------------------------------------------------- 1 | #ifndef __WRITER_H__ 2 | #define __WRITER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "gray-scott.h" 8 | #include "settings.h" 9 | 10 | class Writer 11 | { 12 | public: 13 | Writer(const Settings &settings, const GrayScott &sim, adios2::IO io); 14 | void open(const std::string &fname, bool append); 15 | void write(int step, const GrayScott &sim); 16 | void close(); 17 | 18 | protected: 19 | Settings settings; 20 | 21 | adios2::IO io; 22 | adios2::Engine writer; 23 | adios2::Variable var_u; 24 | adios2::Variable var_v; 25 | adios2::Variable var_step; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/test-firstrun.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 16, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.01, 6 | "k": 0.05, 7 | "dt": 2.0, 8 | "plotgap": 1, 9 | "steps": 10, 10 | "noise": 0.0000000, 11 | "output": "gs.bp", 12 | "checkpoint": true, 13 | "checkpoint_freq": 7, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": false, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": false, 20 | "mesh_type": "image" 21 | } 22 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/test-restart.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 16, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.01, 6 | "k": 0.05, 7 | "dt": 2.0, 8 | "plotgap": 1, 9 | "steps": 10, 10 | "noise": 0.0000000, 11 | "output": "gs.bp", 12 | "checkpoint": true, 13 | "checkpoint_freq": 7, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": true, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": false, 20 | "mesh_type": "image" 21 | } 22 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/visit-bp4.session.gui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3.0.0b 4 | 5 | 6 | gs.bp 7 | * 8 | true 9 | true 10 | true 11 | false 12 | 13 | "gs.bp" 14 | 15 | 16 | 17 | true 18 | #c0c0c0 19 | #000000 20 | Helvetica,12,-1,5,50,0,0,0,0,0 21 | gtk 22 | 0 23 | #000000 24 | #efefef 25 | "Sans Serif,9,-1,5,50,0,0,0,0,0" 26 | Fusion 27 | 0 28 | 29 | false 30 | 31 | 4 32 | 52 33 | 398 34 | 2104 35 | 0 0.544259 0.4537178 36 | 37 | 38 | 2742 39 | 916 40 | 498 41 | 832 42 | false 43 | false 44 | 45 | "localhost:gs.bp/md.0" 46 | 47 | Cycles 48 | 5 49 | 50 | false 51 | true 52 | true 53 | 54 | 55 | -------------------------------------------------------------------------------- /source/cpp/gray-scott-struct/visit-sst.session.gui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3.0.0b 4 | 5 | 6 | /home/adios/Tutorial/share 7 | * 8 | true 9 | true 10 | true 11 | false 12 | 13 | "/home/adios/Tutorial/share" 14 | 15 | 16 | 17 | true 18 | #c0c0c0 19 | #000000 20 | Helvetica,12,-1,5,50,0,0,0,0,0 21 | gtk 22 | 0 23 | #000000 24 | #efefef 25 | "Sans Serif,9,-1,5,50,0,0,0,0,0" 26 | Fusion 27 | 0 28 | 29 | false 30 | 31 | 4 32 | 52 33 | 398 34 | 2104 35 | 0 0.544259 0.4537178 36 | 37 | 38 | 2378 39 | 1078 40 | 498 41 | 832 42 | false 43 | false 44 | 45 | "localhost:gs.bp.sst" 46 | 47 | Cycles 48 | 5 49 | 50 | false 51 | true 52 | true 53 | 54 | 55 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | add_executable(adios2-gray-scott 7 | simulation/main.cpp 8 | simulation/gray-scott.cpp 9 | simulation/settings.cpp 10 | simulation/writer.cpp 11 | simulation/restart.cpp 12 | ) 13 | target_link_libraries(adios2-gray-scott adios2::adios2 MPI::MPI_C) 14 | install(TARGETS adios2-gray-scott 15 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 16 | 17 | add_executable(adios2-pdf-calc analysis/pdf-calc.cpp) 18 | target_link_libraries(adios2-pdf-calc adios2::adios2 MPI::MPI_C) 19 | install(TARGETS adios2-pdf-calc 20 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 21 | 22 | install(FILES "adios2.xml" "adios2-inline-plugin.xml" "adios2-fides-staging.xml" 23 | "visit-bp4.session" "visit-bp4.session.gui" 24 | "visit-sst.session" "visit-sst.session.gui" 25 | "simulation/settings-files.json" 26 | "simulation/settings-staging.json" 27 | "simulation/settings-inline.json" 28 | "plot/decomp.py" "plot/gsplot.py" "plot/pdfplot.py" 29 | "README.md" 30 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/adios2-examples/gray-scott) 31 | 32 | install(DIRECTORY "catalyst" 33 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/adios2-examples/gray-scott) 34 | 35 | 36 | install(PROGRAMS "cleanup.sh" 37 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/adios2-examples/gray-scott) 38 | 39 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/catalyst/gs-fides.json: -------------------------------------------------------------------------------- 1 | { 2 | "VTK-Cartesian-grid": { 3 | "data_sources": [ 4 | { 5 | "name": "source", 6 | "filename_mode": "input" 7 | } 8 | ], 9 | "step_information": { 10 | "data_source": "source", 11 | "variable": "step" 12 | }, 13 | "coordinate_system" : { 14 | "array" : { 15 | "array_type" : "uniform_point_coordinates", 16 | "dimensions" : { 17 | "source" : "variable_dimensions", 18 | "data_source": "source", 19 | "variable" : "U" 20 | }, 21 | "origin" : { 22 | "source" : "array", 23 | "values" : [0.0, 0.0, 0.0] 24 | }, 25 | "spacing" : { 26 | "source" : "array", 27 | "values" : [0.1, 0.1, 0.1] 28 | } 29 | } 30 | }, 31 | "cell_set": { 32 | "cell_set_type" : "structured", 33 | "dimensions" : { 34 | "source" : "variable_dimensions", 35 | "data_source": "source", 36 | "variable" : "U" 37 | } 38 | }, 39 | "fields": [ 40 | { 41 | "name": "U", 42 | "association": "points", 43 | "array" : { 44 | "array_type" : "basic", 45 | "data_source": "source", 46 | "variable" : "U" 47 | } 48 | }, 49 | { 50 | "name": "V", 51 | "association": "points", 52 | "array" : { 53 | "array_type" : "basic", 54 | "data_source": "source", 55 | "variable" : "V" 56 | } 57 | } 58 | ] 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/catalyst/setup.sh: -------------------------------------------------------------------------------- 1 | # The ${PARAVIEW_BUILD_PATH}/lib directory should contain `libADIOSInSituPlugin.so`. 2 | export PARAVIEW_BUILD_PATH=/home/adios/Software/paraview/build 3 | # Set the following env variables. 4 | export ADIOS2_PLUGIN_PATH=${PARAVIEW_BUILD_PATH}/lib 5 | export CATALYST_IMPLEMENTATION_NAME=paraview 6 | export CATALYST_IMPLEMENTATION_PATHS=${PARAVIEW_BUILD_PATH}/lib/catalyst 7 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Cmds: help data code all 4 | cmd=${1:-help} 5 | 6 | fail=yes 7 | 8 | if [ "x$cmd" == "xcode" -o "x$cmd" == "xall" ]; then 9 | echo "== cleanup code in build/" 10 | cd build 11 | make clean 12 | cd - 13 | fail=no 14 | fi 15 | if [ "x$cmd" == "xdata" -o "x$cmd" == "xall" ]; then 16 | echo "== cleanup data" 17 | rm -rf *.bp *.bp.dir *.h5 18 | rm -rf *.sst *.ssc *_insitumpi_* 19 | rm -rf *.png *.pnm *.jpg 20 | rm -rf *.log 21 | fail=no 22 | fi 23 | 24 | 25 | if [ "x$cmd" == "xhelp" -o "x$cmd" == "xh" -o "$fail" == "yes" ]; then 26 | echo "./cleanup.sh [ data | code | all ]" 27 | fi 28 | 29 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/common/timer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_HPP__ 2 | #define __TIMER_HPP__ 3 | 4 | #include 5 | 6 | class Timer 7 | { 8 | private: 9 | bool _is_running; 10 | std::chrono::steady_clock::time_point _start; 11 | std::chrono::steady_clock::duration _total; 12 | 13 | double _to_millis(std::chrono::steady_clock::duration duration) const 14 | { 15 | std::chrono::duration duration_ms(duration); 16 | return duration_ms.count(); 17 | } 18 | 19 | public: 20 | Timer() 21 | : _is_running(false), _total(std::chrono::steady_clock::duration::zero()) 22 | { 23 | } 24 | 25 | void start() 26 | { 27 | _is_running = true; 28 | _start = std::chrono::steady_clock::now(); 29 | } 30 | 31 | double stop() 32 | { 33 | _is_running = false; 34 | 35 | const auto elapsed = std::chrono::steady_clock::now() - _start; 36 | 37 | _total += elapsed; 38 | 39 | return _to_millis(elapsed); 40 | } 41 | 42 | void reset() 43 | { 44 | _is_running = false; 45 | _total = std::chrono::steady_clock::duration::zero(); 46 | } 47 | 48 | bool is_running() const { return _is_running; } 49 | 50 | double elapsed() const { return _to_millis(_total); } 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/img/example1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott/img/example1.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott/img/example2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott/img/example2.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott/img/example3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott/img/example3.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott/img/example4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott/img/example4.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott/img/example5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ornladios/ADIOS2-Examples/86ed1103f5f6faecf70ba7ab9c9713c01e0488b2/source/cpp/gray-scott/img/example5.jpg -------------------------------------------------------------------------------- /source/cpp/gray-scott/meson.build: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | gray_scott_exe = executable('adios2-gray-scott', 7 | ['simulation/main.cpp', 8 | 'simulation/gray-scott.cpp', 9 | 'simulation/settings.cpp', 10 | 'simulation/writer.cpp'], 11 | dependencies : [mpi_dep, adios2_dep], 12 | install: true) 13 | 14 | pdf_calc_exe = executable('adios2-pdf-calc', 'analysis/pdf-calc.cpp', 15 | dependencies : [mpi_dep, adios2_dep], 16 | install: true) 17 | 18 | install_data(['adios2.xml','visit-bp4.session','visit-bp4.session.gui', 19 | 'visit-sst.session','visit-sst.session.gui', 20 | 'simulation/settings-files.json', 21 | 'simulation/settings-staging.json', 22 | 'plot/decomp.py','plot/gsplot.py','plot/pdfplot.py', 23 | 'cleanup.sh', 'README.md'], 24 | install_dir : 'share/adios2-examples/gray-scott') 25 | 26 | install_data(['img/example1.jpg','img/example2.jpg','img/example3.jpg', 27 | 'img/example4.jpg'], 28 | install_dir : 'share/adios2-examples/gray-scott/img') 29 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Keichi Takahashi 2 | Copyright (c) 2018 Hiroshi Watanabe 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/restart.cpp: -------------------------------------------------------------------------------- 1 | #include "../../gray-scott/simulation/restart.h" 2 | 3 | #include 4 | 5 | static bool firstCkpt = true; 6 | 7 | void WriteCkpt(MPI_Comm comm, const int step, const Settings &settings, 8 | const GrayScott &sim, adios2::IO io) 9 | { 10 | int rank, nproc; 11 | MPI_Comm_rank(comm, &rank); 12 | MPI_Comm_size(comm, &nproc); 13 | std::cout << "checkpoint at step " << step << " create file " 14 | << settings.checkpoint_output << std::endl; 15 | adios2::Engine writer = 16 | io.Open(settings.checkpoint_output, adios2::Mode::Write); 17 | if (writer) 18 | { 19 | adios2::Variable var_u; 20 | adios2::Variable var_v; 21 | adios2::Variable var_step; 22 | 23 | if (firstCkpt) 24 | { 25 | size_t X = sim.size_x + 2; 26 | size_t Y = sim.size_y + 2; 27 | size_t Z = sim.size_z + 2; 28 | size_t R = static_cast(rank); 29 | size_t N = static_cast(nproc); 30 | 31 | var_u = io.DefineVariable("U", {N, X, Y, Z}, {R, 0, 0, 0}, 32 | {1, X, Y, Z}); 33 | var_v = io.DefineVariable("V", {N, X, Y, Z}, {R, 0, 0, 0}, 34 | {1, X, Y, Z}); 35 | 36 | var_step = io.DefineVariable("step"); 37 | firstCkpt = false; 38 | } 39 | else 40 | { 41 | var_u = io.InquireVariable("U"); 42 | var_v = io.InquireVariable("V"); 43 | var_step = io.InquireVariable("step"); 44 | } 45 | 46 | writer.Put(var_step, &step); 47 | writer.Put(var_u, sim.u_ghost().data()); 48 | writer.Put(var_v, sim.v_ghost().data()); 49 | 50 | writer.Close(); 51 | } 52 | } 53 | 54 | int ReadRestart(MPI_Comm comm, const Settings &settings, GrayScott &sim, 55 | adios2::IO io) 56 | { 57 | int step = 0; 58 | int rank, nproc; 59 | MPI_Comm_rank(comm, &rank); 60 | MPI_Comm_size(comm, &nproc); 61 | if (!rank) 62 | { 63 | std::cout << "restart from file " << settings.restart_input << std::endl; 64 | } 65 | adios2::Engine reader = 66 | io.Open(settings.restart_input, adios2::Mode::ReadRandomAccess); 67 | if (reader) 68 | { 69 | adios2::Variable var_step = io.InquireVariable("step"); 70 | adios2::Variable var_u = io.InquireVariable("U"); 71 | adios2::Variable var_v = io.InquireVariable("V"); 72 | size_t X = sim.size_x + 2; 73 | size_t Y = sim.size_y + 2; 74 | size_t Z = sim.size_z + 2; 75 | size_t R = static_cast(rank); 76 | std::vector u, v; 77 | 78 | var_u.SetSelection({{R, 0, 0, 0}, {1, X, Y, Z}}); 79 | var_v.SetSelection({{R, 0, 0, 0}, {1, X, Y, Z}}); 80 | reader.Get(var_step, step); 81 | reader.Get(var_u, u); 82 | reader.Get(var_v, v); 83 | reader.Close(); 84 | 85 | if (!rank) 86 | { 87 | std::cout << "restart from step " << step << std::endl; 88 | } 89 | sim.restart(u, v); 90 | } 91 | else 92 | { 93 | std::cout << " failed to open file " << std::endl; 94 | } 95 | return step; 96 | } 97 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/restart.h: -------------------------------------------------------------------------------- 1 | #ifndef __RESTART_H__ 2 | #define __RESTART_H__ 3 | 4 | #include "../../gray-scott/simulation/gray-scott.h" 5 | #include "../../gray-scott/simulation/settings.h" 6 | 7 | #include 8 | #include 9 | 10 | void WriteCkpt(MPI_Comm comm, const int step, const Settings &settings, 11 | const GrayScott &sim, adios2::IO io); 12 | int ReadRestart(MPI_Comm comm, const Settings &settings, GrayScott &sim, 13 | adios2::IO io); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/settings-files.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 64, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.01, 6 | "k": 0.05, 7 | "dt": 2.0, 8 | "plotgap": 10, 9 | "steps": 1000, 10 | "noise": 0.0000001, 11 | "output": "gs.bp", 12 | "checkpoint": true, 13 | "checkpoint_freq": 700, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": false, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": false, 20 | "mesh_type": "image" 21 | } 22 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/settings-inline.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 64, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.01, 6 | "k": 0.05, 7 | "dt": 2.0, 8 | "plotgap": 10, 9 | "steps": 1000, 10 | "noise": 0.0000001, 11 | "output": "gs.bp", 12 | "checkpoint": true, 13 | "checkpoint_freq": 700, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": false, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2-inline-plugin.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": false, 20 | "mesh_type": "image" 21 | } 22 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/settings-staging.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 64, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.01, 6 | "k": 0.05, 7 | "dt": 2.0, 8 | "plotgap": 10, 9 | "steps": 60000, 10 | "noise": 0.0000001, 11 | "output": "gs.bp", 12 | "checkpoint": false, 13 | "checkpoint_freq": 1000, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": false, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": true, 20 | "mesh_type": "image" 21 | } 22 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/settings.cpp: -------------------------------------------------------------------------------- 1 | #include "../../gray-scott/simulation/settings.h" 2 | 3 | #include 4 | 5 | #include "../../gray-scott/simulation/json.hpp" 6 | 7 | void to_json(nlohmann::json &j, const Settings &s) 8 | { 9 | j = nlohmann::json{{"L", s.L}, 10 | {"steps", s.steps}, 11 | {"plotgap", s.plotgap}, 12 | {"F", s.F}, 13 | {"k", s.k}, 14 | {"dt", s.dt}, 15 | {"Du", s.Du}, 16 | {"Dv", s.Dv}, 17 | {"noise", s.noise}, 18 | {"output", s.output}, 19 | {"checkpoint", s.checkpoint}, 20 | {"checkpoint_freq", s.checkpoint_freq}, 21 | {"checkpoint_output", s.checkpoint_output}, 22 | {"restart", s.restart}, 23 | {"restart_input", s.restart_input}, 24 | {"adios_config", s.adios_config}, 25 | {"adios_span", s.adios_span}, 26 | {"adios_memory_selection", s.adios_memory_selection}, 27 | {"mesh_type", s.mesh_type}}; 28 | } 29 | 30 | void from_json(const nlohmann::json &j, Settings &s) 31 | { 32 | j.at("L").get_to(s.L); 33 | j.at("steps").get_to(s.steps); 34 | j.at("plotgap").get_to(s.plotgap); 35 | j.at("F").get_to(s.F); 36 | j.at("k").get_to(s.k); 37 | j.at("dt").get_to(s.dt); 38 | j.at("Du").get_to(s.Du); 39 | j.at("Dv").get_to(s.Dv); 40 | j.at("noise").get_to(s.noise); 41 | j.at("output").get_to(s.output); 42 | j.at("checkpoint").get_to(s.checkpoint); 43 | j.at("checkpoint_freq").get_to(s.checkpoint_freq); 44 | j.at("checkpoint_output").get_to(s.checkpoint_output); 45 | j.at("restart").get_to(s.restart); 46 | j.at("restart_input").get_to(s.restart_input); 47 | j.at("adios_config").get_to(s.adios_config); 48 | j.at("adios_span").get_to(s.adios_span); 49 | j.at("adios_memory_selection").get_to(s.adios_memory_selection); 50 | j.at("mesh_type").get_to(s.mesh_type); 51 | } 52 | 53 | Settings::Settings() 54 | { 55 | L = 128; 56 | steps = 20000; 57 | plotgap = 200; 58 | F = 0.04; 59 | k = 0.06075; 60 | dt = 0.2; 61 | Du = 0.05; 62 | Dv = 0.1; 63 | noise = 0.0; 64 | output = "foo.bp"; 65 | checkpoint = false; 66 | checkpoint_freq = 2000; 67 | checkpoint_output = "ckpt.bp"; 68 | restart = false; 69 | restart_input = "ckpt.bp"; 70 | adios_config = "adios2.xml"; 71 | adios_span = false; 72 | adios_memory_selection = false; 73 | mesh_type = "image"; 74 | } 75 | 76 | Settings Settings::from_json(const std::string &fname) 77 | { 78 | std::ifstream ifs(fname); 79 | nlohmann::json j; 80 | 81 | ifs >> j; 82 | 83 | return j.get(); 84 | } 85 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/settings.h: -------------------------------------------------------------------------------- 1 | #ifndef __SETTINGS_H__ 2 | #define __SETTINGS_H__ 3 | 4 | #include 5 | 6 | struct Settings 7 | { 8 | size_t L; 9 | int steps; 10 | int plotgap; 11 | double F; 12 | double k; 13 | double dt; 14 | double Du; 15 | double Dv; 16 | double noise; 17 | std::string output; 18 | bool checkpoint; 19 | int checkpoint_freq; 20 | std::string checkpoint_output; 21 | bool restart; 22 | std::string restart_input; 23 | std::string adios_config; 24 | bool adios_span; 25 | bool adios_memory_selection; 26 | std::string mesh_type; 27 | 28 | Settings(); 29 | static Settings from_json(const std::string &fname); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/simulation/writer.h: -------------------------------------------------------------------------------- 1 | #ifndef __WRITER_H__ 2 | #define __WRITER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "../../gray-scott/simulation/gray-scott.h" 8 | #include "../../gray-scott/simulation/settings.h" 9 | 10 | class Writer 11 | { 12 | public: 13 | Writer(const Settings &settings, const GrayScott &sim, adios2::IO io); 14 | void open(const std::string &fname, bool append); 15 | void write(int step, const GrayScott &sim); 16 | void close(); 17 | 18 | protected: 19 | Settings settings; 20 | 21 | adios2::IO io; 22 | adios2::Engine writer; 23 | adios2::Variable var_u; 24 | adios2::Variable var_v; 25 | adios2::Variable var_step; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/visit-bp4.session.gui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3.0.0b 4 | 5 | 6 | gs.bp 7 | * 8 | true 9 | true 10 | true 11 | false 12 | 13 | "gs.bp" 14 | 15 | 16 | 17 | true 18 | #c0c0c0 19 | #000000 20 | Helvetica,12,-1,5,50,0,0,0,0,0 21 | gtk 22 | 0 23 | #000000 24 | #efefef 25 | "Sans Serif,9,-1,5,50,0,0,0,0,0" 26 | Fusion 27 | 0 28 | 29 | false 30 | 31 | 4 32 | 52 33 | 398 34 | 2104 35 | 0 0.544259 0.4537178 36 | 37 | 38 | 2742 39 | 916 40 | 498 41 | 832 42 | false 43 | false 44 | 45 | "localhost:gs.bp/md.0" 46 | 47 | Cycles 48 | 5 49 | 50 | false 51 | true 52 | true 53 | 54 | 55 | -------------------------------------------------------------------------------- /source/cpp/gray-scott/visit-sst.session.gui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 3.0.0b 4 | 5 | 6 | /home/adios/Tutorial/share 7 | * 8 | true 9 | true 10 | true 11 | false 12 | 13 | "/home/adios/Tutorial/share" 14 | 15 | 16 | 17 | true 18 | #c0c0c0 19 | #000000 20 | Helvetica,12,-1,5,50,0,0,0,0,0 21 | gtk 22 | 0 23 | #000000 24 | #efefef 25 | "Sans Serif,9,-1,5,50,0,0,0,0,0" 26 | Fusion 27 | 0 28 | 29 | false 30 | 31 | 4 32 | 52 33 | 398 34 | 2104 35 | 0 0.544259 0.4537178 36 | 37 | 38 | 2378 39 | 1078 40 | 498 41 | 832 42 | false 43 | false 44 | 45 | "localhost:gs.bp.sst" 46 | 47 | Cycles 48 | 5 49 | 50 | false 51 | true 52 | true 53 | 54 | 55 | -------------------------------------------------------------------------------- /source/cpp/hello-world/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_executable(adios2-hello-world-cpp hello-world.cpp) 3 | target_link_libraries(adios2-hello-world-cpp ${common_deps}) 4 | add_test_helper(adios2-hello-world-cpp) 5 | install(TARGETS adios2-hello-world-cpp 6 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 7 | ) 8 | 9 | add_executable(adios2-hello-world-hl-cpp hello-world-hl.cpp) 10 | target_link_libraries(adios2-hello-world-hl-cpp ${common_deps}) 11 | add_test_helper(adios2-hello-world-hl-cpp) 12 | install(TARGETS adios2-hello-world-hl-cpp 13 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 14 | ) 15 | -------------------------------------------------------------------------------- /source/cpp/hello-world/hello-world-hl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Distributed under the OSI-approved Apache License, Version 2.0. See 3 | * accompanying file Copyright.txt for details. 4 | * 5 | * hello-world-hl.cpp : adios2 high-level API example to write and read a 6 | * std::string Variable with a greeting 7 | * 8 | * Created on: Nov 14, 2019 9 | * Author: William F Godoy godoywf@ornl.gov 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #if ADIOS2_USE_MPI 17 | #include 18 | #endif 19 | 20 | void writer(const std::string &greeting) 21 | { 22 | #if ADIOS2_USE_MPI 23 | adios2::fstream out("hello-world-hl-cpp.bp", adios2::fstream::out, 24 | MPI_COMM_WORLD); 25 | #else 26 | adios2::fstream out("hello-world-hl-cpp.bp", adios2::fstream::out); 27 | #endif 28 | 29 | out.write("Greeting", greeting); 30 | out.close(); 31 | } 32 | 33 | std::string reader() 34 | { 35 | #if ADIOS2_USE_MPI 36 | adios2::fstream in("hello-world-hl-cpp.bp", adios2::fstream::in, 37 | MPI_COMM_WORLD); 38 | #else 39 | adios2::fstream in("hello-world-hl-cpp.bp", adios2::fstream::in); 40 | #endif 41 | 42 | for (adios2::fstep iStep; adios2::getstep(in, iStep);) 43 | { 44 | const std::vector greetings = 45 | in.read("Greeting"); 46 | return greetings.front(); 47 | } 48 | return ""; 49 | } 50 | 51 | int main(int argc, char *argv[]) 52 | { 53 | #if ADIOS2_USE_MPI 54 | MPI_Init(&argc, &argv); 55 | #endif 56 | 57 | try 58 | { 59 | const std::string greeting = "Hello World from ADIOS2"; 60 | writer(greeting); 61 | 62 | const std::string message = reader(); 63 | std::cout << message << "\n"; 64 | } 65 | catch (std::exception &e) 66 | { 67 | std::cout << "ERROR: ADIOS2 exception: " << e.what() << "\n"; 68 | #if ADIOS2_USE_MPI 69 | MPI_Abort(MPI_COMM_WORLD, -1); 70 | #endif 71 | } 72 | 73 | #if ADIOS2_USE_MPI 74 | MPI_Finalize(); 75 | #endif 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /source/cpp/hello-world/hello-world.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Distributed under the OSI-approved Apache License, Version 2.0. See 3 | * accompanying file Copyright.txt for details. 4 | * 5 | * hello-world.cpp : adios2 low-level API example to write and read a 6 | * std::string Variable with a greeting 7 | * 8 | * Created on: Nov 14, 2019 9 | * Author: William F Godoy godoywf@ornl.gov 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #if ADIOS2_USE_MPI 17 | #include 18 | #endif 19 | 20 | void writer(adios2::ADIOS &adios, const std::string &greeting) 21 | { 22 | adios2::IO io = adios.DeclareIO("hello-world-writer"); 23 | adios2::Variable varGreeting = 24 | io.DefineVariable("Greeting"); 25 | 26 | adios2::Engine writer = io.Open("hello-world-cpp.bp", adios2::Mode::Write); 27 | writer.Put(varGreeting, greeting); 28 | writer.Close(); 29 | } 30 | 31 | std::string reader(adios2::ADIOS &adios) 32 | { 33 | adios2::IO io = adios.DeclareIO("hello-world-reader"); 34 | adios2::Engine reader = io.Open("hello-world-cpp.bp", adios2::Mode::Read); 35 | reader.BeginStep(); 36 | adios2::Variable varGreeting = 37 | io.InquireVariable("Greeting"); 38 | std::string greeting; 39 | reader.Get(varGreeting, greeting); 40 | reader.EndStep(); 41 | reader.Close(); 42 | return greeting; 43 | } 44 | 45 | int main(int argc, char *argv[]) 46 | { 47 | #if ADIOS2_USE_MPI 48 | MPI_Init(&argc, &argv); 49 | #endif 50 | 51 | try 52 | { 53 | #if ADIOS2_USE_MPI 54 | adios2::ADIOS adios(MPI_COMM_WORLD); 55 | #else 56 | adios2::ADIOS adios; 57 | #endif 58 | 59 | const std::string greeting = "Hello World from ADIOS2"; 60 | writer(adios, greeting); 61 | 62 | const std::string message = reader(adios); 63 | std::cout << message << "\n"; 64 | } 65 | catch (std::exception &e) 66 | { 67 | std::cout << "ERROR: ADIOS2 exception: " << e.what() << "\n"; 68 | #if ADIOS2_USE_MPI 69 | MPI_Abort(MPI_COMM_WORLD, -1); 70 | #endif 71 | } 72 | 73 | #if ADIOS2_USE_MPI 74 | MPI_Finalize(); 75 | #endif 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /source/cpp/hello-world/meson.build: -------------------------------------------------------------------------------- 1 | 2 | hello_world_exe = executable('adios2-hello-world-cpp', 'hello-world.cpp', 3 | dependencies : [mpi_dep, adios2_dep], install: true) 4 | # MPI test 5 | test('hello-world.cpp', mpiexec, args:['-np', nprocs, hello_world_exe], 6 | timeout: 10, is_parallel: false) 7 | 8 | hello_world_hl_exe = executable('adios2-hello-world-hl-cpp', 'hello-world-hl.cpp', 9 | dependencies : [mpi_dep, adios2_dep], install: true) 10 | 11 | # MPI test 12 | test('hello-world-hl.cpp', mpiexec, args:['-np', nprocs, hello_world_hl_exe], 13 | timeout: 10, is_parallel: false) 14 | -------------------------------------------------------------------------------- /source/cpp/korteweg-de-vries/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | add_executable(KdV KdV.cpp) 7 | target_link_libraries(KdV ${common_deps}) 8 | -------------------------------------------------------------------------------- /source/cpp/korteweg-de-vries/README.md: -------------------------------------------------------------------------------- 1 | To run: 2 | 3 | ``` 4 | ADIOS2/build$ ./bin/kdv 5 | ``` 6 | 7 | To view data generated: 8 | 9 | ``` 10 | $ conda create -n kdv 11 | $ conda activate kdv 12 | $ conda install -c williamfgc adios2 -c conda-forge 13 | $ conda install pip 14 | $ pip install diagram 15 | ``` 16 | -------------------------------------------------------------------------------- /source/cpp/korteweg-de-vries/graph_solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import time 4 | import argparse 5 | import numpy # pylint: disable=import-error 6 | import adios2 # pylint: disable=import-error 7 | import diagram # pylint: disable=import-error 8 | 9 | def run(): 10 | parser = argparse.ArgumentParser(description=('Graph KdV equation')) 11 | parser.add_argument("-f", "--filename", 12 | help=".bp filename", default="korteweg_de_vries.bp") 13 | options = parser.parse_args() 14 | dgoptions = diagram.DOption() 15 | dgoptions.mode = 'g' 16 | 17 | with adios2.open(options.filename, "r") as file_handle: 18 | for step in file_handle: 19 | points = step.read("u") 20 | # Adding these points helps us with whiplash; 21 | # otherwise the data is minmaxed on every iteration. 22 | # It does produce a visual artefact that I wish wasn't there! 23 | points = numpy.append(points, [3.0, -1.5]) 24 | values = [None] 25 | dg = diagram.DGWrapper(dg_option=dgoptions, data=[points, values]) 26 | os.system('cls' if os.name == 'nt' else 'clear') 27 | dg.show() 28 | time.sleep(0.1) 29 | 30 | 31 | if __name__ == '__main__': 32 | run() 33 | -------------------------------------------------------------------------------- /source/cpp/lorenz_ode/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | add_executable(lorenz_writer lorenz_writer.cpp) 7 | target_link_libraries(lorenz_writer ${common_deps}) 8 | 9 | add_executable(lorenz_reader lorenz_reader.cpp) 10 | target_link_libraries(lorenz_reader ${common_deps}) 11 | -------------------------------------------------------------------------------- /source/cpp/lorenz_ode/README.md: -------------------------------------------------------------------------------- 1 | ## Lorenz System Example 2 | 3 | The [Lorenz system](https://en.wikipedia.org/wiki/Lorenz_system) is a very simple ODE which exhibits large sensitivity to initial conditions. 4 | 5 | This example exhibits a number of capabilities of ADIOS: For example, how do we write data that is completely independent of other data rapidly? 6 | How do we write complex data structures that are not naturally layed out as matrices? 7 | 8 | The ODE to be solved is 9 | 10 | ![Alt text](./lorenz_ode.svg) 11 | 12 | We will use Taylor methods for ODEs, which are very easy to understand. 13 | 14 | Namely, if we differentiate the right-hand side we get 15 | 16 | ![Alt text](./second_derivative.svg) 17 | 18 | and we can propagate our solution via analytic continuation 19 | 20 | ![Alt text](./taylor_series.svg) 21 | 22 | Normally, we would store the list 23 | 24 | ![Alt text](./ode_tuples.svg) 25 | 26 | but we will be able to store less total data if we store the phase-space state 27 | 28 | ![Alt text](./ode_phase_space.svg) 29 | 30 | and use cubic Hermite interpolation for rendering. 31 | In addition, it doesn't make much sense to *solve* our equation more accurately than we render it, so we'll simply use the second derivative to pick stepsizes. 32 | 33 | 34 | 35 | A natural C++ data structure for this is a `std::vector>`. 36 | This will give us a nontrivial data structure to examine in ADIOS2. 37 | 38 | Each MPI rank solves the Lorenz system with a different initial condition, and there is no coordination between ranks. 39 | -------------------------------------------------------------------------------- /source/cpp/lorenz_ode/lorenz_writer.cpp: -------------------------------------------------------------------------------- 1 | #include "lorenz.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void solve_lorenz_ivp() 9 | { 10 | using Real = double; 11 | Real sigma = 10; 12 | Real beta = Real(8) / Real(3); 13 | Real rho = 28; 14 | Real tmax = 10; 15 | Real absolute_error = 1e-5; 16 | 17 | adios2::ADIOS adios; 18 | adios2::IO io = adios.DeclareIO("myio"); 19 | io.DefineAttribute("σ", sigma); 20 | io.DefineAttribute("β", beta); 21 | io.DefineAttribute("ρ", rho); 22 | io.DefineAttribute("‖û-u‖", absolute_error); 23 | io.DefineAttribute( 24 | "interpretation", "7D array of structs {tᵢ, xᵢ, yᵢ, zᵢ, ẋᵢ, ẏᵢ, żᵢ}"); 25 | adios2::Engine adios_engine = io.Open("lorenz.bp", adios2::Mode::Write); 26 | // Check that std::vector> has the proper memory layout. 27 | static_assert(sizeof(std::array) == 7 * sizeof(Real), 28 | "The std::array on your system does not have the proper " 29 | "layout to be correctly serialized in ADIOS2."); 30 | 31 | size_t paths = 2; 32 | for (size_t i = 0; i < paths; ++i) 33 | { 34 | for (size_t j = 0; j < paths; ++j) 35 | { 36 | for (size_t k = 0; k < paths; ++k) 37 | { 38 | const std::array initial_conditions{Real(i), Real(j), 39 | Real(k)}; 40 | auto solution = lorenz( 41 | sigma, beta, rho, initial_conditions, tmax, absolute_error); 42 | auto const &skeleton = solution.states(); 43 | // This is just being *ultra* cautious; this double checks that 44 | // the memory layout is contiguous. 45 | const double *const p = skeleton[0].data(); 46 | for (size_t i = 0; i < skeleton.size(); ++i) 47 | { 48 | for (size_t j = 0; j < 7; ++j) 49 | { 50 | assert(skeleton[i][j] == p[7 * i + j]); 51 | } 52 | } 53 | const std::string variable = "u" + std::to_string(i) + 54 | std::to_string(j) + 55 | std::to_string(k); 56 | auto state_variable = io.DefineVariable( 57 | variable, {7 * skeleton.size()}, {0}, {7 * skeleton.size()}, 58 | adios2::ConstantDims); 59 | adios_engine.Put(state_variable, p, adios2::Mode::Sync); 60 | } 61 | } 62 | } 63 | adios_engine.Close(); 64 | } 65 | 66 | int main() 67 | { 68 | try 69 | { 70 | solve_lorenz_ivp(); 71 | } 72 | catch (std::exception const &e) 73 | { 74 | std::cerr << "Caught an exception solving Lorenz ODE: " << e.what() 75 | << "\n"; 76 | } 77 | 78 | try 79 | { 80 | test_lorenz(); 81 | } 82 | catch (std::exception const &e) 83 | { 84 | std::cout << "Caught and exception from the Lorenz unit tests: " 85 | << e.what() << "\n"; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /source/cpp/meson.build: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | subdir('basics') 7 | subdir('gray-scott') 8 | subdir('hello-world') 9 | -------------------------------------------------------------------------------- /source/fortran/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | if(MPI_FOUND) 7 | add_subdirectory(adios-module) 8 | add_subdirectory(shapes) 9 | endif() 10 | -------------------------------------------------------------------------------- /source/fortran/adios-module/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(adios2-module-example main.F90 mpivars.F90 adiosio.F90) 2 | target_compile_definitions(adios2-module-example PRIVATE ADIOS2) 3 | target_link_libraries(adios2-module-example 4 | adios2::fortran_mpi MPI::MPI_Fortran 5 | ) 6 | -------------------------------------------------------------------------------- /source/fortran/adios-module/Makefile: -------------------------------------------------------------------------------- 1 | include ../../../make.settings 2 | 3 | default: adios2-module-example 4 | 5 | adios2-module-example: mpivars.mod mpivars.o adiosio.mod adiosio.o 6 | ${MPIFC} -DADIOS2 -c -o main.o main.F90 7 | ${MPIFC} -o adios2-module-example main.o mpivars.o adiosio.o ${F90_MPI_LDFLAGS} 8 | 9 | mpivars.mod: mpivars.F90 10 | ${MPIFC} -c mpivars.F90 11 | 12 | adiosio.mod: adiosio.F90 13 | ${MPIFC} -c ${F90_MPI_FLAGS} adiosio.F90 14 | 15 | clean: 16 | rm -rf adios2-module-example 17 | rm -rf mpivars.mod adiosio.mod adiosio.smod 18 | rm -rf *.o *.bp *.sst 19 | -------------------------------------------------------------------------------- /source/fortran/adios-module/adiosio.F90: -------------------------------------------------------------------------------- 1 | module adiosio 2 | use adios2 3 | implicit none 4 | 5 | type(adios2_adios) :: adios2obj 6 | type(adios2_io) :: io_diag 7 | type(adios2_engine) :: engine_diag 8 | 9 | contains 10 | 11 | subroutine init_adiosio() 12 | use mpivars 13 | use adios2 14 | implicit none 15 | integer*4 :: err 16 | call adios2_init(adios2obj, app_comm, err) 17 | if (.not.adios2obj%valid) then 18 | write(*,*) "Error when creating ADIOS2 object" 19 | endif 20 | end subroutine init_adiosio 21 | 22 | subroutine finalize_adiosio() 23 | use adios2 24 | implicit none 25 | integer*4 :: err 26 | ! close the engine now if it was not closed yet 27 | if (engine_diag%valid) then 28 | call adios2_close(engine_diag, err) 29 | endif 30 | if (adios2obj%valid) then 31 | call adios2_finalize(adios2obj, err) 32 | endif 33 | end subroutine finalize_adiosio 34 | 35 | end module adiosio 36 | -------------------------------------------------------------------------------- /source/fortran/adios-module/main.F90: -------------------------------------------------------------------------------- 1 | program adios2_module_example 2 | use mpivars 3 | #ifdef ADIOS2 4 | use adiosio 5 | #endif 6 | implicit none 7 | 8 | integer, parameter :: numsteps = 5 9 | integer :: step 10 | type(adios2_io) :: iotest 11 | type(adios2_variable) :: vartest 12 | 13 | call init_mpi(12345) 14 | #ifdef ADIOS2 15 | call init_adiosio() 16 | #endif 17 | 18 | call adios2_declare_io (iotest, adios2obj, 'Test', ierr) 19 | if (.not.iotest%valid) then 20 | write(*,*) "Error when creating test IO object" 21 | endif 22 | 23 | 24 | call diag_init() 25 | do step=1,numsteps,1 26 | call diag_writer(step) 27 | enddo 28 | call diag_finalize() 29 | 30 | call reader() 31 | 32 | #ifdef ADIOS2 33 | call finalize_adiosio() 34 | #endif 35 | call finalize_mpi() 36 | 37 | contains 38 | 39 | subroutine diag_init 40 | use adiosio 41 | implicit none 42 | type(adios2_variable) :: var 43 | ! var reference will disappear on return but the variable definition is 44 | ! accessible by using the name of the variable ("step") 45 | call adios2_declare_io (io_diag, adios2obj, 'DiagnosticsOutput', ierr) 46 | call adios2_open(engine_diag, io_diag, "diag.bp", adios2_mode_write, ierr) 47 | call adios2_define_variable(var, io_diag, "step", adios2_type_integer4, ierr) 48 | end subroutine diag_init 49 | 50 | 51 | subroutine diag_writer(step) 52 | use adiosio 53 | implicit none 54 | integer, intent(in):: step 55 | call adios2_begin_step(engine_diag, adios2_step_mode_append, ierr) 56 | call adios2_put(engine_diag, "step", step, ierr) 57 | call adios2_end_step(engine_diag, ierr) 58 | end subroutine diag_writer 59 | 60 | 61 | subroutine diag_finalize 62 | use adiosio 63 | implicit none 64 | call adios2_close(engine_diag, ierr) 65 | end subroutine diag_finalize 66 | 67 | 68 | subroutine reader 69 | use adiosio 70 | use mpivars 71 | implicit none 72 | 73 | type(adios2_variable) :: var 74 | type(adios2_io) :: io 75 | type(adios2_engine) :: engine 76 | integer*8 :: numsteps 77 | integer*4, dimension(:), allocatable :: steps 78 | integer :: i 79 | character(len=80)::fmt 80 | 81 | if (rank == 0) then 82 | call adios2_declare_io(io, adios2obj, "DiagnosticsInput", ierr) 83 | call adios2_open(engine, io, "diag.bp", adios2_mode_read, MPI_COMM_SELF, ierr) 84 | call adios2_inquire_variable(var, io, "step", ierr) 85 | call adios2_variable_steps(numsteps, var, ierr) 86 | call adios2_set_step_selection(var, 0_8, numsteps, ierr) 87 | allocate(steps(numsteps)) 88 | call adios2_get(engine, var, steps , ierr) 89 | call adios2_close(engine, ierr) 90 | write(*,'(a,i5)') "Number of steps in diag.bp = ", numsteps 91 | write(fmt,'(a,i5,a)') '(a10,',numsteps,'i4,a2)' 92 | !write(*,'(a)') fmt 93 | write(*,fmt) "Steps = [", steps, " ]" 94 | deallocate(steps) 95 | endif 96 | end subroutine reader 97 | 98 | end program adios2_module_example 99 | -------------------------------------------------------------------------------- /source/fortran/adios-module/mpivars.F90: -------------------------------------------------------------------------------- 1 | module mpivars 2 | implicit none 3 | include 'mpif.h' 4 | 5 | integer:: app_comm, rank, nproc 6 | integer:: wrank, wnproc 7 | integer:: ierr 8 | 9 | contains 10 | 11 | subroutine init_mpi(color) 12 | integer, intent(in):: color 13 | call MPI_Init(ierr) 14 | ! World comm spans all applications started with the same mpirun command 15 | call MPI_Comm_rank(MPI_COMM_WORLD, wrank, ierr) 16 | call MPI_Comm_size(MPI_COMM_WORLD, wnproc, ierr) 17 | 18 | ! Have to split and create a 'world' communicator for this app only 19 | ! color must be unique for each application 20 | call MPI_Comm_split (MPI_COMM_WORLD, color, wrank, app_comm, ierr) 21 | call MPI_Comm_rank (app_comm, rank, ierr) 22 | call MPI_Comm_size (app_comm, nproc , ierr) 23 | end subroutine init_mpi 24 | 25 | subroutine finalize_mpi() 26 | call MPI_Finalize(ierr) 27 | end subroutine finalize_mpi 28 | 29 | end module mpivars 30 | 31 | -------------------------------------------------------------------------------- /source/fortran/shapes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(_mpivars OBJECT mpivars.F90) 2 | target_link_libraries(_mpivars MPI::MPI_Fortran) 3 | 4 | add_library(_decomp OBJECT decomp.F90) 5 | target_link_libraries(_decomp _mpivars) 6 | 7 | add_executable(adios2-values-f values.F90) 8 | target_link_libraries(adios2-values-f adios2::fortran_mpi _mpivars) 9 | 10 | add_executable(adios2-global-array-fixed-write-f global-array-fixed-write.F90) 11 | target_link_libraries(adios2-global-array-fixed-write-f 12 | adios2::fortran_mpi _mpivars _decomp 13 | ) 14 | 15 | add_executable(adios2-global-array-fixed-read-f global-array-fixed-read.F90) 16 | target_link_libraries(adios2-global-array-fixed-read-f 17 | adios2::fortran_mpi _mpivars _decomp 18 | ) 19 | 20 | add_executable(adios2-global-array-changing-shape-write-f 21 | global-array-changing-shape-write.F90 22 | ) 23 | target_link_libraries(adios2-global-array-changing-shape-write-f 24 | adios2::fortran_mpi _mpivars _decomp 25 | ) 26 | 27 | #add_executable(adios2-shapes-write-f shapes-write.F90) 28 | #target_link_libraries(adios2-shapes-write-f 29 | # adios2::fortran_mpi MPI::MPI_Fortran 30 | #) 31 | 32 | #add_executable(adios2-shapes-read-f shapes-read.F90) 33 | #target_link_libraries(adios2-shapes-read-f 34 | # adios2::fortran_mpi MPI::MPI_Fortran 35 | #) 36 | -------------------------------------------------------------------------------- /source/fortran/shapes/Makefile: -------------------------------------------------------------------------------- 1 | include ../../../make.settings 2 | 3 | all: adios2-values-f \ 4 | adios2-global-array-fixed-write-f adios2-global-array-fixed-read-f \ 5 | adios2-global-array-changing-shape-write-f adios2-global-array-changing-shape-read-f 6 | 7 | default: all 8 | 9 | adios2-values-f: mpivars.mod mpivars.o values.F90 10 | ${MPIFC} -g -o adios2-values-f ${F90_MPI_FLAGS} values.F90 mpivars.o ${F90_MPI_LDFLAGS} 11 | 12 | adios2-global-array-fixed-write-f: mpivars.mod mpivars.o decomp.mod decomp.o global-array-fixed-write.F90 13 | ${MPIFC} -g -o adios2-global-array-fixed-write-f ${F90_MPI_FLAGS} global-array-fixed-write.F90 mpivars.o decomp.o ${F90_MPI_LDFLAGS} 14 | 15 | adios2-global-array-fixed-read-f: mpivars.mod mpivars.o decomp.mod decomp.o global-array-fixed-read.F90 16 | ${MPIFC} -g -o adios2-global-array-fixed-read-f ${F90_MPI_FLAGS} global-array-fixed-read.F90 mpivars.o decomp.o ${F90_MPI_LDFLAGS} 17 | 18 | adios2-global-array-changing-shape-write-f: mpivars.mod mpivars.o decomp.mod decomp.o global-array-changing-shape-write.F90 19 | ${MPIFC} -g -o adios2-global-array-changing-shape-write-f ${F90_MPI_FLAGS} global-array-changing-shape-write.F90 mpivars.o decomp.o ${F90_MPI_LDFLAGS} 20 | 21 | mpivars.mod: mpivars.F90 22 | ${MPIFC} -c mpivars.F90 23 | 24 | mpivars.o: mpivars.F90 25 | ${MPIFC} -c mpivars.F90 26 | 27 | decomp.mod: decomp.F90 28 | ${MPIFC} -c decomp.F90 29 | 30 | decomp.o: decomp.F90 31 | ${MPIFC} -c decomp.F90 32 | 33 | 34 | #adios2-shapes-write-f: shapes-write.F90 35 | # ${MPIFC} -o adios2-shapes-write-f ${F90_MPI_FLAGS} shapes-write.F90 ${F90_MPI_LDFLAGS} 36 | # 37 | #adios2-shapes-read-f: shapes-read.F90 38 | # ${MPIFC} -o adios2-shapes-read-f ${F90_MPI_FLAGS} shapes-read.F90 ${F90_MPI_LDFLAGS} 39 | 40 | clean: 41 | rm -rf adios2-values-f 42 | rm -rf adios2-global-array-fixed-write-f adios2-global-array-fixed-read-f 43 | rm -rf adios2-global-array-changing-shape-write-f adios2-global-array-changing-shape-read-f 44 | rm -rf *.o *.mod 45 | rm -rf *.bp *.sst 46 | -------------------------------------------------------------------------------- /source/fortran/shapes/decomp.F90: -------------------------------------------------------------------------------- 1 | ! Helper functions for all examples 2 | module decomp 3 | contains 4 | 5 | ! random integer from {minv, minv+1, ..., maxv} 6 | ! including minv and maxv 7 | function get_random(minv, maxv) result(n) 8 | implicit none 9 | integer, intent(in) :: minv, maxv 10 | real :: r 11 | integer :: n 12 | call random_number(r) 13 | n = minv + FLOOR((maxv+1-minv)*r) 14 | end function get_random 15 | 16 | ! gather the local sizes of arrays and sum them up 17 | ! so that each process knows the global shape 18 | ! and its own offset in the global space 19 | subroutine gather_decomp_1d(mysize, myshape, myoffset) 20 | use mpivars 21 | implicit none 22 | integer*8, intent(in) :: mysize 23 | integer*8, intent(out) :: myshape, myoffset 24 | integer*8, dimension(:), allocatable :: sizes 25 | 26 | allocate(sizes(nproc)) 27 | call MPI_Allgather( mysize, 1, MPI_LONG_LONG, & 28 | sizes, 1, MPI_LONG_LONG, & 29 | app_comm, ierr) 30 | myshape = sum(sizes) 31 | myoffset = sum(sizes(1:rank)) 32 | deallocate(sizes) 33 | end subroutine gather_decomp_1d 34 | 35 | subroutine decompose_1d(globalsize, myoffset, mysize) 36 | use mpivars 37 | implicit none 38 | integer*8, intent(in) :: globalsize 39 | integer*8, intent(out) :: myoffset, mysize 40 | integer*8 :: rem 41 | 42 | mysize = globalsize/nproc 43 | rem = globalsize-(nproc*mysize) 44 | if (rank < rem) then 45 | mysize = mysize + 1 46 | myoffset = rank*mysize 47 | else 48 | myoffset = rank*mysize + rem 49 | endif 50 | end subroutine decompose_1d 51 | 52 | end module decomp 53 | 54 | -------------------------------------------------------------------------------- /source/fortran/shapes/global-array-changing-shape-write.F90: -------------------------------------------------------------------------------- 1 | program adios2_global_arrays_changing_shape_write 2 | use mpivars 3 | use adios2 4 | implicit none 5 | integer, parameter :: numsteps = 5 6 | 7 | ! ADIOS2 variables 8 | type(adios2_adios) :: adios 9 | 10 | ! MPI then ADIOS2 initialization 11 | call init_mpi(123) 12 | call adios2_init(adios, app_comm, ierr) 13 | 14 | call writer() 15 | 16 | ! ADIOS2 then MPI finalization 17 | call adios2_finalize(adios, ierr) 18 | call finalize_mpi() 19 | 20 | contains 21 | 22 | subroutine writer 23 | use mpivars 24 | use decomp 25 | use adios2 26 | implicit none 27 | 28 | type(adios2_io) :: io 29 | type(adios2_engine) :: engine 30 | type(adios2_variable) :: var_g 31 | type(adios2_attribute) :: attr 32 | integer :: step 33 | 34 | ! Application variables 35 | ! g = 1D distributed array, both the global size and 36 | ! the per-process size are changing every step 37 | 38 | integer, dimension(:), allocatable :: g 39 | character(80), parameter :: ga = "Global Array with changing shape and decomposition" 40 | 41 | integer, parameter :: mincount = 2, maxcount = 5 42 | integer*8, dimension(1) :: changing_shape, changing_start, changing_count 43 | 44 | call adios2_declare_io (io, adios, 'output', ierr) 45 | 46 | 47 | changing_count = 1 ! fake data is okay for now 48 | changing_shape = 1 ! we will change the shape,start,count in every step 49 | changing_start = 0 50 | call adios2_define_variable(var_g, io, "GlobalArray", & 51 | adios2_type_integer4, 1, & 52 | changing_count, changing_start, changing_count, & 53 | adios2_variable_dims, ierr) 54 | 55 | 56 | call adios2_define_attribute(attr, io, "GlobalArray/info", ga, ierr) 57 | 58 | call adios2_open(engine, io, "adios2-global-array-changing-shape-f.bp", adios2_mode_write, ierr) 59 | 60 | ! Computation/output loop 61 | do step=0,numsteps-1 62 | ! "compute g" where size of g will change 63 | changing_count = get_random(mincount, maxcount) 64 | call gather_decomp_1d(changing_count(1), changing_shape(1), changing_start(1)) 65 | allocate(g(changing_count(1))) 66 | g = rank 67 | 68 | ! Change the shape and decomposition information for g2 69 | call adios2_set_shape(var_g, 1, changing_shape, ierr) 70 | call adios2_set_selection(var_g, 1, changing_start, changing_count, ierr); 71 | write (*,100) "Decomp rank=", rank, & 72 | " global shape = ", changing_shape(1), & 73 | " local count = ", changing_count(1), & 74 | " offset = ", changing_start(1) 75 | 100 format (a,i2,a,i4,a,i4,a,i4) 76 | 77 | ! Output all data 78 | call adios2_begin_step(engine, adios2_step_mode_append, ierr) 79 | call adios2_put(engine, var_g, g, ierr); 80 | call adios2_end_step(engine, ierr) 81 | 82 | deallocate(g) 83 | enddo 84 | 85 | ! Close the output 86 | call adios2_close(engine, ierr) 87 | 88 | if (rank == 0) then 89 | write (*,*) "Try the following: " 90 | write (*,*) & 91 | " bpls -la adios2-global-array-changing-shape-f.bp" 92 | write (*,*) & 93 | " bpls -l adios2-global-array-changing-shape-f.bp -t" 94 | write (*,*) & 95 | " bpls -l adios2-global-array-changing-shape-f.bp/ GlobalArray -dt -n 9999" 96 | write (*,'(a)') & 97 | " mpirun -n 2 ./adios2-global-array-changing-shape-read-f " 98 | endif 99 | 100 | end subroutine writer 101 | 102 | 103 | end program adios2_global_arrays_changing_shape_write 104 | -------------------------------------------------------------------------------- /source/fortran/shapes/global-array-fixed-read.F90: -------------------------------------------------------------------------------- 1 | program adios2_global_array_fixed_read 2 | use mpivars 3 | use adios2 4 | implicit none 5 | 6 | ! ADIOS2 variables 7 | type(adios2_adios) :: adios 8 | 9 | ! MPI then ADIOS2 initialization 10 | call init_mpi(234) 11 | call adios2_init(adios, app_comm, ierr) 12 | 13 | call reader() 14 | 15 | ! ADIOS2 then MPI finalization 16 | call adios2_finalize(adios, ierr) 17 | call finalize_mpi() 18 | 19 | contains 20 | 21 | subroutine reader 22 | use mpivars 23 | use decomp 24 | use adios2 25 | implicit none 26 | 27 | character(len=256), parameter :: streamname = "adios2-global-array-fixed-f.bp" 28 | 29 | type(adios2_io) :: io 30 | type(adios2_engine) :: engine 31 | type(adios2_variable) :: var_g 32 | type(adios2_attribute) :: attr 33 | integer :: step, istatus 34 | 35 | ! Application variables 36 | ! g = 1D distributed array, global shape and per-process size is fixed 37 | 38 | real*4, dimension(:), allocatable :: g 39 | integer :: ndims 40 | integer*8, dimension(:), allocatable :: fixed_shape 41 | integer*8, dimension(1) :: fixed_start, fixed_count 42 | 43 | call adios2_declare_io (io, adios, 'input', ierr) 44 | call adios2_open(engine, io, streamname, adios2_mode_read, ierr) 45 | if (ierr .ne. 0) then 46 | print '(" Failed to open stream: ",a)', streamname 47 | print '(" open stream ierr=: ",i0)', ierr 48 | return 49 | endif 50 | 51 | ! Reading steps 52 | step = 0 53 | do 54 | call adios2_begin_step(engine, adios2_step_mode_read, 0.0, istatus, ierr) 55 | if (ierr /= 0) then 56 | print '(" Failure when trying to get next step: ",a)', streamname 57 | exit 58 | endif 59 | if (istatus == adios2_step_status_end_of_stream) then 60 | ! Stream has terminated, no more steps are available 61 | !print '(" Input stream has terminated: ",a)', streamname 62 | exit 63 | endif 64 | 65 | ! Variable pointer MUST be retrieved every step, the reference 66 | ! will go invalid after adios2_end_step 67 | call adios2_inquire_variable(var_g, io, "GlobalArray", ierr ) 68 | 69 | ! Get variable dimensions and do decomposition in the first step 70 | ! These don't change for the stream in this example 71 | if (step == 0) then 72 | ! fixed_shape is allocated in the next call 73 | call adios2_variable_shape(fixed_shape, ndims, var_g, ierr) 74 | 75 | call decompose_1d(fixed_shape(1), fixed_start(1), fixed_count(1)) 76 | allocate(g(fixed_count(1))) 77 | 78 | write (*,100) "Read plan rank=", rank, & 79 | " global shape = ", fixed_shape(1), & 80 | " local count = ", fixed_count(1), & 81 | " offset = ", fixed_start(1) 82 | 100 format (a,i2,a,i4,a,i1,a,i4) 83 | endif 84 | 85 | call adios2_set_selection(var_g, 1, fixed_start, fixed_count, ierr) 86 | call adios2_get(engine, var_g, g, ierr) 87 | call adios2_end_step(engine, ierr) 88 | 89 | ! g[] is now filled with data AFTER adios2_end_step/adios2_perform_gets 90 | ! or should call adios2_get(engine, var_g, g, adios2_mode_sync, ierr) 91 | ! to get it immediately in the get() call 92 | 93 | step = step + 1 94 | enddo 95 | 96 | ! Close the output 97 | call adios2_close(engine, ierr) 98 | 99 | deallocate(g) 100 | deallocate(fixed_shape) 101 | 102 | end subroutine reader 103 | 104 | 105 | end program adios2_global_array_fixed_read 106 | -------------------------------------------------------------------------------- /source/fortran/shapes/global-array-fixed-write.F90: -------------------------------------------------------------------------------- 1 | program adios2_global_array_fixed_write 2 | use mpivars 3 | use adios2 4 | implicit none 5 | integer, parameter :: numsteps = 5 6 | 7 | ! ADIOS2 variables 8 | type(adios2_adios) :: adios 9 | 10 | ! MPI then ADIOS2 initialization 11 | call init_mpi(123) 12 | call adios2_init(adios, app_comm, ierr) 13 | 14 | call writer() 15 | 16 | ! ADIOS2 then MPI finalization 17 | call adios2_finalize(adios, ierr) 18 | call finalize_mpi() 19 | 20 | contains 21 | 22 | subroutine writer 23 | use mpivars 24 | use decomp 25 | use adios2 26 | implicit none 27 | 28 | type(adios2_io) :: io 29 | type(adios2_engine) :: engine 30 | type(adios2_variable) :: var_g 31 | type(adios2_attribute) :: attr 32 | integer :: step 33 | 34 | ! Application variables 35 | ! g = 1D distributed array, 36 | ! global shape and per-process size is fixed 37 | 38 | real*4, dimension(:), allocatable :: g 39 | character(80), parameter :: ga = "Global Array with fixed shape and decomposition" 40 | 41 | integer, parameter :: mincount = 2, maxcount = 5 42 | integer*8, dimension(1) :: fixed_shape, fixed_start, fixed_count 43 | 44 | fixed_count(1) = get_random(mincount, maxcount) 45 | allocate(g(fixed_count(1))) 46 | call gather_decomp_1d(fixed_count(1), fixed_shape(1), fixed_start(1)) 47 | 48 | call adios2_declare_io (io, adios, 'output', ierr) 49 | 50 | call adios2_define_variable(var_g, io, "GlobalArray", & 51 | adios2_type_real4, 1, & 52 | fixed_shape, fixed_start, fixed_count, & 53 | adios2_constant_dims, ierr) 54 | 55 | call adios2_define_attribute(attr, io, "GlobalArray/info", ga, ierr) 56 | 57 | call adios2_open(engine, io, "adios2-global-array-fixed-f.bp", adios2_mode_write, ierr) 58 | 59 | write (*,100) "Decomp rank=", rank, & 60 | " global shape = ", fixed_shape(1), & 61 | " local count = ", fixed_count(1), & 62 | " offset = ", fixed_start(1) 63 | 100 format (a,i2,a,i4,a,i1,a,i4) 64 | 65 | ! Computation/output loop 66 | do step=0,numsteps-1 67 | g = rank + (step+1)/100.0 68 | ! Output all data 69 | call adios2_begin_step(engine, adios2_step_mode_append, ierr) 70 | call adios2_put(engine, var_g, g, ierr); 71 | call adios2_end_step(engine, ierr) 72 | enddo 73 | 74 | ! Close the output 75 | call adios2_close(engine, ierr) 76 | 77 | deallocate(g) 78 | 79 | if (rank == 0) then 80 | write (*,*) "Try the following: " 81 | write (*,'(a,a,i4)') & 82 | " bpls -la adios2-global-array-fixed-f.bp ", & 83 | "GlobalArray -d -n ", fixed_shape(1) 84 | write (*,'(a,a,i4)') & 85 | " bpls -la adios2-global-array-fixed-f.bp ", & 86 | "GlobalArray -d -t -n ", fixed_shape(1) 87 | write (*,'(a)') & 88 | " mpirun -n 2 ./adios2-global-array-fixed-read-f " 89 | endif 90 | end subroutine writer 91 | 92 | 93 | end program adios2_global_array_fixed_write 94 | -------------------------------------------------------------------------------- /source/fortran/shapes/mpivars.F90: -------------------------------------------------------------------------------- 1 | module mpivars 2 | implicit none 3 | include 'mpif.h' 4 | 5 | integer:: app_comm, rank, nproc 6 | integer:: wrank, wnproc 7 | integer:: ierr 8 | 9 | contains 10 | 11 | subroutine init_mpi(color) 12 | integer, intent(in):: color 13 | call MPI_Init(ierr) 14 | ! World comm spans all applications started with the same mpirun command 15 | call MPI_Comm_rank(MPI_COMM_WORLD, wrank, ierr) 16 | call MPI_Comm_size(MPI_COMM_WORLD, wnproc, ierr) 17 | 18 | ! Have to split and create a 'world' communicator for this app only 19 | ! color must be unique for each application 20 | call MPI_Comm_split (MPI_COMM_WORLD, color, wrank, app_comm, ierr) 21 | call MPI_Comm_rank (app_comm, rank, ierr) 22 | call MPI_Comm_size (app_comm, nproc , ierr) 23 | end subroutine init_mpi 24 | 25 | subroutine finalize_mpi() 26 | call MPI_Finalize(ierr) 27 | end subroutine finalize_mpi 28 | 29 | end module mpivars 30 | 31 | -------------------------------------------------------------------------------- /source/fortran/shapes/shapes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /source/gpu/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | set(common_deps adios2::cxx11) 7 | 8 | find_package(CUDAToolkit QUIET) 9 | if(CUDAToolkit_FOUND) 10 | add_subdirectory(basics-cuda) 11 | endif() 12 | 13 | find_package(hip QUIET) 14 | if(hip_FOUND) 15 | add_subdirectory(basics-hip) 16 | endif() 17 | 18 | find_package(Kokkos QUIET) 19 | if(Kokkos_FOUND) 20 | add_subdirectory(basics-kokkos) 21 | add_subdirectory(gray-scott-kokkos) 22 | endif() 23 | -------------------------------------------------------------------------------- /source/gpu/basics-cuda/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | enable_language(CUDA) 2 | 3 | add_executable(adios2-write-read-cuda write-read-cuda.cpp) 4 | target_sources(adios2-write-read-cuda PRIVATE cudaRoutines.cu) 5 | target_link_libraries(adios2-write-read-cuda ${common_deps} CUDA::cudart) 6 | add_test_helper(adios2-write-read-cuda) 7 | install(TARGETS adios2-write-read-cuda 8 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 9 | ) 10 | -------------------------------------------------------------------------------- /source/gpu/basics-cuda/cudaRoutines.cu: -------------------------------------------------------------------------------- 1 | #include "cudaRoutines.h" 2 | 3 | __global__ void __cuda_increment(float *vec, float val) 4 | { 5 | vec[blockIdx.x] += val; 6 | } 7 | 8 | void cuda_increment(int M, int N, float *vec, float val) 9 | { 10 | __cuda_increment<<>>(vec, val); 11 | } 12 | 13 | __global__ void __cuda_initialize(float *vec) { vec[blockIdx.x] = blockIdx.x; } 14 | 15 | void cuda_initialize(int M, int N, float *vec) 16 | { 17 | __cuda_initialize<<>>(vec); 18 | } 19 | -------------------------------------------------------------------------------- /source/gpu/basics-cuda/cudaRoutines.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void cuda_increment(int M, int N, float *vec, float val); 4 | 5 | void cuda_initialize(int M, int N, float *vec); 6 | -------------------------------------------------------------------------------- /source/gpu/basics-cuda/write-read-cuda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "cudaRoutines.h" 9 | #include 10 | 11 | int BPWrite(const std::string fname, const size_t N, int nSteps, 12 | const std::string engine) 13 | { 14 | float *gpuSimData; 15 | cudaMalloc((void **)&gpuSimData, N * sizeof(float)); 16 | cuda_initialize(N, 1, gpuSimData); 17 | 18 | adios2::ADIOS adios; 19 | adios2::IO io = adios.DeclareIO("WriteIO"); 20 | io.SetEngine(engine); 21 | 22 | const adios2::Dims shape{static_cast(N)}; 23 | const adios2::Dims start{static_cast(0)}; 24 | const adios2::Dims count{N}; 25 | auto data = io.DefineVariable("data", shape, start, count); 26 | 27 | adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); 28 | 29 | for (size_t step = 0; step < nSteps; ++step) 30 | { 31 | adios2::Box sel({0}, {N}); 32 | data.SetSelection(sel); 33 | 34 | bpWriter.BeginStep(); 35 | bpWriter.Put(data, gpuSimData); 36 | bpWriter.EndStep(); 37 | 38 | cuda_increment(N, 1, gpuSimData, 10); 39 | } 40 | 41 | bpWriter.Close(); 42 | return 0; 43 | } 44 | 45 | int BPRead(const std::string fname, const size_t N, int nSteps, 46 | const std::string engine) 47 | { 48 | adios2::ADIOS adios; 49 | adios2::IO io = adios.DeclareIO("ReadIO"); 50 | io.SetEngine(engine); 51 | 52 | adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read); 53 | 54 | unsigned int step = 0; 55 | float *gpuSimData; 56 | cudaMalloc((void **)&gpuSimData, N * sizeof(float)); 57 | for (; bpReader.BeginStep() == adios2::StepStatus::OK; ++step) 58 | { 59 | auto data = io.InquireVariable("data"); 60 | const adios2::Dims start{0}; 61 | const adios2::Dims count{N}; 62 | const adios2::Box sel(start, count); 63 | data.SetSelection(sel); 64 | 65 | bpReader.Get(data, gpuSimData); 66 | bpReader.EndStep(); 67 | 68 | std::vector cpuData(N); 69 | cudaMemcpy(cpuData.data(), gpuSimData, N * sizeof(float), 70 | cudaMemcpyDeviceToHost); 71 | std::cout << "Simualation step " << step << " : "; 72 | std::cout << cpuData.size() << " elements: " << cpuData[0]; 73 | std::cout << " " << cpuData[1] << " ... "; 74 | std::cout << cpuData[cpuData.size() - 1] << std::endl; 75 | } 76 | bpReader.Close(); 77 | return 0; 78 | } 79 | 80 | int main(int argc, char **argv) 81 | { 82 | const int device_id = 1; 83 | cudaSetDevice(device_id); 84 | const std::vector list_of_engines = {"BP4", "BP5"}; 85 | const size_t N = 6000; 86 | int nSteps = 2, ret = 0; 87 | 88 | for (auto engine : list_of_engines) 89 | { 90 | std::cout << "Using engine " << engine << std::endl; 91 | const std::string fname(engine + "_Cuda_WR.bp"); 92 | ret += BPWrite(fname, N, nSteps, engine); 93 | ret += BPRead(fname, N, nSteps, engine); 94 | } 95 | return ret; 96 | } 97 | -------------------------------------------------------------------------------- /source/gpu/basics-hip/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | enable_language(HIP) 2 | 3 | add_executable(adios2-write-read-hip write-read-hip.cpp) 4 | target_link_libraries(adios2-write-read-hip ${common_deps} hip::device) 5 | add_test_helper(adios2-write-read-hip) 6 | install(TARGETS adios2-write-read-hip 7 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 8 | ) 9 | -------------------------------------------------------------------------------- /source/gpu/basics-kokkos/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | add_executable(adios2-write-read-kokkos write-read-kokkos.cpp) 7 | target_link_libraries(adios2-write-read-kokkos ${common_deps} Kokkos::kokkos) 8 | add_test_helper(adios2-write-read-kokkos) 9 | install(TARGETS adios2-write-read-kokkos 10 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 11 | ) 12 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | add_executable(adios2-gray-scott-kokkos 7 | main.cpp 8 | gray-scott.cpp 9 | settings.cpp 10 | writer.cpp 11 | restart.cpp 12 | ) 13 | target_link_libraries(adios2-gray-scott-kokkos adios2::adios2 MPI::MPI_C Kokkos::kokkos) 14 | install(TARGETS adios2-gray-scott-kokkos 15 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 16 | ) 17 | 18 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/README.md: -------------------------------------------------------------------------------- 1 | Kokkos version of Gray-Scott. 2 | Please use the installed Gray-Scott example directory but run adios2-gray-scott-kokkos binary. 3 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/gray-scott.h: -------------------------------------------------------------------------------- 1 | #ifndef __GRAY_SCOTT_H__ 2 | #define __GRAY_SCOTT_H__ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "settings.h" 11 | 12 | class GrayScott 13 | { 14 | public: 15 | // Dimension of process grid 16 | size_t npx, npy, npz; 17 | // Coordinate of this rank in process grid 18 | size_t px, py, pz; 19 | // Dimension of local array 20 | size_t size_x, size_y, size_z; 21 | // Offset of local array in the global array 22 | size_t offset_x, offset_y, offset_z; 23 | 24 | GrayScott(const Settings &settings, MPI_Comm comm); 25 | ~GrayScott(); 26 | 27 | void init(); 28 | void iterate(); 29 | void restart(Kokkos::View &u, 30 | Kokkos::View &v); 31 | 32 | const Kokkos::View u_ghost() const; 33 | const Kokkos::View v_ghost() const; 34 | 35 | Kokkos::View u_noghost() const; 36 | Kokkos::View v_noghost() const; 37 | 38 | void 39 | u_noghost(Kokkos::View u_no_ghost) const; 40 | void 41 | v_noghost(Kokkos::View v_no_ghost) const; 42 | 43 | Settings settings; 44 | 45 | Kokkos::View u, v, u2, v2; 46 | 47 | int rank, procs; 48 | int west, east, up, down, north, south; 49 | MPI_Comm comm; 50 | MPI_Comm cart_comm; 51 | 52 | // MPI datatypes for halo exchange 53 | MPI_Datatype xy_face_type; 54 | MPI_Datatype xz_face_type; 55 | MPI_Datatype yz_face_type; 56 | 57 | using RandomPool = 58 | Kokkos::Random_XorShift64_Pool; 59 | RandomPool rand_pool; 60 | 61 | // Setup cartesian communicator data types 62 | void init_mpi(); 63 | // Setup initial conditions 64 | void init_field(); 65 | 66 | // Progess simulation for one timestep 67 | void calc(); 68 | 69 | // Exchange faces with neighbors 70 | void 71 | exchange(Kokkos::View u, 72 | Kokkos::View v) 73 | const; 74 | // Exchange XY faces with north/south 75 | void 76 | exchange_xy(Kokkos::View 77 | local_data) const; 78 | // Exchange XZ faces with up/down 79 | void 80 | exchange_xz(Kokkos::View 81 | local_data) const; 82 | // Exchange YZ faces with west/east 83 | void 84 | exchange_yz(Kokkos::View 85 | local_data) const; 86 | 87 | // Return a copy of data with ghosts removed 88 | Kokkos::View data_noghost( 89 | const Kokkos::View &data) const; 90 | 91 | // pointer version 92 | void 93 | data_noghost(const Kokkos::View &data, 94 | Kokkos::View no_ghost) const; 95 | 96 | // Convert local coordinate to local index 97 | KOKKOS_FUNCTION int l2i(int x, int y, int z) const 98 | { 99 | return x + y * (size_x + 2) + z * (size_x + 2) * (size_y + 2); 100 | } 101 | 102 | void data_no_ghost_common( 103 | const Kokkos::View &data, 104 | Kokkos::View data_no_ghost) const; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/restart.cpp: -------------------------------------------------------------------------------- 1 | #include "restart.h" 2 | 3 | #include 4 | 5 | static bool firstCkpt = true; 6 | 7 | void WriteCkpt(MPI_Comm comm, const int step, const Settings &settings, 8 | const GrayScott &sim, adios2::IO io) 9 | { 10 | int rank, nproc; 11 | MPI_Comm_rank(comm, &rank); 12 | MPI_Comm_size(comm, &nproc); 13 | std::cout << "checkpoint at step " << step << " create file " 14 | << settings.checkpoint_output << std::endl; 15 | adios2::Engine writer = 16 | io.Open(settings.checkpoint_output, adios2::Mode::Write); 17 | if (writer) 18 | { 19 | adios2::Variable var_u; 20 | adios2::Variable var_v; 21 | adios2::Variable var_step; 22 | 23 | if (firstCkpt) 24 | { 25 | size_t X = sim.size_x + 2; 26 | size_t Y = sim.size_y + 2; 27 | size_t Z = sim.size_z + 2; 28 | size_t R = static_cast(rank); 29 | size_t N = static_cast(nproc); 30 | 31 | var_u = io.DefineVariable("U", {N, X, Y, Z}, {R, 0, 0, 0}, 32 | {1, X, Y, Z}); 33 | var_v = io.DefineVariable("V", {N, X, Y, Z}, {R, 0, 0, 0}, 34 | {1, X, Y, Z}); 35 | 36 | var_step = io.DefineVariable("step"); 37 | firstCkpt = false; 38 | } 39 | else 40 | { 41 | var_u = io.InquireVariable("U"); 42 | var_v = io.InquireVariable("V"); 43 | var_step = io.InquireVariable("step"); 44 | } 45 | 46 | writer.Put(var_step, &step); 47 | writer.Put(var_u, sim.u_ghost().data()); 48 | writer.Put(var_v, sim.v_ghost().data()); 49 | 50 | writer.Close(); 51 | } 52 | } 53 | 54 | int ReadRestart(MPI_Comm comm, const Settings &settings, GrayScott &sim, 55 | adios2::IO io) 56 | { 57 | int step = 0; 58 | int rank, nproc; 59 | MPI_Comm_rank(comm, &rank); 60 | MPI_Comm_size(comm, &nproc); 61 | if (!rank) 62 | { 63 | std::cout << "restart from file " << settings.restart_input 64 | << std::endl; 65 | } 66 | adios2::Engine reader = 67 | io.Open(settings.restart_input, adios2::Mode::ReadRandomAccess); 68 | if (reader) 69 | { 70 | adios2::Variable var_step = io.InquireVariable("step"); 71 | adios2::Variable var_u = io.InquireVariable("U"); 72 | adios2::Variable var_v = io.InquireVariable("V"); 73 | size_t X = sim.size_x + 2; 74 | size_t Y = sim.size_y + 2; 75 | size_t Z = sim.size_z + 2; 76 | size_t R = static_cast(rank); 77 | Kokkos::View u("u", X, Y, Z), 78 | v("v", X, Y, Z); 79 | 80 | var_u.SetSelection({{R, 0, 0, 0}, {1, X, Y, Z}}); 81 | var_v.SetSelection({{R, 0, 0, 0}, {1, X, Y, Z}}); 82 | reader.Get(var_step, step); 83 | reader.Get(var_u, u.data()); 84 | reader.Get(var_v, v.data()); 85 | reader.Close(); 86 | 87 | if (!rank) 88 | { 89 | std::cout << "restart from step " << step << std::endl; 90 | } 91 | sim.restart(u, v); 92 | } 93 | else 94 | { 95 | std::cout << " failed to open file " << std::endl; 96 | } 97 | return step; 98 | } 99 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/restart.h: -------------------------------------------------------------------------------- 1 | #ifndef __RESTART_H__ 2 | #define __RESTART_H__ 3 | 4 | #include "gray-scott.h" 5 | 6 | #include 7 | #include 8 | 9 | void WriteCkpt(MPI_Comm comm, const int step, const Settings &settings, 10 | const GrayScott &sim, adios2::IO io); 11 | int ReadRestart(MPI_Comm comm, const Settings &settings, GrayScott &sim, 12 | adios2::IO io); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/settings.cpp: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include 4 | 5 | #include "json.hpp" 6 | 7 | void to_json(nlohmann::json &j, const Settings &s) 8 | { 9 | j = nlohmann::json{{"L", s.L}, 10 | {"steps", s.steps}, 11 | {"plotgap", s.plotgap}, 12 | {"F", s.F}, 13 | {"k", s.k}, 14 | {"dt", s.dt}, 15 | {"Du", s.Du}, 16 | {"Dv", s.Dv}, 17 | {"noise", s.noise}, 18 | {"output", s.output}, 19 | {"checkpoint", s.checkpoint}, 20 | {"checkpoint_freq", s.checkpoint_freq}, 21 | {"checkpoint_output", s.checkpoint_output}, 22 | {"restart", s.restart}, 23 | {"restart_input", s.restart_input}, 24 | {"adios_config", s.adios_config}, 25 | {"adios_span", s.adios_span}, 26 | {"adios_memory_selection", s.adios_memory_selection}, 27 | {"mesh_type", s.mesh_type}}; 28 | } 29 | 30 | void from_json(const nlohmann::json &j, Settings &s) 31 | { 32 | j.at("L").get_to(s.L); 33 | j.at("steps").get_to(s.steps); 34 | j.at("plotgap").get_to(s.plotgap); 35 | j.at("F").get_to(s.F); 36 | j.at("k").get_to(s.k); 37 | j.at("dt").get_to(s.dt); 38 | j.at("Du").get_to(s.Du); 39 | j.at("Dv").get_to(s.Dv); 40 | j.at("noise").get_to(s.noise); 41 | j.at("output").get_to(s.output); 42 | j.at("checkpoint").get_to(s.checkpoint); 43 | j.at("checkpoint_freq").get_to(s.checkpoint_freq); 44 | j.at("checkpoint_output").get_to(s.checkpoint_output); 45 | j.at("restart").get_to(s.restart); 46 | j.at("restart_input").get_to(s.restart_input); 47 | j.at("adios_config").get_to(s.adios_config); 48 | j.at("adios_span").get_to(s.adios_span); 49 | j.at("adios_memory_selection").get_to(s.adios_memory_selection); 50 | j.at("mesh_type").get_to(s.mesh_type); 51 | } 52 | 53 | Settings::Settings() 54 | { 55 | L = 128; 56 | steps = 20000; 57 | plotgap = 200; 58 | F = 0.04; 59 | k = 0.06075; 60 | dt = 0.2; 61 | Du = 0.05; 62 | Dv = 0.1; 63 | noise = 0.0; 64 | output = "foo.bp"; 65 | checkpoint = false; 66 | checkpoint_freq = 2000; 67 | checkpoint_output = "ckpt.bp"; 68 | restart = false; 69 | restart_input = "ckpt.bp"; 70 | adios_config = "adios2.xml"; 71 | adios_span = false; 72 | adios_memory_selection = false; 73 | mesh_type = "image"; 74 | } 75 | 76 | Settings Settings::from_json(const std::string &fname) 77 | { 78 | std::ifstream ifs(fname); 79 | nlohmann::json j; 80 | 81 | ifs >> j; 82 | 83 | return j.get(); 84 | } 85 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/settings.h: -------------------------------------------------------------------------------- 1 | #ifndef __SETTINGS_H__ 2 | #define __SETTINGS_H__ 3 | 4 | #include 5 | 6 | struct Settings 7 | { 8 | size_t L; 9 | int steps; 10 | int plotgap; 11 | double F; 12 | double k; 13 | double dt; 14 | double Du; 15 | double Dv; 16 | double noise; 17 | std::string output; 18 | bool checkpoint; 19 | int checkpoint_freq; 20 | std::string checkpoint_output; 21 | bool restart; 22 | std::string restart_input; 23 | std::string adios_config; 24 | bool adios_span; 25 | bool adios_memory_selection; 26 | std::string mesh_type; 27 | 28 | Settings(); 29 | static Settings from_json(const std::string &fname); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/timer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_HPP__ 2 | #define __TIMER_HPP__ 3 | 4 | #include 5 | 6 | class Timer 7 | { 8 | private: 9 | bool _is_running; 10 | std::chrono::steady_clock::time_point _start; 11 | std::chrono::steady_clock::duration _total; 12 | 13 | double _to_millis(std::chrono::steady_clock::duration duration) const 14 | { 15 | std::chrono::duration duration_ms(duration); 16 | return duration_ms.count(); 17 | } 18 | 19 | public: 20 | Timer() 21 | : _is_running(false), _total(std::chrono::steady_clock::duration::zero()) 22 | { 23 | } 24 | 25 | void start() 26 | { 27 | _is_running = true; 28 | _start = std::chrono::steady_clock::now(); 29 | } 30 | 31 | double stop() 32 | { 33 | _is_running = false; 34 | 35 | const auto elapsed = std::chrono::steady_clock::now() - _start; 36 | 37 | _total += elapsed; 38 | 39 | return _to_millis(elapsed); 40 | } 41 | 42 | void reset() 43 | { 44 | _is_running = false; 45 | _total = std::chrono::steady_clock::duration::zero(); 46 | } 47 | 48 | bool is_running() const { return _is_running; } 49 | 50 | double elapsed() const { return _to_millis(_total); } 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /source/gpu/gray-scott-kokkos/writer.h: -------------------------------------------------------------------------------- 1 | #ifndef __WRITER_H__ 2 | #define __WRITER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "gray-scott.h" 8 | 9 | class Writer 10 | { 11 | public: 12 | Writer(const Settings &settings, const GrayScott &sim, adios2::IO io); 13 | void open(const std::string &fname, bool append); 14 | void write(int step, const GrayScott &sim); 15 | void close(); 16 | 17 | protected: 18 | Settings settings; 19 | 20 | adios2::IO io; 21 | adios2::Engine writer; 22 | adios2::Variable var_u; 23 | adios2::Variable var_v; 24 | adios2::Variable var_step; 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/.JuliaFormatter.toml: -------------------------------------------------------------------------------- 1 | margin = 80 2 | join_lines_based_on_source = true 3 | style = "sciml" 4 | format_doctrings = true 5 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/Project.toml: -------------------------------------------------------------------------------- 1 | name = "GrayScott" 2 | uuid = "089a57ea-382b-4fd7-9f05-24902db6ec52" 3 | authors = ["William F Godoy "] 4 | version = "0.1.0" 5 | 6 | [deps] 7 | ADIOS2 = "e0ce9d3b-0dbd-416f-8264-ccca772f60ec" 8 | AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" 9 | ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63" 10 | CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" 11 | Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" 12 | JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 13 | MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" 14 | MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" 15 | PProf = "e4faabce-9ead-11e9-39d9-4379958e3056" 16 | Profile = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" 17 | 18 | [compat] 19 | julia = "1.8" 20 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/examples/settings-files.json: -------------------------------------------------------------------------------- 1 | { 2 | "L": 64, 3 | "Du": 0.2, 4 | "Dv": 0.1, 5 | "F": 0.02, 6 | "k": 0.048, 7 | "dt": 1.0, 8 | "plotgap": 10, 9 | "steps": 10000, 10 | "noise": 0.1, 11 | "output": "gs-julia-1MPI-64L-F32.bp", 12 | "checkpoint": false, 13 | "checkpoint_freq": 700, 14 | "checkpoint_output": "ckpt.bp", 15 | "restart": false, 16 | "restart_input": "ckpt.bp", 17 | "adios_config": "adios2.xml", 18 | "adios_span": false, 19 | "adios_memory_selection": false, 20 | "mesh_type": "image", 21 | "precision": "Float32", 22 | "backend": "CPU" 23 | } -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/gray-scott.jl: -------------------------------------------------------------------------------- 1 | import GrayScott 2 | 3 | # using Profile 4 | # using PProf 5 | 6 | function julia_main()::Cint 7 | GrayScott.main(ARGS) 8 | return 0 9 | end 10 | 11 | if !isdefined(Base, :active_repl) 12 | @time julia_main() 13 | # @profile julia_main() 14 | # pprof() 15 | end -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/scripts/config_crusher.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PROJ_DIR=/gpfs/alpine/proj-shared/csc383 4 | export JULIA_DEPOT_PATH=$PROJ_DIR/etc/crusher/julia_depot 5 | GS_DIR=$PROJ_DIR/wgodoy/ADIOS2-Examples/source/julia/GrayScott.jl 6 | 7 | # remove existing generated Manifest.toml 8 | rm -f $GS_DIR/Manifest.toml 9 | rm -f $GS_DIR/LocalPreferences.toml 10 | 11 | # good practice to avoid conflicts with existing default modules 12 | module purge 13 | 14 | # load required modules 15 | module load PrgEnv-cray/8.3.3 # has required gcc 16 | module load cray-mpich 17 | module load rocm/5.4.0 18 | module load adios2 # only works with PrgEnv-cray 19 | 20 | # existing julia 1.6 module is outdated 21 | export PATH=$PROJ_DIR/opt/crusher/julia-1.9.0-beta3/bin:$PATH 22 | 23 | # Required to point at underlying modules above 24 | export JULIA_AMDGPU_DISABLE_ARTIFACTS=1 25 | # Required to enable underlying ADIOS2 library from loaded module 26 | export JULIA_ADIOS2_PATH=$OLCF_ADIOS2_ROOT 27 | 28 | # MPIPreferences to use spectrum-mpi 29 | julia --project=$GS_DIR -e 'using Pkg; Pkg.add("MPIPreferences")' 30 | julia --project=$GS_DIR -e 'using MPIPreferences; MPIPreferences.use_system_binary(; library_names=["libmpi_cray"], mpiexec="srun")' 31 | 32 | # Regression being fixed with CUDA v4.0.0. CUDA.jl does lazy loading for portability to systems without NVIDIA GPUs 33 | julia --project=$GS_DIR -e 'using Pkg; Pkg.add(name="CUDA", version="v3.13.1")' 34 | 35 | # Instantiate the project by installing packages in Project.toml 36 | julia --project=$GS_DIR -e 'using Pkg; Pkg.instantiate()' 37 | 38 | # Adds a custom branch in case the development version is needed (for devs to test new features) 39 | julia --project=$GS_DIR -e 'using Pkg; Pkg.add(url="https://github.com/eschnett/ADIOS2.jl.git", rev="main")' 40 | 41 | # Build the new ADIOS2 42 | julia --project=$GS_DIR -e 'using Pkg; Pkg.build()' 43 | julia --project=$GS_DIR -e 'using Pkg; Pkg.precompile()' 44 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/scripts/config_summit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Replace these 3 entries 4 | PROJ_DIR=/gpfs/alpine/proj-shared/csc383 5 | export JULIA_DEPOT_PATH=$PROJ_DIR/etc/summit/julia_depot 6 | GS_DIR=$PROJ_DIR/wgodoy/ADIOS2-Examples/source/julia/GrayScott.jl 7 | 8 | # remove existing generated Manifest.toml 9 | rm -f $GS_DIR/Manifest.toml 10 | rm -f $GS_DIR/LocalPreferences.toml 11 | 12 | # good practice to avoid conflicts with existing default modules 13 | # needed to avoid seg fault with MPI 14 | module purge 15 | 16 | # load required modules 17 | module load spectrum-mpi 18 | module load gcc/12.1.0 # needed by julia libraries 19 | module load cuda/11.0.3 # failure with 11.5.2 20 | module load adios2/2.8.1 21 | # module load julia/1.8.2 not working with CUDA.jl as it's missing libLLVM-13jl.so 22 | export PATH=$PROJ_DIR/opt/summit/julia-1.9.0-beta3/bin:$PATH 23 | 24 | # Required to enable underlying ADIOS2 library from loaded module 25 | export JULIA_ADIOS2_PATH=$OLCF_ADIOS2_ROOT 26 | 27 | # MPIPreferences to use spectrum-mpi 28 | julia --project=$GS_DIR -e 'using Pkg; Pkg.add("MPIPreferences")' 29 | julia --project=$GS_DIR -e 'using MPIPreferences; MPIPreferences.use_system_binary(; library_names=["libmpi_ibm"], mpiexec="jsrun")' 30 | 31 | # Instantiate the project by installing packages in Project.toml 32 | julia --project=$GS_DIR -e 'using Pkg; Pkg.instantiate()' 33 | 34 | # Adds to LocalPreferences.toml to use underlying system CUDA since CUDA.jl v4.0.0 35 | # https://cuda.juliagpu.org/stable/installation/overview/#Using-a-local-CUDA 36 | julia --project=$GS_DIR -e 'using CUDA; CUDA.set_runtime_version!("local")' 37 | 38 | # Adds a custom branch in case the development version is needed (for devs to test new features) 39 | julia --project=$GS_DIR -e 'using Pkg; Pkg.add(url="https://github.com/eschnett/ADIOS2.jl.git", rev="main")' 40 | 41 | # Build the new ADIOS2 42 | julia --project=$GS_DIR -e 'using Pkg; Pkg.build()' 43 | julia --project=$GS_DIR -e 'using Pkg; Pkg.precompile()' 44 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/scripts/job_crusher.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH -A CSC383_crusher 3 | #SBATCH -J gs-julia-1MPI-1GPU 4 | #SBATCH -o %x-%j.out 5 | #SBATCH -e %x-%j.err 6 | #SBATCH -t 0:02:00 7 | #SBATCH -p batch 8 | #SBATCH -N 1 9 | 10 | date 11 | 12 | GS_DIR=/gpfs/alpine/proj-shared/csc383/wgodoy/ADIOS2-Examples/source/julia/GrayScott.jl 13 | GS_EXE=$GS_DIR/gray-scott.jl 14 | 15 | srun -n 1 --gpus=1 julia --project=$GS_DIR $GS_EXE settings-files.json 16 | 17 | # launch this file with sbatch `$ sbatch job_crusher.sh` 18 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/scripts/job_summit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Begin LSF directives 3 | #BSUB -P csc383 4 | #BSUB -W 00:02 5 | #BSUB -nnodes 1 6 | #BSUB -J gs-julia 7 | #BSUB -o output.%J 8 | #BSUB -e output.%J 9 | #BSUB -N godoywf@ornl.gov 10 | # End BSUB directives and begin shell commands 11 | 12 | date 13 | GS_DIR=/gpfs/alpine/proj-shared/csc383/wgodoy/ADIOS2-Examples/source/julia/GrayScott.jl 14 | GS_EXE=$GS_DIR/gray-scott.jl 15 | 16 | jsrun -n 1 -g 1 julia --project=$GS_DIR $GS_EXE settings-files.json 17 | 18 | # launch this file with bsub `$ bsub job_summit.sh` 19 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/src/GrayScott.jl: -------------------------------------------------------------------------------- 1 | """ 2 | GrayScott.jl is a Simulation and Analysis parallel framework for solving the 3 | Gray-Scott 3D diffusion reaction system of equations of two variables U and V on 4 | a regular Cartesian mesh. 5 | 6 | The bp output files can be visualized with ParaView. 7 | """ 8 | module GrayScott 9 | 10 | import MPI, ADIOS2 11 | 12 | # contains relevant data containers "structs" for Input, Domain and Fields 13 | include(joinpath("simulation", "Structs.jl")) 14 | 15 | # contains helper functions for general use 16 | include(joinpath("helper", "Helper.jl")) 17 | import .Helper 18 | 19 | # initializes inputs from configuration file 20 | include(joinpath("simulation", "Inputs.jl")) 21 | import .Inputs 22 | 23 | # manages the simulation computation 24 | include(joinpath("simulation", "Simulation.jl")) 25 | import .Simulation 26 | 27 | # manages the I/O 28 | include(joinpath("simulation", "IO.jl")) 29 | import .IO 30 | 31 | function julia_main()::Cint 32 | try 33 | main(ARGS) 34 | catch 35 | Base.invokelatest(Base.display_error, Base.catch_stack()) 36 | return 1 37 | end 38 | return 0 39 | end 40 | 41 | function main(args::Vector{String})::Int32 42 | MPI.Init() 43 | comm = MPI.COMM_WORLD 44 | rank = MPI.Comm_rank(comm) 45 | size = MPI.Comm_size(comm) 46 | 47 | # a data struct that holds settings data from config_file in args 48 | # example config file: ../examples/settings-files.json 49 | settings = Inputs.get_settings(args, comm) 50 | 51 | # initialize MPI Cartesian Domain and Communicator 52 | mpi_cart_domain = Simulation.init_domain(settings, comm) 53 | 54 | # initialize fields 55 | fields = Simulation.init_fields(settings, 56 | mpi_cart_domain, 57 | Helper.get_type(settings.precision)) 58 | 59 | # initialize IOStream struct holding ADIOS-2 components for parallel I/O 60 | stream = IO.init(settings, mpi_cart_domain, fields) 61 | 62 | restart_step::Int32 = 0 63 | # @TODO: checkpoint-restart 64 | step::Int32 = restart_step 65 | 66 | while step < settings.steps 67 | Simulation.iterate!(fields, settings, mpi_cart_domain) 68 | step += 1 69 | 70 | if step % settings.plotgap == 0 71 | if rank == 0 72 | println("Simulation at step ", step, " writing output step ", 73 | step / settings.plotgap) 74 | end 75 | 76 | IO.write_step!(stream, step, fields) 77 | end 78 | end 79 | 80 | IO.close!(stream) 81 | 82 | # Debugging session or Julia REPL session, not needed overall as it would be 83 | # called when the program ends 84 | if !isinteractive() 85 | MPI.Finalize() 86 | end 87 | 88 | return 0 89 | end 90 | 91 | end # module GrayScott 92 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/src/helper/Helper.jl: -------------------------------------------------------------------------------- 1 | 2 | module Helper 3 | 4 | include("helperMPI.jl") 5 | include("helperString.jl") 6 | 7 | end -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/src/helper/helperMPI.jl: -------------------------------------------------------------------------------- 1 | 2 | import MPI 3 | 4 | export bcase_file 5 | 6 | function bcast_file_contents(file_name::String, comm, root = 0)::String 7 | size::UInt32 = 0 8 | data::Vector{UInt8} = [] 9 | if MPI.Comm_rank(comm) == root 10 | data = read(open(file_name, "r")) 11 | end 12 | 13 | data = MPI.bcast(data, comm) 14 | return String(data) 15 | end 16 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/src/helper/helperString.jl: -------------------------------------------------------------------------------- 1 | 2 | export get_type 3 | 4 | function get_type(input::String) 5 | if input == "Float64" 6 | return Float64 7 | elseif input == "Float32" 8 | return Float32 9 | elseif input == "Float16" 10 | return Float16 11 | end 12 | 13 | return nothing 14 | end -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/src/simulation/Inputs.jl: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | Submodule used by GrayScott to handle inputs 4 | """ 5 | module Inputs 6 | 7 | export get_settings 8 | 9 | import ArgParse 10 | import JSON 11 | 12 | import ..Helper 13 | # import directly from parent module (GrayScott) 14 | import ..Settings, ..SettingsKeys 15 | 16 | # public facing function 17 | function get_settings(args::Vector{String}, comm)::Settings 18 | config_file = _parse_args(args) 19 | 20 | # check format extension 21 | if !endswith(config_file, ".json") && 22 | !(endswith(config_file, ".yaml") || endswith(config_file, ".yml")) 23 | throw(ArgumentError("config file must be json, yaml format. Extension not recognized.\n")) 24 | end 25 | 26 | config_file_contents::String = Helper.bcast_file_contents(config_file, comm) 27 | 28 | if endswith(config_file, ".json") 29 | return _parse_settings_json(config_file_contents) 30 | end 31 | 32 | return nothing 33 | end 34 | 35 | # local scope functions 36 | function _parse_args(args::Vector{String}; 37 | error_handler = ArgParse.default_handler)::String 38 | s = ArgParse.ArgParseSettings(description = "gray-scott workflow simulation example configuration file, Julia version, GrayScott.jl", 39 | exc_handler = error_handler) 40 | 41 | # @add_arg_table! s begin 42 | # "--opt1" # an option (will take an argument) 43 | # "--opt2", "-o" # another option, with short form 44 | # "arg1" # a positional argument 45 | # end 46 | 47 | ArgParse.@add_arg_table! s begin 48 | "config_file" 49 | help = "configuration file" 50 | arg_type = String 51 | required = true 52 | end 53 | 54 | # parse_args return a dictionary with key/value for arguments 55 | parsed_arguments = ArgParse.parse_args(args, s) 56 | 57 | # key is mandatory, so it's safe to retrieve 58 | config_file::String = parsed_arguments["config_file"] 59 | 60 | return config_file 61 | end 62 | 63 | function _parse_settings_json(json_contents::String)::Settings 64 | json = JSON.parse(json_contents) 65 | settings = Settings() 66 | 67 | # Iterate through dictionary pairs 68 | for (key, value) in json 69 | # Iterate through predefined keys, else ignore (no error if unrecognized) 70 | if key in SettingsKeys 71 | setproperty!(settings, Symbol(key), value) 72 | end 73 | end 74 | 75 | return settings 76 | end 77 | 78 | end # module -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/src/simulation/Structs.jl: -------------------------------------------------------------------------------- 1 | 2 | """ 3 | Settings carry the settings from the simulation config file (json or yaml formats) 4 | 5 | Using Base.@kwdef macro for easy defaults and enable keyword arguments 6 | Settings(Du = 0.2, noise = 0.2) 7 | See: 8 | https://discourse.julialang.org/t/default-value-of-some-fields-in-a-mutable-struct/33408/24?u=williamfgc 9 | """ 10 | Base.@kwdef mutable struct Settings 11 | L::Int64 = 128 12 | steps::Int32 = 20000 13 | plotgap::Int32 = 200 14 | F::Float64 = 0.04 15 | k::Float64 = 0 16 | dt::Float64 = 0.2 17 | Du::Float64 = 0.05 18 | Dv::Float64 = 0.1 19 | noise::Float64 = 0.0 20 | output::String = "foo.bp" 21 | checkpoint::Bool = false 22 | checkpoint_freq::Int32 = 2000 23 | checkpoint_output::String = "ckpt.bp" 24 | restart::Bool = false 25 | restart_input::String = "ckpt.bp" 26 | adios_config::String = "adios2.yaml" 27 | adios_span::Bool = false 28 | adios_memory_selection::Bool = false 29 | mesh_type::String = "image" 30 | precision::String = "Float64" 31 | backend::String = "CPU" 32 | end 33 | 34 | SettingsKeys = Set{String}([ 35 | "L", 36 | "steps", 37 | "plotgap", 38 | "F", 39 | "k", 40 | "dt", 41 | "Du", 42 | "Dv", 43 | "noise", 44 | "output", 45 | "checkpoint", 46 | "checkpoint_freq", 47 | "checkpoint_output", 48 | "restart", 49 | "restart_input", 50 | "adios_config", 51 | "adios_span", 52 | "adios_memory_selection", 53 | "mesh_type", 54 | "precision", 55 | "backend", 56 | ]) 57 | 58 | Base.@kwdef mutable struct MPICartDomain 59 | cart_comm::MPI.Comm = MPI.COMM_NULL 60 | 61 | # Cartesian communicator info 62 | # Could used StaticArrays.jl? 63 | # start dims with zeros 64 | dims::Vector{Int32} = zeros(Int32, 3) 65 | coords::Vector{Int32} = zeros(Int32, 3) 66 | 67 | # local process mesh sizes and offsets in Cartesian domain info, using defaults 68 | proc_sizes::Vector{Int64} = [128, 128, 128] 69 | proc_offsets::Vector{Int64} = [1, 1, 1] 70 | 71 | # couldn't use NamedTuples as struct is mutable 72 | proc_neighbors = Dict{String, Int32}("west" => -1, "east" => -1, "up" => -1, 73 | "down" => -1, "north" => -1, 74 | "south" => -1) 75 | end 76 | 77 | """ 78 | Carry the physical field outputs: u and v 79 | Using AbstractArray to allow for Array, CuArray and ROCArray 80 | """ 81 | mutable struct Fields{T, N, A <: AbstractArray{T, N}} 82 | u::A 83 | v::A 84 | u_temp::A 85 | v_temp::A 86 | # MPI Datatypes for halo exchange MPI.Datatype(T) 87 | xy_face_t::MPI.Datatype 88 | xz_face_t::MPI.Datatype 89 | yz_face_t::MPI.Datatype 90 | end 91 | 92 | """ 93 | Carry the I/O information for outputs 94 | """ 95 | struct IOStream 96 | adios::ADIOS2.Adios 97 | io::ADIOS2.AIO 98 | engine::ADIOS2.Engine 99 | var_step::ADIOS2.Variable 100 | var_U::ADIOS2.Variable 101 | var_V::ADIOS2.Variable 102 | end 103 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/Project.toml: -------------------------------------------------------------------------------- 1 | [deps] 2 | MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" 3 | Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 4 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/functional/functional-GrayScott.jl: -------------------------------------------------------------------------------- 1 | 2 | import GrayScott 3 | import Test: @testset, @test 4 | 5 | @testset "GrayScott" begin MPI.mpiexec() do runcmd 6 | config_file = joinpath(dirname(Base.active_project()), "examples", 7 | "settings-files.json") 8 | 9 | juliacmd = `julia --project gray-scott.jl $config_file` 10 | 11 | @test run(`mpirun -n 4 $juliacmd`).exitcode == 0 12 | end end -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/runtests.jl: -------------------------------------------------------------------------------- 1 | 2 | import MPI 3 | 4 | # Run all lightweight unit tests within a single MPI session 5 | MPI.Init() 6 | 7 | verbose = false 8 | 9 | # unit tests for module GrayScott 10 | include(joinpath("unit", "helper", "unit-helperMPI.jl")) 11 | 12 | include(joinpath("unit", "simulation", "unit-Inputs.jl")) 13 | include(joinpath("unit", "simulation", "unit-Simulation.jl")) 14 | include(joinpath("unit", "simulation", "unit-Simulation_CUDA.jl")) 15 | include(joinpath("unit", "simulation", "unit-IO.jl")) 16 | 17 | # unit tests for analysis scripts 18 | include(joinpath("unit", "analysis", "unit-pdfcalc.jl")) 19 | 20 | MPI.Finalize() 21 | 22 | # Command line tests. These are heavier tests launched as separate processes. 23 | # The downside is that only global success can be tested and not internal states. 24 | 25 | # functional tests 26 | # include(joinpath("functional", "functional-GrayScott.jl")) 27 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/unit/analysis/unit-pdfcalc.jl: -------------------------------------------------------------------------------- 1 | 2 | import Test: @testset, @test, @test_throws 3 | 4 | include(joinpath(dirname(Base.active_project()), "src", "analysis", 5 | "pdfcalc.jl")) 6 | 7 | @testset "unit-analysis.pdfcalc._parse_args" begin 8 | inputs = _parse_arguments(["foo.bp", "bar.bp", "1500"]) 9 | @test inputs["input"] == "foo.bp" 10 | @test inputs["output"] == "bar.bp" 11 | @test inputs["N"] == 1500 12 | @test inputs["output_inputdata"] == false 13 | 14 | inputs = _parse_arguments(["input.bp", "output.bp", "1000", "true"]) 15 | @test inputs["input"] == "input.bp" 16 | @test inputs["output"] == "output.bp" 17 | @test inputs["N"] == 1000 18 | @test inputs["output_inputdata"] == true 19 | end 20 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/unit/helper/unit-helperMPI.jl: -------------------------------------------------------------------------------- 1 | 2 | import Test: @testset, @test, @test_throws 3 | import GrayScott: Helper 4 | 5 | @testset "unit-Helper.bcast_file_contents" begin 6 | config_file = joinpath(dirname(Base.active_project()), "examples", 7 | "settings-files.json") 8 | 9 | file_contents = Helper.bcast_file_contents(config_file, MPI.COMM_WORLD) 10 | file_contents_expected = String(read(open(config_file, "r"))) 11 | @test file_contents == file_contents_expected 12 | end -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/unit/simulation/unit-IO.jl: -------------------------------------------------------------------------------- 1 | 2 | import Test: @testset, @test, @test_throws 3 | 4 | import ADIOS2 5 | 6 | # import submodule 7 | import GrayScott: IO 8 | # import types 9 | import GrayScott: Settings, MPICartDomain, Fields 10 | 11 | @testset "unit-IO.init" begin 12 | settings = Settings() 13 | mpi_cart_domain = MPICartDomain() 14 | fields = Simulation.init_fields(settings, mpi_cart_domain, Float32) 15 | 16 | @test eltype(fields.u) == Float32 17 | @test eltype(fields.v) == Float32 18 | 19 | stream = IO.init(settings, mpi_cart_domain, fields) 20 | 21 | @test ADIOS2.name(stream.engine) == "foo.bp" 22 | IO.close!(stream) 23 | 24 | # @TODO: needs to be done from rank==0 only 25 | # Base.Filesystem.rm("foo.bp", force = true, recursive = true) 26 | end 27 | 28 | @testset "unit-IO.write" begin 29 | settings = Settings() 30 | settings.L = 6 31 | mpi_cart_domain = Simulation.init_domain(settings, MPI.COMM_WORLD) 32 | fields = Simulation.init_fields(settings, mpi_cart_domain, Float32) 33 | stream = IO.init(settings, mpi_cart_domain, fields) 34 | IO.write_step!(stream, Int32(0), fields) 35 | IO.close!(stream) 36 | end 37 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/unit/simulation/unit-Inputs.jl: -------------------------------------------------------------------------------- 1 | 2 | import Test: @testset, @test, @test_throws 3 | import GrayScott: Inputs 4 | 5 | # Unfortunately due to MPI being a Singleton, single MPI.Init() 6 | # these unit tests don't run as independent files 7 | 8 | @testset "unit-Inputs.get_settings" begin 9 | config_file = joinpath(dirname(Base.active_project()), "examples", 10 | "settings-files.json") 11 | Inputs.get_settings([config_file], MPI.COMM_WORLD) 12 | 13 | @test_throws(ArgumentError, 14 | Inputs.get_settings(["hello.nojson"], MPI.COMM_WORLD)) 15 | end 16 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/unit/simulation/unit-Simulation.jl: -------------------------------------------------------------------------------- 1 | 2 | import Test: @testset, @test, @test_throws 3 | # import submodule 4 | import GrayScott: Simulation 5 | # import types 6 | import GrayScott: Settings, MPICartDomain, Fields 7 | 8 | # Unfortunately due to MPI being a Singleton, single MPI.Init() 9 | # these unit tests don't run as independent files 10 | 11 | @testset "unit-Simulation.init" begin 12 | settings = Settings() 13 | mpi_cart_domain = Simulation.init_domain(settings, MPI.COMM_WORLD) 14 | fields = Simulation.init_fields(settings, mpi_cart_domain, Float32) 15 | 16 | @test typeof(fields) == Fields{Float32, 3, Array{Float32, 3}} 17 | end 18 | 19 | @testset "unit-Simulation.iterate" begin 20 | settings = Settings() 21 | settings.L = 2 22 | mpi_cart_domain = Simulation.init_domain(settings, MPI.COMM_WORLD) 23 | fields = Simulation.init_fields(settings, mpi_cart_domain, Float32) 24 | 25 | Simulation.iterate!(fields, settings, mpi_cart_domain) 26 | 27 | if verbose 28 | sleep(0.01) 29 | rank = MPI.Comm_rank(MPI.COMM_WORLD) 30 | @show rank, fields.v 31 | end 32 | end 33 | 34 | #end 35 | -------------------------------------------------------------------------------- /source/julia/GrayScott.jl/test/unit/simulation/unit-Simulation_CUDA.jl: -------------------------------------------------------------------------------- 1 | 2 | import Test: @testset, @test, @test_throws 3 | # import submodule 4 | import GrayScott: Simulation 5 | # import types 6 | import GrayScott: Settings, MPICartDomain, Fields 7 | 8 | @testset "unit-Simulation.init_fields-cuda" begin 9 | function test_init_cuda(L) 10 | settings = Settings() 11 | settings.L = L 12 | mpi_cart_domain = Simulation.init_domain(settings, MPI.COMM_WORLD) 13 | 14 | fields = Simulation.init_fields(settings, mpi_cart_domain, Float32) 15 | 16 | settings.backend = "CUDA" 17 | fields_cuda = Simulation.init_fields(settings, mpi_cart_domain, Float32) 18 | 19 | @test fields.u ≈ Array(fields_cuda.u) 20 | @test fields.v ≈ Array(fields_cuda.v) 21 | end 22 | 23 | test_init_cuda(8) 24 | test_init_cuda(16) 25 | test_init_cuda(32) 26 | test_init_cuda(64) 27 | test_init_cuda(128) 28 | end -------------------------------------------------------------------------------- /source/manual-build/Makefile: -------------------------------------------------------------------------------- 1 | default: 2 | @echo Only available target is for "make clean" 3 | 4 | clean: 5 | rm -rf example-mpi-cpp example-serial-cpp 6 | rm -rf example-mpi-c example-serial-c 7 | rm -rf example-mpi-f example-serial-f 8 | rm -rf example-*.bp 9 | -------------------------------------------------------------------------------- /source/manual-build/Readme.md: -------------------------------------------------------------------------------- 1 | These examples show how to quickly compile an example from the command line. 2 | The adios2-config script from the ADIOS2 installation provides compiler and linker flags for C, C++ and Fortran. It provides flags for both serial and parallel applications. 3 | 4 | The notes below assume, ADIOS2 is in the path, and the MPI compilers are (mpic++, mpicc, mpif90) and serial compilers are (g++, gcc, gfortran). You need to modify the commands below for your own environment and choice of compilers. 5 | 6 | Compiling and linking a C++/MPI program 7 | ======================================= 8 | 9 | Compile and link example-mpi.cpp -> example-mpi-cpp 10 | 11 | CXXFLAGS=`adios2-config --cxx-flags` 12 | LDFLAGS=`adios2-config --cxx-libs` 13 | mpic++ -o example-mpi-cpp ${CXXFLAGS} example-mpi.cpp ${LDFLAGS} 14 | 15 | Compiling and linking a C++ serial program 16 | ========================================== 17 | 18 | Compile and link example-serial.cpp -> example-serial-cpp 19 | 20 | CXXFLAGS=`adios2-config --cxx-flags -s` 21 | LDFLAGS=`adios2-config --cxx-libs -s` 22 | g++ -o example-serial-cpp ${CXXFLAGS} example-serial.cpp ${LDFLAGS} 23 | 24 | 25 | Compiling and linking a C/MPI program 26 | ===================================== 27 | 28 | Compile and link example-mpi.c -> example-mpi-c 29 | 30 | CFLAGS=`adios2-config --c-flags` 31 | LDFLAGS=`adios2-config --c-libs` 32 | mpicc -o example-mpi-c ${CFLAGS} example-mpi.c ${LDFLAGS} 33 | 34 | Compiling and linking a C serial program 35 | ======================================== 36 | 37 | Compile and link example-serial.c -> example-serial-c 38 | 39 | CFLAGS=`adios2-config --c-flags -s` 40 | LDFLAGS=`adios2-config --c-libs -s` 41 | gcc -o example-serial-c ${CXXFLAGS} example-serial.c ${LDFLAGS} 42 | 43 | 44 | Compiling and linking a Fortran/MPI program 45 | =========================================== 46 | 47 | Compile and link example-mpi.F90 -> example-mpi-f 48 | 49 | FCFLAGS=`adios2-config --fortran-flags` 50 | LDFLAGS=`adios2-config --fortran-libs` 51 | mpif90 -o example-mpi-f ${FCFLAGS} example-mpi.F90 ${LDFLAGS} 52 | 53 | Compiling and linking a Fortran serial program 54 | ============================================== 55 | 56 | Compile and link example-serial.F90 -> example-serial-f 57 | 58 | FCFLAGS=`adios2-config --fortran-flags -s` 59 | LDFLAGS=`adios2-config --fortran-libs -s` 60 | gfortran -o example-serial-f ${FCFLAGS} example-serial.F90 ${LDFLAGS} 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /source/manual-build/example-mpi.F90: -------------------------------------------------------------------------------- 1 | program example_mpi 2 | use mpi 3 | use adios2 4 | 5 | implicit none 6 | 7 | character(*), parameter :: greeting = & 8 | "Hello World from ADIOS2 Fortran/MPI example" 9 | integer(kind=8), dimension(1) :: shape_dims, start_dims, count_dims 10 | integer :: irank, isize, ierr, var_type 11 | type(adios2_adios) :: adios 12 | type(adios2_io) :: io 13 | type(adios2_engine) :: engine 14 | 15 | call MPI_Init(ierr) 16 | call MPI_Comm_rank(MPI_COMM_WORLD, irank, ierr) 17 | call MPI_Comm_size(MPI_COMM_WORLD, isize, ierr) 18 | 19 | call adios2_init(adios, MPI_COMM_WORLD, adios2_debug_mode_on, ierr) 20 | 21 | call writer() 22 | call reader() 23 | 24 | call adios2_finalize(adios, ierr) 25 | 26 | call MPI_Finalize(ierr) 27 | 28 | contains 29 | 30 | subroutine writer 31 | type(adios2_variable) :: var 32 | call adios2_declare_io(io, adios, "hello-world-writer", ierr) 33 | call adios2_define_variable(var, io, "Greeting", adios2_type_string, ierr) 34 | call adios2_open(engine, io, "example-mpi-f.bp", adios2_mode_write, ierr) 35 | call adios2_put(engine, var, greeting, ierr) 36 | call adios2_close(engine, ierr) 37 | end subroutine writer 38 | 39 | 40 | subroutine reader 41 | character(len=40) :: msg 42 | integer*4 :: ndims 43 | integer*8, dimension(:), allocatable :: dims 44 | type(adios2_variable) :: var 45 | 46 | call adios2_declare_io(io, adios, "hello-world-reader", ierr) 47 | call adios2_open(engine, io, "example-mpi-f.bp", adios2_mode_read, ierr) 48 | call adios2_inquire_variable(var, io, "Greeting", ierr) 49 | call adios2_get(engine, var, msg, ierr) 50 | call adios2_close(engine, ierr) 51 | write(*,*) trim(msg) 52 | end subroutine reader 53 | 54 | end program example_mpi 55 | -------------------------------------------------------------------------------- /source/manual-build/example-mpi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hello-world to demonstrate manual compiling/linking an ADIOS2 example 3 | */ 4 | 5 | #include //printf 6 | #include //calloc, free 7 | 8 | #include 9 | #include 10 | 11 | void writer(adios2_adios *adios, const char *greeting) 12 | { 13 | adios2_io *io = adios2_declare_io(adios, "hello-world-writer"); 14 | adios2_variable *var_greeting = 15 | adios2_define_variable(io, "Greeting", adios2_type_string, 0, NULL, 16 | NULL, NULL, adios2_constant_dims_true); 17 | 18 | adios2_engine *engine = 19 | adios2_open(io, "example-mpi-c.bp", adios2_mode_write); 20 | adios2_put(engine, var_greeting, greeting, adios2_mode_deferred); 21 | adios2_close(engine); 22 | } 23 | 24 | void reader(adios2_adios *adios, char *greeting) 25 | { 26 | adios2_io *io = adios2_declare_io(adios, "hello-world-reader"); 27 | adios2_engine *engine = 28 | adios2_open(io, "example-mpi-c.bp", adios2_mode_read); 29 | adios2_variable *var_greeting = adios2_inquire_variable(io, "Greeting"); 30 | adios2_get(engine, var_greeting, greeting, adios2_mode_deferred); 31 | adios2_close(engine); 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | MPI_Init(&argc, &argv); 37 | { 38 | adios2_adios *adios = adios2_init(MPI_COMM_WORLD, adios2_debug_mode_on); 39 | 40 | const char greeting[] = "Hello World from ADIOS2 C/MPI example"; 41 | writer(adios, greeting); 42 | 43 | char *message = (char *)calloc(1, sizeof(greeting) + 1); 44 | reader(adios, message); 45 | printf("%s\n", message); 46 | 47 | free(message); 48 | } 49 | 50 | MPI_Finalize(); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /source/manual-build/example-mpi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * hello-world to demonstrate manual compiling/linking an ADIOS2 example 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | void writer(adios2::ADIOS &adios, const std::string &greeting) 12 | { 13 | adios2::IO io = adios.DeclareIO("hello-world-writer"); 14 | adios2::Variable varGreeting = 15 | io.DefineVariable("Greeting"); 16 | 17 | adios2::Engine writer = io.Open("example-mpi-cpp.bp", adios2::Mode::Write); 18 | writer.Put(varGreeting, greeting); 19 | writer.Close(); 20 | } 21 | 22 | std::string reader(adios2::ADIOS &adios) 23 | { 24 | adios2::IO io = adios.DeclareIO("hello-world-reader"); 25 | adios2::Engine reader = io.Open("example-mpi-cpp.bp", adios2::Mode::Read); 26 | adios2::Variable varGreeting = 27 | io.InquireVariable("Greeting"); 28 | std::string greeting; 29 | reader.Get(varGreeting, greeting); 30 | reader.Close(); 31 | return greeting; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | MPI_Init(&argc, &argv); 37 | 38 | try 39 | { 40 | adios2::ADIOS adios(MPI_COMM_WORLD); 41 | 42 | const std::string greeting = "Hello World from ADIOS2 C++/MPI example"; 43 | writer(adios, greeting); 44 | 45 | const std::string message = reader(adios); 46 | std::cout << message << "\n"; 47 | } 48 | catch (std::exception &e) 49 | { 50 | std::cout << "ERROR: ADIOS2 exception: " << e.what() << "\n"; 51 | MPI_Abort(MPI_COMM_WORLD, -1); 52 | } 53 | 54 | MPI_Finalize(); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /source/manual-build/example-serial.F90: -------------------------------------------------------------------------------- 1 | program example_serial 2 | use adios2 3 | 4 | implicit none 5 | 6 | character(*), parameter :: greeting = & 7 | "Hello World from ADIOS2 Fortran/MPI example" 8 | integer(kind=8), dimension(1) :: shape_dims, start_dims, count_dims 9 | integer :: ierr, var_type 10 | type(adios2_adios) :: adios 11 | type(adios2_io) :: io 12 | type(adios2_engine) :: engine 13 | 14 | call adios2_init(adios, adios2_debug_mode_on, ierr) 15 | 16 | call writer() 17 | call reader() 18 | 19 | call adios2_finalize(adios, ierr) 20 | 21 | contains 22 | 23 | subroutine writer 24 | type(adios2_variable) :: var 25 | call adios2_declare_io(io, adios, "hello-world-writer", ierr) 26 | call adios2_define_variable(var, io, "Greeting", adios2_type_string, ierr) 27 | call adios2_open(engine, io, "example-serial-f.bp", adios2_mode_write, ierr) 28 | call adios2_put(engine, var, greeting, ierr) 29 | call adios2_close(engine, ierr) 30 | end subroutine writer 31 | 32 | 33 | subroutine reader 34 | character(len=40) :: msg 35 | integer*4 :: ndims 36 | integer*8, dimension(:), allocatable :: dims 37 | type(adios2_variable) :: var 38 | 39 | call adios2_declare_io(io, adios, "hello-world-reader", ierr) 40 | call adios2_open(engine, io, "example-serial-f.bp", adios2_mode_read, ierr) 41 | call adios2_inquire_variable(var, io, "Greeting", ierr) 42 | call adios2_get(engine, var, msg, ierr) 43 | call adios2_close(engine, ierr) 44 | write(*,*) trim(msg) 45 | end subroutine reader 46 | 47 | 48 | 49 | end program example_serial 50 | -------------------------------------------------------------------------------- /source/manual-build/example-serial.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hello-world to demonstrate manual compiling/linking an ADIOS2 example 3 | */ 4 | 5 | #include //printf 6 | #include //calloc, free 7 | 8 | #include 9 | 10 | void writer(adios2_adios *adios, const char *greeting) 11 | { 12 | adios2_io *io = adios2_declare_io(adios, "hello-world-writer"); 13 | adios2_variable *var_greeting = 14 | adios2_define_variable(io, "Greeting", adios2_type_string, 0, NULL, 15 | NULL, NULL, adios2_constant_dims_true); 16 | 17 | adios2_engine *engine = 18 | adios2_open(io, "example-serial-c.bp", adios2_mode_write); 19 | adios2_put(engine, var_greeting, greeting, adios2_mode_deferred); 20 | adios2_close(engine); 21 | } 22 | 23 | void reader(adios2_adios *adios, char *greeting) 24 | { 25 | adios2_io *io = adios2_declare_io(adios, "hello-world-reader"); 26 | adios2_engine *engine = 27 | adios2_open(io, "example-serial-c.bp", adios2_mode_read); 28 | adios2_variable *var_greeting = adios2_inquire_variable(io, "Greeting"); 29 | adios2_get(engine, var_greeting, greeting, adios2_mode_deferred); 30 | adios2_close(engine); 31 | } 32 | 33 | int main(int argc, char *argv[]) 34 | { 35 | adios2_adios *adios = adios2_init(adios2_debug_mode_on); 36 | 37 | const char greeting[] = "Hello World from ADIOS2 C/Serial example"; 38 | writer(adios, greeting); 39 | 40 | char *message = (char *)calloc(1, sizeof(greeting) + 1); 41 | reader(adios, message); 42 | printf("%s\n", message); 43 | 44 | free(message); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /source/manual-build/example-serial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * hello-world to demonstrate manual compiling/linking an ADIOS2 example 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void writer(adios2::ADIOS &adios, const std::string &greeting) 11 | { 12 | adios2::IO io = adios.DeclareIO("hello-world-writer"); 13 | adios2::Variable varGreeting = 14 | io.DefineVariable("Greeting"); 15 | 16 | adios2::Engine writer = 17 | io.Open("example-serial-cpp.bp", adios2::Mode::Write); 18 | writer.Put(varGreeting, greeting); 19 | writer.Close(); 20 | } 21 | 22 | std::string reader(adios2::ADIOS &adios) 23 | { 24 | adios2::IO io = adios.DeclareIO("hello-world-reader"); 25 | adios2::Engine reader = 26 | io.Open("example-serial-cpp.bp", adios2::Mode::Read); 27 | adios2::Variable varGreeting = 28 | io.InquireVariable("Greeting"); 29 | std::string greeting; 30 | reader.Get(varGreeting, greeting); 31 | reader.Close(); 32 | return greeting; 33 | } 34 | 35 | int main(int argc, char *argv[]) 36 | { 37 | 38 | try 39 | { 40 | adios2::ADIOS adios; 41 | 42 | const std::string greeting = 43 | "Hello World from ADIOS2 C++/Serial example"; 44 | writer(adios, greeting); 45 | 46 | const std::string message = reader(adios); 47 | std::cout << message << "\n"; 48 | } 49 | catch (std::exception &e) 50 | { 51 | std::cout << "ERROR: ADIOS2 exception: " << e.what() << "\n"; 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /source/meson.build: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | #------------------------------------------------------------------------------# 5 | 6 | subdir('cpp') 7 | subdir('c') 8 | -------------------------------------------------------------------------------- /source/python/hello-world/hello-world-hl.py: -------------------------------------------------------------------------------- 1 | # 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | # 5 | # hello-world.py : adios2 high-level API example to write and read a 6 | # string Variable with a greeting 7 | # 8 | # Created on: 2/2/2021 9 | # Author: Dmitry Ganyushin ganyushindi@ornl.gov 10 | # 11 | import sys 12 | from mpi4py import MPI 13 | import adios2 14 | 15 | DATA_FILENAME = "hello-world-hl-py.bp" 16 | # MPI 17 | comm = MPI.COMM_WORLD 18 | rank = comm.Get_rank() 19 | size = comm.Get_size() 20 | 21 | 22 | def writer(greeting): 23 | """write a string to a bp file""" 24 | with adios2.open(DATA_FILENAME, "w", comm) as fh: 25 | fh.write("Greeting", greeting, end_step=True) 26 | return 0 27 | 28 | 29 | def reader(): 30 | """read a string from to a bp file""" 31 | with adios2.open(DATA_FILENAME, "r", comm) as fh: 32 | for fstep in fh: 33 | message = fstep.read_string("Greeting") 34 | return message 35 | 36 | 37 | def main(): 38 | """driver function""" 39 | greeting = "Hello World from ADIOS2" 40 | writer(greeting) 41 | message = reader() 42 | print("{}".format(message)) 43 | return 0 44 | 45 | 46 | if __name__ == "__main__": 47 | sys.exit(main()) 48 | -------------------------------------------------------------------------------- /source/python/hello-world/hello-world.py: -------------------------------------------------------------------------------- 1 | # 2 | # Distributed under the OSI-approved Apache License, Version 2.0. See 3 | # accompanying file Copyright.txt for details. 4 | # 5 | # hello-world.py : adios2 low-level API example to write and read a 6 | # string Variable with a greeting 7 | # 8 | # Created on: 2/2/2021 9 | # Author: Dmitry Ganyushin ganyushindi@ornl.gov 10 | # 11 | import sys 12 | from mpi4py import MPI 13 | import adios2 14 | 15 | DATA_FILENAME = "hello-world-py.bp" 16 | # MPI 17 | comm = MPI.COMM_WORLD 18 | rank = comm.Get_rank() 19 | size = comm.Get_size() 20 | 21 | 22 | def writer(ad, greeting): 23 | """write a string to a bp file""" 24 | io = ad.DeclareIO("hello-world-writer") 25 | var_greeting = io.DefineVariable("Greeting") 26 | w = io.Open(DATA_FILENAME, adios2.Mode.Write) 27 | w.Put(var_greeting, greeting) 28 | w.Close() 29 | return 0 30 | 31 | 32 | def reader(ad): 33 | """read a string from to a bp file""" 34 | io = ad.DeclareIO("hello-world-reader") 35 | r = io.Open(DATA_FILENAME, adios2.Mode.Read) 36 | r.BeginStep() 37 | var_greeting = io.InquireVariable("Greeting") 38 | message = r.Get(var_greeting) 39 | r.EndStep() 40 | return message 41 | 42 | 43 | def main(): 44 | """driver function""" 45 | ad = adios2.ADIOS(comm) 46 | greeting = "Hello World from ADIOS2" 47 | writer(ad, greeting) 48 | message = reader(ad) 49 | print("{}".format(message)) 50 | return 0 51 | 52 | 53 | if __name__ == "__main__": 54 | sys.exit(main()) 55 | --------------------------------------------------------------------------------