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 35 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
35 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
56f8fe3
Merge branch 'dev' into eschnett/c-bindings
franzpoeschel Nov 8, 2024
bbcd59c
Adhere to deprecated openPMD_Version method
franzpoeschel Nov 8, 2024
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
71 changes: 71 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 @@ -220,6 +221,15 @@ function(openpmd_cuda_required target)
CUDA_STANDARD_REQUIRED ON)
endfunction()

# C standard: requirements for a target
function(openpmd_c_required target)
target_compile_features(${target} PUBLIC c_std_99)
set_target_properties(${target} PROPERTIES
C_EXTENSIONS OFF
C_STANDARD_REQUIRED ON
)
endfunction()


# Dependencies ################################################################
#
Expand Down Expand Up @@ -394,6 +404,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 +615,61 @@ 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.cpp
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)
set_target_properties(openPMD.c PROPERTIES
C_EXTENSIONS OFF
C_STANDARD_REQUIRED ON
# Allow C++ extensions since we read C header code into C++
# code and C99 `_Complex` counts as C++ extension
CXX_STANDARD_REQUIRED ON

CXX_VISIBILITY_PRESET "hidden"
CUDA_VISIBILITY_PRESET "hidden"

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
)

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

# python bindings
if(openPMD_HAVE_PYTHON)
add_library(openPMD.py MODULE
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
51 changes: 51 additions & 0 deletions include/openPMD/binding/c/Container_Iteration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#ifndef OPENPMD_CONTAINER_ITERATION_H
#define OPENPMD_CONTAINER_ITERATION_H

#include <openPMD/binding/c/Iteration.h>

#include <openPMD/binding/c/backend/Attributable.h>

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

#ifdef __cplusplus
extern "C"
{
#endif

typedef struct openPMD_Container_Iteration openPMD_Container_Iteration;

const openPMD_Attributable *
openPMD_Container_Iteration_getConstAttributable(
const openPMD_Container_Iteration *container);
openPMD_Attributable *openPMD_Container_Iteration_getAttributable(
openPMD_Container_Iteration *container);

bool openPMD_Container_Iteration_empty(
const openPMD_Container_Iteration *container);

size_t openPMD_Container_Iteration_size(
const openPMD_Container_Iteration *container);

void
openPMD_Container_Iteration_clear(openPMD_Container_Iteration *container);

openPMD_Iteration *openPMD_Container_Iteration_get(
openPMD_Container_Iteration *container, uint64_t key);

void openPMD_Container_Iteration_set(
openPMD_Container_Iteration *container,
uint64_t key,
const openPMD_Iteration *component);

bool openPMD_Container_Iteration_contains(
const openPMD_Container_Iteration *container, uint64_t key);

void openPMD_Container_Iteration_erase(
openPMD_Container_Iteration *container, uint64_t key);

#ifdef __cplusplus
}
#endif

#endif // #ifndef OPENPMD_CONTAINER_ITERATION_H
46 changes: 46 additions & 0 deletions include/openPMD/binding/c/Container_Mesh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef OPENPMD_CONTAINER_MESH_H
#define OPENPMD_CONTAINER_MESH_H

#include <openPMD/binding/c/Mesh.h>

#include <openPMD/binding/c/backend/Attributable.h>

#include <stddef.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef struct openPMD_Container_Mesh openPMD_Container_Mesh;

const openPMD_Attributable *openPMD_Container_Mesh_getConstAttributable(
const openPMD_Container_Mesh *container);
openPMD_Attributable *
openPMD_Container_Mesh_getAttributable(openPMD_Container_Mesh *container);

bool openPMD_Container_Mesh_empty(const openPMD_Container_Mesh *container);

size_t openPMD_Container_Mesh_size(const openPMD_Container_Mesh *container);

void openPMD_Container_Mesh_clear(openPMD_Container_Mesh *container);

openPMD_Mesh *openPMD_Container_Mesh_get(
openPMD_Container_Mesh *container, const char *key);

void openPMD_Container_Mesh_set(
openPMD_Container_Mesh *container,
const char *key,
const openPMD_Mesh *component);

bool openPMD_Container_Mesh_contains(
const openPMD_Container_Mesh *container, const char *key);

void openPMD_Container_Mesh_erase(
openPMD_Container_Mesh *container, const char *key);

#ifdef __cplusplus
}
#endif

#endif // #ifndef OPENPMD_CONTAINER_MESH_H
76 changes: 76 additions & 0 deletions include/openPMD/binding/c/Datatype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#ifndef OPENPMD_DATATYPE_H
#define OPENPMD_DATATYPE_H

#include <stdbool.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef enum openPMD_Datatype
{
openPMD_Datatype_CHAR,
openPMD_Datatype_UCHAR,
openPMD_Datatype_SCHAR,
openPMD_Datatype_SHORT,
openPMD_Datatype_INT,
openPMD_Datatype_LONG,
openPMD_Datatype_LONGLONG,
openPMD_Datatype_USHORT,
openPMD_Datatype_UINT,
openPMD_Datatype_ULONG,
openPMD_Datatype_ULONGLONG,
openPMD_Datatype_FLOAT,
openPMD_Datatype_DOUBLE,
openPMD_Datatype_LONG_DOUBLE,
openPMD_Datatype_CFLOAT,
openPMD_Datatype_CDOUBLE,
openPMD_Datatype_CLONG_DOUBLE,
openPMD_Datatype_STRING,
openPMD_Datatype_VEC_CHAR,
openPMD_Datatype_VEC_SHORT,
openPMD_Datatype_VEC_INT,
openPMD_Datatype_VEC_LONG,
openPMD_Datatype_VEC_LONGLONG,
openPMD_Datatype_VEC_UCHAR,
openPMD_Datatype_VEC_USHORT,
openPMD_Datatype_VEC_UINT,
openPMD_Datatype_VEC_ULONG,
openPMD_Datatype_VEC_ULONGLONG,
openPMD_Datatype_VEC_FLOAT,
openPMD_Datatype_VEC_DOUBLE,
openPMD_Datatype_VEC_LONG_DOUBLE,
openPMD_Datatype_VEC_CFLOAT,
openPMD_Datatype_VEC_CDOUBLE,
openPMD_Datatype_VEC_CLONG_DOUBLE,
openPMD_Datatype_VEC_SCHAR,
openPMD_Datatype_VEC_STRING,
openPMD_Datatype_ARR_DBL_7,
openPMD_Datatype_BOOL,
openPMD_Datatype_UNDEFINED
} openPMD_Datatype;

const openPMD_Datatype *openPMD_Datatypes();
size_t openPMD_DatatypesSize();

size_t openPMD_toBytes(openPMD_Datatype datatype);
size_t openPMD_toBits(openPMD_Datatype datatype);
bool openPMD_isVector(openPMD_Datatype datatype);
bool openPMD_isFloatingPoint(openPMD_Datatype datatype);
bool openPMD_isComplexFloatingPoint(openPMD_Datatype datatype);
bool openPMD_isInteger(openPMD_Datatype datatype);
bool openPMD_isSigned(openPMD_Datatype datatype);
bool openPMD_isChar(openPMD_Datatype datatype);
bool openPMD_isSame(openPMD_Datatype datatype1, openPMD_Datatype datatype2);
openPMD_Datatype openPMD_basicDatatype(openPMD_Datatype datatype);
openPMD_Datatype openPMD_toVectorType(openPMD_Datatype datatype);
const char *openPMD_datatypeToString(openPMD_Datatype datatype);
openPMD_Datatype openPMD_stringToDatatype(const char *string);

#ifdef __cplusplus
}
#endif

#endif // #ifndef OPENPMD_DATATYPE_H
30 changes: 30 additions & 0 deletions include/openPMD/binding/c/IO/Access.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef OPENPMD_ACCESS_H
#define OPENPMD_ACCESS_H

#include <stdbool.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef enum openPMD_Access
{
openPMD_Access_READ_ONLY,
openPMD_Access_READ_RANDOM_ACCESS = openPMD_Access_READ_ONLY,
openPMD_Access_READ_LINEAR,
openPMD_Access_READ_WRITE,
openPMD_Access_CREATE,
openPMD_Access_APPEND
} openPMD_Access;

bool openPMD_Access_readOnly(openPMD_Access access);
bool openPMD_Access_write(openPMD_Access access);
bool openPMD_Access_writeOnly(openPMD_Access access);
bool openPMD_Access_read(openPMD_Access access);

#ifdef __cplusplus
}
#endif

#endif // #ifndef OPENPMD_ACCESS_H
29 changes: 29 additions & 0 deletions include/openPMD/binding/c/IO/Format.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef OPENPMD_FORMAT_H
#define OPENPMD_FORMAT_H

#ifdef __cplusplus
extern "C"
{
#endif

typedef enum openPMD_Format
{
openPMD_Format_HDF5,
openPMD_Format_ADIOS2_BP,
openPMD_Format_ADIOS2_BP4,
openPMD_Format_ADIOS2_BP5,
openPMD_Format_ADIOS2_SST,
openPMD_Format_ADIOS2_SSC,
openPMD_Format_JSON,
openPMD_Format_TOML,
openPMD_Format_DUMMY
} openPMD_Format;

openPMD_Format openPMD_determineFormat(const char *filename);
const char *suffix(openPMD_Format format);

#ifdef __cplusplus
}
#endif

#endif // #ifndef OPENPMD_FORMAT_H
Loading
Loading