Skip to content
Snippets Groups Projects
Commit a8ef83a3 authored by Pradipta Samanta's avatar Pradipta Samanta
Browse files

added c++ code for mo_lib_interpolation_vector

parent 14acf1aa
No related branches found
No related tags found
1 merge request!37Draft: C++ port of horizontal/mo_lib_gradients.F90
...@@ -13,6 +13,7 @@ add_library( ...@@ -13,6 +13,7 @@ add_library(
iconmath-interpolation iconmath-interpolation
mo_lib_interpolation_scalar.F90 mo_lib_interpolation_scalar.F90
mo_lib_interpolation_vector.F90 mo_lib_interpolation_vector.F90
mo_lib_interpolation_vector.cpp
mo_lib_intp_rbf.F90) mo_lib_intp_rbf.F90)
add_library(${PROJECT_NAME}::interpolation ALIAS iconmath-interpolation) add_library(${PROJECT_NAME}::interpolation ALIAS iconmath-interpolation)
...@@ -55,10 +56,20 @@ target_include_directories( ...@@ -55,10 +56,20 @@ target_include_directories(
$<INSTALL_INTERFACE:$<$<COMPILE_LANGUAGE:Fortran>:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>> $<INSTALL_INTERFACE:$<$<COMPILE_LANGUAGE:Fortran>:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>>
# Path to internal include directory # Path to internal include directory
$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:Fortran>:${PROJECT_SOURCE_DIR}/include>> $<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:Fortran>:${PROJECT_SOURCE_DIR}/include>>
# Path to the internal C/C++ headers (for testing): Requires CMake 3.15+ for
# multiple compile languages
# https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html
$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:C,CXX>:${CMAKE_CURRENT_SOURCE_DIR}>>
PRIVATE
# Path to config.h (for C and C++ only): Requires CMake 3.15+ for multiple
# compile languages
# https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html
$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:C,CXX>:${CMAKE_CURRENT_BINARY_DIR}>>
) )
target_link_libraries(iconmath-interpolation PUBLIC fortran-support::fortran-support) target_link_libraries(iconmath-interpolation PUBLIC fortran-support::fortran-support)
target_link_libraries(iconmath-interpolation PUBLIC iconmath-support) target_link_libraries(iconmath-interpolation PUBLIC iconmath-support)
target_link_libraries(iconmath-interpolation PRIVATE Kokkos::kokkos)
install(TARGETS iconmath-interpolation EXPORT "${PROJECT_NAME}-targets") install(TARGETS iconmath-interpolation EXPORT "${PROJECT_NAME}-targets")
......
#include "mo_lib_loopindices.hpp"
#include "mo_lib_interpolation_vector.hpp"
// The templated C++ function using Kokkos.
// Raw pointer arguments are wrapped into unmanaged Kokkos::Views.
// Note: The dimensions below must match the Fortran arrays.
// - p_vn_in and p_vt_in: dimensions [nproma, nlev, nblks_e]
// - cell_edge_idx and cell_edge_blk: dimensions [nproma, nblks_c, 3]
// - e_bln_c_u and e_bln_c_v: dimensions [nproma, 6, nblks_c]
// - p_u_out and p_v_out: dimensions [nproma, nlev, nblks_c]
template <typename T>
void edges2cells_vector_lib(
const T* p_vn_in, const T* p_vt_in,
const int* cell_edge_idx, const int* cell_edge_blk,
const T* e_bln_c_u, const T* e_bln_c_v,
T* p_u_out, T* p_v_out,
// Additional integer parameters.
int i_startblk, int i_endblk,
int i_startidx_in, int i_endidx_in,
int slev, int elev,
int nproma,
// Dimensions for the arrays.
int nlev, int nblks_e, int nblks_c)
{
// Wrap raw pointers in unmanaged Kokkos Views.
typedef Kokkos::View<const T***, Kokkos::LayoutLeft, Kokkos::MemoryUnmanaged> UnmanagedConstT3D;
typedef Kokkos::View<T***, Kokkos::LayoutLeft, Kokkos::MemoryUnmanaged> UnmanagedT3D;
typedef Kokkos::View<const int***, Kokkos::LayoutLeft, Kokkos::MemoryUnmanaged> UnmanagedConstInt3D;
UnmanagedConstT3D p_vn_in_view(p_vn_in, nproma, nlev, nblks_e);
UnmanagedConstT3D p_vt_in_view(p_vt_in, nproma, nlev, nblks_e);
UnmanagedConstInt3D cell_edge_idx_view(cell_edge_idx, nproma, nblks_c, 3);
UnmanagedConstInt3D cell_edge_blk_view(cell_edge_blk, nproma, nblks_c, 3);
UnmanagedConstT3D e_bln_c_u_view(e_bln_c_u, nproma, 6, nblks_c);
UnmanagedConstT3D e_bln_c_v_view(e_bln_c_v, nproma, 6, nblks_c);
UnmanagedT3D p_u_out_view(p_u_out, nproma, nlev, nblks_c);
UnmanagedT3D p_v_out_view(p_v_out, nproma, nlev, nblks_c);
// Loop over cell blocks as in the original Fortran code.
for (int jb = i_startblk; jb <= i_endblk; ++jb) {
// Call get_indices_c_lib to get inner loop indices for block jb.
int i_startidx, i_endidx;
get_indices_c_lib(i_startidx_in, i_endidx_in, nproma,
jb, i_startblk, i_endblk,
i_startidx, i_endidx);
Kokkos::MDRangePolicy<Kokkos::Rank<2>> innerPolicy(
{slev, i_startidx}, {elev + 1, i_endidx + 1});
Kokkos::parallel_for("edges2cells_inner", innerPolicy,
KOKKOS_LAMBDA(const int jk, const int jc) {
// Compute the bilinear interpolation for cell (jc, jk, jb).
p_u_out_view(jc, jk, jb) =
e_bln_c_u_view(jc, 0, jb) *
p_vn_in_view(cell_edge_idx_view(jc, jb, 0) - 1, jk, cell_edge_blk_view(jc, jb, 0) - 1) +
e_bln_c_u_view(jc, 1, jb) *
p_vt_in_view(cell_edge_idx_view(jc, jb, 0) - 1, jk, cell_edge_blk_view(jc, jb, 0) - 1) +
e_bln_c_u_view(jc, 2, jb) *
p_vn_in_view(cell_edge_idx_view(jc, jb, 1) - 1, jk, cell_edge_blk_view(jc, jb, 1) - 1) +
e_bln_c_u_view(jc, 3, jb) *
p_vt_in_view(cell_edge_idx_view(jc, jb, 1) - 1, jk, cell_edge_blk_view(jc, jb, 1) - 1) +
e_bln_c_u_view(jc, 4, jb) *
p_vn_in_view(cell_edge_idx_view(jc, jb, 2) - 1, jk, cell_edge_blk_view(jc, jb, 2) - 1) +
e_bln_c_u_view(jc, 5, jb) *
p_vt_in_view(cell_edge_idx_view(jc, jb, 2) - 1, jk, cell_edge_blk_view(jc, jb, 2) - 1);
p_v_out_view(jc, jk, jb) =
e_bln_c_v_view(jc, 0, jb) *
p_vn_in_view(cell_edge_idx_view(jc, jb, 0) - 1, jk, cell_edge_blk_view(jc, jb, 0) - 1) +
e_bln_c_v_view(jc, 1, jb) *
p_vt_in_view(cell_edge_idx_view(jc, jb, 0) - 1, jk, cell_edge_blk_view(jc, jb, 0) - 1) +
e_bln_c_v_view(jc, 2, jb) *
p_vn_in_view(cell_edge_idx_view(jc, jb, 1) - 1, jk, cell_edge_blk_view(jc, jb, 1) - 1) +
e_bln_c_v_view(jc, 3, jb) *
p_vt_in_view(cell_edge_idx_view(jc, jb, 1) - 1, jk, cell_edge_blk_view(jc, jb, 1) - 1) +
e_bln_c_v_view(jc, 4, jb) *
p_vn_in_view(cell_edge_idx_view(jc, jb, 2) - 1, jk, cell_edge_blk_view(jc, jb, 2) - 1) +
e_bln_c_v_view(jc, 5, jb) *
p_vt_in_view(cell_edge_idx_view(jc, jb, 2) - 1, jk, cell_edge_blk_view(jc, jb, 2) - 1);
});
// Optionally fence after each block if required.
Kokkos::fence();
}
}
extern "C" void edges2cells_vector_lib_dp(
const double* p_vn_in, const double* p_vt_in,
const int* cell_edge_idx, const int* cell_edge_blk,
const double* e_bln_c_u, const double* e_bln_c_v,
double* p_u_out, double* p_v_out,
int i_startblk, int i_endblk,
int i_startidx_in, int i_endidx_in,
int slev, int elev,
int nproma,
int nlev, int nblks_e, int nblks_c)
{
edges2cells_vector_lib<double>(p_vn_in, p_vt_in,
cell_edge_idx, cell_edge_blk,
e_bln_c_u, e_bln_c_v,
p_u_out, p_v_out,
i_startblk, i_endblk,
i_startidx_in, i_endidx_in,
slev, elev,
nproma,
nlev, nblks_e, nblks_c);
}
extern "C" void edges2cells_vector_lib_sp(
const float* p_vn_in, const float* p_vt_in,
const int* cell_edge_idx, const int* cell_edge_blk,
const float* e_bln_c_u, const float* e_bln_c_v,
float* p_u_out, float* p_v_out,
int i_startblk, int i_endblk,
int i_startidx_in, int i_endidx_in,
int slev, int elev,
int nproma,
int nlev, int nblks_e, int nblks_c)
{
edges2cells_vector_lib<float>(p_vn_in, p_vt_in,
cell_edge_idx, cell_edge_blk,
e_bln_c_u, e_bln_c_v,
p_u_out, p_v_out,
i_startblk, i_endblk,
i_startidx_in, i_endidx_in,
slev, elev,
nproma,
nlev, nblks_e, nblks_c);
}
#include <Kokkos_Core.hpp>
#include <vector>
template <typename T>
void edges2cells_vector_lib(
const T* p_vn_in, const T* p_vt_in,
const int* cell_edge_idx, const int* cell_edge_blk,
const T* e_bln_c_u, const T* e_bln_c_v,
T* p_u_out, T* p_v_out,
// Additional integer parameters.
int i_startblk, int i_endblk,
int i_startidx_in, int i_endidx_in,
int slev, int elev,
int nproma,
// Dimensions for the arrays.
int nlev, int nblks_e, int nblks_c);
extern "C" void edges2cells_vector_lib_dp(
const double* p_vn_in, const double* p_vt_in,
const int* cell_edge_idx, const int* cell_edge_blk,
const double* e_bln_c_u, const double* e_bln_c_v,
double* p_u_out, double* p_v_out,
int i_startblk, int i_endblk,
int i_startidx_in, int i_endidx_in,
int slev, int elev,
int nproma,
int nlev, int nblks_e, int nblks_c);
extern "C" void edges2cells_vector_lib_sp(
const float* p_vn_in, const float* p_vt_in,
const int* cell_edge_idx, const int* cell_edge_blk,
const float* e_bln_c_u, const float* e_bln_c_v,
float* p_u_out, float* p_v_out,
int i_startblk, int i_endblk,
int i_startidx_in, int i_endidx_in,
int slev, int elev,
int nproma,
int nlev, int nblks_e, int nblks_c);
extern "C" {
// get_indices_c_lib function
void get_indices_c_lib(int i_startidx_in, int i_endidx_in, int nproma, int i_blk, int i_startblk, int i_endblk,
int &i_startidx_out, int &i_endidx_out);
void get_indices_e_lib(int i_startidx_in, int i_endidx_in, int nproma, int i_blk, int i_startblk, int i_endblk,
int &i_startidx_out, int &i_endidx_out);
void get_indices_v_lib(int i_startidx_in, int i_endidx_in, int nproma, int i_blk, int i_startblk, int i_endblk,
int &i_startidx_out, int &i_endidx_out);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment