-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adding Adios2 io support #113
base: master
Are you sure you want to change the base?
Conversation
seegyoung
commented
Sep 9, 2024
- support for serial adios2 file I/O (set Omega_h_USE_ADIOS2 ON)
- MPI only with single process at the moment
- testing with kokkos and coda not included
/runtests |
Test Result: failure (details) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Seegyoung, from what I see so far it looks like things are on the right track.
However, it seems like there are some missing files in your commit. I don't see the Omega_h_adios2.hpp
file, or where the write_adios2
code is located.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't need this since find_package
should directly work since adios2 provides a config file.
set(OLD_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) | ||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if you get rid of the config files these should not be needed.
set(ADIOS_REQUIRED_VERSION 2.10) | ||
if (Omega_h_USE_MPI) | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DADIOS2_USE_MPI") | ||
target_include_directories(omega_h PUBLIC "${ADIOS2_INCLUDE_DIR}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't need this if we use the adios2 cmake targets
if (Omega_h_USE_MPI) | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DADIOS2_USE_MPI") | ||
target_include_directories(omega_h PUBLIC "${ADIOS2_INCLUDE_DIR}") | ||
target_link_libraries(omega_h PUBLIC "${ADIOS2_LIBS}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the target should be adios2::cxx11_mpi
see: https://github.com/SCOREC/redev/blob/f4b1d75b6996f5ed0a7c87c25f9d146d22babc80/CMakeLists.txt#L54
Omega_h::Mesh mesh(&lib); | ||
Omega_h::binary::read(argv[1], lib.world(), &mesh); | ||
Omega_h::write_adios2(argv[2], &mesh); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | |
return 0; | |
} |
Thank you @seegyoung. Looks good. If it isn't there already, and while partitioned mesh support is under development, we should add a check to the adios writer and reader to ensure that the mesh is serial. |
I will update based on all the input from both of you. |
for (int dim=0; dim <= mesh.dim(); dim++) | ||
for (int tag=0; tag < mesh.ntags(dim); tag++) { | ||
auto tagbase = mesh.get_tag(dim, tag); | ||
if (tagbase->type() == OMEGA_H_I8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use the apply_to_omega_h_types
function which will avoid code duplication here. Function is defined here:
omega_h/src/Omega_h_defines.hpp
Line 86 in 00131eb
auto apply_to_omega_h_types(Omega_h_Type type, const F&& f) { |
example use case:
omega_h/src/Omega_h_rcFields.cpp
Lines 335 to 339 in 00131eb
auto new_tag = apply_to_omega_h_types( | |
tag->type(), [&,this](auto t) -> std::unique_ptr<TagBase> { | |
using T = decltype(t); | |
return this->get_rc_mesh_tag_from_rc_tag(ent_dim, as<T>(tag)); | |
}); |
@seegyoung I still don't see the definitions for |
Sorry about the trouble - missing files are added |
@seegyoung Would you please remove the |
OK I will do. |
Hi Seegyoung, did you have a chance to address the comments from Cameron and I? |
Yes, it was removed on September 17th. Thanks for checking with me. |
@seegyoung can you update this pull request with your changes? I do not see the requested updates. |
I am not good at GitHub so I don't know what to do to resolve the issue and what's the source of the issue. Can someone can do this for me please? |
If you have changes that are committed into your local copy of the branch (i.e., on the SCOREC filesystem) you can run 'git push' to upload them to github. This PR will automatically be updated. I'm available to discuss via WebEx if needed. Please send me an email and we can pick a time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@seegyoung i have added additional comments. Please address them and update this pull request.
@@ -0,0 +1,104 @@ | |||
# - Try to find ADIOS2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this file. It is not needed and will cause us issues in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I will try to remove it although I don't know what the the alternative is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adios2
creates a config file since it is built with CMake
so, as long as you point omega_h to the correct path during the configure stage it should bring in everything it needs.
src/Omega_h_adios2.hpp
Outdated
template <typename T> | ||
void write_value(adios2::IO &io, adios2::Engine &writer, | ||
T val, std::string &name, bool global=false); | ||
|
||
template <typename T> | ||
void read_value(adios2::IO &io, adios2::Engine &reader, | ||
T *val, std::string &name, bool global=false); | ||
|
||
void write_adios2(filesystem::path const& path, Mesh *mesh); | ||
Mesh read_adios2(filesystem::path const& path, Library* lib); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where are the definitions of these functions? Also, should provide doxygen style comment describing what they do and what the inputs are. Particularly, what is the bool called global doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
global is a flag to tell whether it reads/writes global array or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, by global array do you mean global do you mean what adios2 calls global, or it's global indexes, or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
global flag indicates whether the value is global (the same for all processes) or not. If global, adios2 doesn't need an array to read/write a value of which index is equivalent to the process rank
src/adios2_io.cpp
Outdated
cout<<"\n--- Mesh loaded from \""<<inpath<<"\" ---\n"; | ||
print_info(&lib, mesh); | ||
|
||
// Omega_h::Mesh mesh = build_box(world, OMEGA_H_SIMPLEX, 1., 1., 0., 2, 2, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it.
src/adios2_io.cpp
Outdated
* | ||
* Created on: Aug 25, 2024 | ||
* Author: Seegyoung Seol [email protected] | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this. It is already encoded in the git history.
|
||
// printTagInfo and getNumEq copied from describe.cpp | ||
template <typename T> | ||
void printTagInfo(Omega_h::Mesh mesh, std::ostringstream& oss, int dim, int tag, std::string type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Static?
} | ||
|
||
template <typename T> | ||
int getNumEq(Omega_h::Mesh mesh, std::string tagname, int dim, int value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Static?
using namespace Omega_h; | ||
using namespace std; | ||
|
||
// printTagInfo and getNumEq copied from describe.cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you copying code here from describe? If that functionality is needed in multiple,e places refactor to a function and call function both places.
exit(EXIT_FAILURE); | ||
} | ||
OMEGA_H_CHECK(argc == 3); | ||
Omega_h::Mesh mesh = read_adios2(argv[1], &lib); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This naming is not consistent with how other writer/reader are named in omegah typically they have a namespace for each file type.
src/Omega_h_adios2.hpp
Outdated
void read_value(adios2::IO &io, adios2::Engine &reader, | ||
T *val, std::string &name, bool global=false); | ||
|
||
void write_adios2(filesystem::path const& path, Mesh *mesh); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be consistent this should be inside adios2 namespace and just be called "write"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adios2 has namespace "adios2"
@@ -462,7 +462,7 @@ void read_parents(adios2::IO &io, adios2::Engine &reader, Mesh* mesh, std::strin | |||
} | |||
} | |||
|
|||
void write_adios2(adios2::IO &io, adios2::Engine & writer, | |||
void _write_adios2(adios2::IO &io, adios2::Engine & writer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this named _write_adios2
? We generally avoid having names that start with underscore or double underscore in C++
because depending on the second symbol it could be undefined behavior.
@@ -18,6 +18,8 @@ template <typename T> | |||
void read_value(adios2::IO &, adios2::Engine &reader, | |||
T *val, std::string &name, bool global=false); | |||
|
|||
void write_adios2(filesystem::path const& path, | |||
std::map<Mesh*, std::string>& mesh_map); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this stored as a map? Instead of a list of pairs or struct that holds a name and a omega_h mesh pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, a map is better as it takes less coding and easy to use. I will change it to a list of pairs only if you insist.
src/Omega_h_adios2.cpp
Outdated
long unsigned int comm_size, rank; | ||
|
||
template <typename T> | ||
void write_value(adios2::IO &io, adios2::Engine &writer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make static
src/Omega_h_adios2.cpp
Outdated
|
||
template <typename T> | ||
void read_value(adios2::IO &io, adios2::Engine &reader, | ||
T *val, std::string &name, bool global) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make static
template <typename T> | ||
void write_array(adios2::IO &io, adios2::Engine &writer, Read<T> array, | ||
std::string &name) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make static
std::string name = pref+"ntags_" + to_string(d); | ||
write_value(io, writer, mesh->ntags(d), name, true); | ||
|
||
for (int32_t i = 0; i < mesh->ntags(d); ++i) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should use Int since that's the size of ntags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what's in Omega_h_defines.hpp
typedef std::int32_t I32;
typedef I32 Int;
typedef I32 LO;
typedef I32 ClassId;
} | ||
|
||
void write_pbdry(adios2::IO &io, adios2::Engine &writer, Mesh* mesh, int d, std::string pref) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- rename to
write_partition_boundary
, in general prefer longer, but more informative names. - make static
src/Omega_h_adios2.cpp
Outdated
write_array(io, writer, owners.idxs, name); | ||
} | ||
|
||
void read_pbdry(adios2::IO &io, adios2::Engine &reader, Mesh* mesh, int d, std::string pref) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- rename to
read_partition_boundary
- make static
|
||
|
||
void write_adios2(filesystem::path const& path, Mesh* mesh, std::string pref) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you have your api backwards which is causing some issues. I don't think _write_adios2
should exist, but instead, this function should write to the specified path. If you want to have the function signature that takes a map it will just loop through and call this function multiple times like you have done with write_adios2
.
src/Omega_h_adios2.hpp
Outdated
template <typename T> | ||
void write_value(adios2::IO &, adios2::Engine &writer, | ||
T val, std::string &name, bool global=false); | ||
|
||
template <typename T> | ||
void read_value(adios2::IO &, adios2::Engine &reader, | ||
T *val, std::string &name, bool global=false); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions should not be exposed to the user since they are internal functions. You do not need to declare these in the header file at all since you only use in a single cpp file.