Add parallel task and update old emu tests

All task-related events now require the body id as argument.
Additionally, in nOS-V, nested tasks require the parents to be paused.
This commit is contained in:
Rodrigo Arias 2023-10-23 15:12:43 +02:00 committed by Rodrigo Arias
parent 50837d6173
commit 24324ae734
20 changed files with 310 additions and 184 deletions

View File

@ -3,7 +3,7 @@
test_emu(nested-tasks.c)
test_emu(nested-tasks-bad.c SHOULD_FAIL
REGEX "body_execute: body 1 state must be Created but is Running")
REGEX "body_execute: body(id=1,taskid=1) state must be Created but is Running")
test_emu(task-types.c MP)
test_emu(blocking.c MP)
test_emu(ss-mismatch.c SHOULD_FAIL
@ -14,4 +14,4 @@ test_emu(sponge.c)
test_emu(sponge-breakdown.c BREAKDOWN)
test_emu(breakdown-no-black.c BREAKDOWN)
test_emu(rerun-task-bad.c SHOULD_FAIL
REGEX "body_execute: body 1 cannot resurrect")
REGEX "body_execute: body(id=1,taskid=1) is not allowed to run again")

View File

@ -22,10 +22,12 @@ main(void)
instr_nanos6_handle_task_enter();
instr_nanos6_task_create_and_execute(i + 1, typeid);
sleep_us(500);
instr_nanos6_task_pause(i + 1);
}
/* End the tasks in the opposite order */
for (int i = ntasks - 1; i >= 0; i--) {
instr_nanos6_task_resume(i + 1);
instr_nanos6_task_end(i + 1);
instr_nanos6_task_body_exit();
instr_nanos6_handle_task_exit();

View File

@ -28,6 +28,7 @@ main(void)
/* Change subsystem to prevent duplicates */
instr_nanos6_task_body_enter();
instr_nanos6_task_execute(1);
instr_nanos6_task_pause(1);
instr_nanos6_submit_task_enter();
instr_nanos6_task_body_enter();
instr_nanos6_task_execute(2);
@ -54,6 +55,7 @@ main(void)
instr_nanos6_task_end(2);
instr_nanos6_task_body_exit();
instr_nanos6_submit_task_exit();
instr_nanos6_task_resume(1);
instr_nanos6_task_end(1);
instr_nanos6_task_body_exit();

View File

@ -4,12 +4,10 @@
test_emu(attach.c)
test_emu(attach-old.c)
test_emu(nested-tasks.c)
test_emu(nested-tasks-bad.c SHOULD_FAIL
REGEX "body_execute: body 1 state must be Created but is Running")
test_emu(task-types.c MP)
test_emu(pause.c MP)
#test_emu(mp-rank.c MP)
test_emu(switch-same-type.c)
test_emu(mp-rank.c MP)
test_emu(switch-same-type.c DISABLED) # Does it make sense anymore?
test_emu(multiple-segment.c MP NPROC 4)
test_emu(task-pause-from-submit.c)
test_emu(same-subsystem.c)
@ -19,3 +17,16 @@ test_emu(require-missing.c
NAME flag-enable-all
DRIVER "flag-enable-all.driver.sh"
REGEX "all .* models are enabled")
test_emu(parallel-tasks.c)
test_emu(nest-to-parallel.c)
test_emu(bad-nest-same-task.c SHOULD_FAIL
REGEX "body_execute: refusing to run body(id=1,taskid=1) in Paused state, needs to resume intead")
test_emu(bad-double-execute.c SHOULD_FAIL
REGEX "body_execute: cannot nest body(id=1,taskid=2) over body(id=1,taskid=1) which is already running")
test_emu(bad-double-execute-parallel.c SHOULD_FAIL
REGEX "body_execute: cannot nest body(id=1,taskid=2) over body(id=1,taskid=1) which is already running")
test_emu(bad-pause-parallel.c SHOULD_FAIL
REGEX "body_pause: body(id=1,taskid=1) is not allowed to pause")
test_emu(bad-nest-from-parallel.c SHOULD_FAIL
REGEX "body_execute: cannot nest body(id=2,taskid=2) over body(id=1,taskid=1) which is already running")

View File

@ -0,0 +1,38 @@
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
#include "compat.h"
#include "instr.h"
#include "instr_nosv.h"
#include "emu/task.h"
/* Run two task parallel bodies without pausing the previous one. */
int
main(void)
{
instr_start(0, 1);
instr_nosv_init();
uint32_t typeid = 100;
instr_nosv_type_create(typeid);
instr_nosv_task_create_par(1, typeid);
instr_nosv_task_create_par(2, typeid);
instr_nosv_submit_enter();
instr_nosv_task_execute(1, 1);
{
instr_nosv_submit_enter();
instr_nosv_task_execute(2, 1); /* Must panic */
instr_nosv_task_end(2, 1);
instr_nosv_submit_exit();
}
instr_nosv_task_end(1, 1);
instr_nosv_submit_exit();
instr_end();
return 0;
}

View File

@ -0,0 +1,38 @@
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
#include "compat.h"
#include "instr.h"
#include "instr_nosv.h"
#include "emu/task.h"
/* Run two task bodies without pausing the previous one. */
int
main(void)
{
instr_start(0, 1);
instr_nosv_init();
uint32_t typeid = 100;
instr_nosv_type_create(typeid);
instr_nosv_task_create(1, typeid);
instr_nosv_task_create(2, typeid);
instr_nosv_submit_enter();
instr_nosv_task_execute(1, 0);
{
instr_nosv_submit_enter();
instr_nosv_task_execute(2, 0); /* Must panic */
instr_nosv_task_end(2, 0);
instr_nosv_submit_exit();
}
instr_nosv_task_end(1, 0);
instr_nosv_submit_exit();
instr_end();
return 0;
}

View File

@ -0,0 +1,41 @@
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
#include "compat.h"
#include "instr.h"
#include "instr_nosv.h"
#include "emu/task.h"
/* Run a parallel task body (taskid=1,bodyid=1) and before it finishes, attempt
* to run switch to another body from another task (taskid=2,bodyid=2). This is
* not valid because nOS-V cannot execute a inline task from a parallel task. */
int
main(void)
{
instr_start(0, 1);
instr_nosv_init();
uint32_t typeid = 100;
instr_nosv_type_create(typeid);
instr_nosv_task_create_par(1, typeid);
instr_nosv_task_create_par(2, typeid);
instr_nosv_submit_enter();
instr_nosv_task_execute(1, 1);
{
instr_nosv_submit_enter();
instr_nosv_task_execute(2, 2); /* Should fail */
sleep_us(10);
instr_nosv_task_end(2, 2);
instr_nosv_submit_exit();
}
instr_nosv_task_end(1, 1);
instr_nosv_submit_exit();
instr_end();
return 0;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
@ -14,13 +14,12 @@ main(void)
uint32_t typeid = 666;
instr_nosv_type_create(typeid);
uint32_t taskid = 1;
instr_nosv_task_create(taskid, typeid);
instr_nosv_task_execute(taskid);
/* Change subsystem to prevent duplicates */
instr_nosv_submit_enter();
instr_nosv_task_create(1, typeid);
instr_nosv_task_execute(1, 0);
instr_nosv_task_pause(1, 0);
/* Run another nested task with same id (should fail) */
instr_nosv_task_execute(taskid);
instr_nosv_task_execute(1, 0);
instr_end();

View File

@ -0,0 +1,35 @@
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
#include "compat.h"
#include "instr.h"
#include "instr_nosv.h"
#include "emu/task.h"
/* Run a parallel task body (taskid=1,bodyid=1) and attempt to pause it. This is
* not valid because nOS-V cannot pause a parallel task or execute an inline
* task from a parallel task (which requires the previous one to pause). */
int
main(void)
{
instr_start(0, 1);
instr_nosv_init();
uint32_t typeid = 100;
instr_nosv_type_create(typeid);
instr_nosv_task_create_par(1, typeid);
instr_nosv_submit_enter();
instr_nosv_task_execute(1, 1);
instr_nosv_task_pause(1, 1); /* Should fail */
instr_nosv_task_resume(1, 1);
instr_nosv_task_end(1, 1);
instr_nosv_submit_exit();
instr_end();
return 0;
}

View File

@ -37,11 +37,12 @@ instr_nosv_type_create(int32_t typeid)
return task_get_type_gid(p);
}
INSTR_2ARG(instr_nosv_task_create, "VTc", int32_t, id, uint32_t, typeid)
INSTR_1ARG(instr_nosv_task_execute, "VTx", int32_t, id)
INSTR_1ARG(instr_nosv_task_pause, "VTp", int32_t, id)
INSTR_1ARG(instr_nosv_task_resume, "VTr", int32_t, id)
INSTR_1ARG(instr_nosv_task_end, "VTe", int32_t, id)
INSTR_2ARG(instr_nosv_task_create, "VTc", uint32_t, taskid, uint32_t, typeid)
INSTR_2ARG(instr_nosv_task_create_par, "VTC", uint32_t, taskid, uint32_t, typeid)
INSTR_2ARG(instr_nosv_task_execute, "VTx", uint32_t, taskid, uint32_t, bodyid)
INSTR_2ARG(instr_nosv_task_pause, "VTp", uint32_t, taskid, uint32_t, bodyid)
INSTR_2ARG(instr_nosv_task_resume, "VTr", uint32_t, taskid, uint32_t, bodyid)
INSTR_2ARG(instr_nosv_task_end, "VTe", uint32_t, taskid, uint32_t, bodyid)
INSTR_0ARG(instr_nosv_submit_enter, "VAs")
INSTR_0ARG(instr_nosv_submit_exit, "VAS")

View File

@ -1,133 +1,16 @@
/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "compat.h"
#include "ovni.h"
#include "instr.h"
static void
fail(const char *msg)
{
fprintf(stderr, "%s\n", msg);
abort();
}
#define INSTR_3ARG(name, mcv, ta, a, tb, b, tc, c) \
static inline void name(ta a, tb b, tc c) \
{ \
struct ovni_ev ev = {0}; \
ovni_ev_set_mcv(&ev, mcv); \
ovni_ev_set_clock(&ev, ovni_clock_now()); \
ovni_payload_add(&ev, (uint8_t *) &a, sizeof(a)); \
ovni_payload_add(&ev, (uint8_t *) &b, sizeof(b)); \
ovni_payload_add(&ev, (uint8_t *) &c, sizeof(c)); \
ovni_ev_emit(&ev); \
}
INSTR_3ARG(instr_thread_execute, "OHx", int32_t, cpu, int32_t, creator_tid, uint64_t, tag)
static inline void
instr_thread_end(void)
{
struct ovni_ev ev = {0};
ovni_ev_set_mcv(&ev, "OHe");
ovni_ev_set_clock(&ev, ovni_clock_now());
ovni_ev_emit(&ev);
// Flush the events to disk before killing the thread
ovni_flush();
}
static inline void
instr_start(int rank, int nranks)
{
char hostname[OVNI_MAX_HOSTNAME];
if (gethostname(hostname, OVNI_MAX_HOSTNAME) != 0)
fail("gethostname failed");
ovni_proc_init(1, hostname, getpid());
ovni_proc_set_rank(rank, nranks);
ovni_thread_init(get_tid());
/* Only the rank 0 inform about all CPUs */
if (rank == 0) {
/* Fake nranks cpus */
for (int i = 0; i < nranks; i++)
ovni_add_cpu(i, i);
}
int curcpu = rank;
fprintf(stderr, "thread %d has cpu %d (ncpus=%d)\n",
get_tid(), curcpu, nranks);
instr_thread_execute(curcpu, -1, 0);
}
static inline void
instr_end(void)
{
instr_thread_end();
ovni_thread_free();
ovni_proc_fini();
}
static void
type_create(int32_t typeid)
{
struct ovni_ev ev = {0};
ovni_ev_set_mcv(&ev, "VYc");
ovni_ev_set_clock(&ev, ovni_clock_now());
char buf[256];
char *p = buf;
size_t nbytes = 0;
memcpy(buf, &typeid, sizeof(typeid));
p += sizeof(typeid);
nbytes += sizeof(typeid);
sprintf(p, "testtype%d", typeid);
nbytes += strlen(p) + 1;
ovni_ev_jumbo_emit(&ev, (uint8_t *) buf, nbytes);
}
#include "instr_nosv.h"
static void
task(int32_t id, uint32_t typeid, int us)
{
struct ovni_ev ev = {0};
ovni_ev_set_mcv(&ev, "VTc");
ovni_ev_set_clock(&ev, ovni_clock_now());
ovni_payload_add(&ev, (uint8_t *) &id, sizeof(id));
ovni_payload_add(&ev, (uint8_t *) &typeid, sizeof(id));
ovni_ev_emit(&ev);
memset(&ev, 0, sizeof(ev));
ovni_ev_set_mcv(&ev, "VTx");
ovni_ev_set_clock(&ev, ovni_clock_now());
ovni_payload_add(&ev, (uint8_t *) &id, sizeof(id));
ovni_ev_emit(&ev);
instr_nosv_task_create(id, typeid);
instr_nosv_task_execute(id, 0);
sleep_us(us);
memset(&ev, 0, sizeof(ev));
ovni_ev_set_mcv(&ev, "VTe");
ovni_ev_set_clock(&ev, ovni_clock_now());
ovni_payload_add(&ev, (uint8_t *) &id, sizeof(id));
ovni_ev_emit(&ev);
instr_nosv_task_end(id, 0);
}
int
@ -140,7 +23,7 @@ main(void)
instr_start(rank, nranks);
instr_nosv_init();
type_create(typeid);
instr_nosv_type_create(typeid);
/* Create some fake nosv tasks */
for (int i = 0; i < 10; i++)

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdio.h>
@ -53,9 +53,9 @@ main(void)
uint32_t typeid = 1;
instr_nosv_type_create(typeid);
instr_nosv_task_create(1, typeid);
instr_nosv_task_execute(1);
instr_nosv_task_execute(1, 0);
sleep_us(10000);
instr_nosv_task_end(1);
instr_nosv_task_end(1, 0);
instr_end();

View File

@ -0,0 +1,42 @@
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
#include "compat.h"
#include "instr.h"
#include "instr_nosv.h"
#include "emu/task.h"
/* Run a normal task body (taskid=1,bodyid=0) and before it finishes, switch to
* another body from a parallel task (taskid=2,bodyid=2). This is valid. */
int
main(void)
{
instr_start(0, 1);
instr_nosv_init();
uint32_t typeid = 100;
instr_nosv_type_create(typeid);
instr_nosv_task_create(1, typeid);
instr_nosv_task_create_par(2, typeid);
instr_nosv_task_execute(1, 0);
{
instr_nosv_task_pause(1, 0);
instr_nosv_submit_enter();
{
instr_nosv_task_execute(2, 2);
sleep_us(10);
instr_nosv_task_end(2, 2);
}
instr_nosv_submit_exit();
instr_nosv_task_resume(1, 0);
}
instr_nosv_task_end(1, 0);
instr_end();
return 0;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
@ -6,15 +6,7 @@
#include "instr.h"
#include "instr_nosv.h"
static void
create_and_run(int32_t id, uint32_t typeid, int us)
{
instr_nosv_task_create(id, typeid);
/* Change subsystem to prevent duplicates */
instr_nosv_submit_enter();
instr_nosv_task_execute(id);
sleep_us(us);
}
/* Create and run tasks, one nested into another */
int
main(void)
@ -27,15 +19,19 @@ main(void)
instr_nosv_type_create(typeid);
/* Create and run the tasks, one nested into another */
for (int i = 0; i < ntasks; i++)
create_and_run(i + 1, typeid, 500);
for (int id = 1; id <= ntasks; id++)
instr_nosv_task_create(id, typeid);
/* End the tasks in the opposite order */
for (int i = ntasks - 1; i >= 0; i--) {
instr_nosv_task_end(i + 1);
/* Change subsystem to prevent duplicates */
for (int id = 1; id <= ntasks; id++) {
instr_nosv_task_execute(id, 0);
instr_nosv_task_pause(id, 0);
instr_nosv_submit_enter();
}
for (int id = ntasks; id >= 1; id--) {
instr_nosv_submit_exit();
instr_nosv_task_resume(id, 0);
instr_nosv_task_end(id, 0);
}
instr_end();

View File

@ -0,0 +1,36 @@
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
#include "compat.h"
#include "instr.h"
#include "instr_nosv.h"
#include "emu/task.h"
int
main(void)
{
instr_start(0, 1);
instr_nosv_init();
uint32_t nbodies = 100;
uint32_t typeid = 100;
uint32_t taskid = 200;
instr_nosv_type_create(typeid);
instr_nosv_task_create_par(taskid, typeid);
/* Create and run the tasks, one nested into another */
for (uint32_t bodyid = 1; bodyid <= nbodies; bodyid++) {
/* Change subsystem to prevent duplicates */
instr_nosv_submit_enter();
instr_nosv_task_execute(taskid, bodyid);
sleep_us(100);
instr_nosv_task_end(taskid, bodyid);
instr_nosv_submit_exit();
}
instr_end();
return 0;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
@ -20,13 +20,13 @@ main(void)
instr_nosv_type_create(typeid);
instr_nosv_task_create(1, typeid);
instr_nosv_task_execute(1);
instr_nosv_task_execute(1, 0);
sleep_us(us);
instr_nosv_task_pause(1);
instr_nosv_task_pause(1, 0);
sleep_us(us);
instr_nosv_task_resume(1);
instr_nosv_task_resume(1, 0);
sleep_us(us);
instr_nosv_task_end(1);
instr_nosv_task_end(1, 0);
instr_end();

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
@ -20,10 +20,12 @@ main(void)
instr_nosv_type_create(10);
instr_nosv_task_create(1, 10);
instr_nosv_task_create(2, 10);
instr_nosv_task_execute(1);
instr_nosv_task_execute(2);
instr_nosv_task_end(2);
instr_nosv_task_end(1);
instr_nosv_task_execute(1, 0);
instr_nosv_task_pause(1, 0);
instr_nosv_task_execute(2, 0);
instr_nosv_task_end(2, 0);
instr_nosv_task_resume(1, 0);
instr_nosv_task_end(1, 0);
instr_end();

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
@ -25,11 +25,11 @@ main(void)
instr_nosv_task_create(1, typeid);
instr_nosv_task_create(2, typeid);
instr_nosv_task_execute(1);
instr_nosv_task_execute(1, 0);
/* Change subsystem to prevent duplicates */
instr_nosv_submit_enter();
/* Run another nested task with same type id */
instr_nosv_task_execute(2);
instr_nosv_task_execute(2, 0);
/* Match the PRV line in the trace */
FILE *f = fopen("match.sh", "w");
@ -56,9 +56,9 @@ main(void)
fclose(f);
/* Exit from tasks and subsystem */
instr_nosv_task_end(2);
instr_nosv_task_end(2, 0);
instr_nosv_submit_exit();
instr_nosv_task_end(1);
instr_nosv_task_end(1, 0);
instr_end();

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2023-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
@ -34,7 +34,7 @@ main(void)
instr_nosv_task_create(1, typeid);
instr_nosv_task_execute(1);
instr_nosv_task_execute(1, 0);
/* When starting a task, it must cause the subsystems to enter
* the "Task: In body" state */
@ -44,7 +44,7 @@ main(void)
fprintf(f, "grep ':%ld:%d:%d$' ovni/cpu.prv\n", get_delta(), prvtype, st);
instr_nosv_submit_enter(); /* Blocking submit */
instr_nosv_task_pause(1);
instr_nosv_task_pause(1, 0);
/* Should be left in the submit state, so no state transition in
* subsystems view */
@ -58,8 +58,8 @@ main(void)
fprintf(f, "grep ':%ld:%d:0$' ovni/cpu.prv\n", get_delta(), prvtype);
instr_nosv_submit_exit();
instr_nosv_task_resume(1);
instr_nosv_task_end(1);
instr_nosv_task_resume(1, 0);
instr_nosv_task_end(1, 0);
fclose(f);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
/* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdlib.h>
@ -23,9 +23,9 @@ main(void)
for (int i = 0; i < ntasks; i++) {
instr_nosv_task_create(i + 1, (i % ntypes) + 1);
instr_nosv_task_execute(i + 1);
instr_nosv_task_execute(i + 1, 0);
sleep_us(500);
instr_nosv_task_end(i + 1);
instr_nosv_task_end(i + 1, 0);
}
instr_end();