Skip to content
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

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

adding Adios2 io support #113

wants to merge 13 commits into from

Conversation

seegyoung
Copy link

  • 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

@seegyoung seegyoung added the enhancement New feature or request label Sep 9, 2024
@jacobmerson
Copy link
Collaborator

/runtests

Copy link

Test Result: failure (details)

Copy link
Collaborator

@jacobmerson jacobmerson left a 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.

Copy link
Collaborator

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.

Comment on lines +178 to +179
set(OLD_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
Copy link
Collaborator

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}")
Copy link
Collaborator

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}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Omega_h::Mesh mesh(&lib);
Omega_h::binary::read(argv[1], lib.world(), &mesh);
Omega_h::write_adios2(argv[2], &mesh);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
return 0;
}

@cwsmith
Copy link

cwsmith commented Sep 10, 2024

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.

@cwsmith cwsmith added the adios2 label Sep 10, 2024
@seegyoung
Copy link
Author

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)
Copy link
Collaborator

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:

auto apply_to_omega_h_types(Omega_h_Type type, const F&& f) {

example use case:

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));
});

@jacobmerson
Copy link
Collaborator

@seegyoung I still don't see the definitions for write_value and read_value for adios2.

@seegyoung
Copy link
Author

Sorry about the trouble - missing files are added

@cwsmith
Copy link

cwsmith commented Sep 17, 2024

@seegyoung Would you please remove the romulus-config.sh file? We maintain build instructions for various systems in the wiki: https://github.com/SCOREC/omega_h/wiki

@seegyoung
Copy link
Author

OK I will do.

@jacobmerson
Copy link
Collaborator

Hi Seegyoung, did you have a chance to address the comments from Cameron and I?

@seegyoung
Copy link
Author

Yes, it was removed on September 17th. Thanks for checking with me.

@jacobmerson
Copy link
Collaborator

@seegyoung can you update this pull request with your changes? I do not see the requested updates.

@seegyoung
Copy link
Author

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?

@cwsmith
Copy link

cwsmith commented Dec 13, 2024

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.

Copy link
Collaborator

@jacobmerson jacobmerson left a 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
Copy link
Collaborator

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.

Copy link
Author

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.

Copy link
Collaborator

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.

Comment on lines 13 to 22
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);
Copy link
Collaborator

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?

Copy link
Author

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.

Copy link
Collaborator

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?

Copy link
Author

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

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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it.

Comment on lines 4 to 7
*
* Created on: Aug 25, 2024
* Author: Seegyoung Seol [email protected]
*
Copy link
Collaborator

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) {
Copy link
Collaborator

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) {
Copy link
Collaborator

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
Copy link
Collaborator

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);
Copy link
Collaborator

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.

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);
Copy link
Collaborator

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"

Copy link
Author

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,
Copy link
Collaborator

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.

see: https://en.cppreference.com/w/cpp/language/identifiers

@@ -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);
Copy link
Collaborator

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?

Copy link
Author

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.

long unsigned int comm_size, rank;

template <typename T>
void write_value(adios2::IO &io, adios2::Engine &writer,
Copy link
Collaborator

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 read_value(adios2::IO &io, adios2::Engine &reader,
T *val, std::string &name, bool global)
Copy link
Collaborator

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)
{
Copy link
Collaborator

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)
Copy link
Collaborator

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

Copy link
Author

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)
{
Copy link
Collaborator

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

write_array(io, writer, owners.idxs, name);
}

void read_pbdry(adios2::IO &io, adios2::Engine &reader, Mesh* mesh, int d, std::string pref)
Copy link
Collaborator

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)
{
Copy link
Collaborator

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.

Comment on lines 13 to 20
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);

Copy link
Collaborator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
adios2 enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants