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.
This commit is contained in:
		
							parent
							
								
									c2f9bf0b75
								
							
						
					
					
						commit
						a1a2941b64
					
				| @ -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 */ |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
| 
 | 
 | ||||||
| #include "breakdown.h" | #include "breakdown.h" | ||||||
| @ -49,36 +49,49 @@ create_cpu(struct bay *bay, struct nosv_breakdown_cpu *bcpu, int64_t gindex) | |||||||
| 	return 0; | 	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 | int | ||||||
| model_nosv_breakdown_create(struct emu *emu) | 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) | 	if (emu->args.breakdown == 0) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	struct nosv_emu *memu = EXT(emu, 'V'); | 	/* We need to make sure that *all* threads have the can_breakdown key
 | ||||||
| 	struct nosv_breakdown_emu *bemu = &memu->breakdown; | 	 * 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 */ | 	/* Count phy cpus */ | ||||||
| 	struct system *sys = &emu->system; | 	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; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -241,6 +247,10 @@ model_nosv_breakdown_connect(struct emu *emu) | |||||||
| 
 | 
 | ||||||
| 	struct nosv_emu *memu = EXT(emu, 'V'); | 	struct nosv_emu *memu = EXT(emu, 'V'); | ||||||
| 	struct nosv_breakdown_emu *bemu = &memu->breakdown; | 	struct nosv_breakdown_emu *bemu = &memu->breakdown; | ||||||
|  | 
 | ||||||
|  | 	if (!bemu->enabled) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
| 	struct bay *bay = &emu->bay; | 	struct bay *bay = &emu->bay; | ||||||
| 	struct system *sys = &emu->system; | 	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_emu *memu = EXT(emu, 'V'); | ||||||
| 	struct nosv_breakdown_emu *bemu = &memu->breakdown; | 	struct nosv_breakdown_emu *bemu = &memu->breakdown; | ||||||
|  | 
 | ||||||
|  | 	if (!bemu->enabled) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
| 	struct pcf *pcf = pvt_get_pcf(bemu->pvt); | 	struct pcf *pcf = pvt_get_pcf(bemu->pvt); | ||||||
| 	long typeid = PRV_NOSV_BREAKDOWN; | 	long typeid = PRV_NOSV_BREAKDOWN; | ||||||
| 	char label[] = "CPU: nOS-V Runtime/Idle/Task breakdown"; | 	char label[] = "CPU: nOS-V Runtime/Idle/Task breakdown"; | ||||||
|  | |||||||
| @ -51,6 +51,7 @@ struct nosv_breakdown_emu { | |||||||
| 	int64_t nphycpus; | 	int64_t nphycpus; | ||||||
| 	struct sort sort; | 	struct sort sort; | ||||||
| 	struct pvt *pvt; | 	struct pvt *pvt; | ||||||
|  | 	int enabled; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif /* BREAKDOWN_H */ | #endif /* BREAKDOWN_H */ | ||||||
|  | |||||||
| @ -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 | # SPDX-License-Identifier: GPL-3.0-or-later | ||||||
| 
 | 
 | ||||||
| find_package(Nodes) | 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 | # Same but with breakdown enabled | ||||||
| nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-1 LEVEL 1 SORT BREAKDOWN | 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 | 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 | # 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-3 LEVEL 3 SORT BREAKDOWN) | ||||||
| nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-4 LEVEL 4 SORT BREAKDOWN) | nodes_rt_test(../nanos6/several-tasks.c NAME several-tasks-breakdown-level-4 LEVEL 4 SORT BREAKDOWN) | ||||||
|  | |||||||
| @ -57,11 +57,11 @@ nosv_test(several-tasks.c SORT NAME several-tasks-level-4 LEVEL 4) | |||||||
| 
 | 
 | ||||||
| # Same but with breakdown enabled | # Same but with breakdown enabled | ||||||
| nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-0 LEVEL 0 BREAKDOWN | 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 | 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 | 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 | # 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-3 LEVEL 3 BREAKDOWN) | ||||||
| nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-4 LEVEL 4 BREAKDOWN) | nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-4 LEVEL 4 BREAKDOWN) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user