nOS-V Breakdown
This commit is contained in:
parent
92cc779caf
commit
9fb53df45d
44
cfg/cpu/nosv/breakdown.cfg
Normal file
44
cfg/cpu/nosv/breakdown.cfg
Normal file
@ -0,0 +1,44 @@
|
||||
#ParaverCFG
|
||||
ConfigFile.Version: 3.4
|
||||
ConfigFile.NumWindows: 1
|
||||
|
||||
|
||||
################################################################################
|
||||
< NEW DISPLAYING WINDOW CPU: nOS-V Runtime/Idle/Task breakdown >
|
||||
################################################################################
|
||||
window_name CPU: nOS-V Runtime/Idle/Task breakdown
|
||||
window_type single
|
||||
window_id 1
|
||||
window_position_x 0
|
||||
window_position_y 0
|
||||
window_width 600
|
||||
window_height 150
|
||||
window_comm_lines_enabled false
|
||||
window_flags_enabled false
|
||||
window_noncolor_mode true
|
||||
window_custom_color_enabled true
|
||||
window_custom_color_palette {1.000000000000:0,70,0},{3.000000000000:99,131,0},{4.000000000000:53,121,221},{5.000000000000:223,108,0},{6.000000000000:75,127,82},{7.000000000000:242,110,162},{8.000000000000:255,190,0},{9.000000000000:153,114,0},{10.000000000000:156,12,231},{11.000000000000:177,25,229},{12.000000000000:255,72,50},{15.000000000000:0,171,255},{16.000000000000:124,213,228},{17.000000000000:242,239,141},{18.000000000000:80,80,80},{19.000000000000:94,0,0},{20.000000000000:128,165,214},{22.000000000000:222,101,128},{23.000000000000:110,148,255},{100.000000000000:0,100,0},{101.000000000000:100,100,177},{102.000000000000:150,150,0}
|
||||
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 17
|
||||
window_filter_module evt_type_label 1 "CPU: nOS-V Runtime/Idle/Task breakdown"
|
||||
|
44
cfg/cpu/nosv/idle.cfg
Normal file
44
cfg/cpu/nosv/idle.cfg
Normal file
@ -0,0 +1,44 @@
|
||||
#ParaverCFG
|
||||
ConfigFile.Version: 3.4
|
||||
ConfigFile.NumWindows: 1
|
||||
|
||||
|
||||
################################################################################
|
||||
< NEW DISPLAYING WINDOW CPU: nOS-V idle state of the RUNNING thread >
|
||||
################################################################################
|
||||
window_name CPU: nOS-V idle state 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 false
|
||||
window_flags_enabled false
|
||||
window_noncolor_mode true
|
||||
window_custom_color_enabled true
|
||||
window_custom_color_palette {100.000000000000:0,100,0},{101.000000000000:100,100,177},{102.000000000000:150,150,0}
|
||||
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 16
|
||||
window_filter_module evt_type_label 1 "CPU: nOS-V idle state of the RUNNING thread"
|
||||
|
@ -52,6 +52,7 @@ add_library(emu STATIC
|
||||
nanos6/setup.c
|
||||
nanos6/event.c
|
||||
nanos6/breakdown.c
|
||||
nosv/breakdown.c
|
||||
nosv/setup.c
|
||||
nosv/event.c
|
||||
nodes/setup.c
|
||||
|
@ -19,6 +19,8 @@ enum emu_prv_types {
|
||||
PRV_NOSV_SUBSYSTEM = 13,
|
||||
PRV_NOSV_RANK = 14,
|
||||
PRV_NOSV_BODYID = 15,
|
||||
PRV_NOSV_IDLE = 16,
|
||||
PRV_NOSV_BREAKDOWN = 17,
|
||||
PRV_TAMPI_SUBSYSTEM = 20,
|
||||
PRV_MPI_FUNCTION = 25,
|
||||
PRV_NODES_SUBSYSTEM = 30,
|
||||
|
312
src/emu/nosv/breakdown.c
Normal file
312
src/emu/nosv/breakdown.c
Normal file
@ -0,0 +1,312 @@
|
||||
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#include "breakdown.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "bay.h"
|
||||
#include "chan.h"
|
||||
#include "common.h"
|
||||
#include "cpu.h"
|
||||
#include "emu.h"
|
||||
#include "emu_args.h"
|
||||
#include "emu_prv.h"
|
||||
#include "extend.h"
|
||||
#include "model_cpu.h"
|
||||
#include "mux.h"
|
||||
#include "nosv_priv.h"
|
||||
#include "proc.h"
|
||||
#include "pv/pcf.h"
|
||||
#include "pv/prf.h"
|
||||
#include "pv/prv.h"
|
||||
#include "pv/pvt.h"
|
||||
#include "recorder.h"
|
||||
#include "sort.h"
|
||||
#include "system.h"
|
||||
#include "task.h"
|
||||
#include "track.h"
|
||||
#include "value.h"
|
||||
|
||||
|
||||
static int
|
||||
create_cpu(struct bay *bay, struct nosv_breakdown_cpu *bcpu, int64_t gindex)
|
||||
{
|
||||
enum chan_type t = CHAN_SINGLE;
|
||||
chan_init(&bcpu->tr, t, "nosv.cpu%ld.breakdown.tr", gindex);
|
||||
chan_init(&bcpu->tri, t, "nosv.cpu%ld.breakdown.tri", gindex);
|
||||
|
||||
/* Register all channels in the bay */
|
||||
if (bay_register(bay, &bcpu->tr) != 0) {
|
||||
err("bay_register tr failed");
|
||||
return -1;
|
||||
}
|
||||
if (bay_register(bay, &bcpu->tri) != 0) {
|
||||
err("bay_register tri failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
model_nosv_breakdown_create(struct emu *emu)
|
||||
{
|
||||
if (emu->args.breakdown == 0)
|
||||
return 0;
|
||||
|
||||
struct nosv_emu *memu = EXT(emu, 'V');
|
||||
struct nosv_breakdown_emu *bemu = &memu->breakdown;
|
||||
|
||||
/* Count phy cpus */
|
||||
struct system *sys = &emu->system;
|
||||
int64_t nphycpus = sys->ncpus - sys->nlooms;
|
||||
bemu->nphycpus = nphycpus;
|
||||
|
||||
/* Create a new Paraver trace */
|
||||
struct recorder *rec = &emu->recorder;
|
||||
bemu->pvt = recorder_add_pvt(rec, "nosv-breakdown", nphycpus);
|
||||
if (bemu->pvt == NULL) {
|
||||
err("recorder_add_pvt failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sort_init(&bemu->sort, &emu->bay, nphycpus, "nosv.breakdown.sort") != 0) {
|
||||
err("sort_init failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (struct cpu *cpu = sys->cpus; cpu; cpu = cpu->next) {
|
||||
if (cpu->is_virtual)
|
||||
continue;
|
||||
|
||||
struct nosv_cpu *mcpu = EXT(cpu, 'V');
|
||||
struct nosv_breakdown_cpu *bcpu = &mcpu->breakdown;
|
||||
|
||||
if (create_cpu(&emu->bay, bcpu, cpu->gindex) != 0) {
|
||||
err("create_cpu failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
select_tr(struct mux *mux, struct value value, struct mux_input **input)
|
||||
{
|
||||
/* Only select the task if we are in ST_TASK_BODY and the task_type has
|
||||
* a non-null value */
|
||||
|
||||
int64_t in_body = (value.type == VALUE_INT64 && value.i == ST_TASK_BODY);
|
||||
|
||||
if (in_body) {
|
||||
struct value tt;
|
||||
struct mux_input *ttinput = mux_get_input(mux, 1);
|
||||
if (chan_read(ttinput->chan, &tt) != 0) {
|
||||
err("chan_read failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Only show task type if we have a task */
|
||||
if (tt.type == VALUE_NULL)
|
||||
in_body = 0;
|
||||
}
|
||||
|
||||
if (!in_body) {
|
||||
/* Only select ss if not NULL */
|
||||
struct value ss;
|
||||
struct mux_input *ssinput = mux_get_input(mux, 0);
|
||||
if (chan_read(ssinput->chan, &ss) != 0) {
|
||||
err("chan_read failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Don't select anything, so the default output is shown */
|
||||
if (ss.type == VALUE_NULL) {
|
||||
dbg("not selecting anything");
|
||||
*input = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t i = in_body;
|
||||
char *inputs[] = { "subsystem", "task_type" };
|
||||
dbg("selecting input %ld (%s)", i, inputs[i]);
|
||||
*input = mux_get_input(mux, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
select_idle(struct mux *mux, struct value value, struct mux_input **input)
|
||||
{
|
||||
dbg("selecting tri output for value %s", value_str(value));
|
||||
|
||||
if (value.type == VALUE_INT64 && value.i == ST_PROGRESSING) {
|
||||
dbg("selecting input 0 (tr)");
|
||||
*input = mux_get_input(mux, 0);
|
||||
} else {
|
||||
dbg("selecting input 1 (idle)");
|
||||
*input = mux_get_input(mux, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
connect_cpu(struct bay *bay, struct nosv_cpu *mcpu)
|
||||
{
|
||||
struct nosv_breakdown_cpu *bcpu = &mcpu->breakdown;
|
||||
|
||||
/* Channel aliases */
|
||||
struct chan *ss = &mcpu->m.track[CH_SUBSYSTEM].ch;
|
||||
struct chan *tt = &mcpu->m.track[CH_TYPE].ch;
|
||||
struct chan *idle = &mcpu->m.track[CH_IDLE].ch;
|
||||
struct chan *tr = &bcpu->tr;
|
||||
struct chan *tri = &bcpu->tri;
|
||||
|
||||
/* Connect mux0 using ss as select */
|
||||
if (mux_init(&bcpu->mux0, bay, ss, tr, select_tr, 2) != 0) {
|
||||
err("mux_init failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mux_set_input(&bcpu->mux0, 0, ss) != 0) {
|
||||
err("mux_set_input ss failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mux_set_input(&bcpu->mux0, 1, tt) != 0) {
|
||||
err("mux_set_input tt failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO what do we emit on null? */
|
||||
mux_set_default(&bcpu->mux0, value_int64(666));
|
||||
|
||||
/* Connect mux 1 using idle as select */
|
||||
if (mux_init(&bcpu->mux1, bay, idle, tri, select_idle, 2) != 0) {
|
||||
err("mux_init failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mux_set_input(&bcpu->mux1, 0, tr) != 0) {
|
||||
err("mux_set_input tr failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mux_set_input(&bcpu->mux1, 1, idle) != 0) {
|
||||
err("mux_set_input idle failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
model_nosv_breakdown_connect(struct emu *emu)
|
||||
{
|
||||
if (emu->args.breakdown == 0)
|
||||
return 0;
|
||||
|
||||
struct nosv_emu *memu = EXT(emu, 'V');
|
||||
struct nosv_breakdown_emu *bemu = &memu->breakdown;
|
||||
struct bay *bay = &emu->bay;
|
||||
struct system *sys = &emu->system;
|
||||
|
||||
int64_t i = 0;
|
||||
for (struct cpu *cpu = sys->cpus; cpu; cpu = cpu->next) {
|
||||
if (cpu->is_virtual)
|
||||
continue;
|
||||
|
||||
struct nosv_cpu *mcpu = EXT(cpu, 'V');
|
||||
struct nosv_breakdown_cpu *bcpu = &mcpu->breakdown;
|
||||
|
||||
/* Connect tr and tri channels and muxes */
|
||||
if (connect_cpu(bay, mcpu) != 0) {
|
||||
err("connect_cpu failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Connect tri to sort */
|
||||
if (sort_set_input(&bemu->sort, i, &bcpu->tri) != 0) {
|
||||
err("sort_set_input failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Connect out to PRV */
|
||||
struct prv *prv = pvt_get_prv(bemu->pvt);
|
||||
long type = PRV_NOSV_BREAKDOWN;
|
||||
long flags = PRV_SKIPDUP | PRV_ZERO;
|
||||
|
||||
struct chan *out = sort_get_output(&bemu->sort, i);
|
||||
if (prv_register(prv, i, type, bay, out, flags)) {
|
||||
err("prv_register failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
model_nosv_breakdown_finish(struct emu *emu,
|
||||
const struct pcf_value_label **labels)
|
||||
{
|
||||
if (emu->args.breakdown == 0)
|
||||
return 0;
|
||||
|
||||
struct nosv_emu *memu = EXT(emu, 'V');
|
||||
struct nosv_breakdown_emu *bemu = &memu->breakdown;
|
||||
struct pcf *pcf = pvt_get_pcf(bemu->pvt);
|
||||
long typeid = PRV_NOSV_BREAKDOWN;
|
||||
char label[] = "CPU: nOS-V Runtime/Idle/Task breakdown";
|
||||
struct pcf_type *pcftype = pcf_add_type(pcf, typeid, label);
|
||||
const struct pcf_value_label *v = NULL;
|
||||
|
||||
/* Emit subsystem values */
|
||||
for (v = labels[CH_SUBSYSTEM]; v->label; v++) {
|
||||
if (pcf_add_value(pcftype, v->value, v->label) == NULL) {
|
||||
err("pcf_add_value ss failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit idle values */
|
||||
for (v = labels[CH_IDLE]; v->label; v++) {
|
||||
if (pcf_add_value(pcftype, v->value, v->label) == NULL) {
|
||||
err("pcf_add_value idle failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit task_type values */
|
||||
struct system *sys = &emu->system;
|
||||
for (struct proc *p = sys->procs; p; p = p->gnext) {
|
||||
struct nosv_proc *proc = EXT(p, 'V');
|
||||
struct task_info *info = &proc->task_info;
|
||||
if (task_create_pcf_types(pcftype, info->types) != 0) {
|
||||
err("task_create_pcf_types failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Also populate the row labels */
|
||||
struct prf *prf = pvt_get_prf(bemu->pvt);
|
||||
for (int64_t row = 0; row < bemu->nphycpus; row++) {
|
||||
char name[128];
|
||||
if (snprintf(name, 128, "~CPU %4ld", bemu->nphycpus - row) >= 128) {
|
||||
err("label too long");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (prf_add(prf, row, name) != 0) {
|
||||
err("prf_add failed for %s", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
56
src/emu/nosv/breakdown.h
Normal file
56
src/emu/nosv/breakdown.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
#ifndef BREAKDOWN_H
|
||||
#define BREAKDOWN_H
|
||||
|
||||
/*
|
||||
* The breakdown model is implemented on top of the CPU subsystem, task_type and
|
||||
* idle channels. The first mux0 selects the task type when the subsystem
|
||||
* matches "Task body" otherwise forwards the subsystem as-is to tr. The second
|
||||
* mux1 selects tr only when the CPU is not Idle, otherwise sets the output tri
|
||||
* as Idle.
|
||||
*
|
||||
* +--------+
|
||||
* | |
|
||||
* | v
|
||||
* | +------+
|
||||
* subsystem -+-->--| |
|
||||
* | mux0 | +------+
|
||||
* task_type ---->--| |-->-- tr -->--| |
|
||||
* +------+ | mux1 |-->-- tri
|
||||
* idle --------->-------------------+->--| |
|
||||
* | +------+
|
||||
* | ^
|
||||
* | |
|
||||
* +--------+
|
||||
*
|
||||
* Then the sort module takes the output tri of each CPU and sorts the values
|
||||
* which are propagated to the PRV directly.
|
||||
*
|
||||
* +------+ +-----+
|
||||
* cpu0.tri --->---| |--->---| |
|
||||
* ... | sort | ... | PRV |
|
||||
* cpuN.tri --->---| |--->---| |
|
||||
* +------+ +-----+
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "chan.h"
|
||||
#include "mux.h"
|
||||
#include "sort.h"
|
||||
|
||||
struct nosv_breakdown_cpu {
|
||||
struct mux mux0;
|
||||
struct chan tr;
|
||||
struct mux mux1;
|
||||
struct chan tri;
|
||||
};
|
||||
|
||||
struct nosv_breakdown_emu {
|
||||
int64_t nphycpus;
|
||||
struct sort sort;
|
||||
struct pvt *pvt;
|
||||
};
|
||||
|
||||
#endif /* BREAKDOWN_H */
|
@ -16,7 +16,7 @@
|
||||
#include "thread.h"
|
||||
#include "value.h"
|
||||
|
||||
enum { PUSH = 1, POP = 2, IGN = 3 };
|
||||
enum { PUSH = 1, POP = 2, SET = 3, IGN = 4 };
|
||||
|
||||
#define CHSS CH_SUBSYSTEM
|
||||
|
||||
@ -77,6 +77,11 @@ static const int ss_table[256][256][3] = {
|
||||
['d'] = { CHSS, PUSH, ST_DELEGATE },
|
||||
['D'] = { CHSS, POP, ST_DELEGATE },
|
||||
},
|
||||
['P'] = {
|
||||
['p'] = { CH_IDLE, SET, ST_PROGRESSING },
|
||||
['r'] = { CH_IDLE, SET, ST_RESTING },
|
||||
['a'] = { CH_IDLE, SET, ST_ABSORBING },
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
@ -94,6 +99,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 */
|
||||
} else {
|
||||
@ -574,6 +581,7 @@ process_ev(struct emu *emu)
|
||||
case 'M':
|
||||
case 'H':
|
||||
case 'A':
|
||||
case 'P':
|
||||
return simple(emu);
|
||||
case 'T':
|
||||
return pre_task(emu);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#ifndef NOSV_PRIV_H
|
||||
#define NOSV_PRIV_H
|
||||
|
||||
#include "breakdown.h"
|
||||
#include "emu.h"
|
||||
#include "task.h"
|
||||
#include "model_cpu.h"
|
||||
@ -18,6 +19,7 @@ enum nosv_chan {
|
||||
CH_APPID,
|
||||
CH_SUBSYSTEM,
|
||||
CH_RANK,
|
||||
CH_IDLE,
|
||||
CH_MAX,
|
||||
};
|
||||
|
||||
@ -56,16 +58,36 @@ struct nosv_thread {
|
||||
|
||||
struct nosv_cpu {
|
||||
struct model_cpu m;
|
||||
struct nosv_breakdown_cpu breakdown;
|
||||
};
|
||||
|
||||
struct nosv_proc {
|
||||
struct task_info task_info;
|
||||
};
|
||||
|
||||
struct nosv_emu {
|
||||
int connected;
|
||||
int event;
|
||||
struct nosv_breakdown_emu breakdown;
|
||||
};
|
||||
|
||||
enum nosv_progress {
|
||||
/* Can mix with subsystem values */
|
||||
ST_PROGRESSING = 100,
|
||||
ST_RESTING,
|
||||
ST_ABSORBING,
|
||||
};
|
||||
|
||||
int model_nosv_probe(struct emu *emu);
|
||||
int model_nosv_create(struct emu *emu);
|
||||
int model_nosv_connect(struct emu *emu);
|
||||
int model_nosv_event(struct emu *emu);
|
||||
int model_nosv_finish(struct emu *emu);
|
||||
|
||||
int model_nosv_breakdown_create(struct emu *emu);
|
||||
int model_nosv_breakdown_connect(struct emu *emu);
|
||||
int model_nosv_breakdown_finish(struct emu *emu,
|
||||
const struct pcf_value_label **labels);
|
||||
|
||||
|
||||
#endif /* NOSV_PRIV_H */
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "chan.h"
|
||||
#include "cpu.h"
|
||||
#include "common.h"
|
||||
#include "emu.h"
|
||||
#include "emu_args.h"
|
||||
@ -96,6 +97,7 @@ static const char *chan_name[CH_MAX] = {
|
||||
[CH_APPID] = "appid",
|
||||
[CH_SUBSYSTEM] = "subsystem",
|
||||
[CH_RANK] = "rank",
|
||||
[CH_IDLE] = "idle",
|
||||
};
|
||||
|
||||
static const int chan_stack[CH_MAX] = {
|
||||
@ -121,6 +123,7 @@ static const int pvt_type[CH_MAX] = {
|
||||
[CH_APPID] = PRV_NOSV_APPID,
|
||||
[CH_SUBSYSTEM] = PRV_NOSV_SUBSYSTEM,
|
||||
[CH_RANK] = PRV_NOSV_RANK,
|
||||
[CH_IDLE] = PRV_NOSV_IDLE,
|
||||
};
|
||||
|
||||
static const char *pcf_prefix[CH_MAX] = {
|
||||
@ -130,6 +133,7 @@ static const char *pcf_prefix[CH_MAX] = {
|
||||
[CH_APPID] = "nOS-V task AppID",
|
||||
[CH_SUBSYSTEM] = "nOS-V subsystem",
|
||||
[CH_RANK] = "nOS-V task MPI rank",
|
||||
[CH_IDLE] = "nOS-V idle state",
|
||||
};
|
||||
|
||||
static const struct pcf_value_label nosv_ss_values[] = {
|
||||
@ -160,8 +164,16 @@ static const struct pcf_value_label nosv_ss_values[] = {
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
static const struct pcf_value_label nosv_worker_idle[] = {
|
||||
{ ST_PROGRESSING, "Progressing" },
|
||||
{ ST_RESTING, "Resting" },
|
||||
{ ST_ABSORBING, "Absorbing noise" },
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
static const struct pcf_value_label *pcf_labels[CH_MAX] = {
|
||||
[CH_SUBSYSTEM] = nosv_ss_values,
|
||||
[CH_IDLE] = nosv_worker_idle,
|
||||
};
|
||||
|
||||
static const long prv_flags[CH_MAX] = {
|
||||
@ -171,6 +183,7 @@ static const long prv_flags[CH_MAX] = {
|
||||
[CH_APPID] = PRV_SKIPDUPNULL, /* Switch to task of same appid */
|
||||
[CH_SUBSYSTEM] = PRV_SKIPDUPNULL,
|
||||
[CH_RANK] = PRV_SKIPDUPNULL, /* Switch to task of same rank */
|
||||
[CH_IDLE] = PRV_SKIPDUPNULL,
|
||||
};
|
||||
|
||||
static const struct model_pvt_spec pvt_spec = {
|
||||
@ -189,6 +202,7 @@ static const int th_track[CH_MAX] = {
|
||||
[CH_APPID] = TRACK_TH_RUN,
|
||||
[CH_SUBSYSTEM] = TRACK_TH_ACT,
|
||||
[CH_RANK] = TRACK_TH_RUN,
|
||||
[CH_IDLE] = TRACK_TH_RUN,
|
||||
};
|
||||
|
||||
static const int cpu_track[CH_MAX] = {
|
||||
@ -198,6 +212,7 @@ static const int cpu_track[CH_MAX] = {
|
||||
[CH_APPID] = TRACK_TH_RUN,
|
||||
[CH_SUBSYSTEM] = TRACK_TH_RUN,
|
||||
[CH_RANK] = TRACK_TH_RUN,
|
||||
[CH_IDLE] = TRACK_TH_RUN,
|
||||
};
|
||||
|
||||
/* ----------------- chan_spec ------------------ */
|
||||
@ -279,6 +294,19 @@ model_nosv_create(struct emu *emu)
|
||||
}
|
||||
}
|
||||
|
||||
struct nosv_emu *e = calloc(1, sizeof(struct nosv_emu));
|
||||
if (e == NULL) {
|
||||
err("calloc failed:");
|
||||
return -1;
|
||||
}
|
||||
|
||||
extend_set(&emu->ext, model_id, e);
|
||||
|
||||
if (model_nosv_breakdown_create(emu) != 0) {
|
||||
err("model_nosv_breakdown_create failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -295,6 +323,28 @@ model_nosv_connect(struct emu *emu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (emu->args.breakdown && model_nosv_breakdown_connect(emu) != 0) {
|
||||
err("model_nosv_breakdown_connect failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (struct thread *th = emu->system.threads; th; th = th->gnext) {
|
||||
struct nosv_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 nosv_cpu *mcpu = EXT(cpu, model_id);
|
||||
struct mux *mux = &mcpu->m.track[CH_IDLE].mux;
|
||||
/* Emit Resting when a CPU has no running threads */
|
||||
mux_set_default(mux, value_int64(ST_RESTING));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -343,6 +393,10 @@ finish_pvt(struct emu *emu, const char *name)
|
||||
struct pcf *pcf = pvt_get_pcf(pvt);
|
||||
long typeid = pvt_type[CH_TYPE];
|
||||
struct pcf_type *pcftype = pcf_find_type(pcf, typeid);
|
||||
if (pcftype == NULL) {
|
||||
err("cannot find %s pcf type %d", name, typeid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (struct proc *p = sys->procs; p; p = p->gnext) {
|
||||
struct nosv_proc *proc = EXT(p, model_id);
|
||||
@ -370,6 +424,11 @@ model_nosv_finish(struct emu *emu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (model_nosv_breakdown_finish(emu, pcf_labels) != 0) {
|
||||
err("model_nosv_breakdown_finish failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* When running in linter mode perform additional checks */
|
||||
if (emu->args.linter_mode && end_lint(emu) != 0) {
|
||||
err("end_lint failed");
|
||||
|
Loading…
Reference in New Issue
Block a user