Skip to content

Commit 307ddfe

Browse files
authored
Merge pull request #178 from Fuad-HH/mergecfortapi
C and Fortran API for Interpolator
2 parents b747946 + b7eee41 commit 307ddfe

29 files changed

+4416
-113
lines changed

.github/workflows/cmake-test.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ jobs:
8282
with:
8383
repo-name: 'omega_h'
8484
repo-path: 'SCOREC/omega_h'
85-
repo-ref: 'scorec-v11.0.0'
85+
# set this to a version number when the following issue is closed
86+
# https://github.com/SCOREC/omega_h/issues/195
87+
repo-ref: 'f1eae45f11a166b3f01e2dace233643711ec92be'
8688
cache: true
8789
options: '-DCMAKE_CXX_COMPILER=`which mpicxx`
8890
-DCMAKE_C_COMPILER=`which mpicc`
@@ -98,7 +100,7 @@ jobs:
98100
with:
99101
repo-name: 'meshFields'
100102
repo-path: 'SCOREC/meshFields'
101-
repo-ref: ''
103+
repo-ref: 'b1482bbba288df210784b2345eae08e34faabdc4'
102104
cache: true
103105
options: '-DCMAKE_CXX_COMPILER=`which mpicxx`
104106
-DCMAKE_C_COMPILER=`which mpicc`
@@ -221,16 +223,25 @@ jobs:
221223
run: ctest --test-dir ${{ runner.temp }}/build-pcms --output-on-failure
222224

223225
- name: Print Test
226+
if: always()
224227
run: cat ${{ runner.temp }}/build-pcms/Testing/Temporary/LastTest.log
225228

226229
- name: Test PCMS Installation
227230
shell: bash
228231
run: |
229232
# Configure and build the test
230233
# it should only ask for pcms_DIR/ROOT to find all dependencies
234+
ls ${{ runner.temp }}/build-pcms/install/lib/cmake/pcms
235+
echo "-------- PCMS CONFIG -------------"
236+
cat ${{ runner.temp }}/build-pcms/install/lib/cmake/pcms/pcms-config.cmake
237+
echo "-------- PCMS TARGETS -------------"
238+
cat ${{ runner.temp }}/build-pcms/install/lib/cmake/pcms/pcms-targets.cmake
239+
echo "-------- PCMS INTERPOLATOR TARGETS -------------"
240+
cat ${{ runner.temp }}/build-pcms/install/lib/cmake/pcms/pcms_interpolator-targets.cmake
241+
export VERBOSE=1
231242
cmake \
232243
-B ${{github.workspace}}/examples/external-usage-example/build \
233244
-S ${{github.workspace}}/examples/external-usage-example/ \
234245
-Dpcms_DIR=${{ runner.temp }}/build-pcms/install/lib/cmake/pcms \
235-
246+
--debug-output
236247
cmake --build ${{github.workspace}}/examples/external-usage-example/build

config.cmake.in

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
include(CMakeFindDependencyMacro)
44
find_dependency(redev CONFIG HINTS @redev_DIR@)
55
find_dependency(Kokkos CONFIG HINTS @Kokkos_DIR@)
6+
find_dependency(KokkosKernels CONFIG HINTS @KokkosKernels_DIR@)
67
find_dependency(meshfields CONFIG HINTS @meshfields_DIR@)
78
find_dependency(ADIOS2 CONFIG HINTS @ADIOS2_DIR@)
89
find_dependency(MPI)
@@ -16,14 +17,20 @@ if(@PCMS_ENABLE_OMEGA_H@)
1617
endif()
1718

1819
include("${CMAKE_CURRENT_LIST_DIR}/pcms_core-targets.cmake")
20+
include("${CMAKE_CURRENT_LIST_DIR}/pcms_interpolator-targets.cmake")
21+
1922
if(@PCMS_ENABLE_C@)
23+
include("${CMAKE_CURRENT_LIST_DIR}/pcms_capi_core-targets.cmake")
24+
include("${CMAKE_CURRENT_LIST_DIR}/pcms_capi_interpolator-targets.cmake")
2025
include("${CMAKE_CURRENT_LIST_DIR}/pcms_capi-targets.cmake")
2126
endif()
27+
2228
if(@PCMS_ENABLE_Fortran@)
29+
include("${CMAKE_CURRENT_LIST_DIR}/pcms_fortranapi_core-targets.cmake")
30+
include("${CMAKE_CURRENT_LIST_DIR}/pcms_fortranapi_interpolator-targets.cmake")
2331
include("${CMAKE_CURRENT_LIST_DIR}/pcms_fortranapi-targets.cmake")
2432
endif()
2533

2634
include("${CMAKE_CURRENT_LIST_DIR}/pcms-targets.cmake")
27-
include("${CMAKE_CURRENT_LIST_DIR}/pcms_interpolator-targets.cmake")
2835
# must be called at the end of the config file
2936
check_required_components(pcms)

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ if(PCMS_ENABLE_Fortran)
148148
endif()
149149

150150
add_subdirectory(pcms/interpolator)
151+
target_link_libraries(pcms_pcms INTERFACE pcms::interpolator)
151152

152153
install(
153154
TARGETS pcms_pcms

src/pcms/capi/CMakeLists.txt

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,45 @@
1-
add_library(pcms_capi client.cpp kokkos.cpp)
2-
add_library(pcms::capi ALIAS pcms_capi)
1+
add_library(pcms_capi_core client.cpp kokkos.cpp)
2+
add_library(pcms::capi::core ALIAS pcms_capi_core)
3+
34
target_link_libraries(
4-
pcms_capi
5+
pcms_capi_core
56
PUBLIC MPI::MPI_C
67
PRIVATE pcms::core)
78

89
target_include_directories(
9-
pcms_capi
10+
pcms_capi_core
1011
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..>" # this makes our
1112
# include path
1213
# pcms/capi
1314
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/pcms/capi>")
1415

15-
set(CAPI_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/client.h
16+
set(CAPI_CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/client.h
1617
${CMAKE_CURRENT_SOURCE_DIR}/kokkos.h)
1718
set_target_properties(
18-
pcms_capi PROPERTIES PUBLIC_HEADER "${CAPI_HEADERS}" OUTPUT_NAME pcmscapi
19-
EXPORT_NAME capi)
19+
pcms_capi_core PROPERTIES PUBLIC_HEADER "${CAPI_CORE_HEADERS}" OUTPUT_NAME pcmscapicore
20+
EXPORT_NAME capi::core)
21+
22+
add_library(pcms_capi_interpolator mesh.cpp interpolator.cpp kokkos.cpp)
23+
add_library(pcms::capi::interpolator ALIAS pcms_capi_interpolator)
24+
target_link_libraries(pcms_capi_interpolator PUBLIC MPI::MPI_C PRIVATE pcms::interpolator)
25+
target_include_directories(pcms_capi_interpolator
26+
PUBLIC
27+
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..>" # this makes the module path cpms/capi
28+
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/pcms/capi>")
29+
set(CAPI_INTERPOLATOR_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/interpolator.h
30+
${CMAKE_CURRENT_SOURCE_DIR}/mesh.h)
31+
set_target_properties(pcms_capi_interpolator
32+
PROPERTIES PUBLIC_HEADERS "${CAPI_INTERPOLATOR_HEADERS}"
33+
OUTPUT_NAME pcmscapiinterpolator
34+
EXPORT_NAME capi::interpolator)
35+
36+
# high level interface target
37+
add_library(pcms_capi INTERFACE)
38+
add_library(pcms::capi ALIAS pcms_capi)
39+
set_target_properties(pcms_capi PROPERTIES EXPORT_NAME capi)
40+
# link capi libraries to a high level interface library
41+
target_link_libraries(pcms_capi INTERFACE pcms::capi::core)
42+
target_link_libraries(pcms_capi INTERFACE pcms::capi::interpolator)
2043
install(
2144
TARGETS pcms_capi
2245
EXPORT pcms_capi-targets
@@ -25,8 +48,37 @@ install(
2548
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
2649
INCLUDES
2750
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
28-
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/pcms/capi/)
51+
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/pcms)
2952
install(
3053
EXPORT pcms_capi-targets
3154
NAMESPACE pcms::
3255
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pcms)
56+
57+
# library targets
58+
install(
59+
TARGETS pcms_capi_core
60+
EXPORT pcms_capi_core-targets
61+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
62+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
63+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
64+
INCLUDES
65+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
66+
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/pcms/capi/)
67+
install(
68+
EXPORT pcms_capi_core-targets
69+
NAMESPACE pcms::
70+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pcms)
71+
72+
install(
73+
TARGETS pcms_capi_interpolator
74+
EXPORT pcms_capi_interpolator-targets
75+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
76+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
77+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
78+
INCLUDES
79+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
80+
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/pcms/capi/)
81+
install(
82+
EXPORT pcms_capi_interpolator-targets
83+
NAMESPACE pcms::
84+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pcms)

src/pcms/capi/interpolator.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
//
2+
// Created by hasanm4 on 2/17/25.
3+
//
4+
#include <pcms/capi/kokkos.h>
5+
#include <pcms/capi/interpolator.h>
6+
#include <pcms/interpolator/interpolation_base.h>
7+
#include <Omega_h_file.hpp>
8+
#include <Omega_h_library.hpp>
9+
#include <Omega_h_mesh.hpp>
10+
#include <pcms/print.h>
11+
12+
//[[nodiscard]]
13+
PcmsInterpolatorHandle pcms_create_interpolator(PcmsOmegaHMeshHandle oh_mesh,
14+
double radius)
15+
{
16+
auto* source_mesh = reinterpret_cast<Omega_h::Mesh*>(oh_mesh.mesh_handle);
17+
auto* interpolator = new MLSMeshInterpolation(*source_mesh, radius);
18+
return {reinterpret_cast<void*>(interpolator)};
19+
}
20+
21+
PcmsInterpolatorHandle pcms_create_point_based_interpolator(
22+
void* source_points, int source_points_size, void* target_points,
23+
int target_points_size, double radius, int degree, int min_req_supports,
24+
double lambda, double decay_factor)
25+
{
26+
27+
auto source_points_view = pcms::Rank1View<double, pcms::HostMemorySpace>(
28+
reinterpret_cast<double*>(source_points), source_points_size);
29+
auto target_points_view = pcms::Rank1View<double, pcms::HostMemorySpace>(
30+
reinterpret_cast<double*>(target_points), target_points_size);
31+
auto* interpolator = new MLSPointCloudInterpolation(
32+
source_points_view, target_points_view, 2, radius, min_req_supports, degree,
33+
true, lambda, decay_factor);
34+
return {reinterpret_cast<void*>(interpolator)};
35+
}
36+
37+
Omega_h::HostRead<Omega_h::Real> read_mesh_centroids(const char* mesh_filename,
38+
int& num_elements)
39+
{
40+
auto fname = std::string(mesh_filename);
41+
fname = fname.erase(fname.find_last_not_of(" \n\r\t") + 1);
42+
pcms::printInfo("The interpolator got dg2 mesh file: %s\n", fname.c_str());
43+
auto mesh_lib = Omega_h::Library(nullptr, nullptr, MPI_COMM_SELF);
44+
auto mesh = Omega_h::binary::read(fname, mesh_lib.world());
45+
auto elem_centroids = getCentroids(mesh);
46+
num_elements = mesh.nelems();
47+
OMEGA_H_CHECK_PRINTF(num_elements * 2 == elem_centroids.size(),
48+
"Mesh element centroids size does not match the number "
49+
"of elements %d != %d\n",
50+
num_elements * 2, elem_centroids.size());
51+
52+
pcms::printInfo("Number of element centroids: %d\n",
53+
elem_centroids.size() / 2);
54+
OMEGA_H_CHECK_PRINTF(mesh.dim() == 2, "Mesh dimension is not 2D %d\n",
55+
mesh.dim());
56+
57+
return {elem_centroids};
58+
}
59+
60+
void write_void_int_pointer(void* pointer, int value)
61+
{
62+
if (pointer) {
63+
int* dg2_elem_count_int = reinterpret_cast<int*>(pointer);
64+
*dg2_elem_count_int = value;
65+
} else {
66+
pcms::printError("Error: NULL pointer provided to write integer value\n");
67+
}
68+
}
69+
70+
PcmsInterpolatorHandle pcms_create_degas2xgcnode_interpolator(
71+
void* target_points, int target_points_size, const char* dg2_mesh_filename,
72+
double radius, void* dg2_elem_count, int degree, int min_req_supports,
73+
double lambda, double decay_factor)
74+
{
75+
// same as above pcms_create_degas2xgc_interpolator but the target points are
76+
// provided by the user this is useful when the corresponding xgc mesh is not
77+
// available
78+
79+
int dg2_num_elems = 0;
80+
Omega_h::HostRead<Omega_h::Real> dg2_elem_centroids_host =
81+
read_mesh_centroids(dg2_mesh_filename, dg2_num_elems);
82+
write_void_int_pointer(dg2_elem_count, dg2_num_elems);
83+
84+
return pcms_create_point_based_interpolator(
85+
(void*)dg2_elem_centroids_host.data(), dg2_elem_centroids_host.size(),
86+
target_points, target_points_size, radius, degree, min_req_supports, lambda,
87+
decay_factor);
88+
}
89+
90+
PcmsInterpolatorHandle pcms_create_xgcnodedegas2_interpolator(
91+
const char* dg2_mesh_filename, void* source_points, int source_points_size,
92+
double radius, void* dg2_elem_count, int degree, int min_req_supports,
93+
double lambda, double decay_factor)
94+
{
95+
int dg2_num_elems = 0;
96+
Omega_h::HostRead<Omega_h::Real> dg2_elem_centroids_host =
97+
read_mesh_centroids(dg2_mesh_filename, dg2_num_elems);
98+
write_void_int_pointer(dg2_elem_count, dg2_num_elems);
99+
100+
return pcms_create_point_based_interpolator(
101+
source_points, source_points_size, (void*)dg2_elem_centroids_host.data(),
102+
dg2_elem_centroids_host.size(), radius, degree, min_req_supports, lambda,
103+
decay_factor);
104+
}
105+
106+
void pcms_destroy_interpolator(PcmsInterpolatorHandle interpolator)
107+
{
108+
if (interpolator.pointer != nullptr) {
109+
delete reinterpret_cast<InterpolationBase*>(interpolator.pointer);
110+
}
111+
}
112+
113+
void pcms_interpolate(PcmsInterpolatorHandle interpolator, void* input,
114+
int input_size, void* output, int output_size)
115+
{
116+
auto* mls_interpolator =
117+
reinterpret_cast<InterpolationBase*>(interpolator.pointer);
118+
119+
OMEGA_H_CHECK_PRINTF(
120+
input_size == mls_interpolator->getSourceSize(),
121+
"Input array size does not match the source size %d != %zu\n", input_size,
122+
mls_interpolator->getSourceSize());
123+
OMEGA_H_CHECK_PRINTF(
124+
output_size == mls_interpolator->getTargetSize(),
125+
"Output array size does not match the target size %d != %zu\n", output_size,
126+
mls_interpolator->getTargetSize());
127+
128+
pcms::Rank1View<double, pcms::HostMemorySpace> input_array(
129+
reinterpret_cast<double*>(input), input_size);
130+
pcms::Rank1View<double, pcms::HostMemorySpace> output_array(
131+
reinterpret_cast<double*>(output), output_size);
132+
133+
mls_interpolator->eval(input_array, output_array);
134+
}

0 commit comments

Comments
 (0)