diff --git a/.dockerignore b/.dockerignore index dea25df8..b35cbab0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,15 +4,15 @@ # add things to copy !CMakeLists.txt !Dockerfile -!Dockerfile.ccpp !Dockerfile.mpi !Dockerfile.mpi_openmp !Dockerfile.openmp -!ccpp -!cmake +!musica +!musica-fortran !docs -!include +!cmake !lib -!packaging !src -!test \ No newline at end of file +!test +!.gitmodules +!.git \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 631dc000..c70d6ee4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,4 +46,18 @@ jobs: - name: build Docker image run: docker build -t musica-mpi-openmp -f Dockerfile.mpi_openmp . - name: run tests in container - run: docker run --name test-container -t musica-mpi-openmp bash -c 'make test' \ No newline at end of file + run: docker run --name test-container -t musica-mpi-openmp bash -c 'make test' + build_test_connections_musica-fortran: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + steps: + - name: delete unnessary tools to free up space + run: rm -rf /opt/hostedtoolcache + + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: build Docker image + run: docker build -t musica-fortran -f Dockerfile.fortran . + - name: run tests in container + run: docker run --name test-container -t musica-fortran bash -c 'make test' diff --git a/CMakeLists.txt b/CMakeLists.txt index f08e2710..b4184e79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,53 +1,55 @@ -################################################################################ -# Preamble - cmake_minimum_required(VERSION 3.21) -set(CMAKE_USER_MAKE_RULES_OVERRIDE "cmake/SetDefaults.cmake") project( musica - VERSION 0.3.0 + VERSION 0.4.0 LANGUAGES Fortran CXX C ) +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_LIST_DIR}/cmake") +set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_MODULE_PATH}/SetDefaults.cmake") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${PROJECT_SOURCE_DIR}/cmake") -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING - "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." - FORCE) -endif(NOT CMAKE_BUILD_TYPE) +################################################################################ +include(CMakeDependentOption) -message ( STATUS "CMake build configuration for musica(${CMAKE_BUILD_TYPE}) ${PROJECT_VERSION}" ) +# Library options to build +option(USE_MUSICA "Use MUSICA" ON) +message(STATUS "Building MUSICA sources into a library : ${USE_MUSICA}") -include(musica_util) -checkout_submodules() +option(USE_MUSICA_FORTRAN "Use MUSICA Fortran interface" OFF) +message(STATUS "Building MUSICA-Fortran sources into a library : ${USE_MUSICA_FORTRAN}") ################################################################################ # Projet wide setup options -include(CMakeDependentOption) +cmake_dependent_option( + ENABLE_TESTS "Builds tests that ensures each enabled MUSICA component can be used" ON "USE_MUSICA" OFF) +message(STATUS "Build tests for MUSICA : ${ENABLE_TESTS}") -option( ENABLE_TESTS "Builds tests that ensures each enabled MUSICA component can be used" OFF ) +cmake_dependent_option( + ENABLE_TUVX "Builds TUV-x, a photolysis calculator library" ON "USE_MUSICA" OFF) +message(STATUS "Build TUV-x : ${ENABLE_TUVX}") -option( ENABLE_TUVX "Builds TUV-x, a photolysis calculator library" ON ) -option( ENABLE_MICM "Adds MICM, a model independent chemical mechanism solver" ON ) +cmake_dependent_option( + ENABLE_MICM "Adds MICM, a model independent chemical mechanism solver" ON "USE_MUSICA" OFF) +message(STATUS "Build MICM : ${ENABLE_MICM}") -option( ENABLE_CCPP "Builds the CCPP library" OFF ) +cmake_dependent_option( + ENABLE_MPI "Enable MPI parallel support" OFF "USE_MUSICA" OFF) +message(STATUS "Enable MPI parallel support : ${ENABLE_MPI}") -option( ENABLE_MPI "Enable MPI parallel support" OFF) -option( ENABLE_OPENMP "Enable OpemMP support" OFF ) +cmake_dependent_option( + ENABLE_OPENMP "Enable OpemMP support" OFF "USE_MUSICA" OFF) +message(STATUS "Enable OpemMP support : ${ENABLE_OPENMP}") -option( CREATE_ENVIRONMENT_MODULE "Creates an Lmod environment module file that can be installed on the same machine this library is installed to." OFF ) +cmake_dependent_option( + CREATE_ENVIRONMENT_MODULE "Creates an Lmod environment module file that can be installed on the same machine this library is installed to." OFF "USE_MUSICA" OFF) +message(STATUS "Creates an Lmod environment module : ${CREATE_ENVIRONMENT_MODULE}") if(CREATE_ENVIRONMENT_MODULE) set(INSTALL_MODULE_FILE_PATH "" CACHE STRING "This is the path of the modulefiles location that the Lmod files should be installed to.") endif() -# Set up include and lib directories -set( MUSICA_MOD_DIR "${PROJECT_BINARY_DIR}/include" ) -set( MUSICA_LIB_DIR "${PROJECT_BINARY_DIR}/libs" ) - include(GNUInstallDirs) set(INSTALL_PREFIX "musica-${PROJECT_VERSION}") set(INSTALL_MOD_DIR "${INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") @@ -78,146 +80,19 @@ elseif(${CMAKE_Fortran_COMPILER_ID} MATCHES "PGI") endif() ################################################################################ -# Dependencies - -include(cmake/dependencies.cmake) - -############################################################################## -# MUSICA targets - -#################### # MUSICA -add_library(musica STATIC) -add_library(musica::musica ALIAS musica) - -set_target_properties(musica PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${MUSICA_LIB_DIR} - Fortran_MODULE_DIRECTORY ${MUSICA_MOD_DIR} - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} -) - -target_link_libraries(musica - PUBLIC - PkgConfig::netcdff - ${JSON_LIB} -) - -target_include_directories(musica - PUBLIC - $ - $ -) - -target_include_directories(musica - PUBLIC - $ - $ -) - -add_subdirectory(src) - -#################### -# MUSICA-core -add_library(musicacore_object) -add_library(musica::musicacore ALIAS musicacore_object) -add_subdirectory(lib/musica-core/src) - -set_target_properties(musicacore_object PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${MUSICA_LIB_DIR} - Fortran_MODULE_DIRECTORY ${MUSICA_MOD_DIR} -) - -target_include_directories(musicacore_object - PUBLIC - $ - $ -) - -target_link_libraries(musicacore_object - PUBLIC - PkgConfig::netcdff -) - -# add the sources to musica -target_sources(musica - PRIVATE - $ -) - -#################### -# TUV-x -if (ENABLE_TUVX) - add_definitions(-DMUSICA_USE_TUVX) - - set(TUVX_MOD_DIR ${MUSICA_MOD_DIR}) - set(TUVX_LIB_DIR ${MUSICA_LIB_DIR}) - add_subdirectory(lib/tuv-x/src) - - set_target_properties(tuvx_object PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${MUSICA_LIB_DIR} - Fortran_MODULE_DIRECTORY ${MUSICA_MOD_DIR} - ) - - target_include_directories(tuvx_object - PUBLIC - $ - $ - ) - - target_link_libraries(tuvx_object - PUBLIC - musicacore_object - ) - - # add the sources to musica - target_sources(musica - PRIVATE - $ - ) +if(USE_MUSICA) + add_subdirectory(musica) endif() -#################### -# MICM -if (ENABLE_MICM) - add_definitions(-DMUSICA_USE_MICM) - target_compile_features(musica PUBLIC cxx_std_20) - - target_include_directories(musica - PUBLIC - $ - $ - ) - - install( - DIRECTORY - ${PROJECT_SOURCE_DIR}/lib/micm/include/micm - DESTINATION - ${INSTALL_MOD_DIR} - ) +# MUSICA-Fortran +if(USE_MUSICA_FORTRAN) + add_subdirectory(musica-fortran) endif() -#################### -# CCPP - -if(ENABLE_CCPP) - add_subdirectory(ccpp) -endif() - - ################################################################################ # Tests - -# only include packaging if we are the top level project being built -if(PROJECT_IS_TOP_LEVEL AND ENABLE_TESTS) +if(ENABLE_TESTS) enable_testing() - add_subdirectory(test) + add_subdirectory(musica/test) endif() - -################################################################################ -# Packaging - -# only include packaging if we are the top level project being built -if(PROJECT_IS_TOP_LEVEL) - add_subdirectory(packaging) -endif() \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index cdd6b1b3..7879439b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,26 +12,28 @@ RUN dnf -y update \ valgrind \ && dnf clean all -# install json-fortran +# Install json-fortran RUN curl -LO https://github.com/jacobwilliams/json-fortran/archive/8.2.0.tar.gz \ && tar -zxvf 8.2.0.tar.gz \ && cd json-fortran-8.2.0 \ - && export FC=gfortran \ && mkdir build \ && cd build \ && cmake -D SKIP_DOC_GEN:BOOL=TRUE .. \ && make install -# copy the musica core code -COPY . /musica/ +# Set environment variables +ENV FC=gfortran +ENV JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" -# get a tag and build the model -RUN mkdir /build \ - && cd /build \ - && export JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" \ - && cmake \ - -D ENABLE_TESTS=ON \ - ../musica \ - && make install -j 8 +# Copy the musica code +COPY . musica -WORKDIR /build \ No newline at end of file +# Build +RUN cd musica \ + && cmake -S . \ + -B build \ + -D ENABLE_TESTS=ON \ + && cd build \ + && make install -j 8 + +WORKDIR musica/build diff --git a/Dockerfile.ccpp b/Dockerfile.ccpp deleted file mode 100644 index 43fb3e5d..00000000 --- a/Dockerfile.ccpp +++ /dev/null @@ -1,67 +0,0 @@ -# on macOS this image requires rosetta 2 support for virtualization -# the intel compilers do not support the arm architecture so you must build -# on an amd platform, or virtualize -FROM --platform=linux/amd64 fedora:35 - -RUN dnf -y update \ - && dnf -y install \ - cmake \ - gcc-c++ \ - gcc-gfortran \ - gdb \ - git \ - lcov \ - make \ - netcdf-fortran-devel \ - wget \ - glibc-devel \ - && dnf clean all - -# Basekit -RUN wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/7deeaac4-f605-4bcf-a81b-ea7531577c61/l_BaseKit_p_2023.1.0.46401_offline.sh -RUN chmod +x l_BaseKit_p_2023.1.0.46401_offline.sh -RUN ./l_BaseKit_p_2023.1.0.46401_offline.sh -a -s --eula accept - -# HPC toolkit -RUN wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/1ff1b38a-8218-4c53-9956-f0b264de35a4/l_HPCKit_p_2023.1.0.46346_offline.sh -RUN chmod +x l_HPCKit_p_2023.1.0.46346_offline.sh -RUN ./l_HPCKit_p_2023.1.0.46346_offline.sh -a -s --eula accept - -# Set environment variables for intel compilers -ENV ONEAPI_VERSION=2021.4 -ENV ONEAPI_ROOT=/opt/intel/oneapi -ENV PATH=$PATH:$ONEAPI_ROOT/compiler/latest/linux/bin -ENV PATH=$PATH:$ONEAPI_ROOT/compiler/latest/linux/bin/intel64 -ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ONEAPI_ROOT/compiler/latest/linux/compiler/lib/intel64 - -# install json-fortran using GCC -RUN curl -LO https://github.com/jacobwilliams/json-fortran/archive/8.2.0.tar.gz \ - && tar -zxvf 8.2.0.tar.gz \ - && cd json-fortran-8.2.0 \ - && mkdir build \ - && cd build \ - && FC=gfortran cmake -D SKIP_DOC_GEN:BOOL=TRUE .. \ - && make install - -# copy the musica library -COPY . /musica/ - -ENV JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" - -RUN mkdir -p /build/musica /build/ccpp-integration - -# Build musica with GCC -RUN cd /build/musica \ - && FC=gfortran CC=gcc CXX=g++ cmake \ - -D ENABLE_TESTS=ON \ - /musica \ - && make install -j 8 - -# Build musica::ccpp with ifort and link to musica::musica that was built with GCC -RUN cd /build/ccpp-integration \ - && FC=ifort cmake \ - -DCMAKE_BUILD_TYPE=Debug \ - /musica/test/ccpp/integration \ - && make - -WORKDIR /build/ccpp-integration \ No newline at end of file diff --git a/Dockerfile.fortran b/Dockerfile.fortran new file mode 100644 index 00000000..73b196cd --- /dev/null +++ b/Dockerfile.fortran @@ -0,0 +1,70 @@ +# versions and sizes from here: https://hub.docker.com/r/intel/oneapi-hpckit/tags +FROM intel/oneapi-hpckit:latest + +RUN apt update \ + && apt -y install \ + cmake \ + cmake-curses-gui \ + curl \ + libcurl4-openssl-dev \ + libhdf5-dev \ + m4 \ + vim \ + zlib1g-dev \ + git \ + lcov \ + make \ + libnetcdff-dev \ + valgrind \ + gcc \ + gfortran \ + && apt clean + +# Set environment variables to install MUSICA using gcc +ENV FC=gfortran +ENV FFLAGS="-I/usr/include/" + +# Install json-fortran for gnu version +RUN curl -LO https://github.com/jacobwilliams/json-fortran/archive/8.2.0.tar.gz \ + && tar -zxvf 8.2.0.tar.gz \ + && cd json-fortran-8.2.0 \ + && mkdir build \ + && cd build \ + && cmake -D SKIP_DOC_GEN:BOOL=TRUE .. \ + && make install + +# Copy the musica code +COPY . musica + +# Set json-fortran variable to install MUSICA using gcc +ENV JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" + +# Build and install MUSICA +RUN cd musica \ + && cmake -S . \ + -B build \ + -D ENABLE_TESTS=ON \ + && cd build \ + && make install -j 8 + +# Set environment variables to build MUSICA-Fortran using intel compilers +ENV CC=icx +ENV CXX=icpx +ENV FC=ifort + +# Install json-fortran for intel version +RUN cd json-fortran-8.2.0 \ + && mkdir build-intel \ + && cd build-intel \ + && cmake -D SKIP_DOC_GEN:BOOL=TRUE .. \ + && make install + +# Set json-fortran variable to build MUSICA-Fortran using intel +ENV JSON_FORTRAN_HOME="/usr/local/jsonfortran-intel-8.2.0" + +RUN cd musica/musica-fortran/test \ + && mkdir build && cd build \ + && cmake .. \ + && make + +WORKDIR musica/musica-fortran/test/build \ No newline at end of file diff --git a/Dockerfile.mpi b/Dockerfile.mpi index fe47a9d1..bccbf9ae 100644 --- a/Dockerfile.mpi +++ b/Dockerfile.mpi @@ -20,36 +20,40 @@ RUN sudo dnf -y install \ openmpi-devel \ valgrind-openmpi \ && dnf clean all -ENV PATH="${PATH}:/usr/lib64/openmpi/bin/" # install json-fortran RUN curl -LO https://github.com/jacobwilliams/json-fortran/archive/8.2.0.tar.gz \ && tar -zxvf 8.2.0.tar.gz \ && cd json-fortran-8.2.0 \ - && export FC=gfortran \ && mkdir build \ && cd build \ && cmake -D SKIP_DOC_GEN:BOOL=TRUE .. \ && sudo make install -# copy the MusicBox code -COPY . musica/ - +# Set environment variables +ENV PATH="${PATH}:/usr/lib64/openmpi/bin/" +ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib" ENV OMP_NUM_THREADS=3 +ENV FC=gfortran +ENV JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" + +# Copy the musica code +COPY . musica/ RUN git config --global --add safe.directory '*' RUN sudo chown -R test_user.test_user musica -# get a tag and build the model -RUN mkdir build \ - && cd build \ - && export JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" \ - && cmake -D CMAKE_BUILD_TYPE=debug \ - -D ENABLE_MPI:BOOL=TRUE \ + +# Build +RUN cd musica \ + && cmake -S . \ + -B build \ + -D CMAKE_BUILD_TYPE=debug \ -D ENABLE_TESTS=ON \ + -D ENABLE_MPI=ON \ -D CMAKE_Fortran_COMPILER=/usr/lib64/openmpi/bin/mpif90 \ - ../musica \ + && cd build \ && make \ - && sudo make install \ - && sudo chown -R test_user:test_user . + && sudo make install -j 8 \ + && sudo chown -R test_user:test_user . -WORKDIR /home/test_user/build \ No newline at end of file +WORKDIR /home/test_user/musica/build \ No newline at end of file diff --git a/Dockerfile.mpi_openmp b/Dockerfile.mpi_openmp index 83305b7e..a751b1cd 100644 --- a/Dockerfile.mpi_openmp +++ b/Dockerfile.mpi_openmp @@ -20,37 +20,41 @@ RUN sudo dnf -y install \ openmpi-devel \ valgrind-openmpi \ && dnf clean all -ENV PATH="${PATH}:/usr/lib64/openmpi/bin/" # install json-fortran RUN curl -LO https://github.com/jacobwilliams/json-fortran/archive/8.2.0.tar.gz \ && tar -zxvf 8.2.0.tar.gz \ && cd json-fortran-8.2.0 \ - && export FC=gfortran \ && mkdir build \ && cd build \ && cmake -D SKIP_DOC_GEN:BOOL=TRUE .. \ && sudo make install +# Set environment variables +ENV PATH="${PATH}:/usr/lib64/openmpi/bin/" +ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib" +ENV OMP_NUM_THREADS=3 +ENV FC=gfortran +ENV JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" + # copy the MusicBox code COPY . musica/ -ENV OMP_NUM_THREADS=3 - RUN git config --global --add safe.directory '*' RUN sudo chown -R test_user.test_user musica + # get a tag and build the model -RUN mkdir build \ - && cd build \ - && export JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" \ - && cmake -D CMAKE_BUILD_TYPE=debug \ - -D ENABLE_MPI:BOOL=TRUE \ +RUN cd musica \ + && cmake -S . \ + -B build \ + -D CMAKE_BUILD_TYPE=debug \ + -D ENABLE_MPI=ON \ + -D ENABLE_OPENMP=ON \ -D ENABLE_TESTS=ON \ - -D ENABLE_OPENMP:BOOL=TRUE \ -D CMAKE_Fortran_COMPILER=/usr/lib64/openmpi/bin/mpif90 \ - ../musica \ + && cd build \ && make \ - && sudo make install \ - && sudo chown -R test_user:test_user . + && sudo make install \ + && sudo chown -R test_user:test_user . -WORKDIR /home/test_user/build \ No newline at end of file +WORKDIR /home/test_user/musica/build diff --git a/Dockerfile.openmp b/Dockerfile.openmp index 165204ce..b73afd2e 100644 --- a/Dockerfile.openmp +++ b/Dockerfile.openmp @@ -20,38 +20,40 @@ RUN sudo dnf -y install \ openmpi-devel \ valgrind-openmpi \ && dnf clean all -ENV PATH="${PATH}:/usr/lib64/openmpi/bin/" # install json-fortran RUN curl -LO https://github.com/jacobwilliams/json-fortran/archive/8.2.0.tar.gz \ && tar -zxvf 8.2.0.tar.gz \ && cd json-fortran-8.2.0 \ - && export FC=gfortran \ && mkdir build \ && cd build \ && cmake -D SKIP_DOC_GEN:BOOL=TRUE .. \ && sudo make install +# Set environment variables +ENV PATH="${PATH}:/usr/lib64/openmpi/bin/" +ENV OMP_NUM_THREADS=3 +ENV FC=gfortran +ENV JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" + # copy the MusicBox code COPY . musica/ -ENV OMP_NUM_THREADS=3 - RUN git config --global --add safe.directory '*' RUN sudo chown -R test_user.test_user musica + # get a tag and build the model -RUN mkdir build \ - && cd build \ - && export JSON_FORTRAN_HOME="/usr/local/jsonfortran-gnu-8.2.0" \ - && cmake -D CMAKE_BUILD_TYPE=debug \ +RUN cd musica \ + && cmake -S . \ + -B build \ + -D CMAKE_BUILD_TYPE=debug \ -D ENABLE_OPENMP:BOOL=TRUE \ -D ENABLE_TESTS=ON \ -D CMAKE_Fortran_COMPILER=/usr/lib64/openmpi/bin/mpif90 \ -D CMAKE_CXX_COMPILER=/usr/lib64/openmpi/bin/mpic++ \ - ../musica \ + && cd build \ && make VERBOSE=1 \ - && sudo make install \ + && sudo make install -j 8 \ && sudo chown -R test_user:test_user . - -WORKDIR /home/test_user/build \ No newline at end of file +WORKDIR /home/test_user/musica/build \ No newline at end of file diff --git a/README.md b/README.md index 67d699c2..378815e6 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ At present the project encompasses these components - [TUV-x](https://github.com/NCAR/tuv-x) - A photolysis rate calculator +- [MICM](https://github.com/NCAR/micm) + - Model Independent Chemical Module + ## Available grids Pre-made grids for use in MUSICA are available [here](https://wiki.ucar.edu/display/MUSICA/Available+Grids). @@ -22,7 +25,7 @@ to see how you can contribute new science to MUSICA software. ## Citing MUSICA -MUSICA can be cited in at least two ways. The first is to cite the paper that defines the vision +MUSICA can be cited in at least two ways. The first is to cite [the paper](https://doi.org/10.1175/BAMS-D-19-0331.1) that defines the vision of the MUSICA software. The bibtex entry below can be used to generate a citaiton for this. ``` diff --git a/ccpp/CMakeLists.txt b/ccpp/CMakeLists.txt deleted file mode 100644 index ed73d864..00000000 --- a/ccpp/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -#################### -# CCPP library - -add_library(ccpp STATIC) -add_library(musica::ccpp ALIAS ccpp) - -target_link_libraries(ccpp musica::musica) - -# Overwrite the init values choosen by CMake -if (CMAKE_Fortran_COMPILER_ID MATCHES "Intel") - set(CMAKE_Fortran_FLAGS "-fpp") -endif() - -# Set up include and lib directories -set(CCPP_MOD_DIR "${PROJECT_BINARY_DIR}/include/ccpp" ) -set(CCPP_LIB_DIR "${PROJECT_BINARY_DIR}/libs/ccpp" ) - -set(CCPP_INSTALL_PREFIX "musica-ccpp-${PROJECT_VERSION}") -set(CCPP_INSTALL_MOD_DIR "${INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") - -set_target_properties(ccpp PROPERTIES - Fortran_MODULE_DIRECTORY ${CCPP_MOD_DIR} -) - -set_target_properties(ccpp PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CCPP_LIB_DIR} - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} -) - -target_include_directories(ccpp - PUBLIC - $ - $ -) - - -#################### -# micm ccpp api - -add_subdirectory(micm) \ No newline at end of file diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index eb539e2e..684de281 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -28,8 +28,7 @@ if(ENABLE_TESTS) include(FetchContent) FetchContent_Declare(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.12.1 - FIND_PACKAGE_ARGS NAMES GTest + GIT_TAG be03d00f5f0cc3a997d1a368bee8a1fe93651f48 ) set(INSTALL_GTEST OFF CACHE BOOL "" FORCE) diff --git a/cmake/musica_util.cmake b/cmake/musica_util.cmake index 1682e03f..fde0c037 100644 --- a/cmake/musica_util.cmake +++ b/cmake/musica_util.cmake @@ -12,6 +12,8 @@ function(checkout_submodules) message(FATAL_ERROR "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules") endif() endif() + else() + message(FATAL_ERROR "Git was not found") endif() endfunction(checkout_submodules) diff --git a/docs/Software Development Plan.pdf b/docs/Software Development Plan.pdf index 916853d4..d98f5e3a 100644 Binary files a/docs/Software Development Plan.pdf and b/docs/Software Development Plan.pdf differ diff --git a/lib/micm b/lib/micm index fb5efb82..48d3ed14 160000 --- a/lib/micm +++ b/lib/micm @@ -1 +1 @@ -Subproject commit fb5efb82034def032dbc5d9643947e1641df39d1 +Subproject commit 48d3ed14927e65314e5028590a049d6bb4074591 diff --git a/lib/musica-core b/lib/musica-core index f2133112..a0b2da06 160000 --- a/lib/musica-core +++ b/lib/musica-core @@ -1 +1 @@ -Subproject commit f2133112a25aa0dc8ae1a5109003bf72ac5680cf +Subproject commit a0b2da0681a5f7f24721bf7b9997e297cd88f5be diff --git a/lib/tuv-x b/lib/tuv-x index 35b19b37..aa1fef55 160000 --- a/lib/tuv-x +++ b/lib/tuv-x @@ -1 +1 @@ -Subproject commit 35b19b3716bcce45b0ff93ef7e948a0225ebddd5 +Subproject commit aa1fef550320e2fb3fbd480c11cd473d97cbc02a diff --git a/musica-fortran/CMakeLists.txt b/musica-fortran/CMakeLists.txt new file mode 100644 index 00000000..1c7c7a92 --- /dev/null +++ b/musica-fortran/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.21) + +project( + musica-fortran + VERSION 0.0.0 + LANGUAGES Fortran C CXX +) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +# Options +message(STATUS "Build tests for MUSICA : ${ENABLE_TESTS}") + +# Set up include and lib directories +set(MUSICA_FORTRAN_MOD_DIR "${PROJECT_BINARY_DIR}/include") +set(MUSICA_FORTRAN_LIB_DIR "${PROJECT_BINARY_DIR}/libs") + +add_library(musica-fortran STATIC) +add_library(musica::musica-fortran ALIAS musica-fortran) + +set_target_properties(musica-fortran +PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${MUSICA_FORTRAN_LIB_DIR} + Fortran_MODULE_DIRECTORY ${MUSICA_FORTRAN_MOD_DIR} +) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(netcdff IMPORTED_TARGET REQUIRED netcdf-fortran) + +# Find MUSICA package +find_package(musica 0.3.0 REQUIRED) + +target_link_libraries(musica-fortran + PUBLIC + musica::musica) + +target_include_directories(musica-fortran + PUBLIC + $ + $ +) + +# Add sources +add_subdirectory(src) \ No newline at end of file diff --git a/src/cxx_interface/CMakeLists.txt b/musica-fortran/src/CMakeLists.txt similarity index 100% rename from src/cxx_interface/CMakeLists.txt rename to musica-fortran/src/CMakeLists.txt diff --git a/musica-fortran/src/micm/CMakeLists.txt b/musica-fortran/src/micm/CMakeLists.txt new file mode 100644 index 00000000..7e743d8f --- /dev/null +++ b/musica-fortran/src/micm/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(musica-fortran + PUBLIC + interface.F90 +) \ No newline at end of file diff --git a/musica-fortran/src/micm/interface.F90 b/musica-fortran/src/micm/interface.F90 new file mode 100644 index 00000000..355f69c9 --- /dev/null +++ b/musica-fortran/src/micm/interface.F90 @@ -0,0 +1,22 @@ +module micm + use iso_c_binding + + implicit none + + interface + + type(c_funptr) function get_solver(filepath) bind(c) + import :: c_char, c_funptr + character(len=*, kind=c_char), dimension(*), intent(in) :: filepath + end function get_solver + + subroutine solver(state, state_size, time_step) bind(c) + import :: c_ptr, c_double, c_int64_t + real(c_double), dimension(*) :: state + integer(c_int64_t), value :: state_size + integer(c_int64_t), value :: time_step + end subroutine + + end interface + +end module micm \ No newline at end of file diff --git a/musica-fortran/test/CMakeLists.txt b/musica-fortran/test/CMakeLists.txt new file mode 100644 index 00000000..088216ef --- /dev/null +++ b/musica-fortran/test/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.21) + +project( + test_musica_fortran_wrapper + VERSION 0.0.0 + LANGUAGES Fortran C CXX +) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +include(FetchContent) + +set(USE_MUSICA OFF) +set(USE_MUSICA_FORTRAN ON) + +FetchContent_Declare(musica + GIT_REPOSITORY https://github.com/NCAR/musica.git + GIT_TAG bf1b77b ## todo: jiwon update this +) + +FetchContent_MakeAvailable(musica) + +################################################################################ +# Tests +add_executable(test_musica_api test_musica_api.F90) + +target_link_libraries(test_musica_api + PUBLIC + musica::musica-fortran +) + +set_target_properties(test_musica_api +PROPERTIES +LINKER_LANGUAGE Fortran) + +enable_testing() + +add_test( + NAME test_musica_api + COMMAND $ +) \ No newline at end of file diff --git a/musica-fortran/test/test_musica_api.F90 b/musica-fortran/test/test_musica_api.F90 new file mode 100644 index 00000000..8ec61ac8 --- /dev/null +++ b/musica-fortran/test/test_musica_api.F90 @@ -0,0 +1,10 @@ +program test_musica_api + use iso_c_binding + use micm + + character(len=5, kind=c_char) :: c_filepath + type(c_funptr) :: csolver_func_pointer + c_filepath = 'asdf' + csolver_func_pointer = get_solver(c_filepath) + +end program test_musica_api diff --git a/musica/CMakeLists.txt b/musica/CMakeLists.txt new file mode 100644 index 00000000..cb556df0 --- /dev/null +++ b/musica/CMakeLists.txt @@ -0,0 +1,147 @@ +################################################################################ +# Preamble + +# Set up include and lib directories +set(MUSICA_MOD_DIR "${PROJECT_BINARY_DIR}/include") +set(MUSICA_LIB_DIR "${PROJECT_BINARY_DIR}/libs") + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." + FORCE) +endif(NOT CMAKE_BUILD_TYPE) + +message (STATUS "CMake build configuration for musica(${CMAKE_BUILD_TYPE}) ${PROJECT_VERSION}") + +include(musica_util) + +# Add submodules +checkout_submodules() + +################################################################################ +# Dependencies + +include(dependencies) + +############################################################################## +# MUSICA targets + +#################### +# MUSICA +add_library(musica STATIC) +add_library(musica::musica ALIAS musica) + +add_subdirectory(src) + +set_target_properties(musica PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${MUSICA_LIB_DIR} + Fortran_MODULE_DIRECTORY ${MUSICA_MOD_DIR} + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} +) + +target_link_libraries(musica + PRIVATE + PkgConfig::netcdff + ${JSON_LIB} +) + +target_include_directories(musica + PUBLIC + $ + $ +) + +target_include_directories(musica + PUBLIC + $ + $ +) + +#################### +# MUSICA-core +add_library(musicacore_object) +add_library(musica::musicacore ALIAS musicacore_object) + +set(ENABLE_UTIL_ONLY ON) + +set_target_properties(musicacore_object PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${MUSICA_LIB_DIR} + Fortran_MODULE_DIRECTORY ${MUSICA_MOD_DIR} +) + +target_include_directories(musicacore_object + PUBLIC + $ + $ +) + +target_link_libraries(musicacore_object + PRIVATE + PkgConfig::netcdff +) + +# add the sources to musica +target_sources(musica + PRIVATE + $ +) + +add_subdirectory(${PROJECT_SOURCE_DIR}/lib/musica-core/src ${MUSICA_LIB_DIR}/musica-core/src) + +# #################### +# TUV-x +if (ENABLE_TUVX) + add_definitions(-DMUSICA_USE_TUVX) + + set(TUVX_MOD_DIR ${MUSICA_MOD_DIR}) + set(TUVX_LIB_DIR ${MUSICA_LIB_DIR}) + + add_subdirectory(${PROJECT_SOURCE_DIR}/lib/tuv-x/src ${MUSICA_LIB_DIR}/tuv-x/src) + + set_target_properties(tuvx_object PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${MUSICA_LIB_DIR} + Fortran_MODULE_DIRECTORY ${MUSICA_MOD_DIR} + ) + + target_include_directories(tuvx_object + PUBLIC + $ + $ + ) + + target_link_libraries(tuvx_object + PUBLIC + musicacore_object + ) + + # add the sources to musica + target_sources(musica + PRIVATE + $ + ) +endif() + +# #################### +# MICM +if (ENABLE_MICM) + add_definitions(-DMUSICA_USE_MICM) + target_compile_features(musica PUBLIC cxx_std_20) + + target_include_directories(musica + PUBLIC + $ + $ + ) + + install( + DIRECTORY + ${PROJECT_SOURCE_DIR}/lib/micm/include/micm + DESTINATION + ${INSTALL_MOD_DIR} + ) +endif() + +################################################################################ +# Packaging +add_subdirectory(packaging) diff --git a/include/micm/interface.hpp b/musica/include/micm/interface.hpp similarity index 100% rename from include/micm/interface.hpp rename to musica/include/micm/interface.hpp diff --git a/include/musica/component_versions.h b/musica/include/musica/component_versions.h similarity index 100% rename from include/musica/component_versions.h rename to musica/include/musica/component_versions.h diff --git a/include/musica/version.h b/musica/include/musica/version.h similarity index 100% rename from include/musica/version.h rename to musica/include/musica/version.h diff --git a/packaging/CMakeLists.txt b/musica/packaging/CMakeLists.txt similarity index 100% rename from packaging/CMakeLists.txt rename to musica/packaging/CMakeLists.txt diff --git a/packaging/modulefile.lua.in b/musica/packaging/modulefile.lua.in similarity index 100% rename from packaging/modulefile.lua.in rename to musica/packaging/modulefile.lua.in diff --git a/src/CMakeLists.txt b/musica/src/CMakeLists.txt similarity index 77% rename from src/CMakeLists.txt rename to musica/src/CMakeLists.txt index cfc67e2a..752e230b 100644 --- a/src/CMakeLists.txt +++ b/musica/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# micm version +# version configure_file(version.c.in ${CMAKE_BINARY_DIR}/version.c @ONLY) target_sources(musica @@ -7,4 +7,4 @@ target_sources(musica ${CMAKE_BINARY_DIR}/version.c ) -add_subdirectory(cxx_interface) \ No newline at end of file +add_subdirectory(micm) \ No newline at end of file diff --git a/src/component_versions.c b/musica/src/component_versions.c similarity index 100% rename from src/component_versions.c rename to musica/src/component_versions.c diff --git a/src/cxx_interface/micm/CMakeLists.txt b/musica/src/micm/CMakeLists.txt similarity index 100% rename from src/cxx_interface/micm/CMakeLists.txt rename to musica/src/micm/CMakeLists.txt diff --git a/src/cxx_interface/micm/interface.cpp b/musica/src/micm/interface.cpp similarity index 70% rename from src/cxx_interface/micm/interface.cpp rename to musica/src/micm/interface.cpp index 6fcb42ea..4ec80500 100644 --- a/src/cxx_interface/micm/interface.cpp +++ b/musica/src/micm/interface.cpp @@ -5,17 +5,17 @@ // assumes that photo_rates, matches order in c++ already void fortran_solve(void *micm_address, double time_start, double time_end, double *concentrations, double temperature, double pressure, double *photo_rates) { - MICM *micm = static_cast(micm_address); - micm::State state = micm->solver_->GetState(); + // MICM *micm = static_cast(micm_address); + // micm::State state = micm->solver_->GetState(); - for (auto param : state.custom_rate_parameters_[0]) - { - param = *(photo_rates++); - } - state.conditions_[0].pressure_ = pressure; - state.conditions_[0].temperature_ = temperature; + // for (auto param : state.custom_rate_parameters_[0]) + // { + // param = *(photo_rates++); + // } + // state.conditions_[0].pressure_ = pressure; + // state.conditions_[0].temperature_ = temperature; - auto result = micm->solver_->Solve(time_start, time_end, state); + // auto result = micm->solver_->Solve(time_start, time_end, state); } void solver( diff --git a/src/version.c.in b/musica/src/version.c.in similarity index 100% rename from src/version.c.in rename to musica/src/version.c.in diff --git a/test/CMakeLists.txt b/musica/test/CMakeLists.txt similarity index 67% rename from test/CMakeLists.txt rename to musica/test/CMakeLists.txt index 9221dfc1..0fb7e39c 100644 --- a/test/CMakeLists.txt +++ b/musica/test/CMakeLists.txt @@ -2,8 +2,4 @@ # Add subdirectories containing tests add_subdirectory(connections) -add_subdirectory(unit) - -if(ENABLE_CCPP) - add_subdirectory(ccpp) -endif() \ No newline at end of file +add_subdirectory(unit) \ No newline at end of file diff --git a/test/connections/CMakeLists.txt b/musica/test/connections/CMakeLists.txt similarity index 79% rename from test/connections/CMakeLists.txt rename to musica/test/connections/CMakeLists.txt index 0e741fb7..a13cc463 100644 --- a/test/connections/CMakeLists.txt +++ b/musica/test/connections/CMakeLists.txt @@ -1,15 +1,11 @@ -################################################################################ -# Test utilities - include(test_util) -################################################################################ -# Tests - create_standard_test(NAME connect_to_musica_core SOURCES musica_core.F90) + if (ENABLE_OPENMP) create_standard_test(NAME connect_to_musica_core_openmp SOURCES musica_core_openmp.F90) endif() + if (ENABLE_MPI) create_standard_test(NAME connect_to_musica_core_mpi SOURCES musica_core_mpi.F90) endif() diff --git a/test/connections/micm.cpp b/musica/test/connections/micm.cpp similarity index 100% rename from test/connections/micm.cpp rename to musica/test/connections/micm.cpp diff --git a/test/connections/musica_core.F90 b/musica/test/connections/musica_core.F90 similarity index 100% rename from test/connections/musica_core.F90 rename to musica/test/connections/musica_core.F90 diff --git a/test/connections/musica_core_mpi.F90 b/musica/test/connections/musica_core_mpi.F90 similarity index 100% rename from test/connections/musica_core_mpi.F90 rename to musica/test/connections/musica_core_mpi.F90 diff --git a/test/connections/musica_core_openmp.F90 b/musica/test/connections/musica_core_openmp.F90 similarity index 100% rename from test/connections/musica_core_openmp.F90 rename to musica/test/connections/musica_core_openmp.F90 diff --git a/test/connections/tuvx.F90 b/musica/test/connections/tuvx.F90 similarity index 100% rename from test/connections/tuvx.F90 rename to musica/test/connections/tuvx.F90 diff --git a/test/connections/tuvx_mpi.F90 b/musica/test/connections/tuvx_mpi.F90 similarity index 100% rename from test/connections/tuvx_mpi.F90 rename to musica/test/connections/tuvx_mpi.F90 diff --git a/test/connections/tuvx_openmp.F90 b/musica/test/connections/tuvx_openmp.F90 similarity index 100% rename from test/connections/tuvx_openmp.F90 rename to musica/test/connections/tuvx_openmp.F90 diff --git a/test/unit/CMakeLists.txt b/musica/test/unit/CMakeLists.txt similarity index 100% rename from test/unit/CMakeLists.txt rename to musica/test/unit/CMakeLists.txt diff --git a/test/unit/component_versions.cpp b/musica/test/unit/component_versions.cpp similarity index 100% rename from test/unit/component_versions.cpp rename to musica/test/unit/component_versions.cpp diff --git a/test/ccpp/CMakeLists.txt b/test/ccpp/CMakeLists.txt deleted file mode 100644 index 059f2a25..00000000 --- a/test/ccpp/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(unit) \ No newline at end of file diff --git a/test/ccpp/integration/CMakeLists.txt b/test/ccpp/integration/CMakeLists.txt deleted file mode 100644 index 4aab90e4..00000000 --- a/test/ccpp/integration/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -cmake_minimum_required(VERSION 3.21) - -project( - ccpp_integration - VERSION 0.0.0 - LANGUAGES Fortran -) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) - -find_package(musica 0.2.0 REQUIRED) -find_package(PkgConfig REQUIRED) - -# Find libstdc++ -find_library(LIBSTDCXX_PATH NAMES libstdc++.so.6 - PATHS - /usr/lib - /usr/lib64 - REQUIRED -) - -# NetCDF library -pkg_check_modules(netcdff IMPORTED_TARGET REQUIRED netcdf-fortran) - -# this path is the one expected in the docker image -set(MUSICA_CCPP_WRAPPER "/musica/ccpp" CACHE STRING "The location of the MUSICA ccpp fortran wrapper code") -add_subdirectory(${MUSICA_CCPP_WRAPPER} ${CMAKE_BINARY_DIR}/__ccpp) - -################################################################################ -# Test utilities - -include(test_util.cmake) -enable_testing() - -################################################################################ -# Tests - -create_standard_test(NAME micm_ccpp_api SOURCES ../unit/micm.F90 LIBRARIES musica::ccpp) - -target_link_libraries(test_micm_ccpp_api PRIVATE ${LIBSTDCXX_PATH}) \ No newline at end of file diff --git a/test/ccpp/integration/test_util.cmake b/test/ccpp/integration/test_util.cmake deleted file mode 100644 index aa9e621f..00000000 --- a/test/ccpp/integration/test_util.cmake +++ /dev/null @@ -1,36 +0,0 @@ -################################################################################ -# build and add a standard test (one linked to the tuvx library) - -function(create_standard_test) - set(prefix TEST) - set(singleValues NAME WORKING_DIRECTORY) - set(multiValues SOURCES LIBRARIES) - include(CMakeParseArguments) - cmake_parse_arguments(${prefix} " " "${singleValues}" "${multiValues}" ${ARGN}) - - add_executable(test_${TEST_NAME} ${TEST_SOURCES}) - - # link additional libraries - foreach(library ${TEST_LIBRARIES}) - target_link_libraries(test_${TEST_NAME} PUBLIC ${library}) - endforeach() - - target_link_libraries(test_${TEST_NAME} PUBLIC musica::musica) - - if(NOT DEFINED TEST_WORKING_DIRECTORY) - set(TEST_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") - endif() - - add_musica_test(${TEST_NAME} test_${TEST_NAME} "" ${TEST_WORKING_DIRECTORY}) -endfunction(create_standard_test) - -################################################################################ -# Add a test - -function(add_musica_test test_name test_binary test_args working_dir) - add_test(NAME ${test_name} - COMMAND ${test_binary} ${test_args} - WORKING_DIRECTORY ${working_dir}) -endfunction(add_musica_test) - -################################################################################ diff --git a/test/ccpp/unit/CMakeLists.txt b/test/ccpp/unit/CMakeLists.txt deleted file mode 100644 index 264d157b..00000000 --- a/test/ccpp/unit/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -################################################################################ -# Test utilities - -include(test_util) - -################################################################################ -# Tests - -create_standard_test(NAME micm_ccpp_api SOURCES micm.F90 LIBRARIES musica::ccpp) \ No newline at end of file diff --git a/test/ccpp/unit/micm.F90 b/test/ccpp/unit/micm.F90 deleted file mode 100644 index 7c78bb23..00000000 --- a/test/ccpp/unit/micm.F90 +++ /dev/null @@ -1,32 +0,0 @@ -program micm_ccpp_api_test - - use micm - - implicit none - - ! use ccpp_kinds, only: kind_phys - ! //TODO: figure out how to connect the test to ccpp to use their actual kind - integer, parameter :: kind_phys = kind(8) - - call test_api() - -contains - - subroutine test_api() - character(len=512) :: errmsg - integer :: errflg - - character(len=*), parameter :: filepath = "somepath.json" - - real(kind=kind_phys), dimension(:), allocatable :: state - integer(kind=8) :: state_size = 5 - integer(kind=8) :: time_step = 1 - - allocate(state(state_size)) - state = 1 - - call micm_init(filepath, errmsg, errflg) - call micm_run(state, state_size, time_step, errmsg, errflg) - end subroutine test_api - -end program micm_ccpp_api_test