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

Add C bindings #1537

Draft
wants to merge 33 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
dec21bb
Add C bindings
eschnett Oct 15, 2023
bad5213
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 15, 2023
30c7714
Require C99 standard
eschnett Oct 15, 2023
dc00f7a
Complete Attributable.h
eschnett Oct 15, 2023
230845d
Remove Dataset
eschnett Oct 15, 2023
a9d7baa
Allow C99 code in C++
eschnett Oct 15, 2023
757ad0a
Add C tests
eschnett Oct 15, 2023
be1461f
Handle MPI
eschnett Oct 15, 2023
471603b
Avoid unused variable
eschnett Oct 15, 2023
09d01de
Avoid unitialized variables
eschnett Oct 15, 2023
b2317c0
Use C++ header files where possible
eschnett Oct 15, 2023
7988c43
Disable C++ extensions
eschnett Oct 16, 2023
193d960
Use C++ header files
eschnett Oct 16, 2023
17950ad
Install C bindings as well
eschnett Oct 19, 2023
761411a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 19, 2023
e662ba9
Rename C bindings shared library
eschnett Oct 20, 2023
137488c
Rename C bindings shared library back
eschnett Oct 21, 2023
da41fce
Redesign getAttribute
eschnett Oct 22, 2023
399fb61
Correct Format C bindings
eschnett Oct 22, 2023
c041a6a
Correct Format C bindings
eschnett Oct 22, 2023
3912f1d
New C binding openPMD_Attributable_attributeDatatype
eschnett Oct 22, 2023
7d45d84
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 22, 2023
02aefd0
New C binding openPMD_Attributable_getAttribute_string
eschnett Oct 22, 2023
0bc009c
Correct openPMD_Series_setIterationFormat
eschnett Oct 23, 2023
58f9916
Simply attribute getters for complex values
eschnett Oct 23, 2023
76ed527
Add `delete` C binding for read and write iterations
eschnett Oct 28, 2023
3326bb6
Implement openPMD_Attributable_attributes
eschnett Oct 28, 2023
d9ed4ef
Correct openPMD_Attributable_attributes
eschnett Oct 28, 2023
56e9ba0
Add openPMD_Series_iterations
eschnett Oct 29, 2023
3f685cb
Add C bindings for vector attributes
eschnett Oct 29, 2023
3f1f710
Correct openPMD_Attributable_setAttribute_cfloat2
eschnett Oct 29, 2023
ec1e148
Add C bindings for ReadIterations
eschnett Dec 22, 2023
dbcbe65
Call `new` when copying Iteration
eschnett Dec 23, 2023
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
7 changes: 7 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}
97 changes: 97 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"cmake.configureSettings": {
"CMAKE_INSTALL_PREFIX": "/Users/eschnett/openpmd-api",
"CMAKE_OSX_DEPLOYMENT_TARGET": "14.0",
"openPMD_USE_ADIOS2": "OFF",
"openPMD_USE_JULIA": "OFF",
"openPMD_USE_PYTHON": "OFF"
},
"files.associations": {
"*.tpp": "cpp",
"__bit_reference": "cpp",
"__config": "cpp",
"__debug": "cpp",
"__errc": "cpp",
"__hash_table": "cpp",
"__locale": "cpp",
"__mutex_base": "cpp",
"__node_handle": "cpp",
"__split_buffer": "cpp",
"__threading_support": "cpp",
"__tree": "cpp",
"__verbose_abort": "cpp",
"array": "cpp",
"atomic": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"charconv": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"exception": "cpp",
"forward_list": "cpp",
"fstream": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"ios": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"list": "cpp",
"locale": "cpp",
"map": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"optional": "cpp",
"ostream": "cpp",
"queue": "cpp",
"ratio": "cpp",
"regex": "cpp",
"set": "cpp",
"sstream": "cpp",
"stack": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"thread": "cpp",
"tuple": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"valarray": "cpp",
"variant": "cpp",
"vector": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"chrono": "cpp",
"compare": "cpp",
"concepts": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"random": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"format": "cpp"
}
}
35 changes: 35 additions & 0 deletions BUILD.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Build locally (just to test)
(
cd ~/src/openPMD-api
cmake --build config --verbose && cmake --install config --verbose
)

# Commit
(
cd ~/src/openPMD-api
git add src && git commit -m 'Make changes' && git push
commit=$(git log | head -n 1 | awk '{ print $2; }')
sha256=$(echo $(wget https://github.com/eschnett/openPMD-api/archive/$commit.tar.gz && sha256sum $commit.tar.gz | awk '{ print $1; }' && rm $commit.tar.gz))
echo $commit
echo $sha256
)

# Build in Yggdrasil
(
cd ~/src/Yggdrasil/O/openPMD_api
julia --color=yes build_tarballs.jl --debug --verbose --deploy=local x86_64-apple-darwin-libgfortran5
)

# Commit in local repo
(
cd ~/.julia/dev/openPMD_api_jll
git add . && git commit -m 'Update generated package'
)

# Test in Julia
# julia +1.6 --eval 'using openPMD'
julia +1.7 --eval 'using openPMD'
julia +1.8 --eval 'using openPMD'
julia +1.9 --eval 'using openPMD'
julia +1.10 --eval 'using openPMD'
julia +dev --eval 'using openPMD'
21 changes: 21 additions & 0 deletions BUILD.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
cd $HOME/src/ADIOS2
rm -rf config $HOME/ADIOS2
cmake -S . -B config -G Ninja -DCMAKE_C_COMPILER=mpicc-openmpi-mp -DCMAKE_CXX_COMPILER=mpicxx-openmpi-mp -DCMAKE_Fortran_COMPILER=mpif90-openmpi-mp -DADIOS2_USE_HDF5=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$HOME/ADIOS2
cmake --build config --verbose && cmake --install config --verbose

cd $HOME/src/libcxxwrap-julia
rm -rf config $HOME/libcxxwrap-julia
cmake -S . -B config -G Ninja -DCMAKE_C_COMPILER=mpicc-openmpi-mp -DCMAKE_CXX_COMPILER=mpicxx-openmpi-mp -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$HOME/libcxxwrap-julia
cmake --build config --verbose && cmake --install config --verbose

cd $HOME/src/openPMD-api
rm -rf config $HOME/openPMD-api
cmake -S . -B config -G Ninja -DCMAKE_C_COMPILER=mpicc-openmpi-mp -DCMAKE_CXX_COMPILER=mpicxx-openmpi-mp -DCMAKE_PREFIX_PATH="$HOME/ADIOS2;$HOME/libcxxwrap-julia" -DopenPMD_USE_ADIOS2=ON -DopenPMD_USE_JULIA=ON -DopenPMD_USE_HDF5=OFF -DopenPMD_USE_PYTHON=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$HOME/openPMD-api
cmake --build config --verbose && cmake --install config --verbose



cd $HOME/src/openPMD-api
rm -rf config $HOME/openPMD-api
cmake -S . -B config -G Ninja -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_PREFIX_PATH="$HOME/ADIOS2;$HOME/libcxxwrap-julia" -DopenPMD_USE_HDF5=OFF -DopenPMD_USE_JULIA=ON -DopenPMD_USE_PYTHON=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$HOME/openPMD-api
cmake --build config --verbose && cmake --install config --verbose
98 changes: 98 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ endfunction()
openpmd_option(MPI "Parallel, Multi-Node I/O for clusters" AUTO)
openpmd_option(HDF5 "HDF5 backend (.h5 files)" AUTO)
openpmd_option(ADIOS2 "ADIOS2 backend (.bp files)" AUTO)
openpmd_option(C "Enable C bindings" ON)
openpmd_option(PYTHON "Enable Python bindings" AUTO)

option(openPMD_INSTALL "Add installation targets" ON)
Expand Down Expand Up @@ -394,6 +395,12 @@ endif()

# TODO: Check if ADIOS2 is parallel when openPMD_HAVE_MPI is ON

if(openPMD_USE_C)
set(openPMD_HAVE_C TRUE)
else()
set(openPMD_HAVE_C FALSE)
endif()

# external library: pybind11 (optional)
set(_PY_DEV_MODULE Development.Module)
if(CMAKE_VERSION VERSION_LESS 3.18.0)
Expand Down Expand Up @@ -599,6 +606,64 @@ else()
target_compile_definitions(openPMD PRIVATE openPMD_USE_VERIFY=0)
endif()

# C bindings
if(openPMD_HAVE_C)
add_library(openPMD.c ${_openpmd_lib_type}
src/binding/c/ChunkInfo.cpp
src/binding/c/Container_Iteration.cpp
src/binding/c/Container_Mesh.cpp
src/binding/c/Datatype.cpp
src/binding/c/IO/Access.cpp
src/binding/c/IO/Format.cpp
src/binding/c/Iteration.cpp
src/binding/c/Mesh.cpp
src/binding/c/ReadIterations.cpp
src/binding/c/RecordComponent.cpp
src/binding/c/Series.cpp
src/binding/c/UnitDimension.cpp
src/binding/c/WriteIterations.cpp
src/binding/c/backend/Attributable.c
src/binding/c/backend/Attributable.cpp
#TODO src/binding/c/backend/Attribute.cpp
src/binding/c/backend/BaseRecordComponent.cpp
src/binding/c/backend/Container_MeshRecordComponent.cpp
src/binding/c/backend/MeshRecordComponent.cpp
src/binding/c/version.cpp
)
target_compile_features(openPMD.c PUBLIC c_std_99)
target_compile_features(openPMD.c PRIVATE cxx_std_17)
target_compile_options(openPMD.c PUBLIC ${_msvc_options})
target_link_libraries(openPMD.c PRIVATE openPMD)
if(openPMD_HAVE_MPI)
target_link_libraries(openPMD.c PUBLIC ${openPMD_MPI_TARGETS})
endif()
set_target_properties(openPMD.c PROPERTIES
C_EXTENSIONS OFF
C_STANDARD_VERSION 99
C_STANDARD_REQUIRED ON
# # Allow C++ extensions since we read C header code into C++
# # code and C99 `_Complex` counts as C++ extension
# CXX_EXTENSIONS ON
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED ON

COMPILE_PDB_NAME openPMD
ARCHIVE_OUTPUT_DIRECTORY ${openPMD_ARCHIVE_OUTPUT_DIRECTORY}
LIBRARY_OUTPUT_DIRECTORY ${openPMD_LIBRARY_OUTPUT_DIRECTORY}
RUNTIME_OUTPUT_DIRECTORY ${openPMD_RUNTIME_OUTPUT_DIRECTORY}
PDB_OUTPUT_DIRECTORY ${openPMD_PDB_OUTPUT_DIRECTORY}
COMPILE_PDB_OUTPUT_DIRECTORY ${openPMD_COMPILE_PDB_OUTPUT_DIRECTORY}
POSITION_INDEPENDENT_CODE ON
WINDOWS_EXPORT_ALL_SYMBOLS ON
)

target_include_directories(openPMD.c PUBLIC
$<BUILD_INTERFACE:${openPMD_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${openPMD_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
endif()

# python bindings
if(openPMD_HAVE_PYTHON)
add_library(openPMD.py MODULE
Expand Down Expand Up @@ -737,6 +802,10 @@ set(openPMD_TEST_NAMES
ParallelIO
JSON
)
set(openPMD_C_TEST_NAMES
C
)

# command line tools
set(openPMD_CLI_TOOL_NAMES
ls
Expand Down Expand Up @@ -883,6 +952,25 @@ if(openPMD_BUILD_TESTING)
$<TARGET_PROPERTY:openPMD::thirdparty::toml11,INTERFACE_INCLUDE_DIRECTORIES>)
endif()
endforeach()

if(openPMD_HAVE_C)
foreach(testname ${openPMD_C_TEST_NAMES})
add_executable(${testname}Tests test/c/${testname}Test.c)
target_compile_features(${testname}Tests PUBLIC c_std_99)
target_link_libraries(${testname}Tests PRIVATE openPMD.c)
set_target_properties(${testname}Tests PROPERTIES
C_EXTENSIONS OFF
C_STANDARD_REQUIRED ON

COMPILE_PDB_NAME ${testname}Tests
ARCHIVE_OUTPUT_DIRECTORY ${openPMD_ARCHIVE_OUTPUT_DIRECTORY}
LIBRARY_OUTPUT_DIRECTORY ${openPMD_LIBRARY_OUTPUT_DIRECTORY}
RUNTIME_OUTPUT_DIRECTORY ${openPMD_RUNTIME_OUTPUT_DIRECTORY}
PDB_OUTPUT_DIRECTORY ${openPMD_RUNTIME_OUTPUT_DIRECTORY}
COMPILE_PDB_OUTPUT_DIRECTORY ${openPMD_RUNTIME_OUTPUT_DIRECTORY}
)
endforeach()
endif()
endif()

if(openPMD_BUILD_CLI_TOOLS)
Expand Down Expand Up @@ -1095,6 +1183,9 @@ if(openPMD_INSTALL)
RUNTIME DESTINATION ${openPMD_INSTALL_BINDIR}
INCLUDES DESTINATION ${openPMD_INSTALL_INCLUDEDIR}
)
if(openPMD_HAVE_C)
install(TARGETS openPMD.c DESTINATION ${openPMD_INSTALL_LIBDIR})
endif()
if(openPMD_HAVE_PYTHON)
install(
DIRECTORY ${openPMD_SOURCE_DIR}/src/binding/python/openpmd_api
Expand All @@ -1121,6 +1212,13 @@ if(openPMD_INSTALL)
PATTERN "*.hpp"
PATTERN "*.tpp"
)
if(openPMD_HAVE_C)
install(DIRECTORY "${openPMD_SOURCE_DIR}/include/openPMD"
DESTINATION ${openPMD_INSTALL_INCLUDEDIR}
FILES_MATCHING
PATTERN "*.h"
)
endif()
install(
FILES ${openPMD_BINARY_DIR}/include/openPMD/config.hpp
DESTINATION ${openPMD_INSTALL_INCLUDEDIR}/openPMD
Expand Down
43 changes: 43 additions & 0 deletions include/openPMD/binding/c/ChunkInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef OPENPMD_CHUNKINFO_H
#define OPENPMD_CHUNKINFO_H

#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef struct openPMD_ChunkInfo
{
uint64_t *offset;
uint64_t *extent;
size_t size;
} openPMD_ChunkInfo;

void openPMD_ChunkInfo_construct(openPMD_ChunkInfo *chunkInfo);
void openPMD_ChunkInfo_destruct(openPMD_ChunkInfo *chunkInfo);

typedef struct openPMD_WrittenChunkInfo
{
openPMD_ChunkInfo chunkInfo;
unsigned int sourceID;
} openPMD_WrittenChunkInfo;

void openPMD_WrittenChunkInfo_construct(
openPMD_WrittenChunkInfo *writtenChunkInfo);
void openPMD_WrittenChunkInfo_destruct(
openPMD_WrittenChunkInfo *writtenChunkInfo);

typedef struct openPMD_ChunkTable
{
openPMD_WrittenChunkInfo *writtenChunkInfo;
size_t size;
} openPMD_ChunkTable;

#ifdef __cplusplus
}
#endif

#endif // #ifndef OPENPMD_CHUNKINFO_H
Loading
Loading