Hello World
Like in any language, the first program you write is the “Hello World” program.
In this tutorial, we will see how to write “Hello World from ADIOS2” and read it back with ADIOS2. So let’s dig in!
Start editing the skeleton file ADIOS2/examples/hello/helloWorld/hello-world_tutorialSkeleton.cpp.
We create an ADIOS instance, and define the greeting message in our main function as follows:
int main()
{
adios2::ADIOS adios();
const std::string greeting("Hello World from ADIOS2");
...
return 0;
}
Then we create a writer function in which we pass the adios instance, and the greeting message as follows:
void writer(adios2::ADIOS& adios, const std::string& greeting)
{
...
}
In this writer function, we define an IO object, a string variable for the message as follows:
adios2::IO io = adios.DeclareIO("hello-world-writer");
adios2::Variable<std::string> varGreeting = io.DefineVariable<std::string>("Greeting");
Note
Using the IO object, we can define the engine type that we want to utilize using the io.SetEngine() function. If SetEngine() is not used, the default engine type is BPFile which is an alias for the latest version of the BP engine of the ADIOS2 library. See Available Engines and Supported Engines for more information. It’s important to note that the file extension of an output file, although it’s not a good practice, it can differ from the engine type, e.g. write a foo.h5 file with the BPFile engine. When reading foo.h5 you should explicitly specify the engine type as BPFile to read it properly.
Then we open a file with the name “hello-world-cpp.bp” and write the greeting message to it as follows:
adios2::Engine writer = io.Open("hello-world-cpp.bp", adios2::Mode::Write);
writer.BeginStep();
writer.Put(varGreeting, greeting);
writer.EndStep();
writer.Close();
Note
The BeginStep
and EndStep
calls are optional when writing one step, but they are required
for multiple steps, so it is a good practice to always use them.
Now we create a reader function in which we pass the adios instance, and get the greeting message back as follows:
std::string reader(adios2::ADIOS& adios)
{
...
}
In this reader function, we define an IO object and inquire a string variable for the message as follows:
adios2::IO io = adios.DeclareIO("hello-world-reader");
reader.BeginStep();
adios2::Variable<std::string> varGreeting = io.InquireVariable<std::string>("Greeting");
Then we open the file with the name “hello-world-cpp.bp”, read the greeting message from it and return it as follows:
adios2::Engine reader = io.Open("hello-world-cpp.bp", adios2::Mode::Read);
std::string greeting;
reader.BeginStep();
reader.Get(varGreeting, greeting);
reader.EndStep();
reader.Close();
return greeting;
Note
In Mode::Read, the BeginStep
and EndStep
calls are required when reading one step and multiple steps. We will see in
another tutorial how to read multiple steps. It’s important to note that the BeginStep
should be called before
all Inquire*
/ Available*
function calls.
Finally, we call the writer and reader functions in our main function as follows:
int main()
{
adios2::ADIOS adios();
const std::string greeting("Hello World from ADIOS2");
writer(adios, greeting);
std::string message = reader(adios);
std::cout << message << std::endl;
return 0;
}
The final code should look as follows (excluding try/catch and the optional usage of MPI), and it was derived from the example ADIOS2/examples/hello/helloWorld/hello-world.cpp.
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* hello-world.cpp : adios2 low-level API example to write and read a
* std::string Variable with a greeting
*
* Created on: Nov 14, 2019
* Author: William F Godoy godoywf@ornl.gov
*/
#include <iostream>
#include <stdexcept>
#include <adios2.h>
#if ADIOS2_USE_MPI
#include <mpi.h>
#endif
void writer(adios2::ADIOS &adios, const std::string &greeting)
{
adios2::IO io = adios.DeclareIO("hello-world-writer");
adios2::Variable<std::string> varGreeting = io.DefineVariable<std::string>("Greeting");
adios2::Engine writer = io.Open("hello-world-cpp.bp", adios2::Mode::Write);
writer.BeginStep();
writer.Put(varGreeting, greeting);
writer.EndStep();
writer.Close();
}
std::string reader(adios2::ADIOS &adios)
{
adios2::IO io = adios.DeclareIO("hello-world-reader");
adios2::Engine reader = io.Open("hello-world-cpp.bp", adios2::Mode::Read);
reader.BeginStep();
adios2::Variable<std::string> varGreeting = io.InquireVariable<std::string>("Greeting");
std::string greeting;
reader.Get(varGreeting, greeting);
reader.EndStep();
reader.Close();
return greeting;
}
int main(int argc, char *argv[])
{
#if ADIOS2_USE_MPI
MPI_Init(&argc, &argv);
#endif
try
{
#if ADIOS2_USE_MPI
adios2::ADIOS adios(MPI_COMM_WORLD);
#else
adios2::ADIOS adios;
#endif
const std::string greeting = "Hello World from ADIOS2";
writer(adios, greeting);
const std::string message = reader(adios);
std::cout << message << "\n";
}
catch (std::exception &e)
{
std::cout << "ERROR: ADIOS2 exception: " << e.what() << "\n";
#if ADIOS2_USE_MPI
MPI_Abort(MPI_COMM_WORLD, -1);
#endif
}
#if ADIOS2_USE_MPI
MPI_Finalize();
#endif
return 0;
}
You can compile and run it as follows:
cd Path-To-ADIOS2/examples/hello/helloWorld
mkdir build
cd build
cmake -DADIOS2_DIR=Path-To-ADIOS2/build/ ..
cmake --build .
./adios2_hello_helloWorld
You can check the content of the output file “hello-world-cpp.bp” using bpls as follows:
Path-To-ADIOS2/build/bin/bpls ./hello-world-cpp.bp
string Greeting scalar
The Python version of this tutorial can be found at ADIOS2/examples/hello/helloWorld/hello-world.py. and it looks as follows:
#
# Distributed under the OSI-approved Apache License, Version 2.0. See
# accompanying file Copyright.txt for details.
#
# hello-world.py : adios2 Python API example to write and read a
# string Variable with a greeting
#
# Created on: 2/2/2021
# Author: Dmitry Ganyushin ganyushindi@ornl.gov
#
import sys
from mpi4py import MPI
from adios2 import Stream, FileReader
DATA_FILENAME = "hello-world-py.bp"
# MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
def writer(greeting):
"""write a string to a bp file"""
with Stream(DATA_FILENAME, "w", comm) as fh:
fh.write("Greeting", greeting)
return 0
def reader():
"""read a string from a bp file as Stream"""
message = f"variable Greeting not found in {DATA_FILENAME}"
with Stream(DATA_FILENAME, "r", comm) as fh:
for _ in fh.steps():
message = fh.read("Greeting")
return message
def filereader():
"""read a string from a bp file using random access read mode"""
with FileReader(DATA_FILENAME, comm) as fh:
message = fh.read("Greeting")
return message
def main():
"""driver function"""
greeting = "Hello World from ADIOS2"
writer(greeting)
message = reader()
print("As read from adios2.Stream: {}".format(message))
message2 = filereader()
print("As read from adios2.FileReader: {}".format(message2))
return 0
if __name__ == "__main__":
sys.exit(main())