From a1a2941b646aa330b29a0454d4163f0ea8d789fd Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Thu, 21 Nov 2024 09:58:48 +0100 Subject: [PATCH] Allow -b flag without nosv.can_breakdown As we now have OpenMP and nOS-V models for breakdown, we may have the situation in which nOS-V traces don't have enough events to enable the breakdown model, but we do on OpenMP. Rather than stopping, disable the nOS-V model with a warning and continue. --- src/emu/nosv/breakdown.c | 78 +++++++++++++++++++++--------------- src/emu/nosv/breakdown.h | 1 + test/rt/nodes/CMakeLists.txt | 6 +-- test/rt/nosv/CMakeLists.txt | 6 +-- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/emu/nosv/breakdown.c b/src/emu/nosv/breakdown.c index 40a3e7c..f35c6bd 100644 --- a/src/emu/nosv/breakdown.c +++ b/src/emu/nosv/breakdown.c @@ -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 "breakdown.h" @@ -49,36 +49,49 @@ create_cpu(struct bay *bay, struct nosv_breakdown_cpu *bcpu, int64_t gindex) return 0; } -static int -check_thread_metadata(struct thread *th) -{ - if (th->meta == NULL) { - err("thread has no metadata"); - return -1; - } - - JSON_Value *val = json_object_dotget_value(th->meta, "nosv.can_breakdown"); - if (val == NULL) { - err("missing nosv.can_breakdown attribute"); - return -1; - } - - if (!json_value_get_boolean(val)) { - err("nosv.can_breakdown is false, missing events to enable breakdown"); - return -1; - } - - return 0; -} - int model_nosv_breakdown_create(struct emu *emu) { + struct nosv_emu *memu = EXT(emu, 'V'); + struct nosv_breakdown_emu *bemu = &memu->breakdown; + size_t nbreakdown = 0; + + /* Stop here if breakdown not enabled */ if (emu->args.breakdown == 0) return 0; - struct nosv_emu *memu = EXT(emu, 'V'); - struct nosv_breakdown_emu *bemu = &memu->breakdown; + /* We need to make sure that *all* threads have the can_breakdown key + * present and set to true, as otherwise we may be missing some data in + * the breakdown view. */ + for (struct thread *th = emu->system.threads; th; th = th->gnext) { + /* All threads must have the can_breakdown key */ + JSON_Value *val = json_object_dotget_value(th->meta, + "nosv.can_breakdown"); + + if (val == NULL) { + err("missing nosv.can_breakdown key: %s", th->id); + return -1; + } + + if (json_value_get_type(val) != JSONBoolean) { + err("expected boolean nosv.can_breakdown key: %s", th->id); + return -1; + } + + /* Count how many they have it enabled */ + if (json_value_get_boolean(val)) + nbreakdown++; + } + + /* Enable breakdown if all threads can produce a breakdown trace */ + if (nbreakdown != emu->system.nthreads) { + warn("cannot enable breakdown for nOS-V model (suitable %zd/%zd)", + nbreakdown, emu->system.nthreads); + return 0; + } + + info("enabling breakdown for nOS-V model"); + bemu->enabled = 1; /* Count phy cpus */ struct system *sys = &emu->system; @@ -111,13 +124,6 @@ model_nosv_breakdown_create(struct emu *emu) } } - for (struct thread *th = emu->system.threads; th; th = th->gnext) { - if (check_thread_metadata(th) != 0) { - err("bad nosv metadata in thread: %s", th->id); - return -1; - } - } - return 0; } @@ -241,6 +247,10 @@ model_nosv_breakdown_connect(struct emu *emu) struct nosv_emu *memu = EXT(emu, 'V'); struct nosv_breakdown_emu *bemu = &memu->breakdown; + + if (!bemu->enabled) + return 0; + struct bay *bay = &emu->bay; struct system *sys = &emu->system; @@ -290,6 +300,10 @@ model_nosv_breakdown_finish(struct emu *emu, struct nosv_emu *memu = EXT(emu, 'V'); struct nosv_breakdown_emu *bemu = &memu->breakdown; + + if (!bemu->enabled) + return 0; + struct pcf *pcf = pvt_get_pcf(bemu->pvt); long typeid = PRV_NOSV_BREAKDOWN; char label[] = "CPU: nOS-V Runtime/Idle/Task breakdown"; diff --git a/src/emu/nosv/breakdown.h b/src/emu/nosv/breakdown.h index 376947b..4b74ace 100644 --- a/src/emu/nosv/breakdown.h +++ b/src/emu/nosv/breakdown.h @@ -51,6 +51,7 @@ struct nosv_breakdown_emu { int64_t nphycpus; struct sort sort; struct pvt *pvt; + int enabled; }; #endif /* BREAKDOWN_H */ diff --git a/test/rt/nodes/CMakeLists.txt b/test/rt/nodes/CMakeLists.txt index 4ba2a0e..449a58e 100644 --- a/test/rt/nodes/CMakeLists.txt +++ b/test/rt/nodes/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2022-2024 Barcelona Supercomputing Center (BSC) +# Copyright (c) 2022-2025 Barcelona Supercomputing Center (BSC) # SPDX-License-Identifier: GPL-3.0-or-later find_package(Nodes) @@ -65,9 +65,9 @@ nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-level-4 LEVEL 4 SORT) # Same but with breakdown enabled nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-1 LEVEL 1 SORT BREAKDOWN - SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown") + REGEX "cannot enable breakdown for nOS-V model") nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-2 LEVEL 2 SORT BREAKDOWN - SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown") + REGEX "cannot enable breakdown for nOS-V model") # From level 3 up the breakdown can be enabled nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-3 LEVEL 3 SORT BREAKDOWN) nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-4 LEVEL 4 SORT BREAKDOWN) diff --git a/test/rt/nosv/CMakeLists.txt b/test/rt/nosv/CMakeLists.txt index 8588273..4c23ccf 100644 --- a/test/rt/nosv/CMakeLists.txt +++ b/test/rt/nosv/CMakeLists.txt @@ -57,11 +57,11 @@ nosv_test(several-tasks.c SORT NAME several-tasks-level-4 LEVEL 4) # Same but with breakdown enabled nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-0 LEVEL 0 BREAKDOWN - SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown") + REGEX "cannot enable breakdown for nOS-V model") nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-1 LEVEL 1 BREAKDOWN - SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown") + REGEX "cannot enable breakdown for nOS-V model") nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-2 LEVEL 2 BREAKDOWN - SHOULD_FAIL REGEX "nosv.can_breakdown is false, missing events to enable breakdown") + REGEX "cannot enable breakdown for nOS-V model") # From level 3 up the breakdown can be enabled nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-3 LEVEL 3 BREAKDOWN) nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-4 LEVEL 4 BREAKDOWN)