Add fibonacci and heat RT tests for mark API

This commit is contained in:
Rodrigo Arias 2024-06-20 17:39:42 +02:00
parent 43792fb349
commit e31f0f1ded
3 changed files with 211 additions and 0 deletions

View File

@ -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)

View 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
View 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;
}