From f6d027c4418394211df845fe70f4aa9b42a1551e Mon Sep 17 00:00:00 2001 From: Valentin Seitz Date: Wed, 29 May 2024 15:56:44 +0200 Subject: [PATCH 1/3] Now with fortran support --- CMakeLists.txt | 13 ++++- src/bindings/CMakeLists.txt | 55 +++++++++--------- src/bindings/typessit.h | 31 +++++++++++ src/bindings/utilsit.cpp | 20 +++++++ src/bindings/wrapfsit.f | 108 ++++++++++++++++++++++++++++++++++++ src/bindings/wrapsit.cpp | 90 ++++++++++++++++++++++++++++++ src/bindings/wrapsit.h | 42 ++++++++++++++ tests/CMakeLists.txt | 9 +-- 8 files changed, 331 insertions(+), 37 deletions(-) create mode 100644 src/bindings/typessit.h create mode 100644 src/bindings/utilsit.cpp create mode 100644 src/bindings/wrapfsit.f create mode 100644 src/bindings/wrapsit.cpp create mode 100644 src/bindings/wrapsit.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 719edc2..fefaff5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ list (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") option(ENABLE_EXTRAE "Enable Extrae" OFF) option(ENABLE_DLB "Enable DLB" OFF) option(BUILD_C_FORTRAN "Enable C and Fortran Interfaces" ON) +option(GEN_BINDINGS "Use Shroud to Generate C/Fortran interface" OFF) add_library(sit SHARED) set(SIT_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -26,6 +27,13 @@ target_include_directories(sit PUBLIC #set_target_properties(sit PROPERTIES PUBLIC_HEADER "${SIT_PUBLIC_HEADERS}") +if(BUILD_C_FORTRAN) + enable_language(Fortran) + set(CMAKE_Fortran_FORMAT FREE) + set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/mod) + add_library(sit_f) + add_library(sit::sit_f ALIAS sit_f) +endif() add_subdirectory(src) @@ -54,6 +62,8 @@ install(TARGETS sit sit_f PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sit INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sit ) + install(FILES ${CMAKE_Fortran_MODULE_DIRECTORY}/sit_mod.mod DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + else() install(TARGETS sit @@ -64,10 +74,11 @@ install(TARGETS sit PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sit INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sit ) -install(FILES ${SIT_PUBLIC_HEADERS}/sit/sit.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sit) + endif() +install(FILES ${SIT_PUBLIC_HEADERS}/sit/sit.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sit) # Export the Targets to install install(EXPORT sitTargets diff --git a/src/bindings/CMakeLists.txt b/src/bindings/CMakeLists.txt index 69845ae..46cb24f 100644 --- a/src/bindings/CMakeLists.txt +++ b/src/bindings/CMakeLists.txt @@ -1,34 +1,33 @@ -if(EXISTS ${SHROUD_EXECUTABLE}) - execute_process(COMMAND ${SHROUD_EXECUTABLE} - --cmake ${CMAKE_CURRENT_BINARY_DIR}/SetupShroud.cmake - ERROR_VARIABLE SHROUD_cmake_error - OUTPUT_STRIP_TRAILING_WHITESPACE ) - if(${SHROUD_cmake_error}) - message(FATAL_ERROR "Error from Shroud: ${SHROUD_cmake_error}") +if(GEN_BINDINGS) + if(EXISTS ${SHROUD_EXECUTABLE}) + execute_process(COMMAND ${SHROUD_EXECUTABLE} + --cmake ${CMAKE_CURRENT_BINARY_DIR}/SetupShroud.cmake + ERROR_VARIABLE SHROUD_cmake_error + OUTPUT_STRIP_TRAILING_WHITESPACE ) + if(${SHROUD_cmake_error}) + message(FATAL_ERROR "Error from Shroud: ${SHROUD_cmake_error}") + endif() + include(${CMAKE_CURRENT_BINARY_DIR}/SetupShroud.cmake) + + # Generate the headers + add_shroud( + YAML_INPUT_FILE sit.yaml + ) + else() + message(FATAL_ERROR "Cannot build Fortran and C bindings without -DSHROUD_EXECUTABLE specified") endif() - include(${CMAKE_CURRENT_BINARY_DIR}/SetupShroud.cmake) - add_shroud( - YAML_INPUT_FILE sit.yaml - C_FORTRAN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} - ) - - set_source_files_properties(wrap${_basename}.cpp PROPERTIES GENERATED TRUE) - set_source_files_properties(wrapf${_basename}.f PROPERTIES GENERATED TRUE) - set(CMAKE_Fortran_FORMAT FREE) - list (APPEND SIT_PUBLIC_HEADERS "${LIB_INC}") +endif() - - add_library(${_basename}_f wrapf${_basename}.f wrap${_basename}.cpp ${LIB_SRC}) +target_sources(sit_f PRIVATE wrapfsit.f wrapsit.cpp) +#set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) +#set_source_files_properties(wrapsit.cpp PROPERTIES GENERATED TRUE) +#set_source_files_properties(wrapfsit.f PROPERTIES GENERATED TRUE) + +target_include_directories(sit_f PRIVATE ${SIT_PUBLIC_HEADERS}) +set_target_properties(sit_f PROPERTIES LINKER_LANGUAGE Fortran) +#set_target_properties(st_f PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +#set_target_properties(sit_f PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}) - target_include_directories(${_basename}_f PRIVATE ${SIT_PUBLIC_HEADERS}) - - set_target_properties(${_basename}_f PROPERTIES LINKER_LANGUAGE Fortran) - set_target_properties(${_basename}_f PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) - set_target_properties(${_basename}_f PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/include) - add_dependencies(${_basename}_f generate_${_basename}) -else() -message(FATAL_ERROR "Cannot build Fortran and C bindings without -DSHROUD_EXECUTABLE specified") -endif() diff --git a/src/bindings/typessit.h b/src/bindings/typessit.h new file mode 100644 index 0000000..5cac704 --- /dev/null +++ b/src/bindings/typessit.h @@ -0,0 +1,31 @@ +// typessit.h +// This file is generated by Shroud 0.13.0. Do not edit. +// For C users and C++ implementation + +#ifndef TYPESSIT_H +#define TYPESSIT_H + +// splicer begin types.CXX_declarations +// splicer end types.CXX_declarations + +#ifdef __cplusplus +extern "C" { +#endif + +// splicer begin types.C_declarations +// splicer end types.C_declarations + +// helper capsule_data_helper +struct s_sit_SHROUD_capsule_data { + void *addr; /* address of C++ memory */ + int idtor; /* index of destructor */ +}; +typedef struct s_sit_SHROUD_capsule_data sit_SHROUD_capsule_data; + +void sit_SHROUD_memory_destructor(sit_SHROUD_capsule_data *cap); + +#ifdef __cplusplus +} +#endif + +#endif // TYPESSIT_H diff --git a/src/bindings/utilsit.cpp b/src/bindings/utilsit.cpp new file mode 100644 index 0000000..f5e4899 --- /dev/null +++ b/src/bindings/utilsit.cpp @@ -0,0 +1,20 @@ +// utilsit.cpp +// This file is generated by Shroud 0.13.0. Do not edit. + +#include "typessit.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +// Release library allocated memory. +void sit_SHROUD_memory_destructor(sit_SHROUD_capsule_data *cap) +{ + cap->addr = nullptr; + cap->idtor = 0; // avoid deleting again +} + +#ifdef __cplusplus +} +#endif diff --git a/src/bindings/wrapfsit.f b/src/bindings/wrapfsit.f new file mode 100644 index 0000000..0b6d712 --- /dev/null +++ b/src/bindings/wrapfsit.f @@ -0,0 +1,108 @@ +! wrapfsit.f +! This file is generated by Shroud 0.13.0. Do not edit. +!> +!! \file wrapfsit.f +!! \brief Shroud generated wrapper for sit namespace +!< +! splicer begin file_top +! splicer end file_top +module sit_mod + ! splicer begin module_use + ! splicer end module_use + implicit none + + ! splicer begin module_top + ! splicer end module_top + + interface + + subroutine c_init(backend) & + bind(C, name="sit_init") + use iso_c_binding, only : C_CHAR + implicit none + character(kind=C_CHAR), intent(IN) :: backend(*) + end subroutine c_init + + subroutine c_init_bufferify(backend, SHT_backend_len) & + bind(C, name="sit_init_bufferify") + use iso_c_binding, only : C_CHAR, C_INT + implicit none + character(kind=C_CHAR), intent(IN) :: backend(*) + integer(C_INT), value, intent(IN) :: SHT_backend_len + end subroutine c_init_bufferify + + subroutine c_region_start(name) & + bind(C, name="sit_region_start") + use iso_c_binding, only : C_CHAR + implicit none + character(kind=C_CHAR), intent(IN) :: name(*) + end subroutine c_region_start + + subroutine c_region_start_bufferify(name, SHT_name_len) & + bind(C, name="sit_region_start_bufferify") + use iso_c_binding, only : C_CHAR, C_INT + implicit none + character(kind=C_CHAR), intent(IN) :: name(*) + integer(C_INT), value, intent(IN) :: SHT_name_len + end subroutine c_region_start_bufferify + + subroutine c_region_stop(name) & + bind(C, name="sit_region_stop") + use iso_c_binding, only : C_CHAR + implicit none + character(kind=C_CHAR), intent(IN) :: name(*) + end subroutine c_region_stop + + subroutine c_region_stop_bufferify(name, SHT_name_len) & + bind(C, name="sit_region_stop_bufferify") + use iso_c_binding, only : C_CHAR, C_INT + implicit none + character(kind=C_CHAR), intent(IN) :: name(*) + integer(C_INT), value, intent(IN) :: SHT_name_len + end subroutine c_region_stop_bufferify + + subroutine finalize() & + bind(C, name="sit_finalize") + implicit none + end subroutine finalize + end interface + + ! splicer begin additional_declarations + ! splicer end additional_declarations + +contains + + subroutine init(backend) + use iso_c_binding, only : C_INT + character(len=*), intent(IN) :: backend + ! splicer begin function.init + integer(C_INT) SHT_backend_len + SHT_backend_len = len(backend, kind=C_INT) + call c_init_bufferify(backend, SHT_backend_len) + ! splicer end function.init + end subroutine init + + subroutine region_start(name) + use iso_c_binding, only : C_INT + character(len=*), intent(IN) :: name + ! splicer begin function.region_start + integer(C_INT) SHT_name_len + SHT_name_len = len(name, kind=C_INT) + call c_region_start_bufferify(name, SHT_name_len) + ! splicer end function.region_start + end subroutine region_start + + subroutine region_stop(name) + use iso_c_binding, only : C_INT + character(len=*), intent(IN) :: name + ! splicer begin function.region_stop + integer(C_INT) SHT_name_len + SHT_name_len = len(name, kind=C_INT) + call c_region_stop_bufferify(name, SHT_name_len) + ! splicer end function.region_stop + end subroutine region_stop + + ! splicer begin additional_functions + ! splicer end additional_functions + +end module sit_mod diff --git a/src/bindings/wrapsit.cpp b/src/bindings/wrapsit.cpp new file mode 100644 index 0000000..681c08a --- /dev/null +++ b/src/bindings/wrapsit.cpp @@ -0,0 +1,90 @@ +// wrapsit.cpp +// This file is generated by Shroud 0.13.0. Do not edit. + +#include "sit/sit.hpp" +#include +#include "wrapsit.h" + +// splicer begin CXX_definitions +// splicer end CXX_definitions + +extern "C" { + + +// helper ShroudLenTrim +// Returns the length of character string src with length nsrc, +// ignoring any trailing blanks. +static int ShroudLenTrim(const char *src, int nsrc) { + int i; + + for (i = nsrc - 1; i >= 0; i--) { + if (src[i] != ' ') { + break; + } + } + + return i + 1; +} + +// splicer begin C_definitions +// splicer end C_definitions + +void sit_init(const char * backend) +{ + // splicer begin function.init + const std::string SHCXX_backend(backend); + sit::init(SHCXX_backend); + // splicer end function.init +} + +void sit_init_bufferify(char *backend, int SHT_backend_len) +{ + // splicer begin function.init_bufferify + const std::string SHCXX_backend(backend, + ShroudLenTrim(backend, SHT_backend_len)); + sit::init(SHCXX_backend); + // splicer end function.init_bufferify +} + +void sit_region_start(const char * name) +{ + // splicer begin function.region_start + const std::string SHCXX_name(name); + sit::region_start(SHCXX_name); + // splicer end function.region_start +} + +void sit_region_start_bufferify(char *name, int SHT_name_len) +{ + // splicer begin function.region_start_bufferify + const std::string SHCXX_name(name, + ShroudLenTrim(name, SHT_name_len)); + sit::region_start(SHCXX_name); + // splicer end function.region_start_bufferify +} + +void sit_region_stop(const char * name) +{ + // splicer begin function.region_stop + const std::string SHCXX_name(name); + sit::region_stop(SHCXX_name); + // splicer end function.region_stop +} + +void sit_region_stop_bufferify(char *name, int SHT_name_len) +{ + // splicer begin function.region_stop_bufferify + const std::string SHCXX_name(name, + ShroudLenTrim(name, SHT_name_len)); + sit::region_stop(SHCXX_name); + // splicer end function.region_stop_bufferify +} + +void sit_finalize(void) +{ + // splicer begin function.finalize + sit::finalize(); + // splicer end function.finalize +} + +} // extern "C" diff --git a/src/bindings/wrapsit.h b/src/bindings/wrapsit.h new file mode 100644 index 0000000..ce1dc69 --- /dev/null +++ b/src/bindings/wrapsit.h @@ -0,0 +1,42 @@ +// wrapsit.h +// This file is generated by Shroud 0.13.0. Do not edit. +/** + * \file wrapsit.h + * \brief Shroud generated wrapper for sit namespace + */ +// For C users and C++ implementation + +#ifndef WRAPSIT_H +#define WRAPSIT_H + +#include "typessit.h" + +// splicer begin CXX_declarations +// splicer end CXX_declarations + +#ifdef __cplusplus +extern "C" { +#endif + +// splicer begin C_declarations +// splicer end C_declarations + +void sit_init(const char * backend); + +void sit_init_bufferify(char *backend, int SHT_backend_len); + +void sit_region_start(const char * name); + +void sit_region_start_bufferify(char *name, int SHT_name_len); + +void sit_region_stop(const char * name); + +void sit_region_stop_bufferify(char *name, int SHT_name_len); + +void sit_finalize(void); + +#ifdef __cplusplus +} +#endif + +#endif // WRAPSIT_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f5d1e18..5641c32 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -35,14 +35,7 @@ if(BUILD_C_FORTRAN) add_executable(TestFortranLink fortran/TestFortranModule.f90) target_link_libraries(TestFortranLink sit sit_f) target_include_directories(TestFortranLink - PRIVATE ${SIT_PUBLIC_HEADERS}) - - message(STATUS ${SIT_PUBLIC_HEADERS}) - - target_include_directories(TestFortranLink - PRIVATE ${CMAKE_BINARY_DIR}/include) - - + PRIVATE ${CMAKE_Fortran_MODULE_DIRECTORY}) add_test(NAME TestFortranLink COMMAND TestFortranLink) -- GitLab From b30f034d60610d0e59a62c3f206d1924ef21860d Mon Sep 17 00:00:00 2001 From: Valentin Seitz Date: Wed, 29 May 2024 16:52:46 +0200 Subject: [PATCH 2/3] make libsit_f pure fortran --- src/bindings/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bindings/CMakeLists.txt b/src/bindings/CMakeLists.txt index 46cb24f..838d675 100644 --- a/src/bindings/CMakeLists.txt +++ b/src/bindings/CMakeLists.txt @@ -20,7 +20,8 @@ if(GEN_BINDINGS) endif() -target_sources(sit_f PRIVATE wrapfsit.f wrapsit.cpp) +target_sources(sit_f PRIVATE wrapfsit.f) +target_sources(sit PRIVATE wrapsit.cpp) #set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) #set_source_files_properties(wrapsit.cpp PROPERTIES GENERATED TRUE) #set_source_files_properties(wrapfsit.f PROPERTIES GENERATED TRUE) -- GitLab From 4d2bf0837713a37abe0a03c7aebf2ea547d070c5 Mon Sep 17 00:00:00 2001 From: Valentin Seitz Date: Wed, 29 May 2024 16:55:35 +0200 Subject: [PATCH 3/3] update README --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 9e7f280..74f35f5 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,34 @@ Also some backends require finalization, so please make sure to also call `final To add it to your code, currently just install it and use something similar to: `-I/include -L-I/lib -lsit` in the compiler options +## Fortran + +How to configure and install: + +1. `cmake .. -DCMAKE_INSTALL_PREFIX= -DBUILD_C_FORTRAN=ON` +2. `make install` + +### How to use + +```fortran +program test + use sit_mod + call init("Default") + call region_start("test") + call region_stop("test") + call finalize() + end program test +``` + + + +You **must** call `init` exactly once to init the datastructures before you can use the other functionality. +Also some backends require finalization, so please make sure to also call `finalize` in the end. + +To add it to your code, currently just install it and use something similar to: +`gfortran -I.//include .f90 -o /lib/libsit_f.a /lib/libsit.so` in the compiler of your choice. + + # Backends ## DLB -- GitLab