Skip to content

Commit

Permalink
Executable to rule them all (#1075)
Browse files Browse the repository at this point in the history
Changes e.g. `fv3jedi_variational.x config.yaml` -> `gdas_fv3jedi.x
variational config.yaml`. Do we like this?

---------

Co-authored-by: danholdaway <[email protected]>
  • Loading branch information
danholdaway and danholdaway authored May 3, 2024
1 parent 9b53800 commit 70f1319
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 15 deletions.
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ option(BUILD_GDASBUNDLE "Build GDAS Bundle" ON)
option(CLONE_JCSDADATA "Clone JCSDA test data repositories" OFF)
option(WORKFLOW_TESTS "Include global-workflow dependent tests" OFF)

# Build GDAS-managed JEDI executables
if( BUILD_GDASBUNDLE )
find_package( fv3jedi REQUIRED )
find_package( soca REQUIRED )
add_subdirectory( mains )
endif()

# Install utility scripts.
add_subdirectory(ush)

Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ set -x
if [[ $BUILD_JCSDA == 'YES' ]]; then
make -j ${BUILD_JOBS:-6} VERBOSE=$BUILD_VERBOSE
else
builddirs="fv3-jedi soca iodaconv land-imsproc land-jediincr gdas-utils"
builddirs="gdas iodaconv land-imsproc land-jediincr gdas-utils"
for b in $builddirs; do
cd $b
make -j ${BUILD_JOBS:-6} VERBOSE=$BUILD_VERBOSE
Expand Down
28 changes: 28 additions & 0 deletions mains/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Build the big gdas executable used for all generic JEDI applications
# --------------------------------------------------------------------
ecbuild_add_executable( TARGET gdas.x
SOURCES gdas.cc
LIBS fv3jedi soca
)

# Build the soca executables that are not OOPS-based
# --------------------------------------------------
ecbuild_add_executable( TARGET gdas_soca_gridgen.x
SOURCES ${CMAKE_SOURCE_DIR}/soca/src/mains/GridGen.cc
LIBS soca
)

ecbuild_add_executable( TARGET gdas_soca_error_covariance_toolbox.x
SOURCES ${CMAKE_SOURCE_DIR}/soca/src/mains/ErrorCovarianceToolbox.cc
LIBS soca saber
)

ecbuild_add_executable( TARGET gdas_soca_setcorscales.x
SOURCES ${CMAKE_SOURCE_DIR}/soca/src/mains/SetCorScales.cc
LIBS soca
)

ecbuild_add_executable( TARGET gdas_fv3jedi_error_covariance_toolbox.x
SOURCES ${CMAKE_SOURCE_DIR}/fv3-jedi/src/mains/fv3jediErrorCovarianceToolbox.cc
LIBS fv3jedi saber
)
122 changes: 122 additions & 0 deletions mains/gdas.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// -------------------------------------------------------------------------------------------------

#include <functional>
#include <map>

#include "fv3jedi/ObsLocalization/instantiateObsLocFactory.h"
#include "fv3jedi/Utilities/Traits.h"

#include "soca/Traits.h"

#include "oops/generic/instantiateModelFactory.h"
#include "saber/oops/instantiateCovarFactory.h"
#include "ufo/instantiateObsErrorFactory.h"
#include "ufo/instantiateObsFilterFactory.h"
#include "ufo/ObsTraits.h"

#include "oops/runs/ConvertState.h"
#include "oops/runs/HofX4D.h"
#include "oops/runs/LocalEnsembleDA.h"
#include "oops/runs/Run.h"
#include "oops/runs/Variational.h"

// -------------------------------------------------------------------------------------------------

template<typename Traits>
int runApp(int argc, char** argv, const std::string traits, const std::string appName) {
// Create the Run object
oops::Run run(argc, argv);

// Instantiate oops factories
oops::instantiateModelFactory<Traits>();

// Instantiate saber factories
saber::instantiateCovarFactory<Traits>();

// Intantiate ufo factories
ufo::instantiateObsErrorFactory();
ufo::instantiateObsFilterFactory();

// Localization for ensemble DA
if (appName == "localensembleda") {
if (traits == "fv3jedi") {
fv3jedi::instantiateObsLocFactory();
} else if (traits == "soca") {
ufo::instantiateObsLocFactory<soca::Traits>();
}
}

// Application pointer
std::unique_ptr<oops::Application> app;

// Define a map from app names to lambda functions that create unique_ptr to Applications
std::map<std::string, std::function<std::unique_ptr<oops::Application>()>> apps;

apps["convertstate"] = []() {
return std::make_unique<oops::ConvertState<Traits>>();
};
apps["hofx4d"] = []() {
return std::make_unique<oops::HofX4D<Traits, ufo::ObsTraits>>();
};
apps["localensembleda"] = []() {
return std::make_unique<oops::LocalEnsembleDA<fv3jedi::Traits, ufo::ObsTraits>>();
};
apps["variational"] = []() {
return std::make_unique<oops::Variational<Traits, ufo::ObsTraits>>();
};

// Create application object and point to it
auto it = apps.find(appName);

// Run the application
return run.execute(*(it->second()));
}

// -------------------------------------------------------------------------------------------------

int main(int argc, char ** argv) {
// Check that the number of arguments is correct
// ----------------------------------------------
ASSERT_MSG(argc >= 3, "Usage: " + std::string(argv[0]) + " <traits> <application> <options>");

// Get traits from second argument passed to executable
// ----------------------------------------------------
std::string traits = argv[1];
for (char &c : traits) {c = std::tolower(c);}

// Get the application to be run
std::string app = argv[2];
for (char &c : app) {c = std::tolower(c);}

// Check that the traits are recognized
// ------------------------------------
const std::set<std::string> validTraits = {"fv3jedi", "soca"};
ASSERT_MSG(validTraits.find(traits) != validTraits.end(), "Traits not recognized: " + traits);

// Check that the application is recognized
// ----------------------------------------
const std::set<std::string> validApps = {
"convertstate",
"hofx4d",
"localensembleda",
"variational"
};
ASSERT_MSG(validApps.find(app) != validApps.end(), "Application not recognized: " + app);

// Remove traits and program from argc and argv
// --------------------------------------------
argv[2] = argv[0]; // Move executable name to third position
argv += 2; // Move pointer up two
argc -= 2; // Remove 2 from count

// Call application specific main functions
// ----------------------------------------
if (traits == "fv3jedi") {
fv3jedi::instantiateObsLocFactory();
return runApp<fv3jedi::Traits>(argc, argv, traits, app);
} else if (traits == "soca") {
return runApp<soca::Traits>(argc, argv, traits, app);
}
}

// -------------------------------------------------------------------------------------------------
10 changes: 5 additions & 5 deletions scripts/exgdas_global_marine_analysis_bmat.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ function clean_yaml()
if [[ -e 'soca_gridspec.nc' ]]; then
echo "soca_gridspc.nc already exists, skip the grid generation step"
else
# Run soca_gridgen.x if the grid was not staged
# Run gdas_soca_gridgen.x if the grid was not staged
# TODO (Guillaume): Should not use all pe's for the grid generation
$APRUN_OCNANAL $JEDI_BIN/soca_gridgen.x gridgen.yaml
$APRUN_OCNANAL $JEDI_BIN/gdas_soca_gridgen.x gridgen.yaml
export err=$?; err_chk
if [ $err -gt 0 ]; then
exit $err
Expand Down Expand Up @@ -101,14 +101,14 @@ fi
# Horizontal diffusion
if [ ! -f "ocn.cor_rh.incr.0001-01-01T00:00:00Z.nc" ]; then
# Set decorrelation scales for the static B
$APRUN_OCNANAL $JEDI_BIN/soca_setcorscales.x soca_setcorscales.yaml
$APRUN_OCNANAL $JEDI_BIN/gdas_soca_setcorscales.x soca_setcorscales.yaml
export err=$?; err_chk
if [ $err -gt 0 ]; then
exit $err
fi
# Initialize the horizontal diffusion block and normalize
clean_yaml soca_parameters_diffusion_hz.yaml
$APRUN_OCNANAL $JEDI_BIN/soca_error_covariance_toolbox.x soca_parameters_diffusion_hz.yaml
$APRUN_OCNANAL $JEDI_BIN/gdas_soca_error_covariance_toolbox.x soca_parameters_diffusion_hz.yaml
export err=$?; err_chk
if [ $err -gt 0 ]; then
exit $err
Expand All @@ -125,7 +125,7 @@ python ${HOMEgfs}/sorc/gdas.cd/sorc/soca/tools/calc_scales.py soca_vtscales.yaml
clean_yaml soca_parameters_diffusion_vt.yaml

# Initialize the vertical diffusion block and normalize
$APRUN_OCNANAL $JEDI_BIN/soca_error_covariance_toolbox.x soca_parameters_diffusion_vt.yaml
$APRUN_OCNANAL $JEDI_BIN/gdas_soca_error_covariance_toolbox.x soca_parameters_diffusion_vt.yaml
export err=$?; err_chk
if [ $err -gt 0 ]; then
exit $err
Expand Down
4 changes: 2 additions & 2 deletions scripts/exgdas_global_marine_analysis_chkpt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ fi
# TODO: This should probably be in a separate j-job, that includes
# the mom6 incr postprocessing from above.

$APRUN_OCNANAL ${JEDI_BIN}/soca_convertstate.x soca_2cice_arctic.yaml
$APRUN_OCNANAL ${JEDI_BIN}/soca_convertstate.x soca_2cice_antarctic.yaml
$APRUN_OCNANAL ${JEDI_BIN}/gdas.x soca convertstate soca_2cice_arctic.yaml
$APRUN_OCNANAL ${JEDI_BIN}/gdas.x soca convertstate soca_2cice_antarctic.yaml
export err=$?; err_chk

################################################################################
Expand Down
2 changes: 1 addition & 1 deletion scripts/exgdas_global_marine_analysis_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function clean_yaml()
# run the variational application
cp var.yaml var_original.yaml
clean_yaml var.yaml
$APRUN_OCNANAL $JEDI_BIN/soca_var.x var.yaml
$APRUN_OCNANAL $JEDI_BIN/gdas.x soca variational var.yaml
export err=$?; err_chk

################################################################################
Expand Down
2 changes: 1 addition & 1 deletion test/aero/global-workflow/config.aeroanl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ export BERROR_DATE="20160630.000000"
export io_layout_x=1
export io_layout_y=1

export JEDIEXE=${HOMEgfs}/exec/fv3jedi_var.x
export JEDIEXE=${HOMEgfs}/exec/gdas.x

echo "END: config.aeroanl"
2 changes: 1 addition & 1 deletion test/atm/global-workflow/config.atmanl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ export layout_y_atmanl=@LAYOUT_Y_ATMANL@
export io_layout_x=@IO_LAYOUT_X@
export io_layout_y=@IO_LAYOUT_Y@

export JEDIEXE=${EXECgfs}/fv3jedi_var.x
export JEDIEXE=${EXECgfs}/gdas.x

echo "END: config.atmanl"
2 changes: 1 addition & 1 deletion test/atm/global-workflow/config.atmensanl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ export layout_y_atmensanl=@LAYOUT_Y_ATMENSANL@
export io_layout_x=@IO_LAYOUT_X@
export io_layout_y=@IO_LAYOUT_Y@

export JEDIEXE=${EXECgfs}/fv3jedi_letkf.x
export JEDIEXE=${EXECgfs}/gdas.x

echo "END: config.atmensanl"
2 changes: 1 addition & 1 deletion test/snow/create_bkg_ens.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ if [[ ${DAtype} == 'letkfoi_snow' ]]; then

B=30 # background error std for LETKFOI

JEDI_EXEC="fv3jedi_letkf.x"
JEDI_EXEC="gdas.x fv3jedi localensembleda"

# FOR LETKFOI, CREATE THE PSEUDO-ENSEMBLE
for ens in 001 002
Expand Down
2 changes: 1 addition & 1 deletion test/snow/letkfoi_snowda.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ if [[ ${DAtype} == 'letkfoi_snow' ]]; then

B=30 # background error std for LETKFOI

JEDI_EXEC="fv3jedi_letkf.x"
JEDI_EXEC="gdas.x fv3jedi localensembleda"

# FOR LETKFOI, CREATE THE PSEUDO-ENSEMBLE
for ens in 001 002
Expand Down
2 changes: 1 addition & 1 deletion ush/soca/marine_recenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def run(self):
chdir(self.runtime_config.DATA)

exec_cmd_gridgen = Executable(self.config.APRUN_OCNANALECEN)
exec_name_gridgen = os.path.join(self.config.JEDI_BIN, 'soca_gridgen.x')
exec_name_gridgen = os.path.join(self.config.JEDI_BIN, 'gdas_soca_gridgen.x')
exec_cmd_gridgen.add_default_arg(exec_name_gridgen)
exec_cmd_gridgen.add_default_arg(self.config.gridgen_yaml)

Expand Down

0 comments on commit 70f1319

Please sign in to comment.