These commits fix issues regarding storage of tool data within libomptarget. Both libomp and libomptarget have been modified to accommodate this. We differentiate between two cases depending on the type of the target region: - merged target regions (default, without `nowait` clause): behavior remains unchanged, tool data is stored in the thread local RegionInterface class within libomptarget. - deferred target regions (using `nowait` clause): tool data is moved to `ompt_task_info_t` struct within libomp, as `RegionInterface` is thread local and its data is lost whenever another task is scheduled on the thread, which happens with deferred target regions. In the new implementation, `RegionInterface` receives pointers to `ompt_task_info_t` within libomp which are handled transparently within libomptarget. Thus, the problem of tool data getting lost when a thread receives a new task is resolved: `target_data` and `target_task_data` remain set. Another issue was the value of `task_data` which is supposed to belong to the generating task of the region according to the OpenMP standard, but instead had been set to the `task_data` of the target task itself until now. Test cases have been added which check both of these fixes. --------- Co-authored-by: Joachim <jenke@itc.rwth-aachen.de>
153 lines
5.5 KiB
C
153 lines
5.5 KiB
C
// clang-format off
|
|
// RUN: env LIBOMP_NUM_HIDDEN_HELPER_THREADS=1 %libomptarget-compile-run-and-check-generic
|
|
// REQUIRES: ompt
|
|
// clang-format on
|
|
|
|
#include <inttypes.h>
|
|
#include <omp-tools.h>
|
|
#include <omp.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "register_with_host.h"
|
|
|
|
#define N 1000000
|
|
#define M 1000
|
|
|
|
int main() {
|
|
float *x = malloc(N * sizeof(float));
|
|
float *y = malloc(N * sizeof(float));
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
x[i] = 1;
|
|
y[i] = 1;
|
|
}
|
|
|
|
#pragma omp target enter data map(to : x[0 : N]) map(alloc : y[0 : N])
|
|
#pragma omp target teams distribute parallel for
|
|
for (int i = 0; i < N; i++) {
|
|
for (int j = 0; j < M; j++) {
|
|
y[i] += 3 * x[i];
|
|
}
|
|
}
|
|
|
|
#pragma omp target teams distribute parallel for
|
|
for (int i = 0; i < N; i++) {
|
|
for (int j = 0; j < M; j++) {
|
|
y[i] += 3 * x[i];
|
|
}
|
|
}
|
|
|
|
#pragma omp target exit data map(release : x[0 : N]) map(from : y[0 : N])
|
|
|
|
printf("%f, %f\n", x[0], y[0]);
|
|
|
|
free(x);
|
|
free(y);
|
|
return 0;
|
|
}
|
|
|
|
// clang-format off
|
|
/// CHECK: ompt_event_initial_task_begin
|
|
/// CHECK-SAME: task_id=[[ENCOUNTERING_TASK:[0-f]+]]
|
|
|
|
/// CHECK: Callback Target EMI: kind=ompt_target_enter_data endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: task_data=0x{{[0-f]+}} (0x[[ENCOUNTERING_TASK]])
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA:[0-f]+]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_end
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_end
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_end
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Target EMI: kind=ompt_target_enter_data endpoint=ompt_scope_end
|
|
/// CHECK-SAME: task_data=0x{{[0-f]+}} (0x[[ENCOUNTERING_TASK]])
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Target EMI: kind=ompt_target endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: task_data=0x{{[0-f]+}} (0x[[ENCOUNTERING_TASK]])
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA:[0-f]+]])
|
|
|
|
/// CHECK: Callback Submit EMI: endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Submit EMI: endpoint=ompt_scope_end
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Target EMI: kind=ompt_target endpoint=ompt_scope_end
|
|
/// CHECK-SAME: task_data=0x{{[0-f]+}} (0x[[ENCOUNTERING_TASK]])
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Target EMI: kind=ompt_target endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: task_data=0x{{[0-f]+}} (0x[[ENCOUNTERING_TASK]])
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA:[0-f]+]])
|
|
|
|
/// CHECK: Callback Submit EMI: endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Submit EMI: endpoint=ompt_scope_end
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Target EMI: kind=ompt_target endpoint=ompt_scope_end
|
|
/// CHECK-SAME: task_data=0x{{[0-f]+}} (0x[[ENCOUNTERING_TASK]])
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Target EMI: kind=ompt_target_exit_data endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: task_data=0x{{[0-f]+}} (0x[[ENCOUNTERING_TASK]])
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA:[0-f]+]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_end
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_end
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_begin
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback DataOp EMI: endpoint=ompt_scope_end
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|
|
|
|
/// CHECK: Callback Target EMI: kind=ompt_target_exit_data endpoint=ompt_scope_end
|
|
/// CHECK-SAME: task_data=0x{{[0-f]+}} (0x[[ENCOUNTERING_TASK]])
|
|
/// CHECK-SAME: target_task_data=(nil) (0x0)
|
|
/// CHECK-SAME: target_data=0x{{[0-f]+}} (0x[[TARGET_DATA]])
|