Add support for progress events in OpenMP

Two new events are added (Ppp and Pps) which define the Progressing and
Stalled states respectively. A new pseudo-state Idle is shown in the
view when no thread is running.
This commit is contained in:
Rodrigo Arias 2025-02-27 16:17:33 +01:00
parent 8d78abd07f
commit cc38bcfe91
10 changed files with 119 additions and 12 deletions

View File

@ -39,6 +39,6 @@ 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 53
window_filter_module evt_type 1 54
window_filter_module evt_type_label 1 "CPU: OpenMP Runtime/Label breakdown"

View File

@ -1,7 +1,7 @@
# Emulator events
This is a exhaustive list of the events recognized by the emulator.
Built on Nov 13 2024.
Built on Feb 5 2025.
## 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.2.0`:
List of events for the model *openmp* with identifier **`P`** at version `1.3.0`:
<dl>
<dt><a id="PBb" href="#PBb"><pre>PBb</pre></a></dt>
<dd>begins plain barrier</dd>
@ -575,6 +575,10 @@ List of events for the model *openmp* with identifier **`P`** at version `1.2.0`
<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>
<dt><a id="Ppp" href="#Ppp"><pre>Ppp</pre></a></dt>
<dd>sets progress state to Progressing</dd>
<dt><a id="Pps" href="#Pps"><pre>Pps</pre></a></dt>
<dd>sets progress state to Stalled</dd>
</dl>
## Model tampi

View File

@ -177,6 +177,19 @@ 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.
## Idle view
The idle view shows the progress state of the running threads:
*Progressing* and *Stalled*. The *Progressing* state is shown when they
are making useful progress and the *Stalled* state when they are waiting
for work. When workers start running, by definition, they begin in the
Progressing state and there are some situations that make them
transition to Stalled...
!!! Note
TODO: Complete description
## Limitations
As the compiler generates the code that perform the calls to the libompv

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2021-2025 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#ifndef EMU_PRV_H
@ -35,7 +35,8 @@ enum emu_prv_types {
PRV_OPENMP_SUBSYSTEM = 50,
PRV_OPENMP_LABEL = 51,
PRV_OPENMP_TASKID = 52,
PRV_OPENMP_BREAKDOWN = 53,
PRV_OPENMP_IDLE = 53,
PRV_OPENMP_BREAKDOWN = 54,
PRV_OVNI_MARK = 100,
/* User marks [100, 200) */
PRV_RESERVED = 200,

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2023-2025 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include "openmp_priv.h"
@ -14,7 +14,7 @@
#include "thread.h"
#include "value.h"
enum { PUSH = 1, POP = 2, IGN = 3 };
enum { PUSH = 1, POP, SET, IGN };
static const int fn_table[256][256][3] = {
['B'] = {
@ -95,6 +95,10 @@ static const int fn_table[256][256][3] = {
['f'] = { CH_SUBSYSTEM, PUSH, ST_RT_FORK_CALL },
['F'] = { CH_SUBSYSTEM, POP, ST_RT_FORK_CALL },
},
['p'] = {
['p'] = { CH_IDLE, SET, ST_PROGRESSING },
['s'] = { CH_IDLE, SET, ST_STALLED },
},
};
static int
@ -117,6 +121,8 @@ simple(struct emu *emu)
return chan_push(ch, value_int64(st));
} else if (action == POP) {
return chan_pop(ch, value_int64(st));
} else if (action == SET) {
return chan_set(ch, value_int64(st));
} else if (action == IGN) {
return 0; /* do nothing */
}
@ -369,6 +375,7 @@ process_ev(struct emu *emu)
case 'M':
case 'H':
case 'C':
case 'p':
return simple(emu);
case 'P':
return pre_task(emu);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2023-2025 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#ifndef OPENMP_PRIV_H
@ -16,6 +16,7 @@ enum openmp_chan {
CH_SUBSYSTEM = 0,
CH_LABEL,
CH_TASKID,
CH_IDLE,
CH_MAX,
};
@ -57,6 +58,14 @@ enum openmp_function_values {
ST_RT_WORKER_LOOP,
};
enum openmp_progress_values {
/* Can mix with subsystem values */
ST_PROGRESSING = 100,
ST_STALLED, /* Running thread doing nothing useful */
ST_IDLE, /* No running threads */
};
struct openmp_thread {
struct model_thread m;
struct task_stack task_stack;

View File

@ -1,10 +1,11 @@
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2023-2025 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include "openmp_priv.h"
#include <stddef.h>
#include "chan.h"
#include "common.h"
#include "cpu.h"
#include "emu.h"
#include "emu_args.h"
#include "emu_prv.h"
@ -77,12 +78,15 @@ static struct ev_decl model_evlist[] = {
{ "PQx(u32 typeid)", "begins worksharing with type %{typeid}" },
{ "PQe(u32 typeid)", "ends worksharing with type %{typeid}" },
{ "Ppp", "sets progress state to Progressing" },
{ "Pps", "sets progress state to Stalled" },
{ NULL, NULL },
};
struct model_spec model_openmp = {
.name = model_name,
.version = "1.2.0",
.version = "1.3.0",
.evlist = model_evlist,
.model = model_id,
.create = model_openmp_create,
@ -98,6 +102,7 @@ static const char *chan_name[CH_MAX] = {
[CH_SUBSYSTEM] = "subsystem",
[CH_LABEL] = "label",
[CH_TASKID] = "task ID",
[CH_IDLE] = "idle",
};
static const int chan_stack[CH_MAX] = {
@ -118,12 +123,14 @@ static const int pvt_type[CH_MAX] = {
[CH_SUBSYSTEM] = PRV_OPENMP_SUBSYSTEM,
[CH_LABEL] = PRV_OPENMP_LABEL,
[CH_TASKID] = PRV_OPENMP_TASKID,
[CH_IDLE] = PRV_OPENMP_IDLE,
};
static const char *pcf_prefix[CH_MAX] = {
[CH_SUBSYSTEM] = "OpenMP subsystem",
[CH_LABEL] = "OpenMP label",
[CH_TASKID] = "OpenMP task ID",
[CH_IDLE] = "OpenMP idle",
};
static const struct pcf_value_label openmp_subsystem_values[] = {
@ -166,14 +173,23 @@ static const struct pcf_value_label openmp_subsystem_values[] = {
{ -1, NULL },
};
static const struct pcf_value_label openmp_progress_values[] = {
{ ST_PROGRESSING, "Progressing" },
{ ST_STALLED, "Stalled" },
{ ST_IDLE, "Idle" },
{ -1, NULL },
};
static const struct pcf_value_label *pcf_labels[CH_MAX] = {
[CH_SUBSYSTEM] = openmp_subsystem_values,
[CH_IDLE] = openmp_progress_values,
};
static const long prv_flags[CH_MAX] = {
[CH_SUBSYSTEM] = PRV_SKIPDUPNULL,
[CH_LABEL] = PRV_SKIPDUPNULL,
[CH_TASKID] = PRV_SKIPDUPNULL,
[CH_IDLE] = PRV_SKIPDUPNULL,
};
static const struct model_pvt_spec pvt_spec = {
@ -189,12 +205,14 @@ static const int th_track[CH_MAX] = {
[CH_SUBSYSTEM] = TRACK_TH_ACT,
[CH_LABEL] = TRACK_TH_ACT,
[CH_TASKID] = TRACK_TH_ACT,
[CH_IDLE] = 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,
[CH_IDLE] = TRACK_TH_RUN,
};
/* ----------------- chan_spec ------------------ */
@ -312,6 +330,23 @@ model_openmp_connect(struct emu *emu)
return -1;
}
for (struct thread *th = emu->system.threads; th; th = th->gnext) {
struct openmp_thread *mth = EXT(th, model_id);
struct chan *idle = &mth->m.ch[CH_IDLE];
/* By default set all threads as Progressing */
if (chan_set(idle, value_int64(ST_PROGRESSING)) != 0) {
err("chan_push idle failed");
return -1;
}
}
for (struct cpu *cpu = emu->system.cpus; cpu; cpu = cpu->next) {
struct openmp_cpu *mcpu = EXT(cpu, model_id);
struct mux *mux = &mcpu->m.track[CH_IDLE].mux;
/* Emit Idle when a CPU has no running threads */
mux_set_default(mux, value_int64(ST_IDLE));
}
return 0;
}

View File

@ -1,6 +1,7 @@
# Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
# Copyright (c) 2024-2025 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)
test_emu(idle.c)

34
test/emu/openmp/idle.c Normal file
View File

@ -0,0 +1,34 @@
/* Copyright (c) 2025 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();
instr_openmp_type_create(1, "task");
instr_openmp_task_create(1, 1);
instr_openmp_stalled();
sleep_us(100);
instr_openmp_progressing();
sleep_us(100);
/* Pause the thread to create Idle state */
instr_thread_pause();
sleep_us(100);
instr_thread_resume();
sleep_us(100);
instr_openmp_task_execute(1);
sleep_us(100);
instr_openmp_task_end(1);
instr_end();
return 0;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2024-2025 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#ifndef INSTR_OPENMP_H
@ -44,4 +44,7 @@ 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)
INSTR_0ARG(instr_openmp_progressing, "Ppp")
INSTR_0ARG(instr_openmp_stalled, "Pps")
#endif /* INSTR_OPENMP_H */