Add fibonacci and heat RT tests for mark API
This commit is contained in:
		
							parent
							
								
									43792fb349
								
							
						
					
					
						commit
						e31f0f1ded
					
				| @ -82,3 +82,6 @@ elseif(ENABLE_ALL_TESTS) | ||||
| else() | ||||
|   message(STATUS "Disabling perf paranoid tests for NODES") | ||||
| endif() | ||||
| 
 | ||||
| nodes_rt_test(fibonacci-mark.c SORT) | ||||
| nodes_rt_test(heat-mark.c SORT) | ||||
|  | ||||
							
								
								
									
										47
									
								
								test/rt/nodes/fibonacci-mark.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								test/rt/nodes/fibonacci-mark.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| /* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "compat.h" | ||||
| #include "ovni.h" | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| enum { INDEX = 0, RUN = 1 }; | ||||
| 
 | ||||
| #pragma oss task label("fibonacci") | ||||
| static void | ||||
| fib2(long index, long *res, int run) | ||||
| { | ||||
| 	if (index <= 1) { | ||||
| 		*res = index; | ||||
| 	} else { | ||||
| 		ovni_mark_push(RUN, run); | ||||
| 		ovni_mark_push(INDEX, index); | ||||
| 
 | ||||
| 		long a, b; | ||||
| 		fib2(index-1, &a, run); | ||||
| 		fib2(index-2, &b, run); | ||||
| 		#pragma oss taskwait | ||||
| 		*res = a + b; | ||||
| 
 | ||||
| 		ovni_mark_pop(INDEX, index); | ||||
| 		ovni_mark_pop(RUN, run); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	ovni_mark_type(INDEX, OVNI_MARK_STACK, "Fibonacci index"); | ||||
| 	ovni_mark_type(RUN, OVNI_MARK_STACK, "Fibonacci run"); | ||||
| 
 | ||||
| 	long res = 0; | ||||
| 	for (int i = 1; i <= 30; i++) { | ||||
| 		fib2(15, &res, i); | ||||
| 		#pragma oss taskwait | ||||
| 	} | ||||
| 
 | ||||
| 	#pragma oss taskwait | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										161
									
								
								test/rt/nodes/heat-mark.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								test/rt/nodes/heat-mark.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,161 @@ | ||||
| /* Copyright (c) 2024 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "compat.h" | ||||
| #include "ovni.h" | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <time.h> | ||||
| 
 | ||||
| enum { ITER = 0, ROW, COL, PRIO, TIME }; | ||||
| 
 | ||||
| long rows; | ||||
| long cols; | ||||
| 
 | ||||
| long rbs; | ||||
| long cbs; | ||||
| long timesteps; | ||||
| 
 | ||||
| long nrb; | ||||
| long ncb; | ||||
| 
 | ||||
| int use_prio = 0; | ||||
| int prio_types = 4; | ||||
| 
 | ||||
| static double | ||||
| get_time(void) | ||||
| { | ||||
| 	struct timespec ts; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &ts); | ||||
| 	return (double) ts.tv_sec + (double) ts.tv_nsec * 1.0e-9; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| compute_block(long rstart, long rend, long cstart, long cend, double M[rows][cols]) | ||||
| { | ||||
| 	for (long r = rstart; r <= rend; ++r) { | ||||
| 		for (long c = cstart; c <= cend; ++c) { | ||||
| 			M[r][c] = 0.25*(M[r-1][c] + M[r+1][c] + M[r][c-1] + M[r][c+1]); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| step(double M[rows][cols], char reps[nrb][ncb], long iter) | ||||
| { | ||||
| 	for (long R = 1; R < nrb-1; ++R) { | ||||
| 		for (long C = 1; C < ncb-1; ++C) { | ||||
| 			long prio = 0; | ||||
| 			/* Higher number = runs before */ | ||||
| 			if (use_prio == 0) | ||||
| 				prio = 1; | ||||
| 			else if (use_prio == 1) | ||||
| 				prio = 1 + nrb * ncb - (R * ncb + C); | ||||
| 			else if (use_prio == 2) | ||||
| 				prio = 1 + nrb + ncb - (R + C); | ||||
| 			else if (use_prio == 3) | ||||
| 				prio = (timesteps + 1) * nrb * ncb - (iter * ncb * nrb + R * ncb + C); | ||||
| 
 | ||||
| 			#pragma oss task label("block computation") \ | ||||
| 					in(reps[R-1][C]) in(reps[R+1][C]) \ | ||||
| 					in(reps[R][C-1]) in(reps[R][C+1]) \ | ||||
| 					priority(prio) \ | ||||
| 					inout(reps[R][C]) | ||||
| 			{ | ||||
| 				ovni_mark_push(ITER, iter); | ||||
| 				ovni_mark_push(ROW, R); | ||||
| 				ovni_mark_push(COL, C); | ||||
| 				ovni_mark_push(PRIO, prio); | ||||
| 				compute_block((R-1)*rbs+1, R*rbs, (C-1)*cbs+1, C*cbs, M); | ||||
| 				ovni_mark_pop(PRIO, prio); | ||||
| 				ovni_mark_pop(COL, C); | ||||
| 				ovni_mark_pop(ROW, R); | ||||
| 				ovni_mark_pop(ITER, iter); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static void | ||||
| solve(double *raw_matrix, long n) | ||||
| { | ||||
| 	/* Ignore halos */ | ||||
| 	double (*matrix)[cols] = (double (*)[cols]) raw_matrix; | ||||
| 	char representatives[nrb][ncb]; | ||||
| 	for (long t = 1; t <= n; t++) | ||||
| 		step(matrix, representatives, t); | ||||
| 	#pragma oss taskwait | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| reset(double *matrix) | ||||
| { | ||||
| 	/* Set all elements to zero */ | ||||
| 	memset(matrix, 0, rows * cols * sizeof(double)); | ||||
| 
 | ||||
| 	/* Set the left side to 1.0 */ | ||||
| 	for (long i = 0; i < rows; i++) | ||||
| 		matrix[i * cols] = 1.0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	ovni_mark_type(ITER, OVNI_MARK_STACK, "Heat iteration"); | ||||
| 	ovni_mark_type(ROW, OVNI_MARK_STACK, "Heat row"); | ||||
| 	ovni_mark_type(COL, OVNI_MARK_STACK, "Heat col"); | ||||
| 	ovni_mark_type(PRIO, OVNI_MARK_STACK, "Heat priority"); | ||||
| 	ovni_mark_type(TIME, OVNI_MARK_STACK, "Heat time"); | ||||
| 
 | ||||
| 	/* The real number of allocated rows and columns will be bigger */ | ||||
| 	long _rows = 8L * 1024L; | ||||
| 	long _cols = _rows; | ||||
| 
 | ||||
| 	rows = _rows + 2; | ||||
| 	cols = _cols + 2; | ||||
| 
 | ||||
| 	rbs = 128L; | ||||
| 	cbs = rbs; | ||||
| 	timesteps = 10L; | ||||
| 
 | ||||
| 	nrb = (rows - 2) / rbs + 2; | ||||
| 	ncb = (cols - 2) / cbs + 2; | ||||
| 
 | ||||
| 	long pagesize = sysconf(_SC_PAGESIZE); | ||||
| 	if (pagesize <= 0) | ||||
| 		die("cannot read pagesize"); | ||||
| 
 | ||||
| 	double *matrix; | ||||
| 	int err = posix_memalign((void **) &matrix, pagesize, rows * cols * sizeof(double)); | ||||
| 	if (err || matrix == NULL) | ||||
| 		die("posix_memalign failed:"); | ||||
| 
 | ||||
| 	/* Do a warmup iteration */ | ||||
| 	reset(matrix); | ||||
| 	solve(matrix, 1); | ||||
| 
 | ||||
| 	sleep_us(100000); | ||||
| 
 | ||||
| 	char buf[1024]; | ||||
| 	for (int i = 0; i < prio_types; i++) { | ||||
| 		use_prio = i; | ||||
| 		reset(matrix); | ||||
| 		double t0 = get_time(); | ||||
| 		solve(matrix, timesteps); | ||||
| 		double t1 = get_time(); | ||||
| 		double dt = t1 - t0; | ||||
| 
 | ||||
| 		/* Use label to write a custom string */ | ||||
| 		sprintf(buf, "prio=%d took %e s", i, dt); | ||||
| 		ovni_mark_label(TIME, i+1, buf); | ||||
| 		ovni_mark_push(TIME, i+1); | ||||
| 		sleep_us(100000); | ||||
| 		ovni_mark_pop(TIME, i+1); | ||||
| 	} | ||||
| 
 | ||||
| 	free(matrix); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user