Skip to content

Commit

Permalink
Implement support for cross platform shared object specification via
Browse files Browse the repository at this point in the history
wildcard suffix. Document across layers ESMF->NUOPC->ESMX.
  • Loading branch information
theurich committed May 14, 2024
1 parent f3bf9c9 commit 4bbe0eb
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 29 deletions.
24 changes: 22 additions & 2 deletions src/Superstructure/Component/src/ESMCI_FTable.C
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#ifndef ESMF_NO_DLFCN
#include <dlfcn.h>
#endif
Expand All @@ -43,6 +44,7 @@
#include "ESMCI_Info.h"

using std::string;
using std::vector;

//-----------------------------------------------------------------------------
// leave the following line as-is; it will insert the cvs ident string
Expand Down Expand Up @@ -246,7 +248,16 @@ extern "C" {
if (llen>0){
string sharedObj(sharedObjArg, llen);
sharedObj.resize(sharedObj.find_last_not_of(" ")+1);
lib = dlopen(sharedObj.c_str(), RTLD_LAZY);
if (sharedObj.back()=='*'){
vector<string> suffixes{"so", "dylib", "dll"};
for (auto it=suffixes.begin(); it!=suffixes.end(); ++it){
string sharedObjTemp = sharedObj;
sharedObjTemp.replace(sharedObjTemp.end()-1,sharedObjTemp.end(), *it);
lib = dlopen(sharedObjTemp.c_str(), RTLD_LAZY);
if (lib) break;
}
}else
lib = dlopen(sharedObj.c_str(), RTLD_LAZY);
}else
lib = dlopen(NULL, RTLD_LAZY); // search in executable
if (lib == NULL){
Expand Down Expand Up @@ -298,7 +309,16 @@ extern "C" {
if (llen>0){
string sharedObj(sharedObjArg, llen);
sharedObj.resize(sharedObj.find_last_not_of(" ")+1);
lib = dlopen(sharedObj.c_str(), RTLD_LAZY);
if (sharedObj.back()=='*'){
vector<string> suffixes{"so", "dylib", "dll"};
for (auto it=suffixes.begin(); it!=suffixes.end(); ++it){
string sharedObjTemp = sharedObj;
sharedObjTemp.replace(sharedObjTemp.end()-1,sharedObjTemp.end(), *it);
lib = dlopen(sharedObjTemp.c_str(), RTLD_LAZY);
if (lib) break;
}
}else
lib = dlopen(sharedObj.c_str(), RTLD_LAZY);
}else
lib = dlopen(NULL, RTLD_LAZY); // search in executable
if (lib == NULL){
Expand Down
16 changes: 12 additions & 4 deletions src/Superstructure/Component/src/ESMF_CplComp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2251,8 +2251,12 @@ recursive subroutine ESMF_CplCompSetServicesShObj(cplcomp, userRoutine, &
! standard Component Initialize(), Run(), and Finalize() methods.
! \end{sloppypar}
! \item[{[sharedObj]}]
! Name of shared object that contains {\tt userRoutine}. If the
! {\tt sharedObj} argument is not provided the executable itself will be
! Name of shared object that contains {\tt userRoutine}. The asterisk
! character {\tt (*)} is supported as a wildcard for the file name suffix.
! When present, the asterisk is replaced by "so", "dylib", and "dll", in this
! order, and the first successfully loaded object is used to search for
! {\tt userRoutine}.
! If the {\tt sharedObj} argument is not provided, the executable itself is
! searched for {\tt userRoutine}.
! \item[{[userRoutineFound]}]
! Report back whether the specified {\tt userRoutine} was found and executed,
Expand Down Expand Up @@ -2631,8 +2635,12 @@ recursive subroutine ESMF_CplCompSetVMShObj(cplcomp, userRoutine, &
! {\tt ESMF\_CplCompSetVMxxx()} methods to set the properties of the VM
! associated with the Coupler Component.
! \item[{[sharedObj]}]
! Name of shared object that contains {\tt userRoutine}. If the
! {\tt sharedObj} argument is not provided the executable itself will be
! Name of shared object that contains {\tt userRoutine}. The asterisk
! character {\tt (*)} is supported as a wildcard for the file name suffix.
! When present, the asterisk is replaced by "so", "dylib", and "dll", in this
! order, and the first successfully loaded object is used to search for
! {\tt userRoutine}.
! If the {\tt sharedObj} argument is not provided, the executable itself is
! searched for {\tt userRoutine}.
! \item[{[userRoutineFound]}]
! Report back whether the specified {\tt userRoutine} was found and executed,
Expand Down
16 changes: 12 additions & 4 deletions src/Superstructure/Component/src/ESMF_GridComp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2608,8 +2608,12 @@ recursive subroutine ESMF_GridCompSetServicesShObj(gridcomp, userRoutine, &
! standard Component Initialize(), Run(), and Finalize() methods.
! \end{sloppypar}
! \item[{[sharedObj]}]
! Name of shared object that contains {\tt userRoutine}. If the
! {\tt sharedObj} argument is not provided the executable itself will be
! Name of shared object that contains {\tt userRoutine}. The asterisk
! character {\tt (*)} is supported as a wildcard for the file name suffix.
! When present, the asterisk is replaced by "so", "dylib", and "dll", in this
! order, and the first successfully loaded object is used to search for
! {\tt userRoutine}.
! If the {\tt sharedObj} argument is not provided, the executable itself is
! searched for {\tt userRoutine}.
! \item[{[userRoutineFound]}]
! Report back whether the specified {\tt userRoutine} was found and executed,
Expand Down Expand Up @@ -2989,8 +2993,12 @@ recursive subroutine ESMF_GridCompSetVMShObj(gridcomp, userRoutine, &
! {\tt ESMF\_GridCompSetVMxxx()} methods to set the properties of the VM
! associated with the Gridded Component.
! \item[{[sharedObj]}]
! Name of shared object that contains {\tt userRoutine}. If the
! {\tt sharedObj} argument is not provided the executable itself will be
! Name of shared object that contains {\tt userRoutine}. The asterisk
! character {\tt (*)} is supported as a wildcard for the file name suffix.
! When present, the asterisk is replaced by "so", "dylib", and "dll", in this
! order, and the first successfully loaded object is used to search for
! {\tt userRoutine}.
! If the {\tt sharedObj} argument is not provided, the executable itself is
! searched for {\tt userRoutine}.
! \item[{[userRoutineFound]}]
! Report back whether the specified {\tt userRoutine} was found and executed,
Expand Down
4 changes: 2 additions & 2 deletions src/addon/ESMX/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ This section affects the specific component instance.

There are two options recognized when specifying the value of the `model` field for a component in the `esmxRun.yaml` file:

- First, if the value specified is recognized as a *component-name* provided by any of the components built into `esmx` during build-time, as specified by `esmxBuild.yaml`, the respective component is accessed via its Fortran module.
- Second, if the value does not match a build-time dependency, it is assumed to correspond to a shared object instead. In that case the attempt is made to load the specified shared object file at run-time, and to associate with the generic component label. The search order details of the OS dependent dynamic linker apply to find the specified shared object file. A convenient way to indicate a specific shared object file is to use an absolute or relative path that contains a slash ("/") as part of the specified `model` field value.
- First, if the value specified is recognized as a *component-name* provided by any of the components built into the `esmx_app` during build-time, as specified by `esmxBuild.yaml`, the respective component is accessed via its Fortran module.
- Second, if the value does *not* match a build-time dependency, it is assumed to correspond to a shared object file instead. In that case the attempt is made to load the specified shared object file at run-time, and, if successful, is associated with the generic component label. The search order details of the OS dependent dynamic linker apply when looking for the specified shared object file on the system. A convenient way to target a shared object file at a specific location is to use absolute or relative paths, i.e. the value specified in the `model` field contains at least one slash ("/") character. The asterisk character ("*") is supported as a wildcard for the file name suffix of the specified shared object. This allows portability across systems that differ in shared object suffix. The implemented search order is "so", followed by "dylib", and finally "dll", where the first successfully loaded shared object file is used.

## The Unfied ESMX_Driver

Expand Down
10 changes: 10 additions & 0 deletions src/addon/NUOPC/src/NUOPC_Comp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -4112,6 +4112,11 @@ recursive subroutine NUOPC_GridCompSetServices(comp, sharedObj, userRc, rc)
! and execute the routine. An attempt is made to find a routine that
! is close in name to "{\tt SetServices}", allowing for compiler name
! mangling, i.e. upper and lower case, as well as trailing underscores.
! The asterisk character {\tt (*)} is supported as a wildcard for the
! file name suffix in {\tt sharedObj}. When present, the asterisk is replaced
! by "so", "dylib", and "dll", in this order, and the first successfully
! loaded object is used. If the {\tt sharedObj} argument is not provided, the
! executable itself is searched.
!EOP
!-----------------------------------------------------------------------------
! local variables
Expand Down Expand Up @@ -4247,6 +4252,11 @@ recursive subroutine NUOPC_GridCompSetVM(comp, sharedObj, userRc, rc)
! and execute the routine. An attempt is made to find a routine that
! is close in name to "{\tt SetVM}", allowing for compiler name
! mangling, i.e. upper and lower case, as well as trailing underscores.
! The asterisk character {\tt (*)} is supported as a wildcard for the
! file name suffix in {\tt sharedObj}. When present, the asterisk is replaced
! by "so", "dylib", and "dll", in this order, and the first successfully
! loaded object is used. If the {\tt sharedObj} argument is not provided, the
! executable itself is searched.
!EOP
!-----------------------------------------------------------------------------
! local variables
Expand Down
44 changes: 27 additions & 17 deletions src/addon/NUOPC/src/NUOPC_Driver.F90
Original file line number Diff line number Diff line change
Expand Up @@ -4648,11 +4648,12 @@ recursive subroutine SetVMRoutine(gridcomp, rc)
! or by default across all of the Driver PETs.
!
! The specified {\tt compSetServicesRoutine()} is called back immediately after
! the new child component has been created internally. Very little around the
! component is set up at that time (e.g. NUOPC component attributes will not be
! available). The routine should therefore be very light weight, with the sole
! purpose of setting the entry points of the component -- typically by deriving
! from a generic component followed by the appropriate specilizations.
! the new child component has been created internally.
! Very little around the component is set up at that time (e.g. NUOPC component
! attributes are not yet available at this stage). The routine should therefore
! be very light weight, with the sole purpose of setting the entry points of
! the component -- typically by deriving from a generic component followed by
! the appropriate specilizations.
!
! If provided, the {\tt compSetVMRoutine()} is called back before the
! {\tt compSetServicesRoutine()}. This allows the child component to set
Expand Down Expand Up @@ -4826,13 +4827,21 @@ recursive subroutine NUOPC_DriverAddGridCompSO(driver, compLabel, &
! component to a Driver. The component is created on the provided {\tt petList},
! or by default across all of the Driver PETs.
!
! The {\tt SetServices()} routine in the {\tt sharedObj} is called back
! immediately after the
! new child component has been created internally. Very little around the
! component is set up at that time (e.g. NUOPC component attributes will not be
! available). The routine should therefore be very light weight, with the sole
! purpose of setting the entry points of the component -- typically by deriving
! from a generic component followed by the appropriate specilizations.
! The {\tt SetVM()} and {\tt SetServices()} routines in {\tt sharedObj}
! are called back immediately after the new child component has been created
! internally.
! Very little around the component is set up at that time (e.g. NUOPC component
! attributes are not yet available at this stage). The routine should therefore
! be very light weight, with the sole purpose of setting the entry points of
! the component -- typically by deriving from a generic component followed by
! the appropriate specilizations.
!
! The asterisk character {\tt (*)} is supported as a wildcard for the
! file name suffix in {\tt sharedObj}. When present, the asterisk is replaced
! by "so", "dylib", and "dll", in this order, and the first successfully
! loaded object is used. If the {\tt sharedObj} argument is not provided, the
! executable itself is searched for the "{\tt SetVM}" and "{\tt SetServices}"
! symbols.
!
! The {\tt info} argument can be used to pass custom attributes to the child
! component. These attributes are available on the component when
Expand Down Expand Up @@ -5039,11 +5048,12 @@ recursive subroutine SetVMRoutine(cplcomp, rc)
! and {\tt dstCompLabel}.
!
! The specified {\tt SetServices()} routine is called back immediately after the
! new child component has been created internally. Very little around the
! component is set up at that time (e.g. NUOPC component attributes will not be
! available). The routine should therefore be very light weight, with the sole
! purpose of setting the entry points of the component -- typically by deriving
! from a generic component followed by the appropriate specilizations.
! new child component has been created internally.
! Very little around the component is set up at that time (e.g. NUOPC component
! attributes are not yet available at this stage). The routine should therefore
! be very light weight, with the sole purpose of setting the entry points of
! the component -- typically by deriving from a generic component followed by
! the appropriate specilizations.
!
! The {\tt info} argument can be used to pass custom attributes to the child
! component. These attributes are available on the component when
Expand Down

0 comments on commit 4bbe0eb

Please sign in to comment.