From 649342399e8ef10ab26e73f6a456e166656ad9c4 Mon Sep 17 00:00:00 2001 From: Katherine Rasmussen Date: Fri, 5 Jan 2024 16:29:33 -0800 Subject: [PATCH] feat(fpm): Add new fpm subproject, icar-trainer Add new fpm subproject, icar-trainer, which removes dependencies from inference-engine. This commit contains a working solution for an fpm build of inference-engine. The icar-trainer fpm toml file and associated setup script are not yet complete, and need to be edited to be buildable. --- fpm.toml | 3 +- .../app}/train-cloud-microphysics.f90 | 0 icar-trainer/fpm.toml | 10 ++ icar-trainer/setup.sh | 138 ++++++++++++++++++ .../src}/NetCDF_file_m.f90 | 0 .../src}/NetCDF_file_s.f90 | 0 icar-trainer/test/main.f90 | 27 ++++ .../test}/netCDF_file_test_m.f90 | 0 setup.sh | 74 +--------- src/inference_engine/trainable_engine_s.f90 | 3 +- src/inference_engine_m.f90 | 1 - test/main.f90 | 7 - test/network_configuration_test_m.f90 | 5 +- 13 files changed, 186 insertions(+), 82 deletions(-) rename {app => icar-trainer/app}/train-cloud-microphysics.f90 (100%) create mode 100644 icar-trainer/fpm.toml create mode 100755 icar-trainer/setup.sh rename {src/inference_engine => icar-trainer/src}/NetCDF_file_m.f90 (100%) rename {src/inference_engine => icar-trainer/src}/NetCDF_file_s.f90 (100%) create mode 100644 icar-trainer/test/main.f90 rename {test => icar-trainer/test}/netCDF_file_test_m.f90 (100%) diff --git a/fpm.toml b/fpm.toml index 9cfa64e6e..9b38846f0 100644 --- a/fpm.toml +++ b/fpm.toml @@ -1,10 +1,9 @@ name = "inference-engine" version = "0.5.0" license = "license" -author = "Damian Rouson, Tan Nguyen, Jordan Welsman, David Torres, Brad Richardson" +author = "Damian Rouson, Tan Nguyen, Jordan Welsman, David Torres, Brad Richardson, Katherine Rasmussen" maintainer = "rouson@lbl.gov" [dependencies] assert = {git = "https://github.com/sourceryinstitute/assert", tag = "1.5.0"} sourcery = {git = "https://github.com/sourceryinstitute/sourcery", tag = "4.5.0"} -netcdf-interfaces = {git = "https://github.com/LKedward/netcdf-interfaces.git", rev = "d2bbb71ac52b4e346b62572b1ca1620134481096"} diff --git a/app/train-cloud-microphysics.f90 b/icar-trainer/app/train-cloud-microphysics.f90 similarity index 100% rename from app/train-cloud-microphysics.f90 rename to icar-trainer/app/train-cloud-microphysics.f90 diff --git a/icar-trainer/fpm.toml b/icar-trainer/fpm.toml new file mode 100644 index 000000000..4a6243430 --- /dev/null +++ b/icar-trainer/fpm.toml @@ -0,0 +1,10 @@ +name = "icar-trainer" +version = "0.0.0" +license = "license" +author = "Damian Rouson, Tan Nguyen, Jordan Welsman, David Torres, Brad Richardson, Katherine Rasmussen" +maintainer = "rouson@lbl.gov" + +[dependencies] +assert = {git = "https://github.com/sourceryinstitute/assert", tag = "1.5.0"} +sourcery = {git = "https://github.com/sourceryinstitute/sourcery", tag = "4.5.0"} +netcdf-interfaces = {git = "https://github.com/LKedward/netcdf-interfaces.git", rev = "d2bbb71ac52b4e346b62572b1ca1620134481096"} diff --git a/icar-trainer/setup.sh b/icar-trainer/setup.sh new file mode 100755 index 000000000..7dc1503b4 --- /dev/null +++ b/icar-trainer/setup.sh @@ -0,0 +1,138 @@ +#!/bin/sh + +set -e # exit on error + +usage() +{ + echo "Inference Engine Setup Script" + echo "" + echo "USAGE:" + echo "./setup.sh [--help|-h] | [-p|--prefix=PREFIX]" + echo "" + echo " --help Display this help text" + echo " --prefix=PREFIX Install binary in 'PREFIX/bin'" + echo " Default prefix='\$HOME/.local/bin'" + echo "" +} + +PREFIX="$HOME/.local" + +while [ "$1" != "" ]; do + PARAM=$(echo "$1" | awk -F= '{print $1}') + VALUE=$(echo "$1" | awk -F= '{print $2}') + case $PARAM in + -h | --help) + usage + exit + ;; + -p | --prefix) + PREFIX=$VALUE + ;; + *) + echo "ERROR: unknown parameter \"$PARAM\"" + usage + exit 1 + ;; + esac + shift +done + +set -u # error on use of undefined variable + +if ! command -v brew > /dev/null ; then + if ! command -v curl > /dev/null ; then + echo "Please install curl and then rerun ./setup.sh" + exit 1 + fi + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + if [ $(uname) = "Linux" ]; then + if [ -z "$PATH" ]; then + PATH=/home/linuxbrew/.linuxbrew/bin/ + else + PATH=/home/linuxbrew/.linuxbrew/bin/:"$PATH" + fi + fi +fi + + +brew tap fortran-lang/fortran # required for building fpm +brew install fpm netcdf netcdf-fortran pkg-config coreutils # coreutils supports `realpath` below + +PREFIX=`realpath $PREFIX` + +NETCDF_LIB_PATH="`brew --prefix netcdf`/lib" +HDF5_LIB_PATH="`brew --prefix hdf5`/lib" +NETCDFF_LIB_PATH="`brew --prefix netcdf-fortran`/lib" + +FPM_LD_FLAG=" -L$NETCDF_LIB_PATH -L$HDF5_LIB_PATH -L$NETCDFF_LIB_PATH" +FPM_FLAG="-fcoarray=single -O3 -fallow-argument-mismatch -ffree-line-length-none -L$NETCDF_LIB_PATH -L$HDF5_LIB_PATH" +FPM_FC=${FC:-"gfortran-13"} +FPM_CC=${CC:-"gcc-13"} + +mkdir -p build + +CI=${CI:-"false"} # GitHub Actions workflows set CI=true + +if [ $CI = true ]; then + PKG_CONFIG_PATH=`realpath ./build/pkgconfig` + echo "---------------" + echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" + echo "---------------" +else + PKG_CONFIG_PATH=`realpath "$PREFIX"/lib/pkgconfig` +fi + +if [ ! -d $PKG_CONFIG_PATH ]; then + mkdir -p $PKG_CONFIG_PATH +fi + +INFERENCE_ENGINE_PC="$PKG_CONFIG_PATH/inference-engine.pc" +echo "INFERENCE_ENGINE_FPM_CC=\"$FPM_CC\"" > $INFERENCE_ENGINE_PC +echo "INFERENCE_ENGINE_FPM_FC=\"$FPM_FC\"" >> $INFERENCE_ENGINE_PC +echo "INFERENCE_ENGINE_FPM_LD_FLAG=\"$FPM_LD_FLAG\"" >> $INFERENCE_ENGINE_PC +echo "INFERENCE_ENGINE_FPM_FLAG=\"$FPM_FLAG\"" >> $INFERENCE_ENGINE_PC +echo "Name: inference-engine" >> $INFERENCE_ENGINE_PC +echo "Description: Inference Engine" >> $INFERENCE_ENGINE_PC +echo "URL: https://github.com/berkeleylab/inference-engine" >> $INFERENCE_ENGINE_PC +echo "Version: 0.1.2" >> $INFERENCE_ENGINE_PC +if [ $CI = true ]; then + echo "---------------" + echo "cat $INFERENCE_ENGINE_PC" + cat $INFERENCE_ENGINE_PC + echo "---------------" +fi + +export PKG_CONFIG_PATH +cp scripts/run-fpm.sh-header build/run-fpm.sh +RUN_FPM_SH="`realpath ./build/run-fpm.sh`" +echo "`which fpm` \$fpm_arguments \\" >> $RUN_FPM_SH +echo "--profile release \\" >> $RUN_FPM_SH +echo "--c-compiler \"`pkg-config inference-engine --variable=INFERENCE_ENGINE_FPM_CC`\" \\" >> $RUN_FPM_SH +echo "--compiler \"`pkg-config inference-engine --variable=INFERENCE_ENGINE_FPM_FC`\" \\" >> $RUN_FPM_SH +echo "--flag \"-cpp `pkg-config inference-engine --variable=INFERENCE_ENGINE_FPM_FLAG`\" \\" >> $RUN_FPM_SH +echo "--link-flag \"`pkg-config inference-engine --variable=INFERENCE_ENGINE_FPM_LD_FLAG`\" \\" >> $RUN_FPM_SH +echo "\$program_arguments" >> $RUN_FPM_SH +chmod u+x $RUN_FPM_SH +if [ $CI = true ]; then + echo "---------------" + echo "cat $RUN_FPM_SH" + cat $RUN_FPM_SH + echo "---------------" +fi + +if command -v fpm > /dev/null 2>&1; then + brew tap fortran-lang/fortran + brew install fpm +fi + +echo "$RUN_FPM_SH test" +$RUN_FPM_SH test + +echo "" +echo "____________________ Inference-Engine has been set up! _______________________" +echo "" +echo "To run one of the programs in the example subdirectory, enter a command of the" +echo "following form at a shell command prompt after replacing " +echo "with the base name of a file in the example/ subdirectory:" +echo "" +echo "./build/run-fpm.sh run --example " diff --git a/src/inference_engine/NetCDF_file_m.f90 b/icar-trainer/src/NetCDF_file_m.f90 similarity index 100% rename from src/inference_engine/NetCDF_file_m.f90 rename to icar-trainer/src/NetCDF_file_m.f90 diff --git a/src/inference_engine/NetCDF_file_s.f90 b/icar-trainer/src/NetCDF_file_s.f90 similarity index 100% rename from src/inference_engine/NetCDF_file_s.f90 rename to icar-trainer/src/NetCDF_file_s.f90 diff --git a/icar-trainer/test/main.f90 b/icar-trainer/test/main.f90 new file mode 100644 index 000000000..06c2bdd6b --- /dev/null +++ b/icar-trainer/test/main.f90 @@ -0,0 +1,27 @@ +! Copyright (c), The Regents of the University of California +! Terms of use are as specified in LICENSE.txt +program main + implicit none + + real t_start, t_finish + + integer :: passes=0, tests=0 + + call cpu_time(t_start) +#ifndef __INTEL_FORTRAN + block + use netCDF_file_test_m, only : netCDF_file_test_t + type(netCDF_file_test_t) netCDF_file_test + call netCDF_file_test%report(passes, tests) + end block +#endif // __INTEL_FORTRAN + call cpu_time(t_finish) + + print * + print *,"Test suite execution time: ",t_finish - t_start + print * + print '(*(a,:,g0))',"_________ In total, ",passes," of ",tests, " tests pass. _________" + sync all + print * + if (passes/=tests) error stop "-------- One or more tests failed. See the above report. ---------" +end program diff --git a/test/netCDF_file_test_m.f90 b/icar-trainer/test/netCDF_file_test_m.f90 similarity index 100% rename from test/netCDF_file_test_m.f90 rename to icar-trainer/test/netCDF_file_test_m.f90 diff --git a/setup.sh b/setup.sh index 7dc1503b4..d36ec5b0a 100755 --- a/setup.sh +++ b/setup.sh @@ -7,11 +7,9 @@ usage() echo "Inference Engine Setup Script" echo "" echo "USAGE:" - echo "./setup.sh [--help|-h] | [-p|--prefix=PREFIX]" + echo "./setup.sh [--help|-h]" echo "" echo " --help Display this help text" - echo " --prefix=PREFIX Install binary in 'PREFIX/bin'" - echo " Default prefix='\$HOME/.local/bin'" echo "" } @@ -56,77 +54,15 @@ fi brew tap fortran-lang/fortran # required for building fpm -brew install fpm netcdf netcdf-fortran pkg-config coreutils # coreutils supports `realpath` below +brew install fortran-lang/fortran/fpm -PREFIX=`realpath $PREFIX` - -NETCDF_LIB_PATH="`brew --prefix netcdf`/lib" -HDF5_LIB_PATH="`brew --prefix hdf5`/lib" -NETCDFF_LIB_PATH="`brew --prefix netcdf-fortran`/lib" - -FPM_LD_FLAG=" -L$NETCDF_LIB_PATH -L$HDF5_LIB_PATH -L$NETCDFF_LIB_PATH" -FPM_FLAG="-fcoarray=single -O3 -fallow-argument-mismatch -ffree-line-length-none -L$NETCDF_LIB_PATH -L$HDF5_LIB_PATH" +FPM_FLAG="-fcoarray=single -O3" FPM_FC=${FC:-"gfortran-13"} FPM_CC=${CC:-"gcc-13"} mkdir -p build -CI=${CI:-"false"} # GitHub Actions workflows set CI=true - -if [ $CI = true ]; then - PKG_CONFIG_PATH=`realpath ./build/pkgconfig` - echo "---------------" - echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" - echo "---------------" -else - PKG_CONFIG_PATH=`realpath "$PREFIX"/lib/pkgconfig` -fi - -if [ ! -d $PKG_CONFIG_PATH ]; then - mkdir -p $PKG_CONFIG_PATH -fi - -INFERENCE_ENGINE_PC="$PKG_CONFIG_PATH/inference-engine.pc" -echo "INFERENCE_ENGINE_FPM_CC=\"$FPM_CC\"" > $INFERENCE_ENGINE_PC -echo "INFERENCE_ENGINE_FPM_FC=\"$FPM_FC\"" >> $INFERENCE_ENGINE_PC -echo "INFERENCE_ENGINE_FPM_LD_FLAG=\"$FPM_LD_FLAG\"" >> $INFERENCE_ENGINE_PC -echo "INFERENCE_ENGINE_FPM_FLAG=\"$FPM_FLAG\"" >> $INFERENCE_ENGINE_PC -echo "Name: inference-engine" >> $INFERENCE_ENGINE_PC -echo "Description: Inference Engine" >> $INFERENCE_ENGINE_PC -echo "URL: https://github.com/berkeleylab/inference-engine" >> $INFERENCE_ENGINE_PC -echo "Version: 0.1.2" >> $INFERENCE_ENGINE_PC -if [ $CI = true ]; then - echo "---------------" - echo "cat $INFERENCE_ENGINE_PC" - cat $INFERENCE_ENGINE_PC - echo "---------------" -fi - -export PKG_CONFIG_PATH -cp scripts/run-fpm.sh-header build/run-fpm.sh -RUN_FPM_SH="`realpath ./build/run-fpm.sh`" -echo "`which fpm` \$fpm_arguments \\" >> $RUN_FPM_SH -echo "--profile release \\" >> $RUN_FPM_SH -echo "--c-compiler \"`pkg-config inference-engine --variable=INFERENCE_ENGINE_FPM_CC`\" \\" >> $RUN_FPM_SH -echo "--compiler \"`pkg-config inference-engine --variable=INFERENCE_ENGINE_FPM_FC`\" \\" >> $RUN_FPM_SH -echo "--flag \"-cpp `pkg-config inference-engine --variable=INFERENCE_ENGINE_FPM_FLAG`\" \\" >> $RUN_FPM_SH -echo "--link-flag \"`pkg-config inference-engine --variable=INFERENCE_ENGINE_FPM_LD_FLAG`\" \\" >> $RUN_FPM_SH -echo "\$program_arguments" >> $RUN_FPM_SH -chmod u+x $RUN_FPM_SH -if [ $CI = true ]; then - echo "---------------" - echo "cat $RUN_FPM_SH" - cat $RUN_FPM_SH - echo "---------------" -fi - -if command -v fpm > /dev/null 2>&1; then - brew tap fortran-lang/fortran - brew install fpm -fi - -echo "$RUN_FPM_SH test" -$RUN_FPM_SH test +fpm build --flag ${FPM_FLAG} echo "" echo "____________________ Inference-Engine has been set up! _______________________" @@ -135,4 +71,4 @@ echo "To run one of the programs in the example subdirectory, enter a command of echo "following form at a shell command prompt after replacing " echo "with the base name of a file in the example/ subdirectory:" echo "" -echo "./build/run-fpm.sh run --example " +echo "fpm run --example " diff --git a/src/inference_engine/trainable_engine_s.f90 b/src/inference_engine/trainable_engine_s.f90 index ee696ef43..91eece432 100644 --- a/src/inference_engine/trainable_engine_s.f90 +++ b/src/inference_engine/trainable_engine_s.f90 @@ -35,7 +35,8 @@ class is(differentiable_activation_strategy_t) trainable_engine%differentiable_activation_strategy_ = activation class default - error stop "trainable_engine_s(from_inference_engine): activation strategy must be a differentiable_activation_stragegy_t" + error stop & + "trainable_engine_s(from_inference_engine): activation strategy must be a differentiable_activation_stragegy_t" end select end associate diff --git a/src/inference_engine_m.f90 b/src/inference_engine_m.f90 index 081eb3773..24e79fd9f 100644 --- a/src/inference_engine_m.f90 +++ b/src/inference_engine_m.f90 @@ -9,7 +9,6 @@ module inference_engine_m use inference_engine_m_, only : inference_engine_t, difference_t use kind_parameters_m, only : rkind use mini_batch_m, only : mini_batch_t - use NetCDF_file_m, only : NetCDF_file_t use network_configuration_m, only : network_configuration_t use relu_m, only : relu_t use sigmoid_m, only : sigmoid_t diff --git a/test/main.f90 b/test/main.f90 index cc3f840fd..cfb350749 100644 --- a/test/main.f90 +++ b/test/main.f90 @@ -27,13 +27,6 @@ program main call hyperparameters_test%report(passes, tests) call network_configuration_test%report(passes, tests) call training_configuration_test%report(passes, tests) -#ifndef __INTEL_FORTRAN - block - use netCDF_file_test_m, only : netCDF_file_test_t - type(netCDF_file_test_t) netCDF_file_test - call netCDF_file_test%report(passes, tests) - end block -#endif // __INTEL_FORTRAN call cpu_time(t_finish) print * diff --git a/test/network_configuration_test_m.f90 b/test/network_configuration_test_m.f90 index b512d640f..12afc99e3 100644 --- a/test/network_configuration_test_m.f90 +++ b/test/network_configuration_test_m.f90 @@ -44,7 +44,8 @@ function results() result(test_results) [ write_then_read_network_configuration() & ] & ) - call assert(size(descriptions) == size(outcomes),"network_configuration_test_m(results): size(descriptions) == size(outcomes)") + call assert(size(descriptions) == size(outcomes), & + "network_configuration_test_m(results): size(descriptions) == size(outcomes)") test_results = test_result_t(descriptions, outcomes) end associate @@ -62,4 +63,4 @@ function write_then_read_network_configuration() result(test_passes) end function -end module network_configuration_test_m \ No newline at end of file +end module network_configuration_test_m