Skip to content

Commit

Permalink
Merge pull request #702 from NCAR/libdart
Browse files Browse the repository at this point in the history
Buildtools for compiling dart as a library
  • Loading branch information
hkershaw-brown authored Jul 26, 2024
2 parents 05099fd + 3ca755d commit 75cf8dc
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/run_all_quickbuilds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ jobs:
*GMI* | *GOES* | *forward_operators* | *NSIDC* )
cp /home/mkmf.template.rttov.gfortran mkmf.template
;;
*library*)
cp ../developer_tests/library/mkmf.template.gfortran mkmf.template
;;
*)
cp mkmf.template.gfortran mkmf.template
echo 'FFLAGS = -g -Wuninitialized -Wunused -ffree-line-length-none -fbounds-check -fbacktrace -ffpe-trap=invalid,zero,overflow $(INCS)' >> mkmf.template
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
*.a
*.so
*.mod
*.o
*.swp
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ individual files.

The changes are now listed with the most recent at the top.

**July 26 2024 :: Library build tools for DART. Tag v11.6.0**

- Buildtools for compiling DART as a shared or a static library.
- Bugfix: correct order of arguments in count_state_ens_copies for 'input'
stages_to_write.

**July 11 2024 :: Bgrid documentation and scripting fix. Tag v11.5.1**

- Updated Bgrid documentation and removed outdated scripts and files
Expand Down
12 changes: 12 additions & 0 deletions build_templates/buildfunctions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ for p in ${all_programs[@]}; do
done

\rm -f -- preprocess
\rm -f -- libdart.a
\rm -f -- libdart.so
cleanpreprocess

}
Expand Down Expand Up @@ -253,6 +255,16 @@ fi
$program
}

#-------------------------
# Build a library
#
#-------------------------
function buildlib() {
findsrc
$DART/build_templates/mkmf -x -a $DART $m -p $1 \
$dartsrc \
$EXTRA
}
#-------------------------
# Build a model specific program
# looks in $DART/models/$MODEL/src/programs for {main}.f90
Expand Down
8 changes: 7 additions & 1 deletion build_templates/mkmf
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ my $endline = $/;
my @src_suffixes = ( q/\.F/, q/\.F90/, q/\.c/, q/\.f/, q/\.f90/ );
my @inc_suffixes = ( q/\.H/, q/\.fh/, q/\.h/, q/\.inc/ );
push @inc_suffixes, @src_suffixes; # sourcefiles can be includefiles too
my @tgt_suffixes = ( q/\.a/ );
my @tgt_suffixes = ( q/\.a/, q/\.so/ );

print "Using MPI wrappers\n" if $opt_w;
my %compile_cmd;
Expand Down Expand Up @@ -481,6 +481,12 @@ print MAKEFILE "tags: \$(SRC)\n\tctags \$(SRC)\n";
( $name, $path, $suffix ) = fileparse( $opt_p, @tgt_suffixes );
if( $suffix eq '.a' ) {
print MAKEFILE "$opt_p: \$(OBJ)\n\t\$(AR) \$(ARFLAGS) $opt_p \$(OBJ)\n";
} elsif ( $suffix eq '.so' ) {
if ( $opt_w ) {
print MAKEFILE "$opt_p: \$(OBJ)\n\t\$(MPILD) \$(SHR) \$(OBJ) -o $opt_p \$(LDFLAGS)";
} else {
print MAKEFILE "$opt_p: \$(OBJ)\n\t\$(LD) \$(SHR) \$(OBJ) -o $opt_p \$(LDFLAGS)";
}
} elsif ( $opt_w ){
print MAKEFILE "$opt_p: \$(OBJ)\n\t\$(MPILD) \$(OBJ) -o $opt_p $opt_l \$(LDFLAGS)\n";
} else {
Expand Down
2 changes: 1 addition & 1 deletion conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
author = 'Data Assimilation Research Section'

# The full version, including alpha/beta/rc tags
release = '11.5.1'
release = '11.6.0'
root_doc = 'index'

# -- General configuration ---------------------------------------------------
Expand Down
23 changes: 23 additions & 0 deletions developer_tests/library/mkmf.template.gfortran
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Template for GNU gfortran on Linux or Mac OSX
#
# DART software - Copyright UCAR. This open source software is provided
# by UCAR, "as is", without charge, subject to all terms of use at
# http://www.image.ucar.edu/DAReS/DART/DART_download
#

MPIFC = mpif90
MPILD = mpif90
FC = gfortran
LD = gfortran

#NETCDF = /opt/local

INCS = -I$(NETCDF)/include
LIBS = -L$(NETCDF)/lib -lnetcdff -lnetcdf
FFLAGS = -O2 -ffree-line-length-none -fPIC $(INCS)
LDFLAGS = $(FFLAGS) $(LIBS)
SHR = -shared

# FFLAGS = -g -Wuninitialized -Wunused -ffree-line-length-none -fbounds-check \
# -fbacktrace -ffpe-trap=invalid,zero,overflow $(INCS)

18 changes: 18 additions & 0 deletions developer_tests/library/shared/work/input.nml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
&preprocess_nml
overwrite_output = .true.
input_obs_def_mod_file = '../../../../observations/forward_operators/DEFAULT_obs_def_mod.F90'
output_obs_def_mod_file = '../../../../observations/forward_operators/obs_def_mod.f90'
input_obs_qty_mod_file = '../../../../assimilation_code/modules/observations/DEFAULT_obs_kind_mod.F90'
output_obs_qty_mod_file = '../../../../assimilation_code/modules/observations/obs_kind_mod.f90'
obs_type_files = '../../../../observations/forward_operators/obs_def_1d_state_mod.f90'
quantity_files = '../../../../assimilation_code/modules/observations/oned_quantities_mod.f90'
/

&utilities_nml
termlevel = 1,
module_details = .false.,
logfilename = 'dart_log.out',
nmlfilename = 'dart_log.nml',
write_nml = 'file',
print_debug = .false.,
/
36 changes: 36 additions & 0 deletions developer_tests/library/shared/work/quickbuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash

# DART software - Copyright UCAR. This open source software is provided
# by UCAR, "as is", without charge, subject to all terms of use at
# http://www.image.ucar.edu/DAReS/DART/DART_download

main() {


export DART=$(git rev-parse --show-toplevel)
source "$DART"/build_templates/buildfunctions.sh

MODEL=lorenz_96
LOCATION=oned

# quickbuild arguments
arguments "$@"

# clean the directory
\rm -f -- libdart.so *.o *.mod Makefile .cppdefs

# build any NetCDF files from .cdl files
cdl_to_netcdf

# build and run preprocess before making any other DART executables
buildpreprocess

# build static library
buildlib libdart.so

# clean up
\rm -f -- *.o

}

main "$@"
18 changes: 18 additions & 0 deletions developer_tests/library/static/work/input.nml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
&preprocess_nml
overwrite_output = .true.
input_obs_def_mod_file = '../../../../observations/forward_operators/DEFAULT_obs_def_mod.F90'
output_obs_def_mod_file = '../../../../observations/forward_operators/obs_def_mod.f90'
input_obs_qty_mod_file = '../../../../assimilation_code/modules/observations/DEFAULT_obs_kind_mod.F90'
output_obs_qty_mod_file = '../../../../assimilation_code/modules/observations/obs_kind_mod.f90'
obs_type_files = '../../../../observations/forward_operators/obs_def_1d_state_mod.f90'
quantity_files = '../../../../assimilation_code/modules/observations/oned_quantities_mod.f90'
/

&utilities_nml
termlevel = 1,
module_details = .false.,
logfilename = 'dart_log.out',
nmlfilename = 'dart_log.nml',
write_nml = 'file',
print_debug = .false.,
/
36 changes: 36 additions & 0 deletions developer_tests/library/static/work/quickbuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash

# DART software - Copyright UCAR. This open source software is provided
# by UCAR, "as is", without charge, subject to all terms of use at
# http://www.image.ucar.edu/DAReS/DART/DART_download

main() {


export DART=$(git rev-parse --show-toplevel)
source "$DART"/build_templates/buildfunctions.sh

MODEL=lorenz_96
LOCATION=oned

# quickbuild arguments
arguments "$@"

# clean the directory
\rm -f -- libdart.a *.o *.mod Makefile .cppdefs

# build any NetCDF files from .cdl files
cdl_to_netcdf

# build and run preprocess before making any other DART executables
buildpreprocess

# build static library
buildlib libdart.a

# clean up
\rm -f -- *.o

}

main "$@"
97 changes: 97 additions & 0 deletions developer_tests/library/test_libraries.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env bash

set -e
export DART=$(git rev-parse --show-toplevel)

main () {

NETCDF_LIB=/opt/local/
testdir=$(pwd)

# remove any previous test directoires
rm -rf nolib
rm -rf sharedlib
rm -rf staticlib

# use library mkmf.template
cp "$testdir"/mkmf.template.gfortran "$DART"/build_templates/mkmf.template

# regular filter build - this goes first so test directories get *.nc and obs_seq.out input files
cd "$DART"/models/lorenz_96/work
./quickbuild.sh clean
./quickbuild.sh mpif08 filter
rm *.o *.mod

#-----------------
# setup test direcories
cd "$testdir"
cp -r "$DART"/models/lorenz_96/work nolib
cp -r "$DART"/models/lorenz_96/work sharedlib
cp -r "$DART"/models/lorenz_96/work staticlib

#-----------------
# shared library build
cd "$DART"/developer_tests/library/shared/work
./quickbuild.sh clean
./quickbuild.sh mpif08

mpif90 -o filter "$DART"/assimilation_code/programs/filter/filter.f90 -I. -L. -ldart

#-----------------
# static library build
cd "$DART"/developer_tests/library/static/work
./quickbuild.sh clean
./quickbuild.sh mpif08

mpif90 "$DART"/assimilation_code/programs/filter/filter.f90 -I. -L. -ldart -L/$NETCDF_LIB -lnetcdff -o filter

#-----------------
# copy executables built from libraries to test directories
cd "$testdir"/sharedlib
rm filter
cp "$DART"/developer_tests/library/shared/work/filter .
cp "$DART"/developer_tests/library/shared/work/libdart.so .

cd "$testdir"/staticlib
rm filter
cp "$DART"/developer_tests/library/static/work/filter .

#-----------------
# run filter
cd "$testdir"/nolib/
mpirun -n 4 ./filter

cd "$testdir"/sharedlib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)
mpirun -n 4 ./filter

cd "$testdir"/staticlib/
mpirun -n 4 ./filter

check_bitwise "$testdir"/nolib/ "$testdir"/sharedlib/
check_bitwise "$testdir"/nolib/ "$testdir"/staticlib/

}

#-----------------
check_bitwise () {
diff -s "$1"/obs_seq.final "$2"/obs_seq.final

netcdffiles=(\
analysis.nc
filter_input.nc
filter_output.nc
perfect_input.nc
preassim.nc \
)

for f in "${netcdffiles[@]}"
do
echo -n "$f" " "
nccmp -d "$1"/"$f" "$2"/"$f"
echo ""
done
}

main "$@"

17 changes: 17 additions & 0 deletions guide/quickbuild.rst
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,20 @@ finds your new code and ignores any code you do not want compiled.
a directory, a list of files, or a single file.


Building DART as a library
--------------------------

For developers who want to build DART as a library for use with another applications, we provide
the buildlib buildfunction.

.. code-block :: bash
buildlib libdart.a # for a static library
buildlib libdart.so # for a shared library
Example quickbuild.sh scripts for building a shared and a static library are given in
``DART/developer_tests/library/{shared|static}/work``.



0 comments on commit 75cf8dc

Please sign in to comment.