-
Notifications
You must be signed in to change notification settings - Fork 52
Julia bindings #1025
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
base: dev
Are you sure you want to change the base?
Julia bindings #1025
Changes from 2 commits
8de441a
b657d95
2de8c93
eee0d35
4d71540
0e6ec91
48d6024
2865845
9c81660
d33895e
492912d
5ab016c
34f11ab
d679474
828222b
4697250
bc3d5f9
2492182
8d444e8
29cd7ff
d4d0db7
b41d41e
b1801e1
e7861d6
91b07e7
5839134
933f01a
1f6559b
d7ebecb
0df99cc
e315fe8
895e060
1fe64f1
46a7b00
bcf29cc
a9955b3
b0c1fd0
2f26607
5c192e3
5c4d14f
7c663d8
d42b4d6
cbb0da4
a288938
dd9aff6
19af703
ffac9cf
f32b68b
3d23f12
88d734a
7daa833
218b67e
1e9e69c
de3d451
896daeb
1228708
d146f5f
d7eefb9
d3c042b
3c9f215
32f4fe6
b9c0bc4
9edac3b
a6a4d55
3f1a23d
84bce33
e6a18e7
46d19af
479b3d7
20cdbe7
e31818f
9c97be2
61fe000
c11fcd0
e602993
e364217
7424187
4be71b1
655febb
13ea8b4
130c167
769adbc
b381ad8
c6f63a1
f7e4424
21cecd4
8dc4076
db180de
8fb74b9
ddf4fbc
2ee34a0
a17a10d
5229a57
100a586
3b1b37c
1918464
c6fe874
d548c90
d427b19
184610f
d59773a
724806e
54a5052
fa2efa5
5d5612d
9eaec53
cac9488
5213e2e
805756f
a0b015e
26b6ca7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,7 @@ openpmd_option(MPI "Parallel, Multi-Node I/O for clusters" AUTO) | |
openpmd_option(HDF5 "HDF5 backend (.h5 files)" AUTO) | ||
openpmd_option(ADIOS1 "ADIOS1 backend (.bp files)" AUTO) | ||
openpmd_option(ADIOS2 "ADIOS2 backend (.bp files)" AUTO) | ||
openpmd_option(JULIA "Enable Julia bindings" AUTO) | ||
openpmd_option(PYTHON "Enable Python bindings" AUTO) | ||
|
||
option(openPMD_INSTALL "Add installation targets" ON) | ||
|
@@ -283,6 +284,34 @@ endif() | |
|
||
# TODO: Check if ADIOS2 is parallel when openPMD_HAVE_MPI is ON | ||
|
||
# External library: libcxxwrap-julia | ||
if(openPMD_USE_JULIA STREQUAL AUTO) | ||
find_package(JlCxx 0.8.3) | ||
if(JlCxx_FOUND) | ||
set(openPMD_HAVE_JlCxx TRUE) | ||
else() | ||
set(openPMD_HAVE_JlCxx FALSE) | ||
endif() | ||
if(JULIA_FOUND) | ||
set(openPMD_HAVE_JULIA TRUE) | ||
else() | ||
set(openPMD_HAVE_JULIA FALSE) | ||
endif() | ||
elseif(openPMD_USE_JULIA) | ||
eschnett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
find_package(JlCxx 0.8.3 REQUIRED) | ||
set(openPMD_HAVE_JULIA TRUE) | ||
set(openPMD_HAVE_JlCxx TRUE) | ||
eschnett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else() | ||
set(openPMD_HAVE_JULIA FALSE) | ||
set(openPMD_HAVE_JlCxx FALSE) | ||
endif() | ||
if(openPMD_HAVE_JlCxx) | ||
get_target_property(JlCxx_location JlCxx::cxxwrap_julia LOCATION) | ||
get_filename_component(JlCxx_location ${JlCxx_location} DIRECTORY) | ||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${JlCxx_location}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Memo to myself: generalize.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prepared in #1105 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
message(STATUS "Found JlCxx version ${JlCxx_VERSION} at ${JlCxx_location}") | ||
endif() | ||
|
||
# external library: pybind11 (optional) | ||
set(_PY_DEV_MODULE Development.Module) | ||
if(CMAKE_VERSION VERSION_LESS 3.18.0) | ||
|
@@ -574,6 +603,33 @@ else() | |
target_compile_definitions(openPMD PRIVATE openPMD_USE_VERIFY=0) | ||
endif() | ||
|
||
# Julia bindings | ||
if(openPMD_HAVE_JlCxx) | ||
add_library(openPMD_jl SHARED | ||
src/binding/julia/Access.cpp | ||
src/binding/julia/Attributable.cpp | ||
src/binding/julia/Attribute.cpp | ||
src/binding/julia/BaseRecordComponent.cpp | ||
src/binding/julia/Container.cpp | ||
src/binding/julia/Dataset.cpp | ||
src/binding/julia/Datatype.cpp | ||
src/binding/julia/Format.cpp | ||
src/binding/julia/Iteration.cpp | ||
src/binding/julia/Mesh.cpp | ||
src/binding/julia/MeshRecordComponent.cpp | ||
src/binding/julia/RecordComponent.cpp | ||
src/binding/julia/RecordComponent_load_chunk.cpp | ||
src/binding/julia/RecordComponent_make_constant.cpp | ||
src/binding/julia/RecordComponent_store_chunk.cpp | ||
src/binding/julia/Series.cpp | ||
src/binding/julia/UnitDimension.cpp | ||
src/binding/julia/WriteIterations.cpp | ||
src/binding/julia/openPMD.cpp | ||
src/binding/julia/version.cpp | ||
) | ||
target_link_libraries(openPMD_jl PRIVATE openPMD JlCxx::cxxwrap_julia JlCxx::cxxwrap_julia_stl) | ||
endif() | ||
|
||
# python bindings | ||
if(openPMD_HAVE_PYTHON) | ||
add_library(openPMD.py MODULE | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// IO/Access | ||
eschnett marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#include "defs.hpp" | ||
|
||
void define_julia_Access(jlcxx::Module &mod) { | ||
mod.add_bits<Access>("Access", jlcxx::julia_type("CppEnum")); | ||
jlcxx::stl::apply_stl<Access>(mod); | ||
|
||
mod.set_const("READ_ONLY", Access::READ_ONLY); | ||
mod.set_const("READ_WRITE", Access::READ_WRITE); | ||
mod.set_const("CREATE", Access::CREATE); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Attributable | ||
|
||
#include "defs.hpp" | ||
|
||
void define_julia_Attributable(jlcxx::Module &mod) { | ||
auto type = mod.add_type<Attributable>("Attributable"); | ||
|
||
#define USE_TYPE(NAME, ENUM, TYPE) \ | ||
type.method("set_attribute1_" NAME "!", &Attributable::setAttribute<TYPE>); | ||
{ FORALL_OPENPMD_TYPES } | ||
#undef USE_TYPE | ||
|
||
type.method("get_attribute1", &Attributable::getAttribute); | ||
type.method("delete_attribute!", &Attributable::deleteAttribute); | ||
type.method("attributes", &Attributable::attributes); | ||
type.method("num_attributes1", &Attributable::numAttributes); | ||
type.method("contains_attribute", &Attributable::containsAttribute); | ||
type.method("comment", &Attributable::comment); | ||
type.method("set_comment!", &Attributable::setComment); | ||
type.method("series_flush", static_cast<void (Attributable::*)()>( | ||
&Attributable::seriesFlush)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Attribute | ||
|
||
#include "defs.hpp" | ||
|
||
void define_julia_Attribute(jlcxx::Module &mod) { | ||
auto type = mod.add_type<Attribute>("Attribute"); | ||
|
||
type.method("dtype1", [](const Attribute &attr) { return attr.dtype; }); | ||
|
||
#define USE_TYPE(NAME, ENUM, TYPE) \ | ||
type.method("get1_" NAME, &Attribute::get<TYPE>); | ||
{ FORALL_OPENPMD_TYPES } | ||
#undef USE_TYPE | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// BaseRecordComponent | ||
|
||
#include "defs.hpp" | ||
|
||
// Define supertype relationships | ||
namespace jlcxx { | ||
template <> struct SuperType<BaseRecordComponent> { | ||
typedef Attributable type; | ||
}; | ||
} // namespace jlcxx | ||
|
||
void define_julia_BaseRecordComponent(jlcxx::Module &mod) { | ||
|
||
auto type = mod.add_type<BaseRecordComponent>( | ||
"BaseRecordComponent", jlcxx::julia_base_type<Attributable>()); | ||
|
||
type.method("unit_SI", &BaseRecordComponent::unitSI); | ||
type.method("reset_datatype1!", &BaseRecordComponent::resetDatatype); | ||
type.method("get_datatype1", &BaseRecordComponent::getDatatype); | ||
type.method("is_constant", &BaseRecordComponent::constant); | ||
// TODO: availableChunks | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#include "Container.hpp" | ||
|
||
std::unique_ptr<julia_Container_type_t> julia_Container_type; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#ifndef CONTAINER_HPP | ||
#define CONTAINER_HPP | ||
|
||
// Container | ||
|
||
#include "defs.hpp" | ||
|
||
#include <memory> | ||
#include <type_traits> | ||
|
||
// Define supertype relationships | ||
namespace jlcxx { | ||
template <typename T, typename K> struct SuperType<Container<T, K>> { | ||
typedef Attributable type; | ||
}; | ||
} // namespace jlcxx | ||
|
||
// TODO: use std::optional instead of std::unique_ptr | ||
typedef jlcxx::TypeWrapper< | ||
jlcxx::Parametric<jlcxx::TypeVar<1>, jlcxx::TypeVar<2>>> | ||
julia_Container_type_t; | ||
extern std::unique_ptr<julia_Container_type_t> julia_Container_type; | ||
|
||
template <typename Eltype, typename Keytype> | ||
void define_julia_Container(jlcxx::Module &mod) { | ||
if (!julia_Container_type) | ||
julia_Container_type = std::make_unique<julia_Container_type_t>( | ||
mod.add_type<jlcxx::Parametric<jlcxx::TypeVar<1>, jlcxx::TypeVar<2>>>( | ||
"Container", jlcxx::julia_base_type<Attributable>())); | ||
|
||
julia_Container_type->apply<Container<Eltype, Keytype>>([](auto type) { | ||
using ContainerT = typename decltype(type)::type; | ||
using key_type = typename ContainerT::key_type; | ||
using mapped_type = typename ContainerT::mapped_type; | ||
using size_type = typename ContainerT::size_type; | ||
static_assert(std::is_same_v<Eltype, mapped_type>); | ||
static_assert(std::is_same_v<Keytype, key_type>); | ||
|
||
type.template constructor<const ContainerT &>(); | ||
|
||
type.method("empty1", &ContainerT::empty); | ||
type.method("length1", &ContainerT::size); | ||
type.method("empty1!", &ContainerT::clear); | ||
type.method("getindex1", | ||
static_cast<mapped_type &(ContainerT::*)(const key_type &)>( | ||
&ContainerT::at)); | ||
type.method("get1!", | ||
[](ContainerT &cont, const key_type &key) -> mapped_type & { | ||
return cont[key]; | ||
}); | ||
type.method("setindex1!", | ||
[](ContainerT &cont, const mapped_type &value, | ||
const key_type &key) { return cont[key] = value; }); | ||
type.method("count1", &ContainerT::count); | ||
type.method("contains1", &ContainerT::contains); | ||
type.method("delete1!", | ||
static_cast<size_type (ContainerT::*)(const key_type &)>( | ||
&ContainerT::erase)); | ||
type.method("keys1", [](const ContainerT &cont) { | ||
std::vector<key_type> res; | ||
res.reserve(cont.size()); | ||
for (auto iter = cont.begin(); iter != cont.end(); ++iter) | ||
res.push_back(iter->first); | ||
return res; | ||
}); | ||
// type.method("values1", [](const ContainerT &cont) { | ||
// std::vector<mapped_type *> res; | ||
// res.reserve(cont.size()); | ||
// for (auto iter = cont.begin(); iter != cont.end(); ++iter) | ||
// res.push_back(&iter->second); | ||
// return res; | ||
// }); | ||
// type.method("collect1", [](const ContainerT &cont) { | ||
// std::vector<std::pair<key_type, mapped_type *>> res; | ||
// res.reserve(cont.size()); | ||
// for (auto iter = cont.begin(); iter != cont.end(); ++iter) | ||
// res.emplace_back(iter->first, &iter->second); | ||
// return res; | ||
// }); | ||
}); | ||
} | ||
|
||
#endif // #ifndef CONTAINER_HPP |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Dataset | ||
|
||
#include "defs.hpp" | ||
|
||
void define_julia_Dataset(jlcxx::Module &mod) { | ||
auto type = mod.add_type<Dataset>("Dataset"); | ||
|
||
type.constructor<Datatype, Extent>(); | ||
type.constructor<Datatype, Extent, const std::string &>(); | ||
type.constructor<Extent>(); | ||
|
||
type.method("extend1!", &Dataset::extend); | ||
type.method("set_chunk_size1!", &Dataset::setChunkSize); | ||
type.method("set_compression!", &Dataset::setCompression); | ||
type.method("set_custom_transform!", &Dataset::setCustomTransform); | ||
type.method("extent1", [](const Dataset &d) { return d.extent; }); | ||
type.method("dtype1", [](const Dataset &d) { return d.dtype; }); | ||
type.method("rank1", [](const Dataset &d) { return d.rank; }); | ||
type.method("chunk_size1", [](const Dataset &d) { return d.chunkSize; }); | ||
type.method("compression", [](const Dataset &d) { return d.compression; }); | ||
type.method("transform", [](const Dataset &d) { return d.transform; }); | ||
type.method("options", [](const Dataset &d) { return d.options; }); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Datatype | ||
|
||
#include "defs.hpp" | ||
|
||
void define_julia_Datatype(jlcxx::Module &mod) { | ||
mod.add_bits<Datatype>("Datatype", jlcxx::julia_type("CppEnum")); | ||
jlcxx::stl::apply_stl<Datatype>(mod); | ||
|
||
#define USE_TYPE(NAME, ENUM, TYPE) mod.set_const(NAME, ENUM); | ||
{ FORALL_OPENPMD_TYPES } | ||
#undef USE_TYPE | ||
mod.set_const("DATATYPE", Datatype::DATATYPE); | ||
mod.set_const("UNDEFINED", Datatype::UNDEFINED); | ||
|
||
mod.set_const("openPMD_datatypes", openPMD_Datatypes); | ||
// mod.method("determine_datatype", determineDatatype); | ||
mod.method("to_bytes1", toBytes); | ||
mod.method("to_bits1", toBits); | ||
mod.method("is_vector1", isVector); | ||
mod.method("is_floating_point1", (bool (*)(Datatype))isFloatingPoint); | ||
mod.method("is_complex_floating_point1", | ||
static_cast<bool (*)(Datatype)>(isComplexFloatingPoint)); | ||
mod.method("is_integer1", (std::tuple<bool, bool>(*)(Datatype))isInteger); | ||
// isSameFloatingPoint | ||
// isSameComplexFloatingPoint | ||
// isSameInteger | ||
mod.method("is_same1", isSame); | ||
mod.method("basic_datatype1", basicDatatype); | ||
mod.method("to_vector_type1", toVectorType); | ||
mod.method("datatype_to_string1", datatypeToString); | ||
mod.method("string_to_datatype1", stringToDatatype); | ||
mod.method("warn_wrong_datatype1", warnWrongDtype); | ||
// mod.method("==", operator==); | ||
// mod.method("!=", operator!=); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// IO/Format | ||
|
||
#include "defs.hpp" | ||
|
||
void define_julia_Format(jlcxx::Module &mod) { | ||
mod.add_bits<Format>("Format", jlcxx::julia_type("CppEnum")); | ||
jlcxx::stl::apply_stl<Format>(mod); | ||
|
||
mod.set_const("HDF5", Format::HDF5); | ||
mod.set_const("ADIOS1", Format::ADIOS1); | ||
mod.set_const("ADIOS2", Format::ADIOS2); | ||
mod.set_const("ADIOS2_SST", Format::ADIOS2_SST); | ||
mod.set_const("ADIOS2_SSC", Format::ADIOS2_SSC); | ||
mod.set_const("JSON", Format::JSON); | ||
mod.set_const("DUMMY", Format::DUMMY); | ||
mod.method("determine_format", determineFormat); | ||
mod.method("suffix", suffix); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Iteration | ||
|
||
#include "defs.hpp" | ||
|
||
#include <string> | ||
|
||
// Define supertype relationships | ||
namespace jlcxx { | ||
template <> struct SuperType<Iteration> { typedef Attributable type; }; | ||
} // namespace jlcxx | ||
|
||
void define_julia_Iteration(jlcxx::Module &mod) { | ||
auto type = mod.add_type<Iteration>("Iteration", | ||
jlcxx::julia_base_type<Attributable>()); | ||
|
||
type.method("time1", &Iteration::time<double>); | ||
type.method("set_time!", &Iteration::setTime<double>); | ||
type.method("dt", &Iteration::dt<double>); | ||
type.method("set_dt!", &Iteration::setDt<double>); | ||
type.method("time_unit_SI", &Iteration::timeUnitSI); | ||
type.method("set_time_unit_SI!", &Iteration::setTimeUnitSI); | ||
type.method("close1", | ||
static_cast<Iteration &(Iteration::*)(bool)>(&Iteration::close)); | ||
type.method("open", &Iteration::open); | ||
type.method("closed", &Iteration::closed); | ||
type.method("closed_by_writer", &Iteration::closedByWriter); | ||
type.method("meshes", | ||
[](Iteration &iter) -> Container<Mesh> & { return iter.meshes; }); | ||
// TODO: particles | ||
} |
Uh oh!
There was an error while loading. Please reload this page.