OpenStudioCore:runmanager/lib
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
OpenStudio RunManager

The RunManager library provides a set of tools for queuing and processing of work units called Jobs.Jobs are either tasks that run an external process such as EnergyPlus or an internal process such as ModelToIdf which converts an OSM file to an IDF file.

Jobs can have children, which are able to access the properties of the parents, and execute after the parents have completed. If desired, job trees can become very complicated with multiple branches of child jobs and jobs configured to complete after all other children have completed.

In this page we cover Job Execution, Creating Jobs with Workflow Object, Creating Jobs with JobFactory, Creating Jobs with Hybrid Techniques, and Using Placeholder Jobs. While the latter ones are necessary for the first one to occur, we first show what Job execution means.

Finally, we will cover Searching for Tools which is necessary for telling RunManager where the commonly used tools (such as EnergyPlus) are.

Detailed Descriptions of Job Types Available


Job Execution

The RunManager processes its jobs asynchronously. The developer using the RunManager library may choose to set up the jobs to execute, perform some other tasks, then wait for the jobs to complete. A RunManager object manages its queue via database file, which you will see referenced in the examples below

openstudio::runmanager::RunManager rm(path("file.db"), true, true); // Create a RunManager with a new database file
rm.enqueue(functionThatCreatesJobs()); // Add some jobs to the runmanager
rm.enqueue(functionThatCreatesMoreJobs()); // Add some more jobs to the runmanager
rm.setPaused(false); // Unpause the runmanager so it begins processing of the jobs
// perform foreground work.
doSomeWork(); // RunManager processes in the background while doSomeWork() runs in the foreground
rm.waitForFinished(); // Block until the runamanger has completed running all jobs

Alternatively, the developer may choose to poll the workPending() method.

while(rm.workPending())
{
//Do some other work
}

Creating Jobs with Workflow Object

The primary method for creating jobs is with the Workflow class. Workflow provides repeatable shortcuts for generating job trees.

A typical job process might be to convert an OSM input file to an IDF and process the IDF with EnergyPlus.

The Workflow class has a constructor which can parse simple job tree sequences.

openstudio::runmanager::RunManager rm("newfile.db", true, true);
openstudio::runmanager::Workflow wf("ModelToIdf->EnergyPlus");
rm.enqueue(wf.create("processingdir", "my.osm", "path/to/epws"))
rm.setPaused(false);

For more advanced workflow construction, the individual jobs may be added one at a time:

openstudio::runmanager::RunManager rm("newfile.db", true, true);
wf.addJob(openstudio::runmanager::JobType::ModelToIdf);
wf.addJob(openstudio::runmanager::JobType::EnergyPlus);
rm.enqueue(wf.create("processingdir", "my.osm", "path/to/epws"))
rm.setPaused(false);

The above procedure may seem verbose, but is useful in the case where Files, JobParams, or Tools need to be provided for the job. More on that later.


Creating Jobs with JobFactory

Workflows can only create jobs trees that are linear. In a parent->child->grandchild type of hierarchy with no children that run in parallel. If you need a more complex layout of jobs, or to provide additional parameters to jobs you will need to use the JobFactory.

JobFactory has methods for creating each of the Job types. A factory method returns a job that is ready to begin execution.

= openstudio::runmanager::JobFactory::createModelToIdfJob(openstudio::path("model.osm"), openstudio::path("path/to/outdir")a);
openstudio::runamanger::Files());
openstudio::runmanager::RunManager rm("pathto.db", true, true);
rm.enqueue(j);
rm.setPaused(false);

Creating Jobs with Hybrid Techniques

A third option is to use a combination of techniques to create the job tree you are interested in. Workflow has the ability to create a workflow from an existing job and to append workflows together.

= openstudio::runmanager::JobFactory::createModelObjectPerturbationJob(someRuleset);
openstudio::runmanager::Workflow wf(j); // create workflow from the new job we created
wf.addWorkflow(openstudio::runmanager::Workflow("ModelToIdf->EnergyPlus"));
openstudio::runmanager::RunManager rm("newfile.db", true, true);
rm.enqueue(wf.create("processingdir", "my.osm", "path/to/epws"))
rm.setPaused(false);

Using Placeholder Jobs

The workflow class also supports creating jobs that have a tagname, which can be easily swapped out for a new job or job tree. This can be useful if you want to create a reusable workflow.

wf.addJob(openstudio::runmanager::JobType::NullJob, "keyname");
wf.addWorkflow(openstudio::runmanager::Workflow("ModelToIdf->EnergyPlus"));
// we now have a workflow like: NullJob->ModelToIdf->EnergyPlus
// so we can swap out the NullJob with something more specific
wf.replaceJobs("keyname",openstudio::runmanager::JobFactory::createModelObjectPerturbationJob(someRuleset));
// and now we can create a job from the Workflow and execute it like the previous examples

Searching for Tools

None of the examples above will actually execute because we have failed to tell the system where the tools we need are located. Most notably, we need to find EnergyPlus.

openstudio::runmanager::Tools provides a mechanism for collecting and passing around openstudio::runmanager::ToolInfo objects. ToolInfo objects contain information about tools (xmlpreprocessor, ruby, energyplus, radiance, plus their respective subtools). While ToolInfo objects can be created by hand, it's much more convenient to use one of the provided tool finders.

ConfigOptions co;
co.findTools();
openstudio::runmanager::RunManager rm("newfile.db", true, true);
wf.add(co.getTools());
rm.enqueue(wf.create("processingdir", "my.osm", "path/to/epws"));

Unfortunately, the above procedure can be slow as it searches for all possible tools you have installed on the system. If you do not required Radiance, XMLPreProcessor or Ruby, you can use the faster mechanism which only looks for EnergyPlus.

ConfigOptions co;
co.fastFindEnergyPlus();
openstudio::runmanager::RunManager rm("newfile.db", true, true);
wf.add(co.getTools());
rm.enqueue(wf.create("processingdir", "my.osm", "path/to/epws"));

See also
openstudio::runmanager::RunManager for more information of queuing and monitoring jobs
openstudio::runmanager::Job for more information on Jobs and job properties
openstudio::runmanager::Workflow for more information on creating Jobs with the workflow object
openstudio::runmanager::JobFactory for more information on creating Jobs to be processed with RunManager
openstudio::runmanager::ConfigOptions for more information regarding the configuration of the tool.