This repository was archived by the owner on Mar 2, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathacl_globals.cpp
More file actions
385 lines (333 loc) · 12.2 KB
/
acl_globals.cpp
File metadata and controls
385 lines (333 loc) · 12.2 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
// Copyright (C) 2010-2021 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
// System headers.
#include <stddef.h>
// External library headers.
#include <acl_threadsupport/acl_threadsupport.h>
// Internal headers.
#include <acl.h>
#include <acl_auto.h>
#include <acl_globals.h>
#include <acl_hal.h>
#include <acl_offline_hal.h>
#include <acl_platform.h>
#include <acl_profiler.h>
#include <acl_support.h>
#include <acl_types.h>
#include <acl_util.h>
#ifdef __GNUC__
#pragma GCC visibility push(protected)
#endif
////////////////////////////////////////////////////
// Global data
std::unordered_map<std::string, bool> l_allow_invalid_type{};
// This variable exists only to ensure that the user has linked the host
// library with a matching HAL.
int ACL_VERSION_COMPATIBILITY_SYMBOL = 0;
////////////////////////////////////////////////////
// Static data
// This is the board that is plugged into the host system.
// It might be invalid in the offline compilation scenario.
static int acl_present_board_is_valid_value = 0;
static acl_system_def_t builtin_prog_def_value;
// Static functions
static int l_is_valid_system_def(const acl_system_def_t *sys);
static void l_reset_present_board();
////////////////////////////////////////////////////
// Global functions
acl_system_def_t *acl_present_board_def(void) {
acl_assert_locked();
if (acl_present_board_is_valid_value) {
return &builtin_prog_def_value;
} else {
return 0;
}
}
int acl_present_board_is_valid(void) {
acl_assert_locked();
return acl_present_board_is_valid_value;
}
static void l_reset_present_board() {
acl_assert_locked();
acl_present_board_is_valid_value = 0;
}
// Determine user's offline device setting from the environment variable.
// If it's prefixed by "+", then it's in addition to any auto-discovered
// devices.
// If not, then we don't even probe for auto-discovered devices.
acl_context_offline_mode_t
acl_get_offline_device_user_setting(std::string *offline_device) {
acl_context_offline_mode_t use_offline_only =
ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY;
const char *setting = 0;
const char *setting_deprecated = 0;
const char *result = 0;
static char warn_depr1 = 0;
static char warn_depr3 = 0;
setting = acl_getenv("CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA");
setting_deprecated = acl_getenv("CL_CONTEXT_OFFLINE_DEVICE_ALTERA");
if (!setting && setting_deprecated) {
setting = setting_deprecated;
if (0 == warn_depr1) {
fprintf(stderr, "[Runtime Warning]: CL_CONTEXT_OFFLINE_DEVICE_ALTERA has "
"been deprecated. Use "
"CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA instead.\n");
warn_depr1 = 1;
}
}
if (setting) {
if (*setting == '+') {
use_offline_only = ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY;
result = setting + 1; // Skip over the leading "+"
} else {
use_offline_only = ACL_CONTEXT_OFFLINE_ONLY;
result = setting;
}
// Treat empty string like no setting at all.
if (*result == 0) {
result = 0;
use_offline_only = ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY;
}
} else {
// Look for multi-process simulator before old simulator.
setting = acl_getenv("CL_CONTEXT_MPSIM_DEVICE_INTELFPGA");
// Check if simulation board spec directory is set, which implies
// CL_CONTEXT_MPSIM_DEVICE_INTELFPGA if that is not set
if (!setting && acl_getenv(INTELFPGA_SIM_DEVICE_SPEC_DIR)) {
setting = "1"; // Use 1 simulator device by default
}
if (setting) {
use_offline_only = ACL_CONTEXT_MPSIM;
result = setting;
} else {
setting = acl_getenv("CL_CONTEXT_MSIM_DEVICE_INTELFPGA");
setting_deprecated = acl_getenv("CL_CONTEXT_MSIM_DEVICE_ALTERA");
if (!setting && setting_deprecated) {
setting = setting_deprecated;
if (0 == warn_depr3) {
fprintf(stderr, "[Runtime Warning]: CL_CONTEXT_MSIM_DEVICE_ALTERA "
"has been deprecated. Use "
"CL_CONTEXT_MSIM_DEVICE_INTELFPGA instead.\n");
warn_depr3 = 1;
}
}
if (setting) {
use_offline_only = ACL_CONTEXT_MSIM;
result = 0;
}
}
}
if (offline_device) {
if (use_offline_only == ACL_CONTEXT_MPSIM) {
*offline_device = ACL_MPSIM_DEVICE_NAME;
} else if (result) {
*offline_device = result;
}
}
return use_offline_only;
}
int acl_init(const acl_system_def_t *newsys) {
acl_assert_locked();
// The user/tester really knows what they're doing.
acl_reset();
// Must have set the HAL first, so we can print errors if necessary.
if (acl_get_hal() && l_is_valid_system_def(newsys)) {
builtin_prog_def_value = *newsys;
acl_present_board_is_valid_value =
1; // Must come before acl_init_platform because that *uses* the defined
// system
}
acl_init_platform();
acl_init_profiler();
return acl_present_board_is_valid_value;
}
// Initialize the HAL and load the builtin system definition.
//
// It will handle setting up an offline device, either exclusively (by
// default), or in addition to devices found via HAL probing.
//
// This function returns CL_TRUE if a hal is initialized and CL_FALSE
// if it is not.
cl_bool acl_init_from_hal_discovery(void) {
const acl_hal_t *board_hal;
acl_assert_locked();
acl_context_offline_mode_t use_offline_only =
acl_get_offline_device_user_setting(NULL);
// Two jobs:
// 1. Set the HAL from the linked-in HAL library.
// 2. Discover the device parameters by probing.
acl_reset();
switch (use_offline_only) {
case ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY:
case ACL_CONTEXT_MPSIM:
board_hal = acl_mmd_get_system_definition(&builtin_prog_def_value,
libraries_to_load);
break;
case ACL_CONTEXT_OFFLINE_ONLY:
board_hal = acl_get_offline_hal();
break;
#ifdef __linux__
case ACL_CONTEXT_MSIM:
if (&acl_msim_get_system_definition == NULL) {
return CL_FALSE;
}
board_hal = acl_msim_get_system_definition(&builtin_prog_def_value);
break;
#endif
default:
// Not a valid setting so don't know which HAL to load
return CL_FALSE;
}
if (board_hal == NULL) {
return CL_FALSE;
}
// Probe the HAL for a device.
acl_set_hal(board_hal);
if (use_offline_only != ACL_CONTEXT_OFFLINE_ONLY) {
acl_present_board_is_valid_value = 1;
}
acl_init_platform();
acl_init_profiler();
if (acl_get_hal() == nullptr) {
return CL_FALSE;
}
return CL_TRUE;
}
void acl_reset(void) {
acl_assert_locked();
l_reset_present_board();
acl_platform.offline_mode = ACL_CONTEXT_OFFLINE_AND_AUTODISCOVERY;
acl_platform.has_offline_device = 0;
acl_platform.num_devices = 0;
for (unsigned i = 0; i < ACL_MAX_DEVICE; ++i) {
acl_platform.device[i] = _cl_device_id();
}
acl_platform.initialized = 0;
}
////////////////////////////////////////////////////
// Static functions
static int l_is_valid_range(int (*msg)(const char *, ...),
const std::string &name,
const acl_addr_range_t *range) {
ptrdiff_t begin_addr = ((char *)range->begin) - ((char *)0);
ptrdiff_t next_addr = ((char *)range->next) - ((char *)0);
acl_assert_locked();
if ((char *)range->next < (char *)range->begin) {
msg("Invalid address range for %s: beginning of storage %x comes after "
"next storage %x\n",
name.c_str(), range->begin, range->next);
return 0;
}
// Check alignment.
if ((begin_addr & (ACL_MEM_ALIGN - 1)) & ~(ACL_MEM_ALIGN)) {
msg("Invalid address range for %s: begin pointer %x should be aligned to "
"%d bytes\n",
name.c_str(), range->begin, ACL_MEM_ALIGN);
return 0;
}
if ((next_addr & (ACL_MEM_ALIGN - 1)) & ~(ACL_MEM_ALIGN)) {
msg("Invalid address range for %s: next pointer %x should be aligned to %d "
"bytes\n",
name.c_str(), range->next, ACL_MEM_ALIGN);
return 0;
}
return 1;
}
int l_is_valid_system_def(const acl_system_def_t *sys) {
int is_ok = 1;
int (*msg)(const char *, ...) = acl_print_debug_msg;
acl_assert_locked();
#define AND_ALSO(COND, ISSUE_MSG) \
do { \
if (is_ok) { \
is_ok = COND; \
if (!is_ok) { \
ISSUE_MSG; \
} \
} \
} while (0)
AND_ALSO(sys != 0, msg("System definition is NULL pointer\n"));
if (!is_ok) {
return 0;
}
AND_ALSO(sys->num_devices <= ACL_MAX_DEVICE,
msg("Too many devices %d > %d\n", sys->num_devices, ACL_MAX_DEVICE));
if (!is_ok) {
return 0;
}
// Check each device in turn
for (cl_uint idev = 0; idev < sys->num_devices; idev++) {
AND_ALSO(sys->device[idev].autodiscovery_def.num_global_mem_systems > 0,
msg("Currently loaded device binary version is not supported\n"));
for (unsigned imem = 0;
imem < sys->device[idev].autodiscovery_def.num_global_mem_systems;
imem++) {
AND_ALSO(l_is_valid_range(msg, "global memory",
&sys->device[idev]
.autodiscovery_def.global_mem_defs[imem]
.range), );
AND_ALSO(sys->device[idev]
.autodiscovery_def.global_mem_defs[imem]
.num_global_banks > 0,
msg("num global banks (%d) should be positive.\n",
sys->device[idev]
.autodiscovery_def.global_mem_defs[imem]
.num_global_banks));
}
AND_ALSO(!sys->device[idev].autodiscovery_def.name.empty(),
msg("Accelerator %d does not have a name\n", idev));
// Check each accelerator block in turn.
for (const auto &accel : sys->device[idev].autodiscovery_def.accel) {
AND_ALSO(l_is_valid_range(msg, accel.iface.name.c_str(), &(accel.mem)), );
AND_ALSO(!accel.iface.name.empty(),
msg("Accelerator [%d][%d] has no name\n", idev, accel.id));
// Now check arg specs.
unsigned iarg = 0;
for (const auto &arg_info : accel.iface.args) {
switch (arg_info.addr_space) {
case ACL_ARG_ADDR_LOCAL:
case ACL_ARG_ADDR_GLOBAL:
case ACL_ARG_ADDR_CONSTANT:
case ACL_ARG_ADDR_NONE:
break;
default:
AND_ALSO(0, msg("Accelerator [%d] \"%s\" arg %d is in wrong address "
"space %d\n",
accel.id, accel.iface.name.c_str(), iarg,
static_cast<int>(arg_info.addr_space)));
break;
}
switch (arg_info.category) {
case ACL_ARG_BY_VALUE:
case ACL_ARG_MEM_OBJ:
case ACL_ARG_SAMPLER:
break;
default:
AND_ALSO(0,
msg("Accelerator [%d] \"%s\" arg %d has wrong category %d\n",
accel.id, accel.iface.name.c_str(), iarg,
static_cast<int>(arg_info.category)));
break;
}
AND_ALSO(
(arg_info.addr_space == ACL_ARG_ADDR_LOCAL || arg_info.size > 0),
msg("Accelerator [%d] \"%s\" arg %d is not a __local argument but "
"has 0 or negative size: %d\n",
accel.id, accel.iface.name.c_str(), iarg,
static_cast<int>(arg_info.size)));
// Support devices that use 64-bit pointers or 32-bit pointers
AND_ALSO((arg_info.addr_space != ACL_ARG_ADDR_LOCAL ||
arg_info.size == 4 || arg_info.size == 8),
msg("Accelerator [%d] \"%s\" __local arg %d should have size "
"= 4 or 8 but is size: %d\n",
accel.id, accel.iface.name.c_str(), iarg,
static_cast<int>(arg_info.size)));
++iarg;
}
}
}
return is_ok;
}
#ifdef __GNUC__
#pragma GCC visibility pop
#endif