| // RUN: %libomptarget-compile-run-and-check-generic | |
| #include <omp.h> | |
| #include <stdio.h> | |
| // Test that a mapper that maps a var and a pointee, works on an array of | |
| // structs in terms of properly allocating/deleting the data. | |
| int x[2][10]; | |
| typedef struct { | |
| int x; | |
| int dummy[10000]; | |
| int *p; | |
| } S; | |
| #pragma omp declare mapper(default : S s) map(s.x, s.p[0 : 10]) | |
| S s1[2]; | |
| void print_status(void *p, const char *name) { | |
| int present = omp_target_is_present(p, omp_get_default_device()); | |
| printf("%s is %spresent\n", name, present ? "" : "not "); | |
| } | |
| int main() { | |
| s1[0].x = 111; | |
| s1[1].x = 222; | |
| s1[0].p = (int *)&x[0]; | |
| s1[1].p = (int *)&x[1]; | |
| #pragma omp target enter data map(to : s1) | |
| printf("After mapping\n"); | |
| print_status(&s1[0].x, "s1[0].x"); // CHECK: s1[0].x is present | |
| // dummy/p being present is not ideal, but that's what we get with the | |
| // current implementation because we need to map the full contiguous | |
| // chunk for the array first before invoking the mapper. | |
| print_status(&s1[0].dummy, "s1[0].dummy"); // CHECK: s1[0].dummy is present | |
| print_status(&s1[0].p, "s1[0].p"); // CHECK: s1[0].p is present | |
| print_status(&s1[0].p[0], "s1[0].p[0]"); // CHECK: s1[0].p[0] is present | |
| print_status(&s1[1].x, "s1[1].x"); // CHECK: s1[1].x is present | |
| print_status(&s1[1].dummy, "s1[1].dummy"); // CHECK: s1[1].dummy is present | |
| print_status(&s1[1].p, "s1[1].p"); // CHECK: s1[1].p is present | |
| print_status(&s1[1].p[0], "s1[1].p[0]"); // CHECK: s1[1].p[0] is present | |
| printf("\n"); | |
| #pragma omp target exit data map(delete : s1) | |
| printf("After deleting\n"); | |
| print_status(&s1[0].x, "s1[0].x"); // CHECK: s1[0].x is not present | |
| print_status(&s1[0].dummy, | |
| "s1[0].dummy"); // CHECK: s1[0].dummy is not present | |
| print_status(&s1[0].p, "s1[0].p"); // CHECK: s1[0].p is not present | |
| print_status(&s1[0].p[0], "s1[0].p[0]"); // CHECK: s1[0].p[0] is not present | |
| print_status(&s1[1].x, "s1[1].x"); // CHECK: s1[1].x is not present | |
| print_status(&s1[1].dummy, | |
| "s1[1].dummy"); // CHECK: s1[1].dummy is not present | |
| print_status(&s1[1].p, "s1[1].p"); // CHECK: s1[1].p is not present | |
| print_status(&s1[1].p[0], "s1[1].p[0]"); // CHECK: s1[1].p[0] is not present | |
| } |