This repository has been archived by the owner on May 29, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_target_enter_data_devices.c
155 lines (128 loc) · 4.83 KB
/
test_target_enter_data_devices.c
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//===--- test_target_enter_data_devices.c ---------------------------------===//
//
// OpenMP API Version 4.5 Nov 2015
//
// This file tests the target enter data directive when the device clause is
// specified, and also when the device is set by omp_set_default_device().
// The first function test_set_default_dev() does not specify the device
// clause, but instead uses omp_set_default_device() to set device.
// The second function test_device() uses the device clause on the target
// enter data directive.
//
//===----------------------------------------------------------------------===//
#include <assert.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include "ompvv.h"
#define N 1000
int test_set_default_dev() {
OMPVV_INFOMSG("test_set_default_dev");
// Get number of devices
int num_dev = omp_get_num_devices();
OMPVV_INFOMSG("num_devices: %d", num_dev);
int def_dev = omp_get_default_device();
OMPVV_INFOMSG("initial device: %d", omp_get_initial_device());
OMPVV_INFOMSG("default device: %d", def_dev);
// Allocate num_devices + 1 to avoid zero-sized VLA if num_devices == 0
int sum[num_dev+1], errors = 0, isHost[num_dev+1];
int h_matrix[num_dev+1][N], h_matrix_copy[num_dev+1][N];
// Initialize all the matrices
for (int dev = 0; dev < num_dev; ++dev) {
sum[dev] = 0;
isHost[dev] = 0;
}
for (int dev = 0; dev < num_dev; ++dev) {
omp_set_default_device(dev);
// unstructured mapping
{
#pragma omp target enter data map(alloc: h_matrix[dev][0:N]) // omp_target_alloc sets ref to infinity. alloc: has effect only if ref is zero (page 217 line 21 - Version 4.5 November 2015)
printf(""); // forcing the compiler to not moving out of the scope
}
#pragma omp target map(alloc: h_matrix[dev][0:N]) map(tofrom: isHost[dev:1]) // map(alloc: ) to avoid target to map the entire matrix h_matrix[dev][:]
{
isHost[dev] = omp_is_initial_device();
for (int i = 0; i < N; ++i) {
h_matrix[dev][i] = dev;
}
}
// Since we don't do enter exit data we copy the values from the device
#pragma omp target map(from: h_matrix_copy[dev][0:N]) map(alloc: h_matrix[dev][0:N])
{
for (int i = 0; i < N; ++i) {
h_matrix_copy[dev][i] = h_matrix[dev][i];
}
}
}
// checking results
for (int dev = 0; dev < num_dev; ++dev) {
OMPVV_INFOMSG("device %d ran on the %s", dev, (isHost[dev])? "host" : "device");
for (int i = 0; i < N; ++i)
sum[dev] += h_matrix_copy[dev][i];
OMPVV_TEST_AND_SET(errors, (dev * N != sum[dev]));
}
omp_set_default_device(def_dev);
// Avoiding memory leaks this is outside of testing area
// Iterate over all the devices and delete the memory
for (int dev = 0; dev < num_dev; ++dev) {
#pragma omp target exit data map(delete: h_matrix[dev][0:N]) device(dev)
}
return errors;
}
int test_device() {
OMPVV_INFOMSG("test_device");
// Get number of devices
int num_dev = omp_get_num_devices();
OMPVV_INFOMSG("num_devices: %d", num_dev);
OMPVV_INFOMSG("initial device: %d", omp_get_initial_device());
OMPVV_INFOMSG("default device: %d", omp_get_default_device());
// Allocate num_devices + 1 to avoid zero-sized VLA if num_devices == 0
int sum[num_dev+1], errors = 0, isHost[num_dev+1];
int h_matrix[num_dev+1][N], h_matrix_copy[num_dev+1][N];
// Initialize all the matrices
for (int dev = 0; dev < num_dev; ++dev) {
sum[dev] = 0;
isHost[dev] = 0;
}
for (int dev = 0; dev < num_dev; ++dev) {
// unstructured mapping
{
#pragma omp target enter data map(alloc: h_matrix[dev][0:N]) device(dev)
printf("");
}
// operation
#pragma omp target map(alloc: h_matrix[dev][0:N]) map(tofrom: isHost[dev:1]) device(dev) // map(alloc: ) to avoid target to map the entire matrix h_matrix[dev][:]
{
isHost[dev] = omp_is_initial_device();
for (int i = 0; i < N; ++i)
h_matrix[dev][i] = dev;
}
// Since we don't do enter exit data we copy the values from the device
#pragma omp target map(from: h_matrix_copy[dev][0:N]) map(alloc: h_matrix[dev][0:N]) device(dev)
{
for (int i = 0; i < N; ++i) {
h_matrix_copy[dev][i] = h_matrix[dev][i];
}
}
}
// checking results
for (int dev = 0; dev < num_dev; ++dev) {
OMPVV_INFOMSG("device %d ran on the %s", dev, (isHost[dev])? "host" : "device");
for (int i = 0; i < N; ++i)
sum[dev] += h_matrix_copy[dev][i];
OMPVV_TEST_AND_SET(errors, (dev * N != sum[dev]));
}
// Avoiding memory leaks
// Iterate over all the devices and delete the memory
for (int dev = 0; dev < num_dev; ++dev) {
#pragma omp target exit data map(delete: h_matrix[dev][0:N]) device(dev)
}
return errors;
}
int main() {
OMPVV_TEST_OFFLOADING;
int errors = 0;
OMPVV_TEST_AND_SET(errors, test_set_default_dev());
OMPVV_TEST_AND_SET(errors, test_device());
OMPVV_REPORT_AND_RETURN(errors);
}