It should be possible to choose the step scheduling type, among at least full parallelism (legacy code), and cascading parallelism.
The current chosen mode in the OSP is full parallel. This mode matchs with hard real time systems but can be improved in the case of simulation systems.
A simple way to improve efficiency is to cascade simulators following their output/input dependencies in order to earn in number of execution steps.
For instance, suppose that, in OspSystemStructure.xml, we defined:
the ordered simulator sequence {S1, S2, S3, S4, S5} and then
the connections between outputs (Y) and inputs (U) variables:
S1.Y -> S3.U
S2.Y -> S3.U
S3.Y -> S5.U
S4.Y -> S5.U
S5.Y -> S1.U
S5.Y -> S2.U
If we define the following order relation:
A < B if:
A precedes B in the ordered simulator sequence
AND
A.Y -> B.U
We can deduce from these 2 main informations a STEP PARTIAL ORDER
(that is why parallelism will be possible):
S1 < S3
S2 < S3
S3 < S5
S4 < S5
Assume that we define a task TSi that:
flowchart TB
A["Set inputs from OSP to Si"] --> B["Si.do_step()"] --> C["Get outputs from Si to OSP"]
Then for 1 step, we compute everything using cascade and parallelism,
i.e. see this UML like activity diagram with forks:
... do_step(...){
tf::Executor executor;
tf::Taskflow taskflow;
auto [TS1, TS2, TS3, TS4, TS5] = taskflow.emplace( // create tasks
[] () { std::cout << "TS1\n"; set inputs; S1.do_step(); get outputs; },
[] () { std::cout << "TS2\n"; set inputs; S2.do_step(); get outputs; },
[] () { std::cout << "TS3\n"; set inputs; S3.do_step(); get outputs; },
[] () { std::cout << "TS4\n"; set inputs; S4.do_step(); get outputs; },
[] () { std::cout << "TS5\n"; set inputs; S5.do_step(); get outputs; }
);
// S1 < S3 and S2 < S3
TS3.succeed(TS1, TS2); // TS3 runs after TS1 and TS2
// S3 < S5 and S4 < S5
TS5.succeed(TS1, TS4); // TS5 runs after TS3 and TS4
executor.run(taskflow).wait();
return ...;
}
DESCRIPTION
As a
OSP user
I want to
be able to choose the step scheduling type, among at least: - full parallelism (legacy code), and - cascading parallelism, deduced from the OSP OspSystemStructure.xml configuration file.
So that
at each step of execution, the applied algorithm is the selected one.
ACCEPTANCE TESTS
Given that
an OSP configuration file describe the above example with an increment of 1 from input to output
When
the user selects full parallelism scheduling type
Then
The results are in consequence (to be calculated by the tester before reading them)
Given that
an OSP configuration file describe the above example with an increment of 1 from input to output
When
the user selects cascading parallelism scheduling type
Then
The results are in consequence (to be calculated by the tester before reading them: different from the above test at each step)
EXAMPLE OF SIGNATURES
// Step scheduling type.
typedef enum
{
COSIM_STEP_SCHEDULING_TYPE_FULL_PARALLELISM,
COSIM_STEP_SCHEDULING_TYPE_CASCADING_PARALLELISM,
} cosim_execution_step_scheduling_type;
/**
* Get the execution step scheduling type.
*
* \param [in] execution
* The concerned execution.
*
* \returns
* The execution step scheduling type.
*/
cosim_execution_step_scheduling_type cosim_execution_get_step_scheduling_type(cosim_execution* execution);
/**
* Set the execution default continuity of service level.
*
* \param [in] execution
* The concerned execution.
* \param [in] level
* The execution default continuity of service level.
*/
void cosim_execution_set_step_scheduling_type(cosim_execution* execution, cosim_execution_step_scheduling_type type);
NEED
It should be possible to choose the step scheduling type, among at least full parallelism (legacy code), and cascading parallelism. The current chosen mode in the OSP is full parallel. This mode matchs with hard real time systems but can be improved in the case of simulation systems. A simple way to improve efficiency is to cascade simulators following their output/input dependencies in order to earn in number of execution steps.
For instance, suppose that, in OspSystemStructure.xml, we defined:
If we define the following order relation: A < B if:
We can deduce from these 2 main informations a STEP PARTIAL ORDER (that is why parallelism will be possible):
Assume that we define a task TSi that:
Then for 1 step, we compute everything using cascade and parallelism, i.e. see this UML like activity diagram with forks:
Else in full parallelism you need 2 steps so that computation results of S1 and S2 reach S5.
This can be easily achieved using for instance https://taskflow.github.io/taskflow/index.html
DESCRIPTION
ACCEPTANCE TESTS
EXAMPLE OF SIGNATURES