Add nOS-V HWC rt tests
This commit is contained in:
parent
a164642653
commit
6fbc5e2693
@ -24,7 +24,7 @@ function(nosv_test)
|
||||
cmake_parse_arguments(
|
||||
NOSV_TEST "${switches}" "${single}" "${multi}" ${ARGN})
|
||||
ovni_test(${ARGN})
|
||||
target_link_libraries("${OVNI_TEST_NAME}" PRIVATE PkgConfig::NOSV)
|
||||
target_link_libraries("${OVNI_TEST_NAME}" PRIVATE PkgConfig::NOSV m)
|
||||
set_property(TEST "${OVNI_TEST_NAME}" APPEND
|
||||
PROPERTY
|
||||
ENVIRONMENT "NOSV_CONFIG=${OVNI_TEST_SOURCE_DIR}/rt/nosv/nosv.toml")
|
||||
@ -65,6 +65,9 @@ nosv_test(several-tasks.c SORT NAME several-tasks-breakdown-level-2 LEVEL 2 BREA
|
||||
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 NAME hwc-tasks DRIVER "hwc.driver.sh")
|
||||
nosv_test(hwc-stride.c DRIVER "hwc-stride.driver.sh")
|
||||
|
||||
if (PERF_PARANOID_KERNEL)
|
||||
message(STATUS "Enabling perf paranoid tests for nOS-V")
|
||||
nosv_test(kernel.c NAME kernel-overflow DRIVER "kernel-overflow.driver.sh")
|
||||
|
||||
117
test/rt/nosv/hwc-stride.c
Normal file
117
test/rt/nosv/hwc-stride.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* Copyright (c) 2025 Barcelona Supercomputing Center (BSC)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
|
||||
/*
|
||||
* This test creates several tasks that all perform the computation with the
|
||||
* same instructions. However, the access to the memory is done differently. The
|
||||
* first set of tasks use a stride 1, the next 2, the next 4 and so on until
|
||||
* 2^(NSTRIDE-1). This access causes more L3 cache misses, which increases the
|
||||
* execution time, typically directly proportional to the stride number.
|
||||
*
|
||||
* The number of instructions given by PAPI_TOT_INS should remain constant
|
||||
* across tasks, but it is expected that PAPI_L3_TCM increases with the
|
||||
* stride.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <nosv.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "compat.h"
|
||||
|
||||
#define NTASKS 200
|
||||
atomic_int ncompleted = 0;
|
||||
|
||||
nosv_task_t tasks[NTASKS];
|
||||
|
||||
#define NRUNS 2
|
||||
#define NSTRIDE 4
|
||||
#define MAXN (256L * 1024L) /* Adjust this for larger L3 */
|
||||
|
||||
struct meta {
|
||||
long n;
|
||||
long stride;
|
||||
double *vec;
|
||||
};
|
||||
|
||||
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
|
||||
task_body(nosv_task_t task)
|
||||
{
|
||||
struct meta *meta = nosv_get_task_metadata(task);
|
||||
|
||||
long stride = meta->stride;
|
||||
|
||||
/* Stride access, some computation */
|
||||
for (long i = 0; i < stride; i++)
|
||||
for (long j = i; j < meta->n; j += stride)
|
||||
meta->vec[j] = sqrt(meta->vec[j]);
|
||||
|
||||
atomic_fetch_add(&ncompleted, 1);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
nosv_init();
|
||||
|
||||
nosv_task_type_t task_type;
|
||||
nosv_type_init(&task_type, task_body, NULL, NULL, "task", NULL, NULL, 0);
|
||||
|
||||
for (int i = 0; i < NTASKS; i++) {
|
||||
nosv_create(&tasks[i], task_type, sizeof(struct meta), 0);
|
||||
struct meta *meta = nosv_get_task_metadata(tasks[i]);
|
||||
meta->n = MAXN;
|
||||
meta->vec = calloc(MAXN, sizeof(double));
|
||||
for (long i = 0; i < MAXN; i++)
|
||||
meta->vec[i] = (double) i;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%8s %8s %8s\n", "run", "stride", "time");
|
||||
|
||||
/* Repeat for warmup */
|
||||
for (int run = 0; run < NRUNS; run++) {
|
||||
for (int s = 0; s < NSTRIDE; s++) {
|
||||
long stride = 1L << s;
|
||||
|
||||
atomic_store(&ncompleted, 0); /* reset */
|
||||
|
||||
double t0 = get_time();
|
||||
|
||||
for (int i = 0; i < NTASKS; i++) {
|
||||
struct meta *meta = nosv_get_task_metadata(tasks[i]);
|
||||
meta->stride = stride;
|
||||
nosv_submit(tasks[i], 0);
|
||||
}
|
||||
|
||||
while (atomic_load(&ncompleted) != NTASKS)
|
||||
sleep_us(1000);
|
||||
|
||||
double t1 = get_time();
|
||||
|
||||
printf("%8d %8ld %8.3f\n", run, stride, t1 - t0);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NTASKS; i++) {
|
||||
struct meta *meta = nosv_get_task_metadata(tasks[i]);
|
||||
free(meta->vec);
|
||||
nosv_destroy(tasks[i], 0);
|
||||
}
|
||||
|
||||
nosv_type_destroy(task_type, 0);
|
||||
|
||||
nosv_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
18
test/rt/nosv/hwc-stride.driver.sh
Normal file
18
test/rt/nosv/hwc-stride.driver.sh
Normal file
@ -0,0 +1,18 @@
|
||||
target=$OVNI_TEST_BIN
|
||||
|
||||
# We will set our own
|
||||
unset NOSV_CONFIG
|
||||
unset NOSV_CONFIG_OVERRIDE
|
||||
|
||||
export NOSV_APPID=1
|
||||
|
||||
cat > nosv.toml << EOF
|
||||
instrumentation.version = "ovni"
|
||||
ovni.level = 2
|
||||
hwcounters.backend = "papi"
|
||||
hwcounters.papi_events = [ "PAPI_TOT_INS", "PAPI_TOT_CYC", "PAPI_L3_TCM" ]
|
||||
EOF
|
||||
|
||||
$target
|
||||
|
||||
ovniemu -l ovni
|
||||
18
test/rt/nosv/hwc.driver.sh
Normal file
18
test/rt/nosv/hwc.driver.sh
Normal file
@ -0,0 +1,18 @@
|
||||
target=$OVNI_TEST_BIN
|
||||
|
||||
# We will set our own
|
||||
unset NOSV_CONFIG
|
||||
unset NOSV_CONFIG_OVERRIDE
|
||||
|
||||
export NOSV_APPID=1
|
||||
|
||||
cat > nosv.toml << EOF
|
||||
instrumentation.version = "ovni"
|
||||
ovni.level = 2
|
||||
hwcounters.backend = "papi"
|
||||
hwcounters.papi_events = [ "PAPI_TOT_INS", "PAPI_TOT_CYC" ]
|
||||
EOF
|
||||
|
||||
$target
|
||||
|
||||
ovniemu -l ovni
|
||||
Loading…
x
Reference in New Issue
Block a user