Skip to content

Commit

Permalink
Add deisa plugin (#473)
Browse files Browse the repository at this point in the history
Closes #447 and #487 

* add deisa plugin
* add deisa example
  • Loading branch information
benoitmartin88 authored Nov 15, 2024
1 parent d354993 commit 6db69d2
Show file tree
Hide file tree
Showing 22 changed files with 2,462 additions and 54 deletions.
4 changes: 4 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ Julien Bigot - CEA ([email protected])
* Maintainer (Dec. 2014 - ...)
* Design and initial implementation

Amal Gueroudji - CEA ([email protected])
* Deisa plugin creation

Benoit Martin - CEA ([email protected])
* CMake maintainer (Oct. 2024 - ...)
* Deisa plugin refactoring

Tomasz Paluszkiewicz - PSNC ([email protected])
The scientific/academic work is financed from financial resources for science
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
* NetCDF plugin now support the size_of attribute, fixes
[#446](https://gitlab.maisondelasimulation.fr/pdidev/pdi/-/issues/446)
* Deisa plugin for in-situ analysis using Dask

### Changed
* Replaced the astyle based indentation by a clang-format one, fixes
Expand Down
19 changes: 19 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ option(BUILD_SERIALIZE_PLUGIN "Build Serialize plug-in" ON)
option(BUILD_SHARED_LIBS "Build shared libraries rather than static ones" ON)
option(BUILD_TRACE_PLUGIN "Build Trace plugin" ON)
option(BUILD_USER_CODE_PLUGIN "Build User-code plugin" ON)
option(BUILD_DEISA_PLUGIN "Build Deisa plug-in" OFF)



Expand Down Expand Up @@ -113,6 +114,9 @@ endif()
if("${BUILD_DECL_NETCDF_PLUGIN}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/decl_netcdf/cmake")
endif()
if("${BUILD_DEISA_PLUGIN}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/deisa/cmake")
endif()
if("${BUILD_MPI_PLUGIN}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/plugins/mpi/cmake")
endif()
Expand Down Expand Up @@ -175,6 +179,14 @@ if("${BUILD_DECL_NETCDF_PLUGIN}" AND "${BUILD_NETCDF_PARALLEL}" AND NOT "${BUILD
)
endif()

if("${BUILD_DEISA_PLUGIN}" AND NOT "${BUILD_PYTHON}")
message(FATAL_ERROR
"Deisa plugin is enabled but Python support is disabled.\n"
" you have the following options:\n"
" * enable Python support => pass `-DBUILD_PYTHON=ON' to cmake\n"
" * do not build the Deisa plugin => pass `-DBUILD_DEISA_PLUGIN=OFF' to cmake"
)
endif()


### Dependencies
Expand Down Expand Up @@ -501,6 +513,13 @@ sbuild_add_module(USER_CODE_PLUGIN
)


sbuild_add_module(DEISA_PLUGIN
ENABLE_BUILD_FLAG BUILD_DEISA_PLUGIN
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/plugins/deisa"
DEPENDS PDI
)


sbuild_add_module(PDI_EXAMPLE
ENABLE_BUILD_FLAG BUILD_TESTING
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/example"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ PDI distribution is made of the following submodules:
* `pdi/` : the PDI library,
* `plugins/decl_hdf5/`: the Decl'HDF5 plugin,
* `plugins/decl_netcdf/`: the Decl'NetCDF plugin,
* `plugins/deisa/`: the Deisa plugin,
* `plugins/mpi/`: the MPI plugin,
* `plugins/pycall/`: the Pycall plugin,
* `plugins/serialize/`: the serialize plugin,
Expand Down
3 changes: 3 additions & 0 deletions example/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Mohamed Gaalich - CEA ([email protected])
* Added Fortran example
* Added FTI example

Benoit Martin - CEA ([email protected])
* Added Deisa example

Tomasz Paluszkiewicz - PSNC ([email protected])
The scientific/academic work is financed from financial resources for science
in the years 2016 - 2018 granted for the realization of the international
Expand Down
33 changes: 33 additions & 0 deletions example/deisa.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# duration in seconds
duration: 0.75
# global [height, width] (excluding boundary conditions or ghosts)
datasize: [60, 12]
# degree of parallelism
parallelism: { height: 3, width: 1 }

# only the following config is passed to PDI
pdi:
metadata: # type of small values for which PDI keeps a copy
iter: int # current iteration id
dsize: { size: 2, type: array, subtype: int } # local data size including ghosts/boundary
psize: { size: 2, type: array, subtype: int } # number of processes in each dimension
pcoord: { size: 2, type: array, subtype: int } # coordinate of the process
data: # type of values for which PDI does not keep a copy
main_field: { size: [ '$dsize[0]', '$dsize[1]' ], type: array, subtype: double }

plugins:
mpi:
deisa:
scheduler_info: /tmp/scheduler.json
init_on: main_loop
time_step: $iter
deisa_arrays:
global_t: # Name of the Deisa array
type: array
subtype: double
size: [ 10, '$psize[0]*($dsize[0]-2)', '$psize[1]*($dsize[1]-2)' ] # first dimension corresponds to time steps
subsize: [ 1, '$dsize[0]-2', '$dsize[1]-2' ]
start: [ $iter, '($dsize[0]-2)*$pcoord[0]', '($dsize[1]-2)*$pcoord[1]' ]
+timedim: 0
map_in:
main_field: global_t # `main_field` is mapped to `global_t`
26 changes: 26 additions & 0 deletions example/deisa_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from deisa import Deisa

# Scheduler file name and configuration file
scheduler_info = '/tmp/scheduler.json'

# Initialize Deisa
deisa = Deisa(scheduler_info, nb_workers=1, use_ucx=False)

# either: Get data descriptor as a list of Deisa arrays object
arrays = deisa.get_deisa_arrays()

# Select data
gt = arrays["global_t"][...]

# Check contract
arrays.check_contract()


##########################
# Perform analysis here
##########################


arrays.validate_contract()

deisa.wait_for_last_bridge_and_shutdown()
3 changes: 2 additions & 1 deletion example/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ int main(int argc, char* argv[])
int pcoord[2];
MPI_Cart_coords(cart_com, pcoord_1d, 2, pcoord);

int ii = 0;
PDI_expose("iter", &ii, PDI_OUT);
PDI_expose("dsize", dsize, PDI_OUT);
PDI_expose("psize", psize, PDI_OUT);
PDI_expose("pcoord", pcoord, PDI_OUT);
Expand All @@ -217,7 +219,6 @@ int main(int argc, char* argv[])

PDI_event("main_loop");
double start = MPI_Wtime();
int ii;
int next_reduce = 0;
for (ii = 0;; ++ii) {
PDI_multi_expose("newiter", "iter", &ii, PDI_INOUT, "main_field", cur, PDI_INOUT, NULL);
Expand Down
1 change: 1 addition & 0 deletions pdi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to
#### Added
* Add the `Context::find()` method.
[#445](https://gitlab.maisondelasimulation.fr/pdidev/pdi/-/issues/445)
* Add the `pybind11::dtype to_python(const std::shared_ptr<const Scalar_datatype>& scalar_type)` helper function.

#### Changed
* Update the version of dependencies according to our policy: oldest supported
Expand Down
1 change: 1 addition & 0 deletions pdi/docs/Plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
|:----------------------------------------------------|:------------------------------------------------------------------|
|\subpage Decl_HDF5_plugin "Decl'HDF5 plugin" |Read and write data from HDF5 files in a declarative way. |
|\subpage Decl_NetCDF_plugin "Decl'NetCDF plugin" |Read and write data from NetCDF files in a declarative way. |
|Deisa plugin |Expose data to a Dask analysis script. |
|\subpage mpi_plugin "MPI plugin" |Enables MPI support in %PDI and plugins. |
|\subpage pycall_plugin "Pycall plugin" |Call python scripts from C application |
|\subpage serialize_plugin "Serialize plugin" |Serializes and deserializes shared data. |
Expand Down
1 change: 1 addition & 0 deletions pdi/docs/Source_installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ The following flags define which features of the distribution to enable or not.
|`BUILD_TESTING` |`ON` |Build the tests.|
|`BUILD_TRACE_PLUGIN` |`ON` |Build the Trace plug-in.|
|`BUILD_USER_CODE_PLUGIN` |`ON` |Build the User-code plug-in.|
|`BUILD_DEISA_PLUGIN` |`OFF` |Build the Deisa plug-in.|
|`BUILD_DOCUMENTATION` |`OFF` |Build the documentation website. (devel profile)|
|`BUILD_PYCALL_PLUGIN` |`OFF` |Build Pycall plug-in. (unstable)|
|`BUILD_PYTHON` |`OFF` |Build the Python interface. (unstable)|
Expand Down
7 changes: 7 additions & 0 deletions pdi/include/pdi/python/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ pybind11::object PDI_EXPORT to_python(Ref r, bool force_const = false);
*/
Datatype_sptr PDI_EXPORT python_type(const pybind11::array& a);

/** Convert a Scalar_datatype to a pybind11 data type.
*
* \param scalar_type to convert to pybind11 data type
* \return pybind11 data type for the given scalar type
*/
pybind11::dtype PDI_EXPORT to_python(const std::shared_ptr<const Scalar_datatype>& scalar_type);

} // namespace PDI

#endif // PDI_PYTHON_TOOLS_H_
102 changes: 49 additions & 53 deletions pdi/src/python/tools.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "config.h"

#include <cstdint>
#include <memory>
#include <vector>

#include "pdi/array_datatype.h"
Expand Down Expand Up @@ -92,59 +93,7 @@ pybind11::object to_python(Ref r, bool force_const)
auto&& scalar_type = dynamic_pointer_cast<const Scalar_datatype>(subtype);
if (ndim) strides.emplace_back(scalar_type->buffersize());

pybind11::dtype pytype;
switch (scalar_type->kind()) {
case Scalar_kind::FLOAT: {
switch (scalar_type->datasize()) {
case sizeof(float):
pytype = pybind11::dtype::of<float>();
break;
case sizeof(double):
pytype = pybind11::dtype::of<double>();
break;
default:
throw Type_error{"Unable to pass {} bytes floating point value to python", scalar_type->datasize()};
}
} break;
case Scalar_kind::SIGNED: {
switch (scalar_type->datasize()) {
case sizeof(int8_t):
pytype = pybind11::dtype::of<int8_t>();
break;
case sizeof(int16_t):
pytype = pybind11::dtype::of<int16_t>();
break;
case sizeof(int32_t):
pytype = pybind11::dtype::of<int32_t>();
break;
case sizeof(int64_t):
pytype = pybind11::dtype::of<int64_t>();
break;
default:
throw Type_error{"Unable to pass {} bytes integer value to python", scalar_type->datasize()};
}
} break;
case Scalar_kind::UNSIGNED: {
switch (scalar_type->datasize()) {
case sizeof(uint8_t):
pytype = pybind11::dtype::of<uint8_t>();
break;
case sizeof(uint16_t):
pytype = pybind11::dtype::of<uint16_t>();
break;
case sizeof(uint32_t):
pytype = pybind11::dtype::of<uint32_t>();
break;
case sizeof(uint64_t):
pytype = pybind11::dtype::of<uint64_t>();
break;
default:
throw Type_error{"Unable to pass {} bytes unsigned integer value to python", scalar_type->datasize()};
}
} break;
default:
throw Type_error{"Unable to pass value of unexpected type to python"};
}
pybind11::dtype pytype = to_python(scalar_type);

ssize_t cumulated_stride = 1;
for (auto&& stride = strides.rbegin(); stride != strides.rend(); ++stride) {
Expand Down Expand Up @@ -221,4 +170,51 @@ Datatype_sptr python_type(const pybind11::array& a)
return result;
}

pybind11::dtype to_python(const std::shared_ptr<const Scalar_datatype>& scalar_type)
{
switch (scalar_type->kind()) {
case Scalar_kind::FLOAT: {
switch (scalar_type->datasize()) {
case sizeof(float):
return pybind11::dtype::of<float>();
case sizeof(double):
return pybind11::dtype::of<double>();
default:
throw Type_error{"Unable to pass {} bytes floating point value to python", scalar_type->datasize()};
}
} break;
case Scalar_kind::SIGNED: {
switch (scalar_type->datasize()) {
case sizeof(int8_t):
return pybind11::dtype::of<int8_t>();
case sizeof(int16_t):
return pybind11::dtype::of<int16_t>();
case sizeof(int32_t):
return pybind11::dtype::of<int32_t>();
case sizeof(int64_t):
return pybind11::dtype::of<int64_t>();
default:
throw Type_error{"Unable to pass {} bytes integer value to python", scalar_type->datasize()};
}
} break;
case Scalar_kind::UNSIGNED: {
switch (scalar_type->datasize()) {
case sizeof(uint8_t):
return pybind11::dtype::of<uint8_t>();
case sizeof(uint16_t):
return pybind11::dtype::of<uint16_t>();
case sizeof(uint32_t):
return pybind11::dtype::of<uint32_t>();
case sizeof(uint64_t):
return pybind11::dtype::of<uint64_t>();
default:
throw Type_error{"Unable to pass {} bytes unsigned integer value to python", scalar_type->datasize()};
}
} break;
default:
throw Type_error{"Unable to pass value of unexpected type to python"};
}
}


} // namespace PDI
39 changes: 39 additions & 0 deletions plugins/deisa/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#=============================================================================
# Copyright (c) 2020-2024 Centre national de la recherche scientifique (CNRS)
# Copyright (c) 2020-2024 Commissariat a l'énergie atomique et aux énergies alternatives (CEA)
# Copyright (c) 2020-2023 Institut national de recherche en informatique et en automatique (Inria)
# Copyright (c) 2020-2024 Université Paris-Saclay
# Copyright (c) 2020-2024 Université de Versailles Saint-Quentin-en-Yvelines
#
# SPDX-License-Identifier: MIT
#=============================================================================

cmake_minimum_required(VERSION 3.16...3.29)
project(pdi_deisa_plugin LANGUAGES C CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")

include(GNUInstallDirs)

find_package(Python3Path 3.8.2 REQUIRED COMPONENTS Interpreter Development)

# PyBind11
set(Python_ADDITIONAL_VERSIONS "${Python3_VERSION}" CACHE STRING "Python version found by FindPython3 for coherency" FORCE)
set(PYBIND11_PYTHON_VERSION "${Python3_VERSION}" CACHE STRING "Python version to use for compiling modules" FORCE)
find_package(pybind11 2.4.3 REQUIRED)

# PDI
find_package(PDI REQUIRED COMPONENTS plugins pysupport)
find_package(MPI REQUIRED COMPONENTS CXX)

# The plugin
add_library(pdi_deisa_plugin MODULE deisa.cxx)
target_link_libraries(pdi_deisa_plugin PUBLIC PDI::PDI_plugins PDI::PDI_pysupport pybind11::embed MPI::MPI_CXX)
set_target_properties(pdi_deisa_plugin PROPERTIES
CXX_STANDARD_REQUIRED TRUE
CXX_VISIBILITY_PRESET hidden)

# installation
set(INSTALL_PDIPLUGINDIR "${PDI_DEFAULT_PLUGINDIR}" CACHE PATH "PDI plugins (${PDI_DEFAULT_PLUGINDIR})")
install(TARGETS pdi_deisa_plugin
LIBRARY DESTINATION "${INSTALL_PDIPLUGINDIR}"
)
Loading

0 comments on commit 6db69d2

Please sign in to comment.