1 #include <openacc.h>
2 #include <stdlib.h>
3
4 /* Test attach/detach operation with chained dereferences. */
5
6 typedef struct mystruct {
7 int *a;
8 struct mystruct *next;
9 } mystruct;
10
11 int
12 main (int argc, char* argv[])
13 {
14 const int N = 1024;
15 mystruct *m = (mystruct *) malloc (sizeof (*m));
16 int i;
17
18 m->a = (int *) malloc (N * sizeof (int));
19 m->next = (mystruct *) malloc (sizeof (*m));
20 m->next->a = (int *) malloc (N * sizeof (int));
21 m->next->next = NULL;
22
23 for (i = 0; i < N; i++)
24 {
25 m->a[i] = 0;
26 m->next->a[i] = 0;
27 }
28
29 #pragma acc enter data copyin(m[0:1])
30 acc_copyin (m->next, sizeof (*m));
31
32 for (int i = 0; i < 99; i++)
33 {
34 int j;
35 acc_copyin (m->next->a, N * sizeof (int));
36 acc_attach ((void **) &m->next);
37 /* This will attach only the innermost pointer, i.e. "a[0:N]". That's
38 why we have to attach the "m->next" pointer manually above. */
39 #pragma acc parallel loop copy(m->next->a[0:N])
40 for (j = 0; j < N; j++)
41 m->next->a[j]++;
42 acc_detach ((void **) &m->next);
43 acc_copyout (m->next->a, N * sizeof (int));
44 }
45
46 acc_copyout (m->next, sizeof (*m));
47 #pragma acc exit data copyout(m[0:1])
48
49 for (i = 0; i < N; i++)
50 {
51 if (m->a[i] != 0)
52 abort ();
53 if (m->next->a[i] != 99)
54 abort ();
55 }
56
57 free (m->next->a);
58 free (m->next);
59 free (m->a);
60 free (m);
61
62 return 0;
63 }