...
Delft-FEWS can split ensemble workflows (that have the runInLoop element set to true) over multiple cores. Based on the available amount of cores a number of queues is made, one for each core. When running the activity the different ensemble members are added to the different queues. An example of a workflow that can use this feature is shown below:
Code Block | ||||
---|---|---|---|---|
| ||||
<activity> <runIndependent>true</runIndependent> <moduleInstanceId>MOGREPS_Spatial_Interpolation</moduleInstanceId> <ensemble> <ensembleId>MOGREPS</ensembleId> <runInLoop>true</runInLoop> </ensemble> </activity> |
By default the General Adapter runs are performed in the %TMP% directory. You can force a different directory by defining the %tempDir% variable that overrules the %TMP% environment variable in the global.properties.
Configuration
By default Delft-FEWS will only use one core and all tasks are run one after another. To enable the parallel running of ensemble members the runInLoopParallelProcessorCount entry must be set in the global properties file. Here you either specify the number of cores to use or specify 100 to use all available cores.
...
Config Example |
|
---|
For all internal Delft-FEWS modules that have been tested no changes are needed to the configuration. For external modules that are run using the General adapter some changes may be needed to the configuration.
...
Module | Remarks |
---|---|
Transformation (old) | Test ok |
Interpolation | Test ok. Interpolation via DLL not tested |
TransformationModule (new) | Test ok. Interpolation via DLL not tested |
pcrTransformation | Test ok |
General Adapter | test ok |
Sample input and output
An example for parallel running an import and then processing of the import modules is:
Code Block | ||||
---|---|---|---|---|
| ||||
<parallel>
<activity>
<runIndependent>true</runIndependent>
<moduleInstanceId>Import1</moduleInstanceId>
</activity>
<activity>
<runIndependent>true</runIndependent>
<moduleInstanceId>Import2</moduleInstanceId>
</activity>
<activity>
<runIndependent>true</runIndependent>
<moduleInstanceId>Import3</moduleInstanceId>
</activity>
</parallel>
<activity>
<runIndependent>true</runIndependent>
<moduleInstanceId>CombineImports</moduleInstanceId>
</activity>
<activity>
<runIndependent>true</runIndependent>
<moduleInstanceId>SpatialInterpolation</moduleInstanceId>
</activity>
|
In this example the imports are run in parallel (as many as the runInLoopParallelProcessorCount is defined). Once they are all ready, the postprocessing modules are performed.
Another example for running a SobekRE model requires more advanced configuration. It is possible to run in parallel the sobek models, but the preprocessor of the adapter is not thread safe. So we need to ensure that the preprocessor (that converts the PI-timeseries into model) never runs in parallel.
The workflow shows:
Code Block | ||||
---|---|---|---|---|
| ||||
<activity>
<runIndependent>false</runIndependent>
<moduleInstanceId>Sobek_Prep</moduleInstanceId>
<ensemble>
<ensembleId>EPS</ensembleId>
<runInLoop>true</runInLoop>
</ensemble>
</activity>
<activity>
<runIndependent>false</runIndependent>
<moduleInstanceId>Sobek_GA</moduleInstanceId>
<ensemble>
<ensembleId>EPS</ensembleId>
<runInLoop>true</runInLoop>
</ensemble>
</activity>
<activity>
<runIndependent>true</runIndependent>
<moduleInstanceId>Sobek_Post</moduleInstanceId>
</activity>
|
The workflow first runs the Sobek_Prep module for each ensemble member individually. You can also run the Sobek_prep in one go (like the Sobek_Post). In that case the whole ensemble is looped in the transformation module itselves but that requires more RAM and does not use multiple threading.
The next module Sobek_GA runs the sobek model for each individual ensemble member. See the details for sobek below. The last module Sobek_Post is run in one go. Here defined as an example, but probably it is more efficient to run this activity also in parallel like the Sobek_Prep for performance reasons.
The General Adapter configuration of the Sobek_GA should look like:
Code Block | ||||
---|---|---|---|---|
| ||||
<general>
<rootDir>%TEMP_DIR%</rootDir>
<workDir>%ROOT_DIR%/work</workDir>
...
</general>
<activities>
<exportActivities>
<exportDataSetActivity>
<moduleInstanceId>Sobek_GA</moduleInstanceId>
</exportDataSetActivity>
</exportActivities>
<executeActivities>
<executeActivity>
<command>
<className>nl.wldelft.fews.adapter.sobek.PreSobekModelAdapter</className>
</command>
<arguments>
<argument>%ROOT_DIR%</argument>
<argument>Config/sobekConfig.xml</argument>
</arguments>
<timeOut>60000</timeOut>
<waitForOtherRun>true</waitForOtherRun>
<overrulingDiagnosticFile>%ROOT_DIR%/diagnostics/presobekmodeladapter.xml</overrulingDiagnosticFile>
</executeActivity>
<executeActivity>
<command>
<executable>%ROOT_DIR%/bin/sobeksim.exe</executable>
</command>
<arguments>
<argument>%ROOT_DIR%/bin/sobeksim.fnm</argument>
</arguments>
<timeOut>600000</timeOut>
<ignoreDiagnostics>true</ignoreDiagnostics>
</executeActivity>
<executeActivity>
<command>
<className>nl.wldelft.fews.adapter.sobek.PostSobekModelAdapter</className>
</command>
<arguments>
<argument>%ROOT_DIR%</argument>
<argument>Config/sobekConfig.xml</argument>
</arguments>
<timeOut>60000</timeOut>
<overrulingDiagnosticFile>%ROOT_DIR%/diagnostics/postsobekmodeladapter.xml</overrulingDiagnosticFile>
</executeActivity>
</executeActivities>
<importActivities>
...
</importActivities>
</activities>
|
Notice that it is ensured that the preprocessor does not run in parallel with another ensemblemember by defining the element waitForOtherRun=true.
In this example the next global.properties should be defined:
No Format |
---|
runInLoopParallelProcessorCount=2
tempDir=d:\temp |
This makes that maximum 2 threads are used and the Sobek runs are performed in temporary directories that are created in the tempdir. Per ensemble member a subdirectory is created where the name is defined as %tempdir%\<region>_<_moduleInstance>_<EnsembleId>_<EnsembleMemberIndex>__<threadId>, e.g. d:\temp\TestRegion_Sobek_GA_EPS_1_4438868285134166498. These directories are removed after running. The directories are filled with data that you should export from a moduledataset. Notice that purgeActivities will not work therefore.Sample input and output
Error and warning messages
...