1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
/* { dg-do compile } */
/* { dg-additional-options "-fdump-tree-optimized" } */
/* In configurations without offloading configured, we can resolve many
instances of the target_device context selector at gimplification time
instead of waiting until late resolution. */
/* Device 0 may be either the host or an offloading device, in configurations
that support them. */
void
f1 (int n, double* a, double s)
{
#pragma omp metadirective \
when (target_device={device_num(0), kind(host)} \
: parallel for) \
default (error at(execution) message("f1 match failed"))
for (int i = 0; i < n; i++)
a[i] = a[i] * s;
}
/* { dg-final { scan-tree-dump-not "f1 match failed" "optimized" { target { ! offloading_enabled } } } } */
/* { dg-final { scan-tree-dump "f1 match failed" "optimized" { target offloading_enabled } } } */
/* Device -1 is always the host, even in offloading configurations. */
void
f2 (int n, double* a, double s)
{
#pragma omp metadirective \
when (target_device={device_num(-1), kind(host)} \
: parallel for) \
default (error at(execution) message("f2 match failed"))
for (int i = 0; i < n; i++)
a[i] = a[i] * s;
}
/* { dg-final { scan-tree-dump-not "f2 match failed" "optimized" } } */
/* Constant device numbers < -1 cause the match to fail, even in offloading
configurations. */
void
f3 (int n, double* a, double s)
{
#pragma omp metadirective \
when (target_device={device_num(-42), kind(host)} \
: error at(execution) message("f3 match failed")) \
default (parallel for)
for (int i = 0; i < n; i++)
a[i] = a[i] * s;
}
/* { dg-final { scan-tree-dump-not "f3 match failed" "optimized" } } */
/* In a non-offloading configuration, devices > 0 are always invalid and
will cause the match to fail. In an offload configuration, we don't
know at compile-time if the device number is valid or if it refers to
a host or offload device. */
void
f4 (int n, double* a, double s)
{
#pragma omp metadirective \
when (target_device={device_num(42), kind(host)} \
: error at(execution) message("f4 match failed")) \
default (parallel for)
for (int i = 0; i < n; i++)
a[i] = a[i] * s;
}
/* { dg-final { scan-tree-dump-not "f4 match failed" "optimized" { target { ! offloading_enabled } } } } */
/* { dg-final { scan-tree-dump "f4 match failed" "optimized" { target offloading_enabled } } } */
extern int omp_get_initial_device (void);
extern int omp_get_default_device (void);
extern int omp_get_num_devices (void);
extern int omp_get_device_num (void);
/* On a non-offloading configuration, omp_get_default_device() always refers
to the host. With offloading, we know it's a valid device number but
not whether it's the host. */
void
f5 (int n, double* a, double s)
{
#pragma omp metadirective \
when (target_device={device_num(omp_get_default_device ()), kind(host)} \
: parallel for) \
default (error at(execution) message("f5 match failed"))
for (int i = 0; i < n; i++)
a[i] = a[i] * s;
}
/* { dg-final { scan-tree-dump-not "f5 match failed" "optimized" { target { ! offloading_enabled } } } } */
/* { dg-final { scan-tree-dump "f5 match failed" "optimized" { target offloading_enabled } } } */
/* omp_get_initial_device() always refers to the host, whether offloading is
configured or not. */
void
f6 (int n, double* a, double s)
{
#pragma omp metadirective \
when (target_device={device_num(omp_get_initial_device ()), kind(host)} \
: parallel for) \
default (error at(execution) message("f6 match failed"))
for (int i = 0; i < n; i++)
a[i] = a[i] * s;
}
/* { dg-final { scan-tree-dump-not "f6 match failed" "optimized" } } */
/* omp_get_num_devices() returns the number of non-host offload devices,
therefore using it as a device number always refers to the host, whether
offloading is enabled or not. */
void
f7 (int n, double* a, double s)
{
#pragma omp metadirective \
when (target_device={device_num(omp_get_num_devices ()), kind(host)} \
: parallel for) \
default (error at(execution) message("f7 match failed"))
for (int i = 0; i < n; i++)
a[i] = a[i] * s;
}
/* { dg-final { scan-tree-dump-not "f7 match failed" "optimized" } } */
/* omp_get_device_num() always returns a valid device number but we don't
know whether it's the host or offload device, in configurations that
support offloading. */
void
f8 (int n, double* a, double s)
{
#pragma omp metadirective \
when (target_device={device_num(omp_get_device_num ()), kind(host)} \
: parallel for) \
default (error at(execution) message("f8 match failed"))
for (int i = 0; i < n; i++)
a[i] = a[i] * s;
}
/* { dg-final { scan-tree-dump-not "f8 match failed" "optimized" { target { ! offloading_enabled } } } } */
/* { dg-final { scan-tree-dump "f8 match failed" "optimized" { target offloading_enabled } } } */
|