New “Lazy” Driver

Lazy Drivers

The concept behind a lazy driver is to allow Dakota to “set and forget” its individual evaluations.

  • A lazy driver performs no calculations of its own, but simply wraps itself around the actual analysis driver which performs all the work.

  • With a lazy driver, once Dakota has spun up separate analysis driver processes for each evaluation, Dakota will exit early, returning NaN values in place of the final evaluations. At a later stage, the user is able to re-run Dakota, and, thanks to the logic built in to the lazy analysis driver, each previously calculated evaluation will be picked up without re-running the analysis driver calculations required to arrive at that value.

  • The most beneficial use case for lazy analysis drivers is for evaluations that take an exceedingly long time to run. Lazy analysis drivers can also be used in conjunction with remote job submission, if remote high-performance computers must be used to complete the calculations. The Dakota GUI supports lazy analysis drivers written in Python, Bash, or IWF (Next-Gen Workflow) format.

Using the Wizard

To launch the wizard, select File > New > Other, and then, in the “Select a wizard” dialog, select Dakota > New Lazy Dakota Driver.

Page 1 (Lazy Driver File Creation)

The first page of the wizard is a standard file creation dialog that asks you to select a directory for your new driver, and to provide a name for your new driver.

Page 2 (Lazy Driver Specification)

File creation page

In the first section, “Targeted Analysis Driver,” you should provide information about the analysis driver that your lazy driver is going to wrap around. The wizard will automatically take care of all the hard work of connecting your existing analysis driver to the new lazy driver that it will eventually create.

The idea here is to fill the boxes with the equivalent Dakota keyword values that you would find in your study’s interface block. So, for example, if your Dakota study invokes an analysis_drivers driver of “rosenbrock.py” with parameters_file “params.in” and results_file “results.out,” the wizard’s “Targeted Analysis Driver” fields should be filled out like so:

Example analysis driver target

Note

Here, we omitted the quotes that were provided earlier. Quotes are strictly optional - if you do not provide them, then they will be provided for you when the driver is created.

Note

Also, note the “…” button next to the “analysis_drivers” field. This gives you a file browser that allows you to navigate directly to your analysis driver, if it is a file that is on your machine. This can be easier than typing the entire path into the field.

The next section, simply called “Lazy Analysis Driver,” has two fields.

  • Format is a dropdown that allows you to specify the format of your lazy driver. This wizard is capable of generating drivers in either Python, Bash, or IWF (Next-Gen Workflow) format.

  • Fail Value is an arbitrary value that indicates that your real analysis driver has not returned any result values yet for a given evaluation, so the lazy driver will return this fail value until the real driver provides a real value. We have found in practice that “NaN” is the best default “fail” value, but some drivers provide a return value of “NaN” with special meaning. Nevertheless, you are required to select a fail value that will always indicate the driver has not yet returned results.

Note

We optimistically phrased the language around fail values in the previous section to indicate that the analysis driver will eventually return a valid evaluation value to the lazy driver. However, this may not be the case. If the analysis driver fails to complete for whatever reason, the lazy driver will also use its designated fail value to indicate nothing was returned by the analysis driver. However, the GUI has other introspection tools for indicating driver status beyond checking the fail value in the results file.

Finally, the wizard allows you to provide a list of expected input parameters and output results for your lazy driver. This is also optional, but recommended, as it is best practice for drivers to declare some sort of manifest of their expected inputs and outputs. For example, the Python lazy driver script template is equipped to perform error-checking if a bad list of input parameters are passed in, but ONLY if you tell it what input parameters to expect in the first place.

Once you have entered everything in, click Finish. The new lazy driver script will be added to the directory you specified on the first page.

Note

Lazy drivers do not automatically pipe stdout and stderr from lower-level drivers that are invoked up to the GUI console, where analysis driver output would be most useful. Therefore, it is recommend that the original analysis driver performs as much responsible, self-sufficient logging as possible, so that errors several layers down below the lazy driver level are not lost. For example, the driver could send its output to a separate log file instead of simply dumping messaging on the console.

It is also a good idea to run your Dakota study once without the lazy driver in place to make sure things are running smoothly before you replace your original analysis driver with the lazy driver wrapper.

After Finishing the Wizard

Update your interface block

Wait!!! Before you run your lazy driver, the interface block needs to be modified:

Warning

Lazy drivers require extremely particular Dakota interface blocks in order to work correctly. Not only do your analysis driver’s working directories need to be tagged and saved, but it’s also critically important that all the new lazy driver is linked/copied into the working directory’s list of files, and the allow_existing_results must be used as well, to allow the lazy driver to re-run multiple times without blowing away previous evaluations.

This is a lot of bookkeeping to do by hand. To alleviate this problem, we designed an interface block recipe called “Update interface to use lazy driver.” In the Dakota text editor, simply right-click the “interface” keyword, choose “Replace block with recipe,” and then choose “Update interface to use lazy driver.” Provide this recipe with your new lazy driver file, and all the correct substitutions will be made for you.

Use a run configuration to test out your lazy driver

Lazy drivers can be run through the standard Dakota run configurations, without any further modification.

Once your lazy driver has completed its first successful run, there are several helpful context menu options you might want to take advantage of to inspect the output of each evaluation directory, so that you can decide when it’s time to run the lazy driver a second time and collect output results back to Dakota.