From 4aa12aae3d57e5a873c3bdcf3a27ca1be268f442 Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Mon, 24 Feb 2025 11:45:13 +0100 Subject: [PATCH 1/3] Remove examples, headers, and docs using cpp_bindgen --- docs_src/manuals/user_manual/interface.hrst | 4 + examples/CMakeLists.txt | 11 -- examples/c_bindings/CMakeLists.txt.in | 106 ------------------ examples/c_bindings/README | 18 --- examples/c_bindings/copy_stencil_wrapper.cpp | 86 -------------- examples/c_bindings/driver.F90 | 49 -------- examples/c_bindings/driver_acc.F90 | 52 --------- examples/c_bindings/driver_cpu.c | 61 ---------- examples/c_bindings/driver_gpu.c | 71 ------------ .../storage/adapter/fortran_array_adapter.hpp | 85 -------------- .../storage/adapter/fortran_array_view.hpp | 69 ------------ tests/regression/CMakeLists.txt | 1 - tests/regression/c_bindings/CMakeLists.txt | 43 ------- tests/regression/c_bindings/driver.c | 68 ----------- tests/regression/c_bindings/fdriver.f90 | 41 ------- .../regression/c_bindings/fdriver_wrapper.f90 | 36 ------ .../regression/c_bindings/implementation.cpp | 66 ----------- .../regression/c_bindings/implementation.f90 | 31 ----- tests/regression/c_bindings/implementation.h | 18 --- .../c_bindings/implementation_wrapper.cpp | 43 ------- .../c_bindings/implementation_wrapper.f90 | 85 -------------- .../c_bindings/implementation_wrapper.h | 16 --- .../unit_tests/storage/adapter/CMakeLists.txt | 18 --- .../adapter/test_fortran_array_adapter.cpp | 87 -------------- 24 files changed, 4 insertions(+), 1161 deletions(-) delete mode 100644 examples/c_bindings/CMakeLists.txt.in delete mode 100644 examples/c_bindings/README delete mode 100644 examples/c_bindings/copy_stencil_wrapper.cpp delete mode 100644 examples/c_bindings/driver.F90 delete mode 100644 examples/c_bindings/driver_acc.F90 delete mode 100644 examples/c_bindings/driver_cpu.c delete mode 100644 examples/c_bindings/driver_gpu.c delete mode 100644 include/gridtools/storage/adapter/fortran_array_adapter.hpp delete mode 100644 include/gridtools/storage/adapter/fortran_array_view.hpp delete mode 100644 tests/regression/c_bindings/CMakeLists.txt delete mode 100644 tests/regression/c_bindings/driver.c delete mode 100644 tests/regression/c_bindings/fdriver.f90 delete mode 100644 tests/regression/c_bindings/fdriver_wrapper.f90 delete mode 100644 tests/regression/c_bindings/implementation.cpp delete mode 100644 tests/regression/c_bindings/implementation.f90 delete mode 100644 tests/regression/c_bindings/implementation.h delete mode 100644 tests/regression/c_bindings/implementation_wrapper.cpp delete mode 100644 tests/regression/c_bindings/implementation_wrapper.f90 delete mode 100644 tests/regression/c_bindings/implementation_wrapper.h delete mode 100644 tests/unit_tests/storage/adapter/test_fortran_array_adapter.cpp diff --git a/docs_src/manuals/user_manual/interface.hrst b/docs_src/manuals/user_manual/interface.hrst index f58f991003..447748099b 100644 --- a/docs_src/manuals/user_manual/interface.hrst +++ b/docs_src/manuals/user_manual/interface.hrst @@ -1,3 +1,5 @@ +TODO: Remove? Or are the instructions still valid for using cpp_bindgen separately? + Interfacing to other programming languages ============================================ @@ -216,6 +218,8 @@ C arrays and ``fortran_array_adapter`` are `fortran_array_wrappable`. The latter Fortran arrays and |GT| storages, such that the user can pass a Fortran array to a C++ function, which then can be transformed into a |GT| storage. +TODO: fortran_array_adapter.hpp is removed + .. code-block:: gridtools #include diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3ec4eddc82..0012538d99 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -36,17 +36,6 @@ if(GT_INSTALL_EXAMPLES) install_example(DIRECTORY boundaries SOURCES boundaries boundaries_provided) - configure_file(c_bindings/CMakeLists.txt.in - ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/c_bindings/CMakeLists.txt @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/c_bindings/CMakeLists.txt - DESTINATION ${GT_INSTALL_EXAMPLES_PATH}/c_bindings) - install( - DIRECTORY c_bindings - DESTINATION ${GT_INSTALL_EXAMPLES_PATH} - PATTERN "CMakeLists.txt.in" EXCLUDE - ) - list(APPEND enabled_examples c_bindings) - configure_file(cmake_skeletons/CMakeLists.txt.driver.in ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeLists.txt @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeLists.txt DESTINATION ${GT_INSTALL_EXAMPLES_PATH}) diff --git a/examples/c_bindings/CMakeLists.txt.in b/examples/c_bindings/CMakeLists.txt.in deleted file mode 100644 index 2cd996f4fd..0000000000 --- a/examples/c_bindings/CMakeLists.txt.in +++ /dev/null @@ -1,106 +0,0 @@ -cmake_minimum_required(VERSION @CMAKE_MINIMUM_REQUIRED_VERSION@) - -# 1) GridTools needs the language CXX -project(GridTools-examples LANGUAGES CXX) - -set(CMAKE_CXX_EXTENSIONS OFF) -set(CMAKE_CUDA_EXTENSIONS OFF) - -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/..") - -# detect CUDA variant (Clang with CUDA support or NVCC) -include(detect_features) -detect_cuda_type(GT_CUDA_TYPE AUTO) - -if(GT_CUDA_TYPE STREQUAL "NVCC-CUDA") - # 2) Enable the CUDA language if you want to run your code on a CUDA-capable GPU. - # This needs to be done before find_package(GridTools) to properly setup the GridTools targets for CUDA. - enable_language(CUDA) -endif() - -# 3) find installed GridTools version -find_package(GridTools @GridTools_VERSION@ REQUIRED - HINTS @CMAKE_INSTALL_PREFIX@/lib/cmake/GridTools) - -# 4) In the future cpp_bindgen will not be shipped with GridTools, then the following -# steps are needed to make the library available -include(FetchContent) -FetchContent_Declare( - cpp_bindgen - GIT_REPOSITORY https://github.com/GridTools/cpp_bindgen.git - GIT_TAG v1.0.1 - ) -FetchContent_MakeAvailable(cpp_bindgen) - -enable_testing() - -# 5) generate a bindings library for cpu_ifirst backend. This generates two targets: -# - copy_stencil_lib_cpu_c (the C library) -# - copy_stencil_lib_cpu_fortran (the Fortran Library) -bindgen_add_library(copy_stencil_lib_cpu SOURCES copy_stencil_wrapper.cpp) -target_link_libraries(copy_stencil_lib_cpu PUBLIC GridTools::stencil_cpu_ifirst) - -include(CheckLanguage) -check_language(C) -if(CMAKE_C_COMPILER) - enable_language(C) - - add_executable(example_driver_cpu_c driver_cpu.c) - target_link_libraries(example_driver_cpu_c copy_stencil_lib_cpu_c) - - add_test(NAME example_driver_cpu_c COMMAND $) -endif() - -check_language(Fortran) -if(CMAKE_Fortran_COMPILER) - enable_language(Fortran) - # 6) If a library needs to be used from Fortran, it is necessary to call - # bindgen_enable_fortran_library with the bindings library in order to - # build the right modules - bindgen_enable_fortran_library(copy_stencil_lib_cpu) - - add_executable(example_driver_fortran driver.F90) - target_link_libraries(example_driver_fortran copy_stencil_lib_cpu_fortran) - set_target_properties(example_driver_fortran PROPERTIES LINKER_LANGUAGE Fortran) - add_test(NAME example_driver_fortran COMMAND $) -endif() - -if(TARGET GridTools::stencil_gpu) - set(EXAMPLE_CUDA_ARCH "@GT_CUDA_ARCH@" CACHE STRING "CUDA compute capability to be used for this example.") - - bindgen_add_library(copy_stencil_lib_gpu SOURCES copy_stencil_wrapper.cpp) - target_link_libraries(copy_stencil_lib_gpu PUBLIC GridTools::stencil_gpu) - gridtools_setup_target(copy_stencil_lib_gpu CUDA_ARCH ${EXAMPLE_CUDA_ARCH}) - - if(CMAKE_C_COMPILER_LOADED) - add_executable(example_driver_gpu_c driver_gpu.c) - target_link_libraries(example_driver_gpu_c copy_stencil_lib_gpu_c) - add_test(NAME example_driver_gpu_c COMMAND $) - endif() - - if(CMAKE_Fortran_COMPILER_LOADED) - if(CMAKE_Fortran_COMPILER_ID MATCHES "PGI") - # FindOpenACC seems to be broken for modern versions of PGI, we assume PGI has OpenACC... - set(OpenACC_Fortran_FLAGS -acc) - set(OpenACC_Fortran_FOUND ON) - else() - find_package(OpenACC) - endif() - if(OpenACC_Fortran_FOUND) - # OpenACC support in gfortran is fragile, by default we switch off compilation - option(C_BINDING_ENABLE_GNU_OPENACC "Enable OpenACC example with the gfortran" OFF) - if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" OR C_BINDING_ENABLE_GNU_OPENACC) - bindgen_enable_fortran_library(copy_stencil_lib_gpu) - target_compile_options(copy_stencil_lib_gpu PUBLIC $<$:${OpenACC_Fortran_FLAGS}>) - target_link_options(copy_stencil_lib_gpu PUBLIC $<$:${OpenACC_Fortran_FLAGS}>) - - add_executable(example_driver_gpu_fortran driver_acc.F90) - set_target_properties(example_driver_gpu_fortran PROPERTIES LINKER_LANGUAGE Fortran) - target_link_libraries(example_driver_gpu_fortran copy_stencil_lib_gpu_fortran) - add_test(NAME example_driver_gpu_fortran COMMAND $) - endif() - else() - message(WARNING "OpenACC not supported. The Fortran CUDA example won't be compiled.") - endif() - endif() -endif() diff --git a/examples/c_bindings/README b/examples/c_bindings/README deleted file mode 100644 index 19aca153ac..0000000000 --- a/examples/c_bindings/README +++ /dev/null @@ -1,18 +0,0 @@ -This example demonstrate how to export C bindings using GridTools, -and how to use them from another language. - -CMakeLists.txt: Shows how to use the C bindings generator in the build - system. -copy_stencil_wrapper.cpp: The core functionality, exports several functions. -copy_stencil_lib_*: Those C headers and fortran files are autogenerated - files when compiling the c bindings. - These files are generated into the source tree to give - the user the opportunity to check them into the version - control system. This is useful in case the code that - generates the files cnanot be run on each host (namely, - in case of cross compiling, the generator binary will be - biult for the target, and thus, cannot necessarily be - executed on the host system). -driver_cpu.c Shows how to call the exported functions from C. -driver_gpu.c Shows how to call the exported functions from C. -driver.f90 Shows how to call the exported functions from Fortran. diff --git a/examples/c_bindings/copy_stencil_wrapper.cpp b/examples/c_bindings/copy_stencil_wrapper.cpp deleted file mode 100644 index 943ac82862..0000000000 --- a/examples/c_bindings/copy_stencil_wrapper.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ -// In this example, we demonstrate how the cpp_bindgen library can be used to export functions to C and Fortran. We are -// going to export the functions required to run a simple copy stencil (see also the commented example in -// examples/stencil/copy_stencil.cpp) - -#include -#include - -#include - -#include -#include -#include -#include -#include - -#ifdef GT_CUDACC -#include -#include -#include -#include -using stencil_backend_t = gridtools::stencil::gpu<>; -using storage_traits_t = gridtools::storage::gpu; -#else -#include -#include -using stencil_backend_t = gridtools::stencil::cpu_ifirst<>; -using storage_traits_t = gridtools::storage::cpu_ifirst; -#endif - -namespace { - using namespace gridtools; - using namespace stencil; - using namespace cartesian; - - struct copy_functor { - using in = in_accessor<0>; - using out = inout_accessor<1>; - using param_list = make_param_list; - - template - GT_FUNCTION static void apply(Eval &&eval) { - eval(out()) = eval(in()); - } - }; - - using data_store_t = decltype(storage::builder.type().dimensions(0, 0, 0).build()); - - auto make_data_store_impl(int x, int y, int z) { - return storage::builder.type().dimensions(x, y, z).build(); - } - BINDGEN_EXPORT_BINDING_3(make_data_store, make_data_store_impl); - - void run_copy_stencil_impl(data_store_t in, data_store_t out) { - assert(in->lengths() == out->lengths()); - auto &&lengths = out->lengths(); - auto grid = make_grid(lengths[0], lengths[1], lengths[2]); - run_single_stage(copy_functor(), stencil_backend_t(), grid, in, out); -#ifdef GT_CUDACC - GT_CUDA_CHECK(cudaDeviceSynchronize()); -#endif - } - BINDGEN_EXPORT_BINDING_2(run_copy_stencil, run_copy_stencil_impl); - - template - void transform_f_to_c_impl(D c, fortran_array_adapter f) { - f.transform_to(c); - } - // In order to generate the additional wrapper for Fortran array, the *_WRAPPED_* versions need to be used - BINDGEN_EXPORT_BINDING_WRAPPED_2(transform_f_to_c, transform_f_to_c_impl); - - template - void transform_c_to_f_impl(fortran_array_adapter f, D c) { - f.transform_from(c); - } - // In order to generate the additional wrapper for Fortran array, the *_WRAPPED_* versions need to be used - BINDGEN_EXPORT_BINDING_WRAPPED_2(transform_c_to_f, transform_c_to_f_impl); -} // namespace diff --git a/examples/c_bindings/driver.F90 b/examples/c_bindings/driver.F90 deleted file mode 100644 index fa595e1ace..0000000000 --- a/examples/c_bindings/driver.F90 +++ /dev/null @@ -1,49 +0,0 @@ -! GridTools -! -! Copyright (c) 2014-2019, ETH Zurich -! All rights reserved. -! -! Please, refer to the LICENSE file in the root directory. -! SPDX-License-Identifier: BSD-3-Clause - -program main - use iso_c_binding - use bindgen_handle - use copy_stencil_lib_cpu - implicit none - integer, parameter :: i = 9, j = 10, k = 11 - real(c_float), dimension(i, j, k) :: in_array, out_array - type(c_ptr) grid_handle, storage_info_handle, computation_handle, in_handle, out_handle - - ! fill some input values - in_array = initial() - out_array(:, :, :) = 0 - - in_handle = make_data_store(i, j, k) - out_handle = make_data_store(i, j, k) - - ! transform data from Fortran to C layout - call transform_f_to_c(in_handle, in_array) - - call run_copy_stencil(in_handle, out_handle) - - ! transform data from C layout to Fortran layout - call transform_c_to_f(out_array, out_handle) - - ! check output - if (any(in_array /= initial())) stop 1 - if (any(out_array /= initial())) stop 1 - - ! bindgen_handles need to be released explicitly - call bindgen_release(in_handle) - call bindgen_release(out_handle) - - print *, "It works!" - -contains - function initial() - integer :: x - integer, dimension(i, j, k) :: initial - initial = reshape((/(x, x = 1, size(initial))/) , shape(initial)) - end -end diff --git a/examples/c_bindings/driver_acc.F90 b/examples/c_bindings/driver_acc.F90 deleted file mode 100644 index 8a91e09516..0000000000 --- a/examples/c_bindings/driver_acc.F90 +++ /dev/null @@ -1,52 +0,0 @@ -! GridTools -! -! Copyright (c) 2014-2019, ETH Zurich -! All rights reserved. -! -! Please, refer to the LICENSE file in the root directory. -! SPDX-License-Identifier: BSD-3-Clause - -program main - use iso_c_binding - use bindgen_handle - use copy_stencil_lib_gpu - - implicit none - integer, parameter :: i = 9, j = 10, k = 11 - real(c_float), dimension(i, j, k) :: in_array, out_array - type(c_ptr) grid_handle, storage_info_handle, computation_handle, in_handle, out_handle - - ! fill some input values - in_array = initial() - out_array(:, :, :) = 0 - - in_handle = make_data_store(i, j, k) - out_handle = make_data_store(i, j, k) - -!$acc data copy(out_array,in_array) - ! transform data from Fortran to C layout - call transform_f_to_c(in_handle, in_array) - - call run_copy_stencil(in_handle, out_handle) - - ! transform data from C layout to Fortran layout - call transform_c_to_f(out_array, out_handle) -!$acc end data - - ! check output - if (any(in_array /= initial())) stop 1 - if (any(out_array /= initial())) stop 1 - - ! bindgen_handles need to be released explicitly - call bindgen_release(in_handle) - call bindgen_release(out_handle) - - print *, "It works!" - -contains - function initial() - integer :: x - integer, dimension(i, j, k) :: initial - initial = reshape((/(x, x = 1, size(initial))/) , shape(initial)) - end -end diff --git a/examples/c_bindings/driver_cpu.c b/examples/c_bindings/driver_cpu.c deleted file mode 100644 index 7663578aac..0000000000 --- a/examples/c_bindings/driver_cpu.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "copy_stencil_lib_cpu.h" - -int main() { - const int nx = 9; - const int ny = 10; - const int nz = 11; - - bindgen_handle *in_handle = make_data_store(nx, ny, nz); - bindgen_handle *out_handle = make_data_store(nx, ny, nz); - - // Note that the order of the indices array here is k, j, i (which is the internal Fortran layout). This is the - // layout that is expected by the bindings we have written. - float in_array[nz][ny][nx], out_array[nz][ny][nx]; - - // fill some inputs - float n1 = 0; - float n2 = nz * ny * nx; - for (int k = 0; k < nz; ++k) - for (int j = 0; j < ny; ++j) - for (int i = 0; i < nx; ++i, ++n1, --n2) { - in_array[k][j][i] = n1; - out_array[k][j][i] = n2; - } - - // in the C bindings, the fortran array descriptors need to be filled explicitly - bindgen_fortran_array_descriptor in_descriptor = { - .rank = 3, .type = bindgen_fk_Float, .dims = {nx, ny, nz}, .data = in_array}; - bindgen_fortran_array_descriptor out_descriptor = { - .rank = 3, .type = bindgen_fk_Float, .dims = {nx, ny, nz}, .data = out_array}; - - transform_f_to_c(in_handle, &in_descriptor); - run_copy_stencil(in_handle, out_handle); - transform_c_to_f(&out_descriptor, out_handle); - - // now, the output can be verified - for (int k = 0; k < nz; ++k) - for (int j = 0; j < ny; ++j) - for (int i = 0; i < nx; ++i) - if (in_array[k][j][i] != out_array[k][j][i]) { - printf("Error at position (k=%i, j=%i, i=%i)\n", k, j, i); - return 1; - } - - printf("It works!\n"); - - bindgen_release(in_handle); - bindgen_release(out_handle); -} diff --git a/examples/c_bindings/driver_gpu.c b/examples/c_bindings/driver_gpu.c deleted file mode 100644 index 2dede68fab..0000000000 --- a/examples/c_bindings/driver_gpu.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "copy_stencil_lib_gpu.h" -#include "cuda_runtime.h" - -int main() { - const int nx = 9; - const int ny = 10; - const int nz = 11; - - bindgen_handle *in_handle = make_data_store(nx, ny, nz); - bindgen_handle *out_handle = make_data_store(nx, ny, nz); - - // Note that the order of the indices array here is k, j, i (which is the internal - // Fortran layout). This is the layout that is expected by the bindings we have - // written. - float *in_array, *out_array; - cudaMallocManaged((void **)&in_array, nx * ny * nz * sizeof(float), cudaMemAttachGlobal); - cudaMallocManaged((void **)&out_array, nx * ny * nz * sizeof(float), cudaMemAttachGlobal); - - // fill some inputs - float n1 = 0; - float n2 = nz * ny * nx; - for (int k = 0; k < nz; ++k) - for (int j = 0; j < ny; ++j) - for (int i = 0; i < nx; ++i, ++n1, --n2) { - int index = k * ny * nx + j * nx + i; - in_array[index] = n1; - out_array[index] = n2; - } - - // in the C bindings, the fortran array descriptors need to be filled explicitly - bindgen_fortran_array_descriptor in_descriptor = { - .rank = 3, .type = bindgen_fk_Float, .dims = {nx, ny, nz}, .data = in_array}; - bindgen_fortran_array_descriptor out_descriptor = { - .rank = 3, .type = bindgen_fk_Float, .dims = {nx, ny, nz}, .data = out_array}; - - transform_f_to_c(in_handle, &in_descriptor); - run_copy_stencil(in_handle, out_handle); - transform_c_to_f(&out_descriptor, out_handle); - - // now, the output can be verified - for (int k = 0; k < nz; ++k) - for (int j = 0; j < ny; ++j) - for (int i = 0; i < nx; ++i) { - int idx = k * ny * nx + j * nx + i; - if (in_array[idx] != out_array[idx]) { - printf("Error at position (k=%i, j=%i, i=%i)\n", k, j, i); - return 1; - } - } - - printf("It works!\n"); - - cudaFree(in_array); - cudaFree(out_array); - - bindgen_release(in_handle); - bindgen_release(out_handle); -} diff --git a/include/gridtools/storage/adapter/fortran_array_adapter.hpp b/include/gridtools/storage/adapter/fortran_array_adapter.hpp deleted file mode 100644 index 1b8390ca4e..0000000000 --- a/include/gridtools/storage/adapter/fortran_array_adapter.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ -#pragma once - -#include - -#include - -#include "../../layout_transformation.hpp" -#include "../data_store.hpp" - -namespace gridtools { - template - class fortran_array_adapter { - static_assert(storage::is_data_store_ptr::value); - using data_store_t = typename DataStorePtr::element_type; - using lengths_t = std::decay_tlengths())>; - using strides_t = std::decay_tstrides())>; - using data_ptr_t = decltype(DataStorePtr()->get_target_ptr()); - - bindgen_fortran_array_descriptor const &m_descriptor; - - data_ptr_t fortran_ptr() const { - assert(m_descriptor.data); - return static_cast(m_descriptor.data); - } - - // verify dimensions of fortran array - void check_fortran_lengths(DataStorePtr const &ds) const { - auto &&lengths = ds->lengths(); - auto &&strides = ds->strides(); - for (size_t c_dim = 0, fortran_dim = 0; c_dim < data_store_t::layout_t::masked_length; ++c_dim) - if (strides[c_dim] != 0) { - if (m_descriptor.dims[fortran_dim] != lengths[c_dim]) - throw std::runtime_error("dimensions do not match (descriptor [" + - std::to_string(m_descriptor.dims[fortran_dim]) + "] != data_store [" + - std::to_string(lengths[c_dim]) + "])"); - ++fortran_dim; - } - } - - strides_t fortran_strides(DataStorePtr const &ds) const { - auto &&lengths = ds->lengths(); - auto &&strides = ds->strides(); - strides_t res = {}; - uint_t current_stride = 1; - for (size_t i = 0; i < res.size(); ++i) - if (strides[i] != 0) { - res[i] = current_stride; - current_stride *= lengths[i]; - } - return res; - } - - public: - fortran_array_adapter(const bindgen_fortran_array_descriptor &descriptor) : m_descriptor(descriptor) { - if (m_descriptor.rank != bindgen_view_rank::value) - throw std::runtime_error("rank does not match (descriptor-rank [" + std::to_string(m_descriptor.rank) + - "] != datastore-rank [" + std::to_string(bindgen_view_rank::value) + "]"); - } - - using bindgen_view_rank = std::integral_constant; - using bindgen_view_element_type = std::remove_pointer_t; - using bindgen_is_acc_present = std::true_type; - - void transform_to(DataStorePtr const &dst) const { - check_fortran_lengths(dst); - transform_layout( - dst->get_target_ptr(), fortran_ptr(), dst->lengths(), dst->strides(), fortran_strides(dst)); - } - - void transform_from(DataStorePtr const &src) const { - check_fortran_lengths(src); - transform_layout( - fortran_ptr(), src->get_target_ptr(), src->lengths(), fortran_strides(src), src->strides()); - } - }; -} // namespace gridtools diff --git a/include/gridtools/storage/adapter/fortran_array_view.hpp b/include/gridtools/storage/adapter/fortran_array_view.hpp deleted file mode 100644 index e2ed512333..0000000000 --- a/include/gridtools/storage/adapter/fortran_array_view.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ -#pragma once - -#include -#include -#include -#include - -#include - -#include "../../common/integral_constant.hpp" -#include "../../common/stride_util.hpp" -#include "../../sid/simple_ptr_holder.hpp" - -namespace gridtools { - namespace fortran_array_view_impl_ { - struct default_kind {}; - - template - class fortran_array_view { - static_assert(std::is_arithmetic_v, "fortran_array_view should be instantiated with arithmetic type"); - - using upper_bounds_t = std::array; - using lower_bounds_t = std::array, Rank>; - using strides_t = decltype(stride_util::make_strides_from_sizes(lower_bounds_t())); - - bindgen_fortran_array_descriptor const &m_desc; - - friend sid::simple_ptr_holder sid_get_origin(fortran_array_view const &obj) { - return {static_cast(obj.m_desc.data)}; - } - friend strides_t sid_get_strides(fortran_array_view const &obj) { - return stride_util::make_strides_from_sizes(sid_get_upper_bounds(obj)); - } - friend upper_bounds_t sid_get_upper_bounds(fortran_array_view const &obj) { - upper_bounds_t res; - for (size_t i = 0; i != Rank; ++i) - res[i] = obj.m_desc.dims[i]; - return res; - } - friend Kind sid_get_strides_kind(fortran_array_view const &) { return {}; } - friend lower_bounds_t sid_get_lower_bounds(fortran_array_view const &) { return {}; } - - public: - using bindgen_view_rank = std::integral_constant; - using bindgen_view_element_type = T; - using bindgen_is_acc_present = std::integral_constant; - - fortran_array_view(bindgen_fortran_array_descriptor const &desc) : m_desc(desc) { -#ifndef NDEBUG - assert(desc.rank == Rank); - for (size_t i = 0; i != Rank; ++i) - assert(desc.dims[i] > 0); -#endif - } - }; - } // namespace fortran_array_view_impl_ - - // Models both gridtools SID concept and bindgen FortranArrayView concept - using fortran_array_view_impl_::fortran_array_view; -} // namespace gridtools diff --git a/tests/regression/CMakeLists.txt b/tests/regression/CMakeLists.txt index 9297dd0c71..e872566c54 100644 --- a/tests/regression/CMakeLists.txt +++ b/tests/regression/CMakeLists.txt @@ -172,7 +172,6 @@ if(TARGET stencil_dump) endif() add_subdirectory(icosahedral) -add_subdirectory(c_bindings) add_subdirectory(py_bindings) add_subdirectory(gcl) add_subdirectory(fn) diff --git a/tests/regression/c_bindings/CMakeLists.txt b/tests/regression/c_bindings/CMakeLists.txt deleted file mode 100644 index dadfdec591..0000000000 --- a/tests/regression/c_bindings/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -if (NOT CMAKE_C_COMPILER_LOADED AND NOT CMAKE_Fortran_COMPILER_LOADED) - return() -endif() - -include(FetchContent) -FetchContent_Declare( - cpp_bindgen - GIT_REPOSITORY https://github.com/GridTools/cpp_bindgen.git - GIT_TAG v1.0.1 -) - -set(build_testing_ ${BUILD_TESTING}) -set(BUILD_TESTING OFF) -FetchContent_GetProperties(cpp_bindgen) -if(NOT cpp_bindgen_POPULATED) - FetchContent_Populate(cpp_bindgen) - add_subdirectory(${cpp_bindgen_SOURCE_DIR} ${cpp_bindgen_BINARY_DIR} EXCLUDE_FROM_ALL) -endif() -set(BUILD_TESTING ${build_testing_}) - -bindgen_add_library(implementation SOURCES implementation.cpp FORTRAN_MODULE_NAME implementation) -target_link_libraries(implementation PRIVATE gridtools) - -if (CMAKE_C_COMPILER_LOADED) - add_executable(driver driver.c) - target_link_libraries(driver implementation_c) -endif() - -if (CMAKE_Fortran_COMPILER_LOADED) - bindgen_enable_fortran_library(implementation) - add_executable(fdriver fdriver.f90) - target_link_libraries(fdriver implementation_fortran) - set_target_properties(fdriver PROPERTIES LINKER_LANGUAGE Fortran) - - bindgen_add_library(implementation_wrapper - SOURCES implementation_wrapper.cpp FORTRAN_MODULE_NAME implementation_wrapper) - target_link_libraries(implementation_wrapper PRIVATE gridtools) - bindgen_enable_fortran_library(implementation_wrapper) - - add_executable(fdriver_wrapper fdriver_wrapper.f90) - target_link_libraries(fdriver_wrapper implementation_wrapper_fortran) - set_target_properties(fdriver_wrapper PROPERTIES LINKER_LANGUAGE Fortran) -endif() diff --git a/tests/regression/c_bindings/driver.c b/tests/regression/c_bindings/driver.c deleted file mode 100644 index dc3763c43e..0000000000 --- a/tests/regression/c_bindings/driver.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "implementation.h" - -#define I 9 -#define J 10 -#define K 11 - -double initial_value(int i, int j, int k) { return i + j + k; } - -void init_in(double arr[I][J][K]) { - int i, j, k; - for (i = 0; i != I; ++i) - for (j = 0; j != J; ++j) - for (k = 0; k != K; ++k) - arr[i][j][k] = initial_value(i, j, k); -} - -void verify(const char *label, double arr[I][J][K]) { - int i, j, k; - for (i = 0; i != I; ++i) - for (j = 0; j != J; ++j) - for (k = 0; k != K; ++k) - if (arr[i][j][k] != initial_value(i, j, k)) { - fprintf(stderr, - "data mismatch in %s[%d][%d][%d]: actual - %f , expected - %f\n", - label, - i, - j, - k, - arr[i][j][k], - initial_value(i, j, k)); - exit(i); - } -} - -int main() { - double in[I][J][K]; - double out[I][J][K]; - bindgen_handle *in_handle = create_data_store(I, J, K); - bindgen_handle *out_handle = create_data_store(I, J, K); - - init_in(in); - copy_to_data_store(in_handle, (double *)in); - - run_copy_stencil(in_handle, out_handle); - - copy_from_data_store(out_handle, (double *)out); - - bindgen_release(in_handle); - bindgen_release(out_handle); - - verify("in", in); - verify("out", out); - - printf("It works!\n"); -} diff --git a/tests/regression/c_bindings/fdriver.f90 b/tests/regression/c_bindings/fdriver.f90 deleted file mode 100644 index eadcbe9f9f..0000000000 --- a/tests/regression/c_bindings/fdriver.f90 +++ /dev/null @@ -1,41 +0,0 @@ -! GridTools -! -! Copyright (c) 2014-2019, ETH Zurich -! All rights reserved. -! -! Please, refer to the LICENSE file in the root directory. -! SPDX-License-Identifier: BSD-3-Clause - -program main - use iso_c_binding - use bindgen_handle - use implementation - implicit none - integer, parameter :: i = 9, j = 10, k = 11 - real(8), dimension(i, j, k) :: in, out - type(c_ptr) in_handle, out_handle - - in = initial() - - in_handle = create_data_store(i, j, k) - out_handle = create_data_store(i, j, k) - - call copy_to_data_store(in_handle, in(:,1,1)) - call run_copy_stencil(in_handle, out_handle) - call copy_from_data_store(out_handle, out(:,1,1)) - - if (any(in /= initial())) stop 1 - if (any(out /= initial())) stop 1 - - call bindgen_release(out_handle) - call bindgen_release(in_handle) - - print *, "It works!" - -contains - function initial() - integer :: x - integer, dimension(i, j, k) :: initial - initial = reshape((/(x, x = 1, size(initial))/) , shape(initial)) - end -end diff --git a/tests/regression/c_bindings/fdriver_wrapper.f90 b/tests/regression/c_bindings/fdriver_wrapper.f90 deleted file mode 100644 index 026d4b5394..0000000000 --- a/tests/regression/c_bindings/fdriver_wrapper.f90 +++ /dev/null @@ -1,36 +0,0 @@ -! GridTools -! -! Copyright (c) 2014-2019, ETH Zurich -! All rights reserved. -! -! Please, refer to the LICENSE file in the root directory. -! SPDX-License-Identifier: BSD-3-Clause - -program main - use iso_c_binding - use bindgen_handle - use implementation_wrapper - implicit none - integer, parameter :: i = 9, j = 10, k = 11 - real(4), dimension(i, j, k) :: in4, out4 - real(8), dimension(i, j, k) :: in8, out8 - - in4 = initial() - call run_copy_functor(in4, out4) - if (any(in4 /= initial())) stop 1 - if (any(out4 /= initial())) stop 1 - - in8 = initial() - call run_copy_functor(in8, out8) - if (any(in8 /= initial())) stop 1 - if (any(out8 /= initial())) stop 1 - - print *, "It works!" - -contains - function initial() - integer :: x - integer, dimension(i, j, k) :: initial - initial = reshape((/(x, x = 1, size(initial))/) , shape(initial)) - end -end diff --git a/tests/regression/c_bindings/implementation.cpp b/tests/regression/c_bindings/implementation.cpp deleted file mode 100644 index 8328570643..0000000000 --- a/tests/regression/c_bindings/implementation.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include - -namespace { - using namespace gridtools; - using namespace stencil; - using namespace cartesian; - - struct copy_functor { - using in = in_accessor<0>; - using out = inout_accessor<1>; - using param_list = make_param_list; - - template - GT_FUNCTION static void apply(Eval &&eval) { - eval(out()) = eval(in()); - } - }; - - auto make_data_store(uint_t x, uint_t y, uint_t z) { - return storage::builder.type().dimensions(x, y, z)(); - } - BINDGEN_EXPORT_BINDING_3(create_data_store, make_data_store); - - using data_store_t = decltype(make_data_store(0, 0, 0)); - - void run(data_store_t const &in, data_store_t const &out) { - auto lengths = out->lengths(); - run_single_stage(copy_functor(), naive(), make_grid(lengths[0], lengths[1], lengths[2]), in, out); - } - BINDGEN_EXPORT_BINDING_2(run_copy_stencil, run); - - void copy_to(data_store_t const &dst, double const *src) { - auto lengths = dst->lengths(); - auto view = dst->host_view(); - for (int i = 0; i < lengths[0]; ++i) - for (int j = 0; j < lengths[1]; ++j) - for (int k = 0; k < lengths[2]; ++k) - view(i, j, k) = *(src++); - } - BINDGEN_EXPORT_BINDING_2(copy_to_data_store, copy_to); - - void copy_from(data_store_t const &src, double *dst) { - auto lengths = src->lengths(); - auto view = src->const_host_view(); - for (int i = 0; i < lengths[0]; ++i) - for (int j = 0; j < lengths[1]; ++j) - for (int k = 0; k < lengths[2]; ++k) - *(dst++) = view(i, j, k); - } - BINDGEN_EXPORT_BINDING_2(copy_from_data_store, copy_from); -} // namespace diff --git a/tests/regression/c_bindings/implementation.f90 b/tests/regression/c_bindings/implementation.f90 deleted file mode 100644 index f8eee8e1f0..0000000000 --- a/tests/regression/c_bindings/implementation.f90 +++ /dev/null @@ -1,31 +0,0 @@ -! This file is generated! -module implementation -use iso_c_binding -implicit none - interface - - subroutine copy_from_data_store(arg0, arg1) bind(c) - use iso_c_binding - type(c_ptr), value :: arg0 - real(c_double), dimension(*) :: arg1 - end subroutine - subroutine copy_to_data_store(arg0, arg1) bind(c) - use iso_c_binding - type(c_ptr), value :: arg0 - real(c_double), dimension(*) :: arg1 - end subroutine - type(c_ptr) function create_data_store(arg0, arg1, arg2) bind(c) - use iso_c_binding - integer(c_int), value :: arg0 - integer(c_int), value :: arg1 - integer(c_int), value :: arg2 - end function - subroutine run_copy_stencil(arg0, arg1) bind(c) - use iso_c_binding - type(c_ptr), value :: arg0 - type(c_ptr), value :: arg1 - end subroutine - - end interface -contains -end diff --git a/tests/regression/c_bindings/implementation.h b/tests/regression/c_bindings/implementation.h deleted file mode 100644 index e239d408cc..0000000000 --- a/tests/regression/c_bindings/implementation.h +++ /dev/null @@ -1,18 +0,0 @@ -// This file is generated! -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void copy_from_data_store(bindgen_handle*, double*); -void copy_to_data_store(bindgen_handle*, double*); -bindgen_handle* create_data_store(unsigned int, unsigned int, unsigned int); -void run_copy_stencil(bindgen_handle*, bindgen_handle*); - -#ifdef __cplusplus -} -#endif diff --git a/tests/regression/c_bindings/implementation_wrapper.cpp b/tests/regression/c_bindings/implementation_wrapper.cpp deleted file mode 100644 index b33fa7dd24..0000000000 --- a/tests/regression/c_bindings/implementation_wrapper.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include - -namespace { - using namespace gridtools; - using namespace stencil; - using namespace cartesian; - - struct copy_functor { - using in = in_accessor<0>; - using out = inout_accessor<1>; - using param_list = make_param_list; - - template - GT_FUNCTION static void apply(Evaluation &&eval) { - eval(out{}) = eval(in{}); - } - }; - - template - void run_copy_functor_impl(fortran_array_view in, fortran_array_view out) { - auto &&size = sid::get_upper_bounds(out); - run_single_stage(copy_functor(), - naive(), - make_grid(at_key(size), at_key(size), at_key(size)), - in, - out); - } - BINDGEN_EXPORT_GENERIC_BINDING_WRAPPED(2, run_copy_functor, run_copy_functor_impl, (double)(float)); -} // namespace diff --git a/tests/regression/c_bindings/implementation_wrapper.f90 b/tests/regression/c_bindings/implementation_wrapper.f90 deleted file mode 100644 index da53c39eb0..0000000000 --- a/tests/regression/c_bindings/implementation_wrapper.f90 +++ /dev/null @@ -1,85 +0,0 @@ -! This file is generated! -module implementation_wrapper -use iso_c_binding -implicit none - interface - - subroutine run_copy_functor0_impl(arg0, arg1) bind(c, name="run_copy_functor0") - use iso_c_binding - use bindgen_array_descriptor - type(bindgen_fortran_array_descriptor) :: arg0 - type(bindgen_fortran_array_descriptor) :: arg1 - end subroutine - subroutine run_copy_functor1_impl(arg0, arg1) bind(c, name="run_copy_functor1") - use iso_c_binding - use bindgen_array_descriptor - type(bindgen_fortran_array_descriptor) :: arg0 - type(bindgen_fortran_array_descriptor) :: arg1 - end subroutine - - end interface - interface run_copy_functor - procedure run_copy_functor0, run_copy_functor1 - end interface -contains - subroutine run_copy_functor0(arg0, arg1) - use iso_c_binding - use bindgen_array_descriptor - real(c_double), dimension(:,:,:), target :: arg0 - real(c_double), dimension(:,:,:), target :: arg1 - type(bindgen_fortran_array_descriptor) :: descriptor0 - type(bindgen_fortran_array_descriptor) :: descriptor1 - - !$acc data present(arg0) - !$acc host_data use_device(arg0) - descriptor0%rank = 3 - descriptor0%type = 6 - descriptor0%dims = reshape(shape(arg0), & - shape(descriptor0%dims), (/0/)) - descriptor0%data = c_loc(arg0(lbound(arg0, 1),lbound(arg0, 2),lbound(arg0, 3))) - !$acc end host_data - !$acc end data - - !$acc data present(arg1) - !$acc host_data use_device(arg1) - descriptor1%rank = 3 - descriptor1%type = 6 - descriptor1%dims = reshape(shape(arg1), & - shape(descriptor1%dims), (/0/)) - descriptor1%data = c_loc(arg1(lbound(arg1, 1),lbound(arg1, 2),lbound(arg1, 3))) - !$acc end host_data - !$acc end data - - call run_copy_functor0_impl(descriptor0, descriptor1) - end subroutine - subroutine run_copy_functor1(arg0, arg1) - use iso_c_binding - use bindgen_array_descriptor - real(c_float), dimension(:,:,:), target :: arg0 - real(c_float), dimension(:,:,:), target :: arg1 - type(bindgen_fortran_array_descriptor) :: descriptor0 - type(bindgen_fortran_array_descriptor) :: descriptor1 - - !$acc data present(arg0) - !$acc host_data use_device(arg0) - descriptor0%rank = 3 - descriptor0%type = 5 - descriptor0%dims = reshape(shape(arg0), & - shape(descriptor0%dims), (/0/)) - descriptor0%data = c_loc(arg0(lbound(arg0, 1),lbound(arg0, 2),lbound(arg0, 3))) - !$acc end host_data - !$acc end data - - !$acc data present(arg1) - !$acc host_data use_device(arg1) - descriptor1%rank = 3 - descriptor1%type = 5 - descriptor1%dims = reshape(shape(arg1), & - shape(descriptor1%dims), (/0/)) - descriptor1%data = c_loc(arg1(lbound(arg1, 1),lbound(arg1, 2),lbound(arg1, 3))) - !$acc end host_data - !$acc end data - - call run_copy_functor1_impl(descriptor0, descriptor1) - end subroutine -end diff --git a/tests/regression/c_bindings/implementation_wrapper.h b/tests/regression/c_bindings/implementation_wrapper.h deleted file mode 100644 index 3573a028a6..0000000000 --- a/tests/regression/c_bindings/implementation_wrapper.h +++ /dev/null @@ -1,16 +0,0 @@ -// This file is generated! -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void run_copy_functor0(bindgen_fortran_array_descriptor*, bindgen_fortran_array_descriptor*); -void run_copy_functor1(bindgen_fortran_array_descriptor*, bindgen_fortran_array_descriptor*); - -#ifdef __cplusplus -} -#endif diff --git a/tests/unit_tests/storage/adapter/CMakeLists.txt b/tests/unit_tests/storage/adapter/CMakeLists.txt index 5f00fd3292..309a305324 100644 --- a/tests/unit_tests/storage/adapter/CMakeLists.txt +++ b/tests/unit_tests/storage/adapter/CMakeLists.txt @@ -1,21 +1,3 @@ -include(FetchContent) -FetchContent_Declare( - cpp_bindgen - GIT_REPOSITORY https://github.com/GridTools/cpp_bindgen.git - GIT_TAG v1.0.1 -) - -set(build_testing_ ${BUILD_TESTING}) -set(BUILD_TESTING OFF) -FetchContent_MakeAvailable(cpp_bindgen) -set(BUILD_TESTING ${build_testing_}) - -gridtools_add_unit_test(test_fortran_array_adapter - SOURCES test_fortran_array_adapter.cpp - LIBRARIES cpp_bindgen_interface - NO_NVCC) - - if (${GT_TESTS_ENABLE_PYTHON_TESTS}) if (${Python_Development_FOUND}) FetchContent_Declare( diff --git a/tests/unit_tests/storage/adapter/test_fortran_array_adapter.cpp b/tests/unit_tests/storage/adapter/test_fortran_array_adapter.cpp deleted file mode 100644 index 08795a0eb8..0000000000 --- a/tests/unit_tests/storage/adapter/test_fortran_array_adapter.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * GridTools - * - * Copyright (c) 2014-2023, ETH Zurich - * All rights reserved. - * - * Please, refer to the LICENSE file in the root directory. - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include - -const auto builder = gridtools::storage::builder.type(); - -TEST(FortranArrayAdapter, TransformAdapterIntoDataStore) { - constexpr size_t x_size = 6; - constexpr size_t y_size = 5; - constexpr size_t z_size = 4; - double fortran_array[z_size][y_size][x_size]; - - bindgen_fortran_array_descriptor descriptor; - descriptor.rank = 3; - descriptor.dims[0] = x_size; - descriptor.dims[1] = y_size; - descriptor.dims[2] = z_size; - descriptor.type = bindgen_fk_Double; - descriptor.data = fortran_array; - descriptor.is_acc_present = false; - - auto data_store = builder.dimensions(x_size, y_size, z_size)(); - - int i = 0; - for (size_t z = 0; z < z_size; ++z) - for (size_t y = 0; y < y_size; ++y) - for (size_t x = 0; x < x_size; ++x, ++i) - fortran_array[z][y][x] = i; - - // transform adapter into data_store - gridtools::fortran_array_adapter{descriptor}.transform_to(data_store); - - i = 0; - auto view = data_store->host_view(); - for (size_t z = 0; z < z_size; ++z) - for (size_t y = 0; y < y_size; ++y) - for (size_t x = 0; x < x_size; ++x, ++i) - EXPECT_EQ(view(x, y, z), i); -} - -TEST(FortranArrayAdapter, TransformDataStoreIntoAdapter) { - constexpr size_t x_size = 6; - constexpr size_t y_size = 5; - constexpr size_t z_size = 4; - double fortran_array[z_size][y_size][x_size]; - - bindgen_fortran_array_descriptor descriptor; - descriptor.rank = 3; - descriptor.dims[0] = x_size; - descriptor.dims[1] = y_size; - descriptor.dims[2] = z_size; - descriptor.type = bindgen_fk_Double; - descriptor.data = fortran_array; - descriptor.is_acc_present = false; - - auto data_store = builder.dimensions(x_size, y_size, z_size)(); - - auto view = data_store->host_view(); - - int i = 0; - for (size_t z = 0; z < z_size; ++z) - for (size_t y = 0; y < y_size; ++y) - for (size_t x = 0; x < x_size; ++x, ++i) - view(x, y, z) = i; - - // transform data_store into adapter - gridtools::fortran_array_adapter{descriptor}.transform_from(data_store); - - i = 0; - for (size_t z = 0; z < z_size; ++z) - for (size_t y = 0; y < y_size; ++y) - for (size_t x = 0; x < x_size; ++x, ++i) - EXPECT_EQ(fortran_array[z][y][x], i); -} From 4e7d3f459b07a26c30f09abe87c53500ffef07aa Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Wed, 26 Feb 2025 14:40:24 +0100 Subject: [PATCH 2/3] Remove documentation todos --- docs_src/manuals/user_manual/interface.hrst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs_src/manuals/user_manual/interface.hrst b/docs_src/manuals/user_manual/interface.hrst index 447748099b..f58f991003 100644 --- a/docs_src/manuals/user_manual/interface.hrst +++ b/docs_src/manuals/user_manual/interface.hrst @@ -1,5 +1,3 @@ -TODO: Remove? Or are the instructions still valid for using cpp_bindgen separately? - Interfacing to other programming languages ============================================ @@ -218,8 +216,6 @@ C arrays and ``fortran_array_adapter`` are `fortran_array_wrappable`. The latter Fortran arrays and |GT| storages, such that the user can pass a Fortran array to a C++ function, which then can be transformed into a |GT| storage. -TODO: fortran_array_adapter.hpp is removed - .. code-block:: gridtools #include From e387ed47c9e731841d17528123f52e983ce09ed0 Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Wed, 26 Feb 2025 14:42:03 +0100 Subject: [PATCH 3/3] Restore fortran_array_adapter.hpp and fortran_array_view.hpp headers --- .../storage/adapter/fortran_array_adapter.hpp | 85 +++++++++++++++++++ .../storage/adapter/fortran_array_view.hpp | 69 +++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 include/gridtools/storage/adapter/fortran_array_adapter.hpp create mode 100644 include/gridtools/storage/adapter/fortran_array_view.hpp diff --git a/include/gridtools/storage/adapter/fortran_array_adapter.hpp b/include/gridtools/storage/adapter/fortran_array_adapter.hpp new file mode 100644 index 0000000000..1b8390ca4e --- /dev/null +++ b/include/gridtools/storage/adapter/fortran_array_adapter.hpp @@ -0,0 +1,85 @@ +/* + * GridTools + * + * Copyright (c) 2014-2023, ETH Zurich + * All rights reserved. + * + * Please, refer to the LICENSE file in the root directory. + * SPDX-License-Identifier: BSD-3-Clause + */ +#pragma once + +#include + +#include + +#include "../../layout_transformation.hpp" +#include "../data_store.hpp" + +namespace gridtools { + template + class fortran_array_adapter { + static_assert(storage::is_data_store_ptr::value); + using data_store_t = typename DataStorePtr::element_type; + using lengths_t = std::decay_tlengths())>; + using strides_t = std::decay_tstrides())>; + using data_ptr_t = decltype(DataStorePtr()->get_target_ptr()); + + bindgen_fortran_array_descriptor const &m_descriptor; + + data_ptr_t fortran_ptr() const { + assert(m_descriptor.data); + return static_cast(m_descriptor.data); + } + + // verify dimensions of fortran array + void check_fortran_lengths(DataStorePtr const &ds) const { + auto &&lengths = ds->lengths(); + auto &&strides = ds->strides(); + for (size_t c_dim = 0, fortran_dim = 0; c_dim < data_store_t::layout_t::masked_length; ++c_dim) + if (strides[c_dim] != 0) { + if (m_descriptor.dims[fortran_dim] != lengths[c_dim]) + throw std::runtime_error("dimensions do not match (descriptor [" + + std::to_string(m_descriptor.dims[fortran_dim]) + "] != data_store [" + + std::to_string(lengths[c_dim]) + "])"); + ++fortran_dim; + } + } + + strides_t fortran_strides(DataStorePtr const &ds) const { + auto &&lengths = ds->lengths(); + auto &&strides = ds->strides(); + strides_t res = {}; + uint_t current_stride = 1; + for (size_t i = 0; i < res.size(); ++i) + if (strides[i] != 0) { + res[i] = current_stride; + current_stride *= lengths[i]; + } + return res; + } + + public: + fortran_array_adapter(const bindgen_fortran_array_descriptor &descriptor) : m_descriptor(descriptor) { + if (m_descriptor.rank != bindgen_view_rank::value) + throw std::runtime_error("rank does not match (descriptor-rank [" + std::to_string(m_descriptor.rank) + + "] != datastore-rank [" + std::to_string(bindgen_view_rank::value) + "]"); + } + + using bindgen_view_rank = std::integral_constant; + using bindgen_view_element_type = std::remove_pointer_t; + using bindgen_is_acc_present = std::true_type; + + void transform_to(DataStorePtr const &dst) const { + check_fortran_lengths(dst); + transform_layout( + dst->get_target_ptr(), fortran_ptr(), dst->lengths(), dst->strides(), fortran_strides(dst)); + } + + void transform_from(DataStorePtr const &src) const { + check_fortran_lengths(src); + transform_layout( + fortran_ptr(), src->get_target_ptr(), src->lengths(), fortran_strides(src), src->strides()); + } + }; +} // namespace gridtools diff --git a/include/gridtools/storage/adapter/fortran_array_view.hpp b/include/gridtools/storage/adapter/fortran_array_view.hpp new file mode 100644 index 0000000000..e2ed512333 --- /dev/null +++ b/include/gridtools/storage/adapter/fortran_array_view.hpp @@ -0,0 +1,69 @@ +/* + * GridTools + * + * Copyright (c) 2014-2023, ETH Zurich + * All rights reserved. + * + * Please, refer to the LICENSE file in the root directory. + * SPDX-License-Identifier: BSD-3-Clause + */ +#pragma once + +#include +#include +#include +#include + +#include + +#include "../../common/integral_constant.hpp" +#include "../../common/stride_util.hpp" +#include "../../sid/simple_ptr_holder.hpp" + +namespace gridtools { + namespace fortran_array_view_impl_ { + struct default_kind {}; + + template + class fortran_array_view { + static_assert(std::is_arithmetic_v, "fortran_array_view should be instantiated with arithmetic type"); + + using upper_bounds_t = std::array; + using lower_bounds_t = std::array, Rank>; + using strides_t = decltype(stride_util::make_strides_from_sizes(lower_bounds_t())); + + bindgen_fortran_array_descriptor const &m_desc; + + friend sid::simple_ptr_holder sid_get_origin(fortran_array_view const &obj) { + return {static_cast(obj.m_desc.data)}; + } + friend strides_t sid_get_strides(fortran_array_view const &obj) { + return stride_util::make_strides_from_sizes(sid_get_upper_bounds(obj)); + } + friend upper_bounds_t sid_get_upper_bounds(fortran_array_view const &obj) { + upper_bounds_t res; + for (size_t i = 0; i != Rank; ++i) + res[i] = obj.m_desc.dims[i]; + return res; + } + friend Kind sid_get_strides_kind(fortran_array_view const &) { return {}; } + friend lower_bounds_t sid_get_lower_bounds(fortran_array_view const &) { return {}; } + + public: + using bindgen_view_rank = std::integral_constant; + using bindgen_view_element_type = T; + using bindgen_is_acc_present = std::integral_constant; + + fortran_array_view(bindgen_fortran_array_descriptor const &desc) : m_desc(desc) { +#ifndef NDEBUG + assert(desc.rank == Rank); + for (size_t i = 0; i != Rank; ++i) + assert(desc.dims[i] > 0); +#endif + } + }; + } // namespace fortran_array_view_impl_ + + // Models both gridtools SID concept and bindgen FortranArrayView concept + using fortran_array_view_impl_::fortran_array_view; +} // namespace gridtools