Port nOS-V model to task bodies
The nOS-V events are modified in two ways: 1) to create a parallel task the new VTC event must be used and 2) all task events for both normal (VTc) and parallel (VTC) tasks require an extra argument in the payload to indicate the body id. As a consequence, the nOS-V model version is now increased to 2.0.0. Additionally, all the channel PRV flags are set to PRV_SKIPDUPNULL, so duplicates are only emitted if they are not null. It solves the problem when a task switches to another task with the same body id. A new Paraver configuration is added for the body id.
This commit is contained in:
parent
27a23f25ca
commit
815633221d
@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Add new body model to support parallel tasks in nOS-V (used in taskfor).
|
||||
- Add the ability to restrict transitions in the task model states.
|
||||
- Add nOS-V support for parallel tasks reading the body id from the
|
||||
event payload.
|
||||
|
||||
### Changed
|
||||
|
||||
- The task model now requires the previous task body to be paused before nesting
|
||||
|
42
cfg/cpu/nosv/body-id.cfg
Normal file
42
cfg/cpu/nosv/body-id.cfg
Normal file
@ -0,0 +1,42 @@
|
||||
#ParaverCFG
|
||||
ConfigFile.Version: 3.4
|
||||
ConfigFile.NumWindows: 1
|
||||
|
||||
|
||||
################################################################################
|
||||
< NEW DISPLAYING WINDOW CPU: nOS-V task body ID of the RUNNING thread >
|
||||
################################################################################
|
||||
window_name CPU: nOS-V task body ID of the RUNNING thread
|
||||
window_type single
|
||||
window_id 1
|
||||
window_position_x 0
|
||||
window_position_y 0
|
||||
window_width 600
|
||||
window_height 150
|
||||
window_comm_lines_enabled true
|
||||
window_flags_enabled false
|
||||
window_noncolor_mode true
|
||||
window_color_mode window_in_null_gradient_mode
|
||||
window_logical_filtered true
|
||||
window_physical_filtered false
|
||||
window_comm_fromto true
|
||||
window_comm_tagsize true
|
||||
window_comm_typeval true
|
||||
window_units Microseconds
|
||||
window_maximum_y 1000.0
|
||||
window_minimum_y 1.0
|
||||
window_compute_y_max true
|
||||
window_level thread
|
||||
window_scale_relative 1.000000000000
|
||||
window_end_time_relative 1.000000000000
|
||||
window_object appl { 1, { All } }
|
||||
window_begin_time_relative 0.000000000000
|
||||
window_open true
|
||||
window_drawmode draw_randnotzero
|
||||
window_drawmode_rows draw_randnotzero
|
||||
window_pixel_size 1
|
||||
window_labels_to_draw 1
|
||||
window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } }
|
||||
window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } }
|
||||
window_filter_module evt_type 1 15
|
||||
window_filter_module evt_type_label 1 "CPU: nOS-V task body ID of the RUNNING thread"
|
42
cfg/thread/nosv/body-id.cfg
Normal file
42
cfg/thread/nosv/body-id.cfg
Normal file
@ -0,0 +1,42 @@
|
||||
#ParaverCFG
|
||||
ConfigFile.Version: 3.4
|
||||
ConfigFile.NumWindows: 1
|
||||
|
||||
|
||||
################################################################################
|
||||
< NEW DISPLAYING WINDOW Thread: nOS-V task body ID of the RUNNING thread >
|
||||
################################################################################
|
||||
window_name Thread: nOS-V task body ID of the RUNNING thread
|
||||
window_type single
|
||||
window_id 1
|
||||
window_position_x 0
|
||||
window_position_y 0
|
||||
window_width 600
|
||||
window_height 150
|
||||
window_comm_lines_enabled true
|
||||
window_flags_enabled false
|
||||
window_noncolor_mode true
|
||||
window_color_mode window_in_null_gradient_mode
|
||||
window_logical_filtered true
|
||||
window_physical_filtered false
|
||||
window_comm_fromto true
|
||||
window_comm_tagsize true
|
||||
window_comm_typeval true
|
||||
window_units Microseconds
|
||||
window_maximum_y 1000.0
|
||||
window_minimum_y 1.0
|
||||
window_compute_y_max true
|
||||
window_level thread
|
||||
window_scale_relative 1.000000000000
|
||||
window_end_time_relative 1.000000000000
|
||||
window_object appl { 1, { All } }
|
||||
window_begin_time_relative 0.000000000000
|
||||
window_open true
|
||||
window_drawmode draw_randnotzero
|
||||
window_drawmode_rows draw_randnotzero
|
||||
window_pixel_size 1
|
||||
window_labels_to_draw 1
|
||||
window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } }
|
||||
window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } }
|
||||
window_filter_module evt_type 1 15
|
||||
window_filter_module evt_type_label 1 "Thread: nOS-V task body ID of the RUNNING thread"
|
@ -1,7 +1,7 @@
|
||||
# Emulator events
|
||||
|
||||
This is a exhaustive list of the events recognized by the emulator.
|
||||
Built on Feb 15 2024.
|
||||
Built on Mar 13 2024.
|
||||
|
||||
## Model nanos6
|
||||
|
||||
@ -615,18 +615,20 @@ List of events for the model *tampi* with identifier **`T`** at version `1.0.0`:
|
||||
|
||||
## Model nosv
|
||||
|
||||
List of events for the model *nosv* with identifier **`V`** at version `1.1.0`:
|
||||
List of events for the model *nosv* with identifier **`V`** at version `2.0.0`:
|
||||
<dl>
|
||||
<dt><a id="VTc" href="#VTc"><pre>VTc(u32 taskid, u32 typeid)</pre></a></dt>
|
||||
<dd>creates task %{taskid} with type %{typeid}</dd>
|
||||
<dt><a id="VTx" href="#VTx"><pre>VTx(u32 taskid)</pre></a></dt>
|
||||
<dd>executes the task %{taskid}</dd>
|
||||
<dt><a id="VTe" href="#VTe"><pre>VTe(u32 taskid)</pre></a></dt>
|
||||
<dd>ends the task %{taskid}</dd>
|
||||
<dt><a id="VTp" href="#VTp"><pre>VTp(u32 taskid)</pre></a></dt>
|
||||
<dd>pauses the task %{taskid}</dd>
|
||||
<dt><a id="VTr" href="#VTr"><pre>VTr(u32 taskid)</pre></a></dt>
|
||||
<dd>resumes the task %{taskid}</dd>
|
||||
<dt><a id="VTC" href="#VTC"><pre>VTC(u32 taskid, u32 typeid)</pre></a></dt>
|
||||
<dd>creates parallel task %{taskid} with type %{typeid}</dd>
|
||||
<dt><a id="VTx" href="#VTx"><pre>VTx(u32 taskid, u32 bodyid)</pre></a></dt>
|
||||
<dd>executes the task %{taskid} with bodyid %{bodyid}</dd>
|
||||
<dt><a id="VTe" href="#VTe"><pre>VTe(u32 taskid, u32 bodyid)</pre></a></dt>
|
||||
<dd>ends the task %{taskid} with bodyid %{bodyid}</dd>
|
||||
<dt><a id="VTp" href="#VTp"><pre>VTp(u32 taskid, u32 bodyid)</pre></a></dt>
|
||||
<dd>pauses the task %{taskid} with bodyid %{bodyid}</dd>
|
||||
<dt><a id="VTr" href="#VTr"><pre>VTr(u32 taskid, u32 bodyid)</pre></a></dt>
|
||||
<dd>resumes the task %{taskid} with bodyid %{bodyid}</dd>
|
||||
<dt><a id="VYc" href="#VYc"><pre>VYc+(u32 typeid, str label)</pre></a></dt>
|
||||
<dd>creates task type %{typeid} with label "%{label}"</dd>
|
||||
<dt><a id="VSr" href="#VSr"><pre>VSr</pre></a></dt>
|
||||
|
9
doc/user/emulation/fig/body-model.dot
Normal file
9
doc/user/emulation/fig/body-model.dot
Normal file
@ -0,0 +1,9 @@
|
||||
digraph {
|
||||
graph [size="6!", ranksep="0.7", nodesep="1"];
|
||||
|
||||
Created -> Running;
|
||||
Running -> Paused [label=BODY_FLAG_PAUSE];
|
||||
Paused -> Running;
|
||||
Running -> Dead;
|
||||
Dead -> Running [label="BODY_FLAG_RESURRECT\niteration++"];
|
||||
}
|
69
doc/user/emulation/fig/body-model.svg
Normal file
69
doc/user/emulation/fig/body-model.svg
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 8.1.0 (0)
|
||||
-->
|
||||
<!-- Pages: 1 -->
|
||||
<svg width="432pt" height="202pt"
|
||||
viewBox="0.00 0.00 432.00 202.47" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(0.805048 0.805048) rotate(0) translate(4 247.5)">
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-247.5 532.61,-247.5 532.61,4 -4,4"/>
|
||||
<!-- Created -->
|
||||
<g id="node1" class="node">
|
||||
<title>Created</title>
|
||||
<ellipse fill="none" stroke="black" cx="246.61" cy="-225.5" rx="51.21" ry="18"/>
|
||||
<text text-anchor="middle" x="246.61" y="-220.82" font-family="Times,serif" font-size="14.00">Created</text>
|
||||
</g>
|
||||
<!-- Running -->
|
||||
<g id="node2" class="node">
|
||||
<title>Running</title>
|
||||
<ellipse fill="none" stroke="black" cx="246.61" cy="-138.5" rx="53.31" ry="18"/>
|
||||
<text text-anchor="middle" x="246.61" y="-133.82" font-family="Times,serif" font-size="14.00">Running</text>
|
||||
</g>
|
||||
<!-- Created->Running -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>Created->Running</title>
|
||||
<path fill="none" stroke="black" d="M246.61,-207.3C246.61,-195.97 246.61,-180.86 246.61,-167.79"/>
|
||||
<polygon fill="black" stroke="black" points="250.11,-167.97 246.61,-157.97 243.11,-167.97 250.11,-167.97"/>
|
||||
</g>
|
||||
<!-- Paused -->
|
||||
<g id="node3" class="node">
|
||||
<title>Paused</title>
|
||||
<ellipse fill="none" stroke="black" cx="132.61" cy="-18" rx="47" ry="18"/>
|
||||
<text text-anchor="middle" x="132.61" y="-13.32" font-family="Times,serif" font-size="14.00">Paused</text>
|
||||
</g>
|
||||
<!-- Running->Paused -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>Running->Paused</title>
|
||||
<path fill="none" stroke="black" d="M193.44,-135.87C130.26,-132.68 30.43,-123.26 7.11,-95.5 -2.75,-83.76 -1.84,-73.44 7.11,-61 22.79,-39.22 50.29,-28.57 75.56,-23.43"/>
|
||||
<polygon fill="black" stroke="black" points="75.98,-26.73 85.22,-21.55 74.76,-19.84 75.98,-26.73"/>
|
||||
<text text-anchor="middle" x="80.36" y="-73.58" font-family="Times,serif" font-size="14.00">BODY_FLAG_PAUSE</text>
|
||||
</g>
|
||||
<!-- Dead -->
|
||||
<g id="node4" class="node">
|
||||
<title>Dead</title>
|
||||
<ellipse fill="none" stroke="black" cx="343.61" cy="-18" rx="37" ry="18"/>
|
||||
<text text-anchor="middle" x="343.61" y="-13.32" font-family="Times,serif" font-size="14.00">Dead</text>
|
||||
</g>
|
||||
<!-- Running->Dead -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>Running->Dead</title>
|
||||
<path fill="none" stroke="black" d="M260.31,-120.77C276.79,-100.63 304.62,-66.64 323.53,-43.53"/>
|
||||
<polygon fill="black" stroke="black" points="326.68,-46.22 330.3,-36.26 321.26,-41.78 326.68,-46.22"/>
|
||||
</g>
|
||||
<!-- Paused->Running -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>Paused->Running</title>
|
||||
<path fill="none" stroke="black" d="M148.33,-35.34C167.75,-55.52 200.96,-90.04 223.34,-113.31"/>
|
||||
<polygon fill="black" stroke="black" points="220.31,-115.24 229.76,-120.02 225.35,-110.39 220.31,-115.24"/>
|
||||
</g>
|
||||
<!-- Dead->Running -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>Dead->Running</title>
|
||||
<path fill="none" stroke="black" d="M343.24,-36.22C342.05,-52.96 337.96,-78.31 324.61,-95.5 316.51,-105.94 305.06,-114.1 293.42,-120.34"/>
|
||||
<polygon fill="black" stroke="black" points="292.09,-117.59 284.66,-125.14 295.18,-123.87 292.09,-117.59"/>
|
||||
<text text-anchor="middle" x="434.11" y="-82.2" font-family="Times,serif" font-size="14.00">BODY_FLAG_RESURRECT</text>
|
||||
<text text-anchor="middle" x="434.11" y="-64.95" font-family="Times,serif" font-size="14.00">iteration++</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
176
doc/user/emulation/fig/parallel-tasks.svg
Normal file
176
doc/user/emulation/fig/parallel-tasks.svg
Normal file
@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="117.73958mm"
|
||||
height="26.458332mm"
|
||||
viewBox="0 0 117.73958 26.458332"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
|
||||
sodipodi:docname="parallel-tasks.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="true"
|
||||
inkscape:zoom="1.4289282"
|
||||
inkscape:cx="335.21629"
|
||||
inkscape:cy="58.085495"
|
||||
inkscape:window-width="1914"
|
||||
inkscape:window-height="1025"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
id="grid1"
|
||||
units="px"
|
||||
originx="-9.9999997"
|
||||
originy="-9.9999997"
|
||||
spacingx="0.26458333"
|
||||
spacingy="0.26458334"
|
||||
empcolor="#3f3fff"
|
||||
empopacity="0.25098039"
|
||||
color="#3f3fff"
|
||||
opacity="0.1254902"
|
||||
empspacing="5"
|
||||
dotted="false"
|
||||
gridanglex="30"
|
||||
gridanglez="30"
|
||||
visible="true" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-2.6458333,-2.6458333)">
|
||||
<rect
|
||||
style="fill:none;stroke:none;stroke-width:0.3;stroke-linecap:round"
|
||||
id="rect9"
|
||||
width="117.73958"
|
||||
height="26.458332"
|
||||
x="2.6458333"
|
||||
y="2.6458333" />
|
||||
<rect
|
||||
style="fill:#f2f2f2;stroke:#000000;stroke-width:0.3;stroke-linecap:round"
|
||||
id="rect1"
|
||||
width="44.979168"
|
||||
height="23.8125"
|
||||
x="3.96875"
|
||||
y="3.9687502" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:4.23333px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="6.6805291"
|
||||
y="9.5720644"
|
||||
id="text1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Droid Sans';-inkscape-font-specification:'Droid Sans';stroke-width:0.264583"
|
||||
x="6.6805291"
|
||||
y="9.5720644">Normal task</tspan></text>
|
||||
<rect
|
||||
style="fill:#d5ffd5;stroke:#000000;stroke-width:0.3;stroke-linecap:round"
|
||||
id="rect3"
|
||||
width="39.6875"
|
||||
height="10.583333"
|
||||
x="6.614583"
|
||||
y="14.552083" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:4.23333px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="18.784389"
|
||||
y="21.011637"
|
||||
id="text3"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3"
|
||||
style="stroke-width:0.264583"
|
||||
x="18.784389"
|
||||
y="21.011637">Body 1</tspan></text>
|
||||
<rect
|
||||
style="fill:#f2f2f2;stroke:#000000;stroke-width:0.3;stroke-linecap:round"
|
||||
id="rect4"
|
||||
width="67.46875"
|
||||
height="23.8125"
|
||||
x="51.59375"
|
||||
y="3.9687502" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:4.23333px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="54.704952"
|
||||
y="9.4792204"
|
||||
id="text4"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Droid Sans';-inkscape-font-specification:'Droid Sans';stroke-width:0.264583"
|
||||
x="54.704952"
|
||||
y="9.4792204">Parallel task</tspan></text>
|
||||
<rect
|
||||
style="fill:#d5ffd5;stroke:#000000;stroke-width:0.3;stroke-linecap:round"
|
||||
id="rect6"
|
||||
width="21.166662"
|
||||
height="10.583335"
|
||||
x="54.239586"
|
||||
y="14.552083" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:4.23333px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="57.148972"
|
||||
y="21.011637"
|
||||
id="text6"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6"
|
||||
style="stroke-width:0.264583"
|
||||
x="57.148972"
|
||||
y="21.011637">Body 1</tspan></text>
|
||||
<rect
|
||||
style="fill:#d5ffd5;stroke:#000000;stroke-width:0.3;stroke-linecap:round"
|
||||
id="rect7"
|
||||
width="21.166662"
|
||||
height="10.583335"
|
||||
x="78.052078"
|
||||
y="14.552084" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:4.23333px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="80.997643"
|
||||
y="21.011639"
|
||||
id="text7"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan7"
|
||||
style="stroke-width:0.264583"
|
||||
x="80.997643"
|
||||
y="21.011639">Body 2</tspan></text>
|
||||
<rect
|
||||
style="fill:#d5ffd5;stroke:#000000;stroke-width:0.3;stroke-linecap:round"
|
||||
id="rect8"
|
||||
width="14.552085"
|
||||
height="10.583334"
|
||||
x="101.86458"
|
||||
y="14.552084" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:4.23333px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
x="105.3207"
|
||||
y="20.895952"
|
||||
id="text8"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan8"
|
||||
style="stroke-width:0.264583"
|
||||
x="105.3207"
|
||||
y="20.895952">...</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.9 KiB |
@ -1,9 +1,42 @@
|
||||
# nOS-V model
|
||||
|
||||
The [nOS-V library][nosv] implements a user space runtime that can schedule
|
||||
tasks to run in multiple CPUs. The nOS-V library is instrumented to
|
||||
track the internal state of the runtime as well as emit information
|
||||
about the tasks that are running.
|
||||
|
||||
[nosv]: https://github.com/bsc-pm/nos-v
|
||||
|
||||
## Task model
|
||||
|
||||
The nOS-V runtime is composed of tasks that can be scheduled to run in
|
||||
threads. Tasks can be paused and resumed, leaving the CPUs free to
|
||||
execute other tasks. The nOS-V model tracks the state of each task as
|
||||
well as the state of the runtime internal state.
|
||||
execute other tasks.
|
||||
|
||||
In nOS-V, parallel tasks can also be scheduled multiple times and the
|
||||
same task may run concurrently in several CPUs. To model this scenario,
|
||||
we introduce the concept of *body*, which maps to each execution of the
|
||||
same task, with a unique body id.
|
||||
|
||||
![Parallel tasks](fig/parallel-tasks.svg)
|
||||
|
||||
A normal task only has one body, while a parallel task (created with
|
||||
`TASK_FLAG_PARALLEL`) can have more than one body. Each body holds the
|
||||
execution state, and can transition to different execution states
|
||||
following this state diagram:
|
||||
|
||||
![Body model](fig/body-model.svg)
|
||||
|
||||
Bodies begin in the Created state and transition to Running when they
|
||||
begin the execution. Bodies that can be paused (created with the flag
|
||||
`BODY_FLAG_PAUSE` can transition to the Paused state.
|
||||
|
||||
Additionally, bodies can run multiple times if they are created with the
|
||||
`BODY_FLAG_RESURRECT`, and transition from Dead to Running. This
|
||||
transition is required to model the tasks that implement the taskiter in
|
||||
NODES, which will be submitted multiple times for execution reusing the
|
||||
same task id and body id. Every time a body runs again, the iteration
|
||||
number is increased.
|
||||
|
||||
## Task type colors
|
||||
|
||||
|
@ -18,6 +18,7 @@ enum emu_prv_types {
|
||||
PRV_NOSV_APPID = 12,
|
||||
PRV_NOSV_SUBSYSTEM = 13,
|
||||
PRV_NOSV_RANK = 14,
|
||||
PRV_NOSV_BODYID = 15,
|
||||
PRV_TAMPI_SUBSYSTEM = 20,
|
||||
PRV_MPI_FUNCTION = 25,
|
||||
PRV_NODES_SUBSYSTEM = 30,
|
||||
|
@ -97,12 +97,16 @@ simple(struct emu *emu)
|
||||
}
|
||||
|
||||
static int
|
||||
chan_task_stopped(struct emu *emu)
|
||||
chan_body_stopped(struct emu *emu)
|
||||
{
|
||||
struct nosv_thread *th = EXT(emu->thread, 'V');
|
||||
struct chan *ch = th->m.ch;
|
||||
|
||||
struct value null = value_null();
|
||||
if (chan_set(&ch[CH_BODYID], null) != 0) {
|
||||
err("chan_set taskid failed");
|
||||
return -1;
|
||||
}
|
||||
if (chan_set(&ch[CH_TASKID], null) != 0) {
|
||||
err("chan_set taskid failed");
|
||||
return -1;
|
||||
@ -128,8 +132,9 @@ chan_task_stopped(struct emu *emu)
|
||||
}
|
||||
|
||||
static int
|
||||
chan_task_running(struct emu *emu, struct task *task)
|
||||
chan_body_running(struct emu *emu, struct body *body)
|
||||
{
|
||||
struct task *task = body_get_task(body);
|
||||
struct nosv_thread *th = EXT(emu->thread, 'V');
|
||||
struct proc *proc = emu->proc;
|
||||
struct chan *ch = th->m.ch;
|
||||
@ -147,6 +152,10 @@ chan_task_running(struct emu *emu, struct task *task)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chan_set(&ch[CH_BODYID], value_int64(body_get_id(body))) != 0) {
|
||||
err("chan_set bodyid failed");
|
||||
return -1;
|
||||
}
|
||||
if (chan_set(&ch[CH_TASKID], value_int64(task->id)) != 0) {
|
||||
err("chan_set taskid failed");
|
||||
return -1;
|
||||
@ -171,22 +180,24 @@ chan_task_running(struct emu *emu, struct task *task)
|
||||
}
|
||||
|
||||
static int
|
||||
chan_task_switch(struct emu *emu, struct task *prev, struct task *next)
|
||||
chan_body_switch(struct emu *emu, struct body *bprev, struct body *bnext)
|
||||
{
|
||||
struct nosv_thread *th = EXT(emu->thread, 'V');
|
||||
struct chan *ch = th->m.ch;
|
||||
struct proc *proc = emu->proc;
|
||||
|
||||
if (!prev || !next) {
|
||||
err("cannot switch to or from a NULL task");
|
||||
if (!bprev || !bnext) {
|
||||
err("cannot switch to or from a NULL body");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (prev == next) {
|
||||
err("cannot switch to the same task");
|
||||
if (bprev == bnext) {
|
||||
err("cannot switch to the same body");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct task *next = body_get_task(bnext);
|
||||
|
||||
if (next->id == 0) {
|
||||
err("next task id cannot be 0");
|
||||
return -1;
|
||||
@ -197,11 +208,10 @@ chan_task_switch(struct emu *emu, struct task *prev, struct task *next)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (prev->thread != next->thread) {
|
||||
err("cannot switch to a task of another thread");
|
||||
if (chan_set(&ch[CH_BODYID], value_int64(body_get_id(bnext))) != 0) {
|
||||
err("chan_set taskid failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chan_set(&ch[CH_TASKID], value_int64(next->id)) != 0) {
|
||||
err("chan_set taskid failed");
|
||||
return -1;
|
||||
@ -235,12 +245,15 @@ update_task_state(struct emu *emu)
|
||||
|
||||
uint32_t task_id = emu->ev->payload->u32[0];
|
||||
|
||||
if (emu->ev->payload_size < 8) {
|
||||
err("missing body id in payload");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct nosv_thread *th = EXT(emu->thread, 'V');
|
||||
struct nosv_proc *proc = EXT(emu->proc, 'V');
|
||||
|
||||
struct task_info *info = &proc->task_info;
|
||||
struct task_stack *stack = &th->task_stack;
|
||||
|
||||
struct task *task = task_find(info->tasks, task_id);
|
||||
|
||||
if (task == NULL) {
|
||||
@ -248,19 +261,37 @@ update_task_state(struct emu *emu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t body_id = emu->ev->payload->u32[1];
|
||||
|
||||
if (task_is_parallel(task)) {
|
||||
if (body_id == 0) {
|
||||
err("the body_id must be > 0 for parallel task %u",
|
||||
task_get_id(task));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (body_id != 0) {
|
||||
err("the body_id must be 0 for non-parallel task %u",
|
||||
task_get_id(task));
|
||||
return -1;
|
||||
}
|
||||
/* We use body_id = 1 internally, as they cannot be zero. */
|
||||
body_id = 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
switch (emu->ev->v) {
|
||||
case 'x':
|
||||
ret = task_execute(stack, task);
|
||||
ret = task_execute(stack, task, body_id);
|
||||
break;
|
||||
case 'e':
|
||||
ret = task_end(stack, task);
|
||||
ret = task_end(stack, task, body_id);
|
||||
break;
|
||||
case 'p':
|
||||
ret = task_pause(stack, task);
|
||||
ret = task_pause(stack, task, body_id);
|
||||
break;
|
||||
case 'r':
|
||||
ret = task_resume(stack, task);
|
||||
ret = task_resume(stack, task, body_id);
|
||||
break;
|
||||
default:
|
||||
err("unexpected nOS-V task event");
|
||||
@ -297,22 +328,22 @@ expand_transition_value(struct emu *emu, int was_running, int runs_now, char *tr
|
||||
}
|
||||
|
||||
static int
|
||||
update_task_channels(struct emu *emu, char tr, struct task *prev, struct task *next)
|
||||
update_task_channels(struct emu *emu, char tr, struct body *bprev, struct body *bnext)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (tr) {
|
||||
case 'x':
|
||||
case 'r':
|
||||
ret = chan_task_running(emu, next);
|
||||
ret = chan_body_running(emu, bnext);
|
||||
break;
|
||||
case 'e':
|
||||
case 'p':
|
||||
ret = chan_task_stopped(emu);
|
||||
ret = chan_body_stopped(emu);
|
||||
break;
|
||||
/* Additional nested transitions */
|
||||
case 'X':
|
||||
case 'E':
|
||||
ret = chan_task_switch(emu, prev, next);
|
||||
ret = chan_body_switch(emu, bprev, bnext);
|
||||
break;
|
||||
default:
|
||||
err("unexpected transition value %c", tr);
|
||||
@ -328,7 +359,7 @@ update_task_channels(struct emu *emu, char tr, struct task *prev, struct task *n
|
||||
}
|
||||
|
||||
static int
|
||||
enforce_task_rules(struct emu *emu, char tr, struct task *next)
|
||||
enforce_task_rules(struct emu *emu, char tr, struct body *next)
|
||||
{
|
||||
if (tr != 'x' && tr != 'X')
|
||||
return 0;
|
||||
@ -336,8 +367,8 @@ enforce_task_rules(struct emu *emu, char tr, struct task *next)
|
||||
/* If a task has just entered the running state, it must show
|
||||
* the running task body subsystem */
|
||||
|
||||
if (next->state != TASK_ST_RUNNING) {
|
||||
err("task not in running state on begin");
|
||||
if (body_get_state(next) != BODY_ST_RUNNING) {
|
||||
err("body not in running state on begin");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -384,7 +415,7 @@ update_task(struct emu *emu)
|
||||
struct nosv_thread *th = EXT(emu->thread, 'V');
|
||||
struct task_stack *stack = &th->task_stack;
|
||||
|
||||
struct task *prev = task_get_running(stack);
|
||||
struct body *prev = task_get_running(stack);
|
||||
|
||||
/* Update the emulator state, but don't modify the channels */
|
||||
if (update_task_state(emu) != 0) {
|
||||
@ -392,7 +423,7 @@ update_task(struct emu *emu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct task *next = task_get_running(stack);
|
||||
struct body *next = task_get_running(stack);
|
||||
|
||||
/* Update the subsystem channel */
|
||||
if (update_task_ss_channel(emu, emu->ev->v) != 0) {
|
||||
@ -423,9 +454,9 @@ update_task(struct emu *emu)
|
||||
}
|
||||
|
||||
static int
|
||||
create_task(struct emu *emu)
|
||||
create_task(struct emu *emu, char value)
|
||||
{
|
||||
if (emu->ev->payload_size != 8) {
|
||||
if (emu->ev->payload_size < 8) {
|
||||
err("unexpected payload size");
|
||||
return -1;
|
||||
}
|
||||
@ -433,10 +464,20 @@ create_task(struct emu *emu)
|
||||
uint32_t task_id = emu->ev->payload->u32[0];
|
||||
uint32_t type_id = emu->ev->payload->u32[1];
|
||||
|
||||
int is_parallel = (value == 'C');
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
/* Parallel tasks cannot pause or resurrect */
|
||||
if (is_parallel)
|
||||
flags = TASK_FLAG_PARALLEL;
|
||||
else
|
||||
flags = TASK_FLAG_RESURRECT | TASK_FLAG_PAUSE;
|
||||
|
||||
struct nosv_proc *proc = EXT(emu->proc, 'V');
|
||||
struct task_info *info = &proc->task_info;
|
||||
|
||||
if (task_create(info, type_id, task_id) != 0) {
|
||||
if (task_create(info, type_id, task_id, flags) != 0) {
|
||||
err("task_create failed");
|
||||
return -1;
|
||||
}
|
||||
@ -451,8 +492,9 @@ pre_task(struct emu *emu)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (emu->ev->v) {
|
||||
case 'C':
|
||||
case 'c':
|
||||
ret = create_task(emu);
|
||||
ret = create_task(emu, emu->ev->v);
|
||||
break;
|
||||
case 'x':
|
||||
case 'e':
|
||||
|
@ -12,7 +12,8 @@
|
||||
/* Private enums */
|
||||
|
||||
enum nosv_chan {
|
||||
CH_TASKID = 0,
|
||||
CH_BODYID = 0,
|
||||
CH_TASKID,
|
||||
CH_TYPE,
|
||||
CH_APPID,
|
||||
CH_SUBSYSTEM,
|
||||
|
@ -32,10 +32,11 @@ enum { model_id = 'V' };
|
||||
|
||||
static struct ev_decl model_evlist[] = {
|
||||
{ "VTc(u32 taskid, u32 typeid)", "creates task %{taskid} with type %{typeid}" },
|
||||
{ "VTx(u32 taskid)", "executes the task %{taskid}" },
|
||||
{ "VTe(u32 taskid)", "ends the task %{taskid}" },
|
||||
{ "VTp(u32 taskid)", "pauses the task %{taskid}" },
|
||||
{ "VTr(u32 taskid)", "resumes the task %{taskid}" },
|
||||
{ "VTC(u32 taskid, u32 typeid)", "creates parallel task %{taskid} with type %{typeid}" },
|
||||
{ "VTx(u32 taskid, u32 bodyid)", "executes the task %{taskid} with bodyid %{bodyid}" },
|
||||
{ "VTe(u32 taskid, u32 bodyid)", "ends the task %{taskid} with bodyid %{bodyid}" },
|
||||
{ "VTp(u32 taskid, u32 bodyid)", "pauses the task %{taskid} with bodyid %{bodyid}" },
|
||||
{ "VTr(u32 taskid, u32 bodyid)", "resumes the task %{taskid} with bodyid %{bodyid}" },
|
||||
|
||||
{ "VYc+(u32 typeid, str label)", "creates task type %{typeid} with label \"%{label}\"" },
|
||||
|
||||
@ -72,7 +73,7 @@ static struct ev_decl model_evlist[] = {
|
||||
|
||||
struct model_spec model_nosv = {
|
||||
.name = model_name,
|
||||
.version = "1.1.0",
|
||||
.version = "2.0.0",
|
||||
.evlist = model_evlist,
|
||||
.model = model_id,
|
||||
.create = model_nosv_create,
|
||||
@ -85,6 +86,7 @@ struct model_spec model_nosv = {
|
||||
/* ----------------- channels ------------------ */
|
||||
|
||||
static const char *chan_name[CH_MAX] = {
|
||||
[CH_BODYID] = "bodyid",
|
||||
[CH_TASKID] = "taskid",
|
||||
[CH_TYPE] = "task_type",
|
||||
[CH_APPID] = "appid",
|
||||
@ -97,6 +99,7 @@ static const int chan_stack[CH_MAX] = {
|
||||
};
|
||||
|
||||
static const int chan_dup[CH_MAX] = {
|
||||
[CH_BODYID] = 1, /* Switch to another task with body 1 */
|
||||
[CH_APPID] = 1,
|
||||
[CH_TYPE] = 1,
|
||||
[CH_RANK] = 1,
|
||||
@ -108,6 +111,7 @@ static const int chan_dup[CH_MAX] = {
|
||||
/* ----------------- pvt ------------------ */
|
||||
|
||||
static const int pvt_type[CH_MAX] = {
|
||||
[CH_BODYID] = PRV_NOSV_BODYID,
|
||||
[CH_TASKID] = PRV_NOSV_TASKID,
|
||||
[CH_TYPE] = PRV_NOSV_TYPE,
|
||||
[CH_APPID] = PRV_NOSV_APPID,
|
||||
@ -116,6 +120,7 @@ static const int pvt_type[CH_MAX] = {
|
||||
};
|
||||
|
||||
static const char *pcf_prefix[CH_MAX] = {
|
||||
[CH_BODYID] = "nOS-V task body ID",
|
||||
[CH_TASKID] = "nOS-V task ID",
|
||||
[CH_TYPE] = "nOS-V task type",
|
||||
[CH_APPID] = "nOS-V task AppID",
|
||||
@ -152,11 +157,12 @@ static const struct pcf_value_label *pcf_labels[CH_MAX] = {
|
||||
};
|
||||
|
||||
static const long prv_flags[CH_MAX] = {
|
||||
[CH_TASKID] = PRV_SKIPDUP,
|
||||
[CH_TYPE] = PRV_EMITDUP, /* Switch to task of same type */
|
||||
[CH_APPID] = PRV_EMITDUP, /* Switch to task of same appid */
|
||||
[CH_SUBSYSTEM] = PRV_SKIPDUP,
|
||||
[CH_RANK] = PRV_EMITDUP, /* Switch to task of same rank */
|
||||
[CH_BODYID] = PRV_SKIPDUPNULL, /* Switch to different task, same bodyid */
|
||||
[CH_TASKID] = PRV_SKIPDUPNULL, /* Switch to another body of the same task */
|
||||
[CH_TYPE] = PRV_SKIPDUPNULL, /* Switch to task of same type */
|
||||
[CH_APPID] = PRV_SKIPDUPNULL, /* Switch to task of same appid */
|
||||
[CH_SUBSYSTEM] = PRV_SKIPDUPNULL,
|
||||
[CH_RANK] = PRV_SKIPDUPNULL, /* Switch to task of same rank */
|
||||
};
|
||||
|
||||
static const struct model_pvt_spec pvt_spec = {
|
||||
@ -169,6 +175,7 @@ static const struct model_pvt_spec pvt_spec = {
|
||||
/* ----------------- tracking ------------------ */
|
||||
|
||||
static const int th_track[CH_MAX] = {
|
||||
[CH_BODYID] = TRACK_TH_RUN,
|
||||
[CH_TASKID] = TRACK_TH_RUN,
|
||||
[CH_TYPE] = TRACK_TH_RUN,
|
||||
[CH_APPID] = TRACK_TH_RUN,
|
||||
@ -177,6 +184,7 @@ static const int th_track[CH_MAX] = {
|
||||
};
|
||||
|
||||
static const int cpu_track[CH_MAX] = {
|
||||
[CH_BODYID] = TRACK_TH_RUN,
|
||||
[CH_TASKID] = TRACK_TH_RUN,
|
||||
[CH_TYPE] = TRACK_TH_RUN,
|
||||
[CH_APPID] = TRACK_TH_RUN,
|
||||
@ -256,12 +264,6 @@ model_nosv_create(struct emu *emu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Init task stack thread pointer */
|
||||
for (struct thread *t = sys->threads; t; t = t->gnext) {
|
||||
struct nosv_thread *th = EXT(t, model_id);
|
||||
th->task_stack.thread = t;
|
||||
}
|
||||
|
||||
for (struct proc *p = sys->procs; p; p = p->gnext) {
|
||||
if (init_proc(p) != 0) {
|
||||
err("init_proc failed");
|
||||
|
@ -5,7 +5,7 @@ test_emu(attach.c)
|
||||
test_emu(attach-old.c)
|
||||
test_emu(nested-tasks.c)
|
||||
test_emu(nested-tasks-bad.c SHOULD_FAIL
|
||||
REGEX "cannot execute task 1: state is not created")
|
||||
REGEX "body_execute: body 1 state must be Created but is Running")
|
||||
test_emu(task-types.c MP)
|
||||
test_emu(pause.c MP)
|
||||
#test_emu(mp-rank.c MP)
|
||||
|
Loading…
Reference in New Issue
Block a user