-
Notifications
You must be signed in to change notification settings - Fork 32
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
WIP: Add OpenPMD support #1050
base: develop
Are you sure you want to change the base?
WIP: Add OpenPMD support #1050
Conversation
src/outputs/openpmd.cpp
Outdated
for (auto &pmb : pm->block_list) { | ||
// TODO(pgrete) check if we should skip the suffix for level 0 | ||
const auto level = pmb->loc.level() - pm->GetRootLevel(); | ||
const std::string &mesh_record_name = var_name + "_lvl" + std::to_string(level); |
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.
Writing level
src/outputs/restart_opmd.cpp
Outdated
for (auto &pmb : pm->block_list) { | ||
// TODO(pgrete) check if we should skip the suffix for level 0 | ||
// TODO(pgrete) ask LR why this is not mirrored from writing | ||
// const auto level = pmb->loc.level() - pm->GetRootLevel(); | ||
const auto level = pmb->loc.level(); | ||
const std::string &mesh_record_name = var_name + "_lvl" + std::to_string(level); |
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.
Reading level
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.
Many comments below. However, because this was such a big lift, I am of the opinion that we should merge even a not feature complete or not perfect contribution so that it doesn't start to drift away from develop. And the full feature complete capability can be created via later PRs. So I'm approving.
fill_derived = false # whether to fill one-copy test vars | ||
|
||
<parthenon/output1> | ||
file_type = openpmd |
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.
Does openpmd always output everything?
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.
It currently mimics restart output (with support for additional explicit variables), but this doesn't need to remain that way.
@@ -118,6 +118,12 @@ class Params { | |||
return it->second; | |||
} | |||
|
|||
const Mutability &GetMutability(const std::string &key) const { |
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.
👍
// TODO(reviewers) Why was the loop originally there? Does the direct Get causes | ||
// issue? |
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'm not sure---it may have just been crazy code that no one tried to change.
@@ -241,6 +243,45 @@ std::vector<int> ComputeIDsAndFlags(Mesh *pm) { | |||
}); | |||
} | |||
|
|||
template <typename T> | |||
std::vector<T> FlattendedLocalToGlobal(Mesh *pm, const std::vector<T> &data_local) { |
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 don't understand what this function does. Is it actually doing an MPI all-to-all to build up a global data vector? Is this something we ever want to do?
it.setAttribute("blub", host_vec); | ||
|
||
for (const auto &[key, pkg] : pm->packages.AllPackages()) { | ||
// WriteAllParams<bool>(pkg, &it); // check why this (vector of bool) doesn't work |
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.
Is it just std::vector<bool>
that doesn't work? That's probably because std::vector<bool>
has a particular template specialization in the stl that is weirdly incompatible with generic code. Probably need to write a pointer-based array of bool instead.
// TODO(pgrete) check var name standard compatiblity | ||
// e.g., description: names of records and their components are only allowed to contain | ||
// the characters a-Z, the numbers 0-9 and the underscore _ |
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 broken by PR #1043
// TODO(pgrete) adjust for single prec output | ||
// openPMD::Datatype dtype = openPMD::determineDatatype<Real>(); | ||
using OutT = | ||
Real; // typename std::conditional<WRITE_SINGLE_PRECISION, float, Real>::type; | ||
std::vector<OutT> tmp_data(var_size_max * num_blocks_local); |
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.
reminder
for (int t = 0; t < Nt; ++t) { | ||
for (int u = 0; u < Nu; ++u) { | ||
for (int v = 0; v < Nv; ++v) { | ||
const auto [record_name, comp_name] = | ||
OpenPMDUtils::GetMeshRecordAndComponentNames(vinfo, comp_idx, level); | ||
auto mesh_comp = it.meshes[record_name][comp_name]; | ||
|
||
const auto comp_offset = tmp_offset; | ||
for (int k = kb.s; k <= kb.e; ++k) { | ||
for (int j = jb.s; j <= jb.e; ++j) { | ||
for (int i = ib.s; i <= ib.e; ++i) { | ||
tmp_data[tmp_offset] = static_cast<OutT>(out_var_h(t, u, v, k, j, i)); | ||
tmp_offset++; | ||
} | ||
} | ||
} |
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.
Feels like this should be possible to merge with the higher-order functions in utils
# Given that the shapes are guaranteed to match (follow the check above) | ||
# we can load chunks from both files. | ||
# Note that we have to go over chunks as data might be sparse on disk so | ||
# loading the entire record will contain gargabe in sparse places. |
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.
gargabe -> garbage
In terms of packaging the OpenPMD dependency, is the user expected to install OpenPMD themselves to get the Python package? If I don't have OpenPMD installed externally, it uses
If I do have openpmd-api installed externally, it doesn't complain, but it still uses the built-in openPMD module for the C++ build, which (I think) could lead to an inconsistency. |
Also, we now have two very confusingly named CMake options for I/O: |
I am getting a CMake configuration error when trying this:
Edit: ok, it turns out this is a weird Conda environment issue. You have to explicitly request MPI support when installing $ conda install -c conda-forge "openpmd-api=*=mpi_openmpi*" TL;DR: I think this is a good reason to ensure that the internal OpenPMD build also installs the Python module. |
I am getting regression test failures on my Mac laptop:
They all have mysterious errors like this:
|
I propose installing the OpenPMD python package from the submodule using, e.g.:
|
PR Summary
PR Checklist