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

CI: Add ADIOS1 (BP3) Python Test #1197

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,32 @@ jobs:
cmake --build build --parallel 2
ctest --test-dir build --output-on-failure

clang6_nopy_ompi_h5_ad1_ad2_bp3_libcpp:
clang6_py38_ompi_h5_ad1_ad2_bp3_libcpp:
runs-on: ubuntu-18.04
if: github.event.pull_request.draft == false
steps:
- uses: actions/checkout@v2
- name: Spack Cache
uses: actions/cache@v2
with: {path: /opt/spack, key: clang6_nopy_ompi_h5_ad1_ad2_bp3_libcpp }
with: {path: /opt/spack, key: clang6_py38_ompi_h5_ad1_ad2_bp3_libcpp }
- name: Install
run: |
sudo apt-get update
sudo apt-get install clang-6.0 libc++-dev libc++abi-dev gfortran libopenmpi-dev python3
sudo apt-get install clang-6.0 libc++-dev libc++abi-dev gfortran libopenmpi-dev python3 python3-numpy python3-mpi4py python3-pandas
sudo .github/workflows/dependencies/install_spack
- name: Build
env: {CC: clang-6.0, CXX: clang++-6.0, CXXFLAGS: -stdlib=libc++ -Werror -Wno-deprecated-declarations -Wno-ignored-attributes -Wno-unused-const-variable}
# -Wno-ignored-attributes -Wno-unused-const-variable: clang-6 has a
# false positive on src/auxiliary/Filesystem.cpp
# [[maybe_unused]] MPI_Datatype const MPI_Types< unsigned >::value = MPI_UNSIGNED;
run: |
eval $(spack env activate --sh .github/ci/spack-envs/clang6_nopy_ompi_h5_ad1_ad2_bp3_libcpp/)
eval $(spack env activate --sh .github/ci/spack-envs/clang6_py38_ompi_h5_ad1_ad2_bp3_libcpp/)
spack install

share/openPMD/download_samples.sh build
chmod u-w build/samples/git-sample/*.h5
cmake -S . -B build \
-DopenPMD_USE_PYTHON=OFF \
-DopenPMD_USE_PYTHON=ON \
-DopenPMD_USE_MPI=ON \
-DopenPMD_USE_HDF5=ON \
-DopenPMD_USE_ADIOS1=ON \
Expand Down
7 changes: 6 additions & 1 deletion include/openPMD/IO/ADIOS/CommonADIOS1IOHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ class CommonADIOS1IOHandlerImpl : public AbstractIOHandlerImpl
m_openWriteFileHandles;
std::unordered_map<std::shared_ptr<std::string>, ADIOS_FILE *>
m_openReadFileHandles;
std::unordered_map<ADIOS_FILE *, std::vector<ADIOS_SELECTION *> >
struct ScheduledRead
{
ADIOS_SELECTION *selection;
std::shared_ptr<void> data; // needed to avoid early freeing
};
std::unordered_map<ADIOS_FILE *, std::vector<ScheduledRead> >
m_scheduledReads;
std::unordered_map<int64_t, std::unordered_map<std::string, Attribute> >
m_attributeWrites;
Expand Down
38 changes: 38 additions & 0 deletions include/openPMD/backend/Attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <complex>
#include <cstdint>
#include <iterator>
#include <sstream>
#include <stdexcept>
#include <string>
#include <type_traits>
Expand Down Expand Up @@ -229,3 +230,40 @@ U Attribute::get() const
}

} // namespace openPMD

namespace std
{
inline string to_string(openPMD::Attribute const &attr)
{
return std::visit(
[](auto const &val) {
using Val_t = remove_cv_t<remove_reference_t<decltype(val)> >;

std::stringstream os;
if constexpr (
openPMD::auxiliary::IsVector_v<Val_t> ||
openPMD::auxiliary::IsArray_v<Val_t>)
{
if (val.empty())
{
os << "[]";
}
else
{
os << "[" << val[0];
for (size_t i = 1; i < val.size(); ++i)
{
os << ", " << val[i];
}
os << "]";
}
}
else
{
os << val;
}
return os.str();
},
attr.getResource());
}
} // namespace std
2 changes: 1 addition & 1 deletion src/IO/ADIOS/ADIOS1IOHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ std::future<void> ADIOS1IOHandlerImpl::flush()
"dataset reading");

for (auto &sel : file.second)
adios_selection_delete(sel);
adios_selection_delete(sel.selection);
}
m_scheduledReads.clear();

Expand Down
4 changes: 2 additions & 2 deletions src/IO/ADIOS/CommonADIOS1IOHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ void CommonADIOS1IOHandlerImpl<ChildClass>::closeFile(
"dataset reading");

for (auto &sel : scheduled->second)
adios_selection_delete(sel);
adios_selection_delete(sel.selection);
m_scheduledReads.erase(scheduled);
}
close(handle_read->second);
Expand Down Expand Up @@ -1183,7 +1183,7 @@ void CommonADIOS1IOHandlerImpl<ChildClass>::readDataset(
"[ADIOS1] Internal error: Failed to schedule ADIOS read during dataset "
"reading");

m_scheduledReads[f].push_back(sel);
m_scheduledReads[f].push_back({sel, parameters.data});
}

template <typename ChildClass>
Expand Down
2 changes: 1 addition & 1 deletion src/IO/ADIOS/ParallelADIOS1IOHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ std::future<void> ParallelADIOS1IOHandlerImpl::flush()
"dataset reading");

for (auto &sel : file.second)
adios_selection_delete(sel);
adios_selection_delete(sel.selection);
}
m_scheduledReads.clear();

Expand Down
3 changes: 3 additions & 0 deletions src/binding/python/Attributable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@ void init_Attributable(py::module &m)
"get_attribute",
[](Attributable &attr, std::string const &key) {
auto v = attr.getAttribute(key);
std::cout << "Attribute '" << key << "' has type: " << v.dtype
<< std::endl
<< " and value: " << std::to_string(v) << std::endl;
return v.getResource();
// TODO instead of returning lists, return all arrays (ndim > 0)
// as numpy arrays?
Expand Down
9 changes: 8 additions & 1 deletion src/binding/python/PatchRecordComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,14 @@ void init_PatchRecordComponent(py::module &m)
py::ssize_t numElements = 1;
if (buf.ndim > 0)
{
std::cout << "Buffer has dimensionality: " << buf.ndim
<< std::endl;
for (auto d = 0; d < buf.ndim; ++d)
{
std::cout << "Extent of dimensionality " << d << ": "
<< buf.shape.at(d) << std::endl;
numElements *= buf.shape.at(d);
}
}

// Numpy: Handling of arrays and scalars
Expand Down Expand Up @@ -177,7 +183,8 @@ void init_PatchRecordComponent(py::module &m)
{
throw std::runtime_error(
"store: "
"Only scalar values supported!");
"Only scalar values supported! (found " +
std::to_string(numElements) + "values)");
}
},
py::arg("idx"),
Expand Down
67 changes: 36 additions & 31 deletions src/binding/python/RecordComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,53 +539,51 @@ void load_chunk(
}
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't really know if this part is necessary. But it looks like we forgot it earlier? Copied this from the other overload of load_chunk.
This fix is irrelevant to the use-after-free issue that I saw.

auto load_data =
[&r, &buffer, &buffer_info, &offset, &extent](auto cxxtype) {
using CXXType = decltype(cxxtype);
buffer.inc_ref();
// buffer_info.inc_ref();
void *data = buffer_info.ptr;
std::shared_ptr<CXXType> shared(
(CXXType *)data, [buffer](CXXType *) { buffer.dec_ref(); });
r.loadChunk(std::move(shared), offset, extent);
};

if (r.getDatatype() == Datatype::CHAR)
r.loadChunk<char>(shareRaw((char *)buffer_info.ptr), offset, extent);
load_data((char)0);
else if (r.getDatatype() == Datatype::UCHAR)
r.loadChunk<unsigned char>(
shareRaw((unsigned char *)buffer_info.ptr), offset, extent);
load_data((unsigned char)0);
else if (r.getDatatype() == Datatype::SHORT)
r.loadChunk<short>(shareRaw((short *)buffer_info.ptr), offset, extent);
load_data((short)0);
else if (r.getDatatype() == Datatype::INT)
r.loadChunk<int>(shareRaw((int *)buffer_info.ptr), offset, extent);
load_data((int)0);
else if (r.getDatatype() == Datatype::LONG)
r.loadChunk<long>(shareRaw((long *)buffer_info.ptr), offset, extent);
load_data((long)0);
else if (r.getDatatype() == Datatype::LONGLONG)
r.loadChunk<long long>(
shareRaw((long long *)buffer_info.ptr), offset, extent);
load_data((long long)0);
else if (r.getDatatype() == Datatype::USHORT)
r.loadChunk<unsigned short>(
shareRaw((unsigned short *)buffer_info.ptr), offset, extent);
load_data((unsigned short)0);
else if (r.getDatatype() == Datatype::UINT)
r.loadChunk<unsigned int>(
shareRaw((unsigned int *)buffer_info.ptr), offset, extent);
load_data((unsigned int)0);
else if (r.getDatatype() == Datatype::ULONG)
r.loadChunk<unsigned long>(
shareRaw((unsigned long *)buffer_info.ptr), offset, extent);
load_data((unsigned long)0);
else if (r.getDatatype() == Datatype::ULONGLONG)
r.loadChunk<unsigned long long>(
shareRaw((unsigned long long *)buffer_info.ptr), offset, extent);
load_data((unsigned long long)0);
else if (r.getDatatype() == Datatype::LONG_DOUBLE)
r.loadChunk<long double>(
shareRaw((long double *)buffer_info.ptr), offset, extent);
load_data((long double)0);
else if (r.getDatatype() == Datatype::DOUBLE)
r.loadChunk<double>(
shareRaw((double *)buffer_info.ptr), offset, extent);
load_data((double)0);
else if (r.getDatatype() == Datatype::FLOAT)
r.loadChunk<float>(shareRaw((float *)buffer_info.ptr), offset, extent);
load_data((float)0);
else if (r.getDatatype() == Datatype::CLONG_DOUBLE)
r.loadChunk<std::complex<long double>>(
shareRaw((std::complex<long double> *)buffer_info.ptr),
offset,
extent);
load_data((std::complex<long double>)0);
else if (r.getDatatype() == Datatype::CDOUBLE)
r.loadChunk<std::complex<double>>(
shareRaw((std::complex<double> *)buffer_info.ptr), offset, extent);
load_data((std::complex<double>)0);
else if (r.getDatatype() == Datatype::CFLOAT)
r.loadChunk<std::complex<float>>(
shareRaw((std::complex<float> *)buffer_info.ptr), offset, extent);
load_data((std::complex<float>)0);
else if (r.getDatatype() == Datatype::BOOL)
r.loadChunk<bool>(shareRaw((bool *)buffer_info.ptr), offset, extent);
load_data((bool)0);
else
throw std::runtime_error(
std::string("Datatype not known in 'loadChunk'!"));
Expand Down Expand Up @@ -777,8 +775,14 @@ void init_RecordComponent(py::module &m)
py::ssize_t numElements = 1;
if (buf.ndim > 0)
{
std::cout << "Buffer has dimensionality: " << buf.ndim
<< std::endl;
for (auto d = 0; d < buf.ndim; ++d)
{
std::cout << "Extent of dimensionality " << d << ": "
<< buf.shape.at(d) << std::endl;
numElements *= buf.shape.at(d);
}
}

// Numpy: Handling of arrays and scalars
Expand Down Expand Up @@ -869,7 +873,8 @@ void init_RecordComponent(py::module &m)
{
throw std::runtime_error(
"make_constant: "
"Only scalar values supported!");
"Only scalar values supported! (found " +
std::to_string(numElements) + "values)");
}
},
py::arg("value"))
Expand Down
2 changes: 1 addition & 1 deletion test/python/unittest/API/APITest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1905,7 +1905,7 @@ def writeFromTemporary(self, ext):
)

r_E_x = read.iterations[0].meshes["E"]["x"]
if read.backend == 'ADIOS2':
if read.backend == 'ADIOS2' or read.backend == 'ADIOS1':
self.assertEqual(len(r_E_x.available_chunks()), 3)
else:
self.assertEqual(len(r_E_x.available_chunks()), 1)
Expand Down