Sampling Loop

This tutorial explains performing batch calculations with an application integrated into a pSeven workflow and provides an example of creating loops.


This tutorial requires the workflow from Workflow as a Block.

Before You Begin

This tutorial requires an existing prjTutorials project. If you have not created this project yet, see Tutorial Project first.

  • Open the prjTutorials project.
  • Open wfToySolverBlock (ToySolverBlock.p7wf).
  • Select File ‣ Save Workflow As... to create a copy of the workflow. Save the workflow as wfTestLoop.
  • Verify that you are editing wfTestLoop and continue with the tutorial.


As noted before, the original Toy Solver integration workflow cannot process batch input — that is, it does not allow you to specify a list of input vectors and calculate all outputs in one run.

The task is to create a Toy Solver sampling workflow. It shall generate some input sample, process it automatically, and collect output values for analysis.


Creating a sampling workflow in this example can be divided into the following general steps:

  • Generate an input sample.
  • Feed input points to the solver, one-by-one.
  • Collect results to get an output sample.

The second step is the most important — the sample must somehow be split into individual vectors (data points) so the solver can process them. In fact, there are two possible solutions:

  1. create a loop which processes the input sequentially, or
  2. configure the Model block to start in parallel mode.

This tutorial focuses on the first approach, sequential processing. The second one is discussed in the Parallelization tutorial; it is recommended to complete both of them so you can make comparison.

Input Sample Generation

To simplify the example, let us use a simple random data sample (alternatively, you can use a DoE block as described in the Model Evaluation tutorial, section Test Sample Generation).


If you have already completed the Parallelization tutorial, you can copy the GenerateInputs block from there to skip this step.

  • Add a Random block. Name it GenerateInputs.

Configure the block to output a random matrix with a set number of columns (input dimension) and the number of rows as a workflow parameter.

  • Open GenerateInputs configuration. On the Configuration tab, change output mode to matrix. Leave other settings default.
  • Switch to the Ports tab.
  • Assign a value to GenerateInputs.cols, 2.
  • Select GenerateInputs.rows as a parameter.
  • Click b_ok in the configuration dialog to save settings and close the window.

The block will generate a random data sample and output it to GenerateInputs.value. Sample size should be set in Run (the number of matrix rows is a parameter).

Loop Configuration

To process the generated input sample sequentially you can use a Map block.

  • Add a Map block. Name it Loop.

Map accepts a List of input points to the x_list input port (it can also be a vector or matrix type because they can be converted to List). The list is split into elements which are queued to the x port. The block expects that the loop body (the Model block in the current example) processes these inputs and returns responses to the f port. All responses are accumulated and finally output to the f_list port. Thus you obtain a response sample which can further be used, for example, to train an approximation model.

In this tutorial the response sample is not used in the workflow, so f_list remains unconnected. Required links are:

  • GenerateInputs.value to Loop.x_list,
  • Loop.x to Model.x, and
  • Model.f to Loop.f.

The Loop block does not require additional configuration. Loop.x and Loop.f are monitored automatically, so input-response data is stored to the project database.


Final workflow implements a Toy Solver sampling loop.


Toy Solver integrated into the loop (the Model block) processes the sample generated by GenerateInputs. Sample dimension is fixed in the GenerateInputs configuration, and sample size is specified in Run. Results (loop inputs and outputs) are stored to the project database.


To get a Toy Solver response sample, specify the sample size in Run (for example, 500) and run the workflow.

Input and output values are stored to the Loop.x and Loop.f records respectively.


With these results, you can plot response surfaces for Toy Solver outputs, for example:

  • Create a new report.
  • Add Loop.x and Loop.f to data series.
  • Add a 3D surface plot with two datasets.
  • First dataset: “Loop.x[0]” as X, “Loop.x[1]” as Y, “Loop.f[0]” as Z.
  • Second dataset: “Loop.x[0]” as X, “Loop.x[1]” as Y, “Loop.f[1]” as Z.


This tutorial provides an example of a typical sampling workflow that uses a loop to sequentially process an input sample with an external program. It is also an important example of using an existing workflow as a custom block. Many workflows are created in a similar way — for example, see the Integrated Component Optimization tutorial.

An alternative sampling approach is to use the parallelization feature of Composite blocks. Its benefits are that it does not require a Map block and, in general, runs faster because several solver instances are started in parallel. This solution is detailed in the Parallelization tutorial.