Add OpenMP support for labels and taskID views
Some checks failed
Some checks failed
Co-authored-by: Rodrigo Arias Mallo <rodrigo.arias@bsc.es>
This commit is contained in:
parent
a7103f8510
commit
9826879bcd
@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- OpenMP model version increased to 1.2.0.
|
||||
|
||||
### Added
|
||||
|
||||
- Add support OpenMP label and task ID views.
|
||||
|
||||
## [1.11.0] - 2024-11-08
|
||||
|
||||
### Added
|
||||
|
41
cfg/cpu/openmp/label.cfg
Normal file
41
cfg/cpu/openmp/label.cfg
Normal file
@ -0,0 +1,41 @@
|
||||
#ParaverCFG
|
||||
ConfigFile.Version: 3.4
|
||||
ConfigFile.NumWindows: 1
|
||||
|
||||
|
||||
################################################################################
|
||||
< NEW DISPLAYING WINDOW CPU: OpenMP label of the RUNNING thread >
|
||||
################################################################################
|
||||
window_name CPU: OpenMP label of the RUNNING thread
|
||||
window_type single
|
||||
window_id 1
|
||||
window_position_x 100
|
||||
window_position_y 100
|
||||
window_width 600
|
||||
window_height 150
|
||||
window_comm_lines_enabled true
|
||||
window_flags_enabled false
|
||||
window_noncolor_mode true
|
||||
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 51
|
||||
window_filter_module evt_type_label 1 "CPU: OpenMP label of the RUNNING thread"
|
41
cfg/cpu/openmp/task-id.cfg
Normal file
41
cfg/cpu/openmp/task-id.cfg
Normal file
@ -0,0 +1,41 @@
|
||||
#ParaverCFG
|
||||
ConfigFile.Version: 3.4
|
||||
ConfigFile.NumWindows: 1
|
||||
|
||||
|
||||
################################################################################
|
||||
< NEW DISPLAYING WINDOW CPU: OpenMP task id of the RUNNING thread >
|
||||
################################################################################
|
||||
window_name CPU: OpenMP task id of the RUNNING thread
|
||||
window_type single
|
||||
window_id 1
|
||||
window_position_x 100
|
||||
window_position_y 100
|
||||
window_width 600
|
||||
window_height 150
|
||||
window_comm_lines_enabled true
|
||||
window_flags_enabled false
|
||||
window_noncolor_mode true
|
||||
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 52
|
||||
window_filter_module evt_type_label 1 "CPU: OpenMP task id of the RUNNING thread"
|
41
cfg/thread/openmp/label.cfg
Normal file
41
cfg/thread/openmp/label.cfg
Normal file
@ -0,0 +1,41 @@
|
||||
#ParaverCFG
|
||||
ConfigFile.Version: 3.4
|
||||
ConfigFile.NumWindows: 1
|
||||
|
||||
|
||||
################################################################################
|
||||
< NEW DISPLAYING WINDOW Thread: OpenMP label of the ACTIVE thread >
|
||||
################################################################################
|
||||
window_name Thread: OpenMP label of the ACTIVE thread
|
||||
window_type single
|
||||
window_id 1
|
||||
window_position_x 100
|
||||
window_position_y 100
|
||||
window_width 600
|
||||
window_height 150
|
||||
window_comm_lines_enabled true
|
||||
window_flags_enabled false
|
||||
window_noncolor_mode true
|
||||
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 51
|
||||
window_filter_module evt_type_label 1 "Thread: OpenMP label of the ACTIVE thread"
|
41
cfg/thread/openmp/task-id.cfg
Normal file
41
cfg/thread/openmp/task-id.cfg
Normal file
@ -0,0 +1,41 @@
|
||||
#ParaverCFG
|
||||
ConfigFile.Version: 3.4
|
||||
ConfigFile.NumWindows: 1
|
||||
|
||||
|
||||
################################################################################
|
||||
< NEW DISPLAYING WINDOW Thread: OpenMP task id of the ACTIVE thread >
|
||||
################################################################################
|
||||
window_name Thread: OpenMP task id of the ACTIVE thread
|
||||
window_type single
|
||||
window_id 1
|
||||
window_position_x 100
|
||||
window_position_y 100
|
||||
window_width 600
|
||||
window_height 150
|
||||
window_comm_lines_enabled true
|
||||
window_flags_enabled false
|
||||
window_noncolor_mode true
|
||||
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 52
|
||||
window_filter_module evt_type_label 1 "Thread: OpenMP task id of the ACTIVE thread"
|
@ -1,7 +1,7 @@
|
||||
# Emulator events
|
||||
|
||||
This is a exhaustive list of the events recognized by the emulator.
|
||||
Built on Jun 17 2024.
|
||||
Built on Nov 13 2024.
|
||||
|
||||
## Model nanos6
|
||||
|
||||
@ -437,7 +437,7 @@ List of events for the model *ovni* with identifier **`O`** at version `1.1.0`:
|
||||
|
||||
## Model openmp
|
||||
|
||||
List of events for the model *openmp* with identifier **`P`** at version `1.1.0`:
|
||||
List of events for the model *openmp* with identifier **`P`** at version `1.2.0`:
|
||||
<dl>
|
||||
<dt><a id="PBb" href="#PBb"><pre>PBb</pre></a></dt>
|
||||
<dd>begins plain barrier</dd>
|
||||
@ -563,6 +563,18 @@ List of events for the model *openmp* with identifier **`P`** at version `1.1.0`
|
||||
<dd>begins initialization</dd>
|
||||
<dt><a id="PCI" href="#PCI"><pre>PCI</pre></a></dt>
|
||||
<dd>ceases initialization</dd>
|
||||
<dt><a id="POc" href="#POc"><pre>POc+(u32 typeid, str label)</pre></a></dt>
|
||||
<dd>creates a type %{typeid} with label "%{label}"</dd>
|
||||
<dt><a id="PPc" href="#PPc"><pre>PPc(u32 taskid, u32 typeid)</pre></a></dt>
|
||||
<dd>creates the task %{taskid} with type %{typeid}</dd>
|
||||
<dt><a id="PPx" href="#PPx"><pre>PPx(u32 taskid)</pre></a></dt>
|
||||
<dd>executes the task %{taskid}</dd>
|
||||
<dt><a id="PPe" href="#PPe"><pre>PPe(u32 taskid)</pre></a></dt>
|
||||
<dd>ends the task %{taskid}</dd>
|
||||
<dt><a id="PQx" href="#PQx"><pre>PQx(u32 typeid)</pre></a></dt>
|
||||
<dd>begins worksharing with type %{typeid}</dd>
|
||||
<dt><a id="PQe" href="#PQe"><pre>PQe(u32 typeid)</pre></a></dt>
|
||||
<dd>ends worksharing with type %{typeid}</dd>
|
||||
</dl>
|
||||
|
||||
## Model tampi
|
||||
|
@ -8,21 +8,20 @@ refer to the
|
||||
|
||||
The [LLVM OpenMP Runtime](https://openmp.llvm.org/design/Runtimes.html) provides
|
||||
an implementation of the OpenMP specification as a component of the LLVM
|
||||
compiler infrastructure. We have modified the LLVM OpenMP runtime to run on top
|
||||
compiler infrastructure. We have modified the LLVM OpenMP runtime (libomp) to run on top
|
||||
of the [nOS-V](https://gitlab.bsc.es/nos-v/nos-v) runtime as part of the
|
||||
[OmpSs-2 LLVM compiler](https://pm.bsc.es/llvm-ompss), named **OpenMP-V**.
|
||||
[OmpSs-2 LLVM compiler](https://pm.bsc.es/llvm-ompss), named **libompv**.
|
||||
|
||||
We have added instrumentation events to OpenMP-V designed to be enabled along
|
||||
We have added instrumentation events to libompv designed to be enabled along
|
||||
the [nOS-V instrumentation](nosv.md). This document describes all the
|
||||
instrumentation features included in our modified OpenMP-V runtime to identify
|
||||
instrumentation features included in our modified libompv runtime to identify
|
||||
what is happening. This data is useful for both users and developers of the
|
||||
OpenMP runtime to analyze issues and undesired behaviors.
|
||||
|
||||
!!! Note
|
||||
|
||||
Instrumenting the original OpenMP runtime from the LLVM project is planned
|
||||
but is not yet posible. For now you must use the modified OpenMP-V runtime
|
||||
with nOS-V.
|
||||
Instrumenting libomp is planned but is not yet posible.
|
||||
For now you must use libompv.
|
||||
|
||||
## Enable the instrumentation
|
||||
|
||||
@ -33,25 +32,25 @@ To generate runtime traces, you will have to:
|
||||
documentation](https://github.com/bsc-pm/nos-v/blob/master/docs/user/tracing.md).
|
||||
Typically you should use the `--with-ovni` option at configure time to specify
|
||||
where ovni is installed.
|
||||
2. **Build OpenMP-V with ovni and nOS-V support:** Use the `PKG_CONFIG_PATH`
|
||||
2. **Build libompv with ovni and nOS-V support:** Use the `PKG_CONFIG_PATH`
|
||||
environment variable to specify the nOS-V and ovni installation
|
||||
when configuring CMake.
|
||||
3. **Enable the instrumentation in nOS-V at runtime:** Refer to the
|
||||
[nOS-V documentation](https://github.com/bsc-pm/nos-v/blob/master/docs/user/tracing.md)
|
||||
to find out how to enable the tracing at runtime. Typically you can just set
|
||||
`NOSV_CONFIG_OVERRIDE="instrumentation.version=ovni"`.
|
||||
4. **Enable the instrumentation of OpenMP-V at runtime:** Set the environment
|
||||
4. **Enable the instrumentation of libompv at runtime:** Set the environment
|
||||
variable `OMP_OVNI=1`.
|
||||
|
||||
Currently there is only support for the subsystem view, which is documented
|
||||
below. The view is complemented with the information of [nOS-V views](nosv.md),
|
||||
as OpenMP-V uses nOS-V tasks to run the workers.
|
||||
Next sections describe each of the views included for analysis.
|
||||
|
||||
## Subsystem view
|
||||
|
||||

|
||||
|
||||
This view illustrates the activities of each thread with different states:
|
||||
The view is complemented with the information of [nOS-V views](nosv.md),
|
||||
as libompv uses nOS-V tasks to run the workers.
|
||||
Subsystem illustrates the activities of each thread with different states:
|
||||
|
||||
- **Work-distribution subsystem**: Related to work-distribution constructs,
|
||||
[in Chapter 11][workdis].
|
||||
@ -135,9 +134,9 @@ This view illustrates the activities of each thread with different states:
|
||||
- **Fork call**: Preparing a parallel section using the fork-join model.
|
||||
Only called from the master thread.
|
||||
|
||||
- **Init**: Initializing the OpenMP-V runtime.
|
||||
- **Init**: Initializing the libompv runtime.
|
||||
|
||||
- **Internal microtask**: Running a internal OpenMP-V function as a microtask.
|
||||
- **Internal microtask**: Running a internal libompv function as a microtask.
|
||||
|
||||
- **User microtask**: Running user code as a microtask in a worker thread.
|
||||
|
||||
@ -156,9 +155,31 @@ This view illustrates the activities of each thread with different states:
|
||||
[critical]: https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5-2.pdf#section.15.2
|
||||
[barrier]: https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5-2.pdf#section.15.3
|
||||
|
||||
## Label view
|
||||
|
||||
The label view displays the text in the `label()` clause of OpenMP
|
||||
tasks and work distribution constructs (static and dynamic for, single
|
||||
and section). When the label is not provided, the source file and source
|
||||
line location is used instead.
|
||||
|
||||
When nesting multiple tasks or work distribution constructs, only the
|
||||
innermost label is shown.
|
||||
|
||||
Note that in this view, the numeric event value is a hash function of
|
||||
the type label, so two distinct tasks (declared in different parts of
|
||||
the code) with the same label will share the event value and have the
|
||||
same color.
|
||||
|
||||
## Task ID view
|
||||
|
||||
The task ID view represents the numeric ID of the OpenMP task that is
|
||||
currently running on each thread. The ID is a monotonically increasing
|
||||
identifier assigned on task creation. Lower IDs correspond to tasks
|
||||
created at an earlier point than higher IDs.
|
||||
|
||||
## Limitations
|
||||
|
||||
As the compiler generates the code that perform the calls to the OpenMP-V
|
||||
As the compiler generates the code that perform the calls to the libompv
|
||||
runtime, there are some parts of the execution that are complicated to
|
||||
instrument by just placing a pair of events to delimite a function.
|
||||
|
||||
|
@ -33,6 +33,8 @@ Track changes in emulator model versions.
|
||||
|
||||
## OpenMP
|
||||
|
||||
- openmp 1.2.0:
|
||||
- Add support for labels and task ID views
|
||||
- openmp 1.1.0: Initial version
|
||||
|
||||
## TAMPI
|
||||
|
@ -30,7 +30,7 @@
|
||||
clangOmpss2Unwrapped = prev.clangOmpss2Unwrapped.override {
|
||||
useGit = true;
|
||||
gitBranch = "master";
|
||||
gitCommit = "246e2df2eb10f52e48a57c8165074daecdb623f2";
|
||||
gitCommit = "b7af30b36be3e7e90b33c5f01a3f7e3656df785f";
|
||||
};
|
||||
openmp = prev.openmp.overrideAttrs (old: {
|
||||
# Newer version of LLVM OpenMP requires python3
|
||||
|
@ -33,6 +33,8 @@ enum emu_prv_types {
|
||||
PRV_NANOS6_BREAKDOWN = 41,
|
||||
PRV_KERNEL_CS = 45,
|
||||
PRV_OPENMP_SUBSYSTEM = 50,
|
||||
PRV_OPENMP_LABEL = 51,
|
||||
PRV_OPENMP_TASKID = 52,
|
||||
PRV_OVNI_MARK = 100,
|
||||
/* User marks [100, 200) */
|
||||
PRV_RESERVED = 200,
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "emu_ev.h"
|
||||
#include "extend.h"
|
||||
#include "model_thread.h"
|
||||
#include "ovni.h"
|
||||
#include "proc.h"
|
||||
#include "task.h"
|
||||
#include "thread.h"
|
||||
#include "value.h"
|
||||
|
||||
@ -95,7 +98,7 @@ static const int fn_table[256][256][3] = {
|
||||
};
|
||||
|
||||
static int
|
||||
process_ev(struct emu *emu)
|
||||
simple(struct emu *emu)
|
||||
{
|
||||
if (!emu->thread->is_running) {
|
||||
err("current thread %d not running", emu->thread->tid);
|
||||
@ -122,6 +125,263 @@ process_ev(struct emu *emu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
create_task(struct emu *emu)
|
||||
{
|
||||
if (emu->ev->payload_size != 8) {
|
||||
err("unexpected payload size");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t taskid = emu->ev->payload->u32[0];
|
||||
uint32_t typeid = emu->ev->payload->u32[1];
|
||||
|
||||
if (taskid == 0) {
|
||||
err("taskid cannot be 0");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (typeid == 0) {
|
||||
err("typeid cannot be 0");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct openmp_proc *proc = EXT(emu->proc, 'P');
|
||||
struct task_info *info = &proc->task_info;
|
||||
|
||||
/* OpenMP submits inline tasks without pausing the previous
|
||||
* task, so we relax the model to allow this for now. */
|
||||
uint32_t flags = TASK_FLAG_RELAX_NESTING;
|
||||
|
||||
if (task_create(info, typeid, taskid, flags) != 0) {
|
||||
err("task_create failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbg("task created with taskid %u", taskid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
update_task(struct emu *emu)
|
||||
{
|
||||
if (emu->ev->payload_size < 4) {
|
||||
err("missing task id in payload");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t taskid = emu->ev->payload->u32[0];
|
||||
|
||||
if (taskid == 0) {
|
||||
err("taskid cannot be 0");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct openmp_thread *th = EXT(emu->thread, 'P');
|
||||
struct openmp_proc *proc = EXT(emu->proc, 'P');
|
||||
|
||||
struct task_info *info = &proc->task_info;
|
||||
struct task_stack *stack = &th->task_stack;
|
||||
|
||||
struct task *task = task_find(info->tasks, taskid);
|
||||
|
||||
if (task == NULL) {
|
||||
err("cannot find task with id %u", taskid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* OpenMP doesn't have parallel tasks */
|
||||
uint32_t body_id = 1;
|
||||
|
||||
if (emu->ev->v == 'x') {
|
||||
if (task_execute(stack, task, body_id) != 0) {
|
||||
err("cannot change task state to running");
|
||||
return -1;
|
||||
}
|
||||
if (chan_push(&th->m.ch[CH_TASKID], value_int64(task->id)) != 0) {
|
||||
err("chan_push taskid failed");
|
||||
return -1;
|
||||
}
|
||||
if (chan_push(&th->m.ch[CH_LABEL], value_int64(task->type->gid)) != 0) {
|
||||
err("chan_push task label failed");
|
||||
return -1;
|
||||
}
|
||||
} else if (emu->ev->v == 'e') {
|
||||
if (task_end(stack, task, body_id) != 0) {
|
||||
err("cannot change task state to end");
|
||||
return -1;
|
||||
}
|
||||
if (chan_pop(&th->m.ch[CH_TASKID], value_int64(task->id)) != 0) {
|
||||
err("chan_pop taskid failed");
|
||||
return -1;
|
||||
}
|
||||
if (chan_pop(&th->m.ch[CH_LABEL], value_int64(task->type->gid)) != 0) {
|
||||
err("chan_pop task label failed");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
err("unexpected task event %c", emu->ev->v);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_task(struct emu *emu)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (emu->ev->v) {
|
||||
case 'c':
|
||||
ret = create_task(emu);
|
||||
break;
|
||||
case 'x':
|
||||
case 'e':
|
||||
ret = update_task(emu);
|
||||
break;
|
||||
default:
|
||||
err("unexpected task event value");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
err("cannot update task state");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_type(struct emu *emu)
|
||||
{
|
||||
uint8_t value = emu->ev->v;
|
||||
|
||||
if (value != 'c') {
|
||||
err("unexpected event value %c", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!emu->ev->is_jumbo) {
|
||||
err("expecting a jumbo event");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *data = &emu->ev->payload->jumbo.data[0];
|
||||
uint32_t typeid;
|
||||
memcpy(&typeid, data, 4); /* May be unaligned */
|
||||
data += 4;
|
||||
|
||||
const char *label = (const char *) data;
|
||||
|
||||
struct openmp_proc *proc = EXT(emu->proc, 'P');
|
||||
struct task_info *info = &proc->task_info;
|
||||
|
||||
/* It will be used for tasks and worksharings. */
|
||||
if (task_type_create(info, typeid, label) != 0) {
|
||||
err("task_type_create failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
update_ws_state(struct emu *emu, uint8_t action)
|
||||
{
|
||||
if (emu->ev->payload_size < 4) {
|
||||
err("missing worksharing id in payload");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t typeid = emu->ev->payload->u32[0];
|
||||
|
||||
if (typeid == 0) {
|
||||
err("worksharing type id cannot be 0");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct openmp_thread *th = EXT(emu->thread, 'P');
|
||||
struct openmp_proc *proc = EXT(emu->proc, 'P');
|
||||
|
||||
struct task_info *info = &proc->task_info;
|
||||
|
||||
/* Worksharings share the task type */
|
||||
struct task_type *ttype = task_type_find(info->types, typeid);
|
||||
|
||||
if (ttype == NULL) {
|
||||
err("cannot find ws with type %"PRIu32, typeid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (action == 'x') {
|
||||
if (chan_push(&th->m.ch[CH_LABEL], value_int64(ttype->gid)) != 0) {
|
||||
err("chan_push worksharing label failed");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (chan_pop(&th->m.ch[CH_LABEL], value_int64(ttype->gid)) != 0) {
|
||||
err("chan_pop worksharing label failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pre_worksharing(struct emu *emu)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (emu->ev->v) {
|
||||
case 'x':
|
||||
case 'e':
|
||||
ret = update_ws_state(emu, emu->ev->v);
|
||||
break;
|
||||
default:
|
||||
err("unexpected ws event value %c", emu->ev->v);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
err("cannot update worksharing channels");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
process_ev(struct emu *emu)
|
||||
{
|
||||
if (!emu->thread->is_running) {
|
||||
err("current thread %d not running", emu->thread->tid);
|
||||
return -1;
|
||||
}
|
||||
switch (emu->ev->c) {
|
||||
case 'B':
|
||||
case 'I':
|
||||
case 'W':
|
||||
case 'T':
|
||||
case 'A':
|
||||
case 'M':
|
||||
case 'H':
|
||||
case 'C':
|
||||
return simple(emu);
|
||||
case 'P':
|
||||
return pre_task(emu);
|
||||
case 'O':
|
||||
return pre_type(emu);
|
||||
case 'Q':
|
||||
return pre_worksharing(emu);
|
||||
}
|
||||
|
||||
err("unknown event category");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
model_openmp_event(struct emu *emu)
|
||||
{
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define OPENMP_PRIV_H
|
||||
|
||||
#include "emu.h"
|
||||
#include "task.h"
|
||||
#include "model_cpu.h"
|
||||
#include "model_thread.h"
|
||||
|
||||
@ -12,6 +13,8 @@
|
||||
|
||||
enum openmp_chan {
|
||||
CH_SUBSYSTEM = 0,
|
||||
CH_LABEL,
|
||||
CH_TASKID,
|
||||
CH_MAX,
|
||||
};
|
||||
|
||||
@ -55,12 +58,18 @@ enum openmp_function_values {
|
||||
|
||||
struct openmp_thread {
|
||||
struct model_thread m;
|
||||
struct task_stack task_stack;
|
||||
};
|
||||
|
||||
struct openmp_cpu {
|
||||
struct model_cpu m;
|
||||
};
|
||||
|
||||
struct openmp_proc {
|
||||
/* Shared among tasks and ws */
|
||||
struct task_info task_info;
|
||||
};
|
||||
|
||||
int model_openmp_probe(struct emu *emu);
|
||||
int model_openmp_create(struct emu *emu);
|
||||
int model_openmp_connect(struct emu *emu);
|
||||
|
@ -15,8 +15,10 @@
|
||||
#include "model_cpu.h"
|
||||
#include "model_pvt.h"
|
||||
#include "model_thread.h"
|
||||
#include "proc.h"
|
||||
#include "pv/pcf.h"
|
||||
#include "pv/prv.h"
|
||||
#include "pv/pvt.h"
|
||||
#include "system.h"
|
||||
#include "thread.h"
|
||||
#include "track.h"
|
||||
@ -65,12 +67,22 @@ static struct ev_decl model_evlist[] = {
|
||||
PAIR_B("PCf", "PCF", "fork call")
|
||||
PAIR_B("PCi", "PCI", "initialization")
|
||||
|
||||
/* Task or worksharing type */
|
||||
{ "POc+(u32 typeid, str label)", "creates a type %{typeid} with label \"%{label}\"" },
|
||||
|
||||
{ "PPc(u32 taskid, u32 typeid)", "creates the task %{taskid} with type %{typeid}" },
|
||||
{ "PPx(u32 taskid)", "executes the task %{taskid}" },
|
||||
{ "PPe(u32 taskid)", "ends the task %{taskid}" },
|
||||
|
||||
{ "PQx(u32 typeid)", "begins worksharing with type %{typeid}" },
|
||||
{ "PQe(u32 typeid)", "ends worksharing with type %{typeid}" },
|
||||
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
struct model_spec model_openmp = {
|
||||
.name = model_name,
|
||||
.version = "1.1.0",
|
||||
.version = "1.2.0",
|
||||
.evlist = model_evlist,
|
||||
.model = model_id,
|
||||
.create = model_openmp_create,
|
||||
@ -84,24 +96,34 @@ struct model_spec model_openmp = {
|
||||
|
||||
static const char *chan_name[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = "subsystem",
|
||||
[CH_LABEL] = "label",
|
||||
[CH_TASKID] = "task ID",
|
||||
};
|
||||
|
||||
static const int chan_stack[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = 1,
|
||||
[CH_LABEL] = 1,
|
||||
[CH_TASKID] = 1,
|
||||
};
|
||||
|
||||
static const int chan_dup[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = 1,
|
||||
[CH_LABEL] = 1, /* Two tasks nested with same type */
|
||||
[CH_TASKID] = 1,
|
||||
};
|
||||
|
||||
/* ----------------- pvt ------------------ */
|
||||
|
||||
static const int pvt_type[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = PRV_OPENMP_SUBSYSTEM,
|
||||
[CH_LABEL] = PRV_OPENMP_LABEL,
|
||||
[CH_TASKID] = PRV_OPENMP_TASKID,
|
||||
};
|
||||
|
||||
static const char *pcf_prefix[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = "OpenMP subsystem",
|
||||
[CH_LABEL] = "OpenMP label",
|
||||
[CH_TASKID] = "OpenMP task ID",
|
||||
};
|
||||
|
||||
static const struct pcf_value_label openmp_subsystem_values[] = {
|
||||
@ -149,7 +171,9 @@ static const struct pcf_value_label *pcf_labels[CH_MAX] = {
|
||||
};
|
||||
|
||||
static const long prv_flags[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = PRV_EMITDUP,
|
||||
[CH_SUBSYSTEM] = PRV_SKIPDUPNULL,
|
||||
[CH_LABEL] = PRV_SKIPDUPNULL,
|
||||
[CH_TASKID] = PRV_SKIPDUPNULL,
|
||||
};
|
||||
|
||||
static const struct model_pvt_spec pvt_spec = {
|
||||
@ -163,10 +187,14 @@ static const struct model_pvt_spec pvt_spec = {
|
||||
|
||||
static const int th_track[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = TRACK_TH_ACT,
|
||||
[CH_LABEL] = TRACK_TH_ACT,
|
||||
[CH_TASKID] = TRACK_TH_ACT,
|
||||
};
|
||||
|
||||
static const int cpu_track[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = TRACK_TH_RUN,
|
||||
[CH_LABEL] = TRACK_TH_RUN,
|
||||
[CH_TASKID] = TRACK_TH_RUN,
|
||||
};
|
||||
|
||||
/* ----------------- chan_spec ------------------ */
|
||||
@ -213,9 +241,24 @@ model_openmp_probe(struct emu *emu)
|
||||
return model_version_probe(&model_openmp, emu);
|
||||
}
|
||||
|
||||
static int
|
||||
init_proc(struct proc *sysproc)
|
||||
{
|
||||
struct openmp_proc *proc = calloc(1, sizeof(struct openmp_proc));
|
||||
if (proc == NULL) {
|
||||
err("calloc failed:");
|
||||
return -1;
|
||||
}
|
||||
|
||||
extend_set(&sysproc->ext, model_id, proc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
model_openmp_create(struct emu *emu)
|
||||
{
|
||||
|
||||
if (model_thread_create(emu, &th_spec) != 0) {
|
||||
err("model_thread_init failed");
|
||||
return -1;
|
||||
@ -226,6 +269,15 @@ model_openmp_create(struct emu *emu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct system *sys = &emu->system;
|
||||
|
||||
for (struct proc *p = sys->procs; p; p = p->gnext) {
|
||||
if (init_proc(p) != 0) {
|
||||
err("init_proc failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -245,6 +297,44 @@ model_openmp_connect(struct emu *emu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
create_pcf_type(struct system *sys, struct pcf *pcf, long typeid)
|
||||
{
|
||||
struct pcf_type *pcftype = pcf_find_type(pcf, (int) typeid);
|
||||
|
||||
for (struct proc *p = sys->procs; p; p = p->gnext) {
|
||||
struct openmp_proc *proc = EXT(p, model_id);
|
||||
struct task_info *info = &proc->task_info;
|
||||
if (task_create_pcf_types(pcftype, info->types) != 0) {
|
||||
err("task_create_pcf_types failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
finish_pvt(struct emu *emu, const char *name)
|
||||
{
|
||||
struct system *sys = &emu->system;
|
||||
|
||||
/* Emit task types for all channel types and processes */
|
||||
struct pvt *pvt = recorder_find_pvt(&emu->recorder, name);
|
||||
if (pvt == NULL) {
|
||||
err("cannot find pvt with name '%s'", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct pcf *pcf = pvt_get_pcf(pvt);
|
||||
if (create_pcf_type(sys, pcf, pvt_type[CH_LABEL]) != 0) {
|
||||
err("create_pcf_type failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
end_lint(struct emu *emu)
|
||||
{
|
||||
@ -278,6 +368,17 @@ end_lint(struct emu *emu)
|
||||
int
|
||||
model_openmp_finish(struct emu *emu)
|
||||
{
|
||||
/* Fill task types */
|
||||
if (finish_pvt(emu, "thread") != 0) {
|
||||
err("finish_pvt thread failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (finish_pvt(emu, "cpu") != 0) {
|
||||
err("finish_pvt cpu failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* When running in linter mode perform additional checks */
|
||||
if (emu->args.linter_mode && end_lint(emu) != 0) {
|
||||
err("end_lint failed");
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2022-2023 Barcelona Supercomputing Center (BSC)
|
||||
# Copyright (c) 2022-2024 Barcelona Supercomputing Center (BSC)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
function(test_emu)
|
||||
@ -13,3 +13,4 @@ add_subdirectory(nosv)
|
||||
add_subdirectory(nanos6)
|
||||
add_subdirectory(tampi)
|
||||
add_subdirectory(mpi)
|
||||
add_subdirectory(openmp)
|
||||
|
6
test/emu/openmp/CMakeLists.txt
Normal file
6
test/emu/openmp/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
test_emu(nested-ws.c)
|
||||
test_emu(nested-task.c)
|
||||
test_emu(mix-task-ws.c)
|
47
test/emu/openmp/instr_openmp.h
Normal file
47
test/emu/openmp/instr_openmp.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#ifndef INSTR_OPENMP_H
|
||||
#define INSTR_OPENMP_H
|
||||
|
||||
#include "instr.h"
|
||||
|
||||
#include "task.h"
|
||||
|
||||
static inline void
|
||||
instr_openmp_init(void)
|
||||
{
|
||||
instr_require("openmp");
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
instr_openmp_type_create(uint32_t typeid, const char *label)
|
||||
{
|
||||
struct ovni_ev ev = {0};
|
||||
|
||||
ovni_ev_set_mcv(&ev, "POc");
|
||||
ovni_ev_set_clock(&ev, (uint64_t) get_clock());
|
||||
|
||||
char buf[256];
|
||||
char *p = buf;
|
||||
|
||||
size_t nbytes = 0;
|
||||
memcpy(buf, &typeid, sizeof(typeid));
|
||||
p += sizeof(typeid);
|
||||
nbytes += sizeof(typeid);
|
||||
sprintf(p, "%s.%d", label, typeid);
|
||||
nbytes += strlen(p) + 1;
|
||||
|
||||
ovni_ev_jumbo_emit(&ev, (uint8_t *) buf, (uint32_t) nbytes);
|
||||
|
||||
return task_get_type_gid(p);
|
||||
}
|
||||
|
||||
INSTR_2ARG(instr_openmp_task_create, "PPc", uint32_t, taskid, uint32_t, typeid)
|
||||
INSTR_1ARG(instr_openmp_task_execute, "PPx", uint32_t, taskid)
|
||||
INSTR_1ARG(instr_openmp_task_end, "PPe", uint32_t, taskid)
|
||||
|
||||
INSTR_1ARG(instr_openmp_ws_enter, "PQx", uint32_t, typeid)
|
||||
INSTR_1ARG(instr_openmp_ws_exit, "PQe", uint32_t, typeid)
|
||||
|
||||
#endif /* INSTR_OPENMP_H */
|
47
test/emu/openmp/mix-task-ws.c
Normal file
47
test/emu/openmp/mix-task-ws.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "compat.h"
|
||||
#include "instr.h"
|
||||
#include "instr_openmp.h"
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
instr_start(0, 1);
|
||||
instr_openmp_init();
|
||||
|
||||
enum { TASK=1, WS1=2, WS2=3 };
|
||||
instr_openmp_type_create(TASK, "main task");
|
||||
instr_openmp_type_create(WS1, "outer for");
|
||||
instr_openmp_type_create(WS2, "inner for");
|
||||
|
||||
instr_openmp_task_create(1, TASK);
|
||||
instr_openmp_task_execute(1);
|
||||
sleep_us(100);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
instr_openmp_ws_enter(WS1);
|
||||
sleep_us(10);
|
||||
{
|
||||
instr_openmp_ws_enter(WS2);
|
||||
sleep_us(10);
|
||||
instr_openmp_ws_exit(WS2);
|
||||
}
|
||||
sleep_us(10);
|
||||
instr_openmp_ws_exit(WS1);
|
||||
sleep_us(10);
|
||||
}
|
||||
sleep_us(10);
|
||||
instr_openmp_task_end(1);
|
||||
sleep_us(10);
|
||||
/* Another task from the same type */
|
||||
instr_openmp_task_create(2, TASK);
|
||||
instr_openmp_task_execute(2);
|
||||
sleep_us(100);
|
||||
instr_openmp_task_end(2);
|
||||
|
||||
instr_end();
|
||||
|
||||
return 0;
|
||||
}
|
32
test/emu/openmp/nested-task.c
Normal file
32
test/emu/openmp/nested-task.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "compat.h"
|
||||
#include "instr.h"
|
||||
#include "instr_openmp.h"
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
instr_start(0, 1);
|
||||
instr_openmp_init();
|
||||
|
||||
enum { TYPE=1, A=1, B=2 };
|
||||
|
||||
instr_openmp_type_create(TYPE, "task");
|
||||
instr_openmp_task_create(A, TYPE);
|
||||
instr_openmp_task_create(B, TYPE);
|
||||
|
||||
instr_openmp_task_execute(A);
|
||||
sleep_us(100);
|
||||
instr_openmp_task_execute(B);
|
||||
sleep_us(100);
|
||||
instr_openmp_task_end(B);
|
||||
sleep_us(100);
|
||||
instr_openmp_task_end(A);
|
||||
|
||||
instr_end();
|
||||
|
||||
return 0;
|
||||
}
|
33
test/emu/openmp/nested-ws.c
Normal file
33
test/emu/openmp/nested-ws.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "compat.h"
|
||||
#include "instr.h"
|
||||
#include "instr_openmp.h"
|
||||
|
||||
#define N 30
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
instr_start(0, 1);
|
||||
instr_openmp_init();
|
||||
|
||||
for (uint32_t type = 1; type <= N; type++)
|
||||
instr_openmp_type_create(type, "ws");
|
||||
|
||||
for (uint32_t type = 1; type <= N; type++) {
|
||||
instr_openmp_ws_enter(type);
|
||||
sleep_us(100);
|
||||
}
|
||||
|
||||
for (uint32_t type = N; type > 0; type--) {
|
||||
instr_openmp_ws_exit(type);
|
||||
sleep_us(100);
|
||||
}
|
||||
|
||||
instr_end();
|
||||
|
||||
return 0;
|
||||
}
|
@ -14,12 +14,23 @@ if(NOT OPENMPV_COMPILER_FOUND OR NOT OPENMPV_LINKER_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(Nosv)
|
||||
|
||||
if(NOT NOSV_FOUND)
|
||||
if(ENABLE_ALL_TESTS)
|
||||
message(FATAL_ERROR "nOS-V not found, cannot enable OpenMP-V RT tests")
|
||||
else()
|
||||
message(STATUS "nOS-V not found, disabling OpenMP-V RT tests")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
function(openmp_rt_test)
|
||||
ovni_test(${ARGN})
|
||||
target_compile_options("${OVNI_TEST_NAME}" PUBLIC "-fopenmp=libompv"
|
||||
"-no-pedantic")
|
||||
target_link_options("${OVNI_TEST_NAME}" PUBLIC "-fopenmp=libompv")
|
||||
target_link_libraries("${OVNI_TEST_NAME}" PRIVATE "m")
|
||||
target_link_libraries("${OVNI_TEST_NAME}" PRIVATE "m" PkgConfig::NOSV)
|
||||
set_property(TEST "${OVNI_TEST_NAME}" APPEND PROPERTY
|
||||
ENVIRONMENT "OMP_OVNI=1")
|
||||
set_property(TEST "${OVNI_TEST_NAME}" APPEND PROPERTY
|
||||
@ -48,3 +59,4 @@ openmp_rt_test(worksharing.c)
|
||||
openmp_rt_test(worksharing01.c)
|
||||
openmp_rt_test(worksharing02.c)
|
||||
openmp_rt_test(worksharing03.c)
|
||||
openmp_rt_test(worksharing-active-th.c DRIVER worksharing-active-th.driver.sh)
|
||||
|
@ -11,7 +11,7 @@ int main(void)
|
||||
#pragma omp taskloop
|
||||
for (int i = 0; i < 10000; i++)
|
||||
{
|
||||
#pragma omp task
|
||||
#pragma omp task label("taskloop task")
|
||||
sleep_us(1);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
22
test/rt/openmp/worksharing-active-th.c
Normal file
22
test/rt/openmp/worksharing-active-th.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include <nosv.h>
|
||||
#include "ovni.h"
|
||||
|
||||
/* Ensure that the thread is paused on nosv_waitfor(), so there is a hole in the
|
||||
* OpenMP views, as they track the active thread (in the thread views) and the
|
||||
* running thread (in the CPU views). */
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
ovni_mark_type(0, OVNI_MARK_STACK, "tracker");
|
||||
|
||||
#pragma omp parallel for num_threads(1)
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
ovni_mark_push(0, 123);
|
||||
/* We should see a hole here */
|
||||
nosv_waitfor(10, NULL);
|
||||
ovni_mark_pop(0, 123);
|
||||
}
|
||||
}
|
29
test/rt/openmp/worksharing-active-th.driver.sh
Normal file
29
test/rt/openmp/worksharing-active-th.driver.sh
Normal file
@ -0,0 +1,29 @@
|
||||
target=$OVNI_TEST_BIN
|
||||
|
||||
export NOSV_APPID=1
|
||||
export OMP_NUM_THREADS=1
|
||||
|
||||
$target
|
||||
|
||||
ovniemu -l ovni
|
||||
|
||||
# Mark API adds 100 to the type
|
||||
prvtype="100"
|
||||
|
||||
row=$(grep '100:123$' ovni/thread.prv | head -1 | cut -d: -f 5)
|
||||
t0=$(grep '100:123$' ovni/thread.prv | head -1 | cut -d: -f 6)
|
||||
t1=$(grep '100:123$' ovni/thread.prv | tail -1 | cut -d: -f 6)
|
||||
|
||||
PRV_THREAD_STATE=4
|
||||
TH_ST_PAUSED=2
|
||||
|
||||
# 2:0:1:1:1:15113228:100:123
|
||||
count=$(grep "2:0:1:1:$row:.*:$PRV_THREAD_STATE:$TH_ST_PAUSED" ovni/thread.prv |\
|
||||
awk -F: '$6 >= '$t0' && $6 <= '$t1' {n++} END {print n}')
|
||||
|
||||
if [ "$count" != 100 ]; then
|
||||
echo "FAIL: expected 100 pause events"
|
||||
exit 1
|
||||
else
|
||||
echo "OK: found 100 pause events"
|
||||
fi
|
@ -7,7 +7,7 @@ int main(void)
|
||||
{
|
||||
//#pragma omp single nowait
|
||||
for (int i = 0; i < 100; i++) {
|
||||
#pragma omp task
|
||||
#pragma omp task label("minitask")
|
||||
sleep_us(10);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ int main(void)
|
||||
{
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp for
|
||||
#pragma omp for label("static-for-1")
|
||||
for (int i = 0; i < 100; i++) {
|
||||
sleep_us(1);
|
||||
}
|
||||
@ -26,7 +26,7 @@ int main(void)
|
||||
{ sleep_us(104); printf("104\n"); }
|
||||
}
|
||||
|
||||
#pragma omp for
|
||||
#pragma omp for label("static-for-2")
|
||||
for (int i = 0; i < 100; i++) {
|
||||
sleep_us(1);
|
||||
}
|
||||
@ -46,11 +46,11 @@ int main(void)
|
||||
|
||||
#pragma omp barrier
|
||||
|
||||
#pragma omp for
|
||||
#pragma omp for label("static-for-3")
|
||||
for (int i = 0; i < 100; i++) {
|
||||
sleep_us(1);
|
||||
}
|
||||
#pragma omp for schedule(dynamic, 1)
|
||||
#pragma omp for schedule(dynamic, 1) label("dynamic-for")
|
||||
for (int i = 0; i < 100; i++) {
|
||||
sleep_us(i);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user