Skip to content

Commit 1239fd7

Browse files
committed
Remove runtime unit test dependency on aoc
1 parent 0d6db43 commit 1239fd7

File tree

12 files changed

+284
-96
lines changed

12 files changed

+284
-96
lines changed

test/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ target_link_libraries(acl_test PRIVATE
5252
)
5353
add_test(NAME acl_test COMMAND acl_test -v)
5454
set_property(TEST acl_test PROPERTY ENVIRONMENT
55-
"AOCL_BOARD_PACKAGE_ROOT=${CMAKE_CURRENT_SOURCE_DIR}/board/a10_ref"
55+
"\
56+
AOCL_BOARD_PACKAGE_ROOT=${CMAKE_CURRENT_SOURCE_DIR}/board/a10_ref;\
57+
ACL_TEST_EXAMPLE_BINARY=${CMAKE_CURRENT_SOURCE_DIR}/example_binary\
58+
"
5659
)
5760

5861
add_subdirectory(fake_bsp)

test/acl_program_test.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ MT_TEST_GROUP(from_source) {
844844

845845
void load(int compiler_mode =
846846
CL_CONTEXT_COMPILER_MODE_OFFLINE_CREATE_EXE_LIBRARY_INTELFPGA,
847-
const char *compile_command = 0, bool print_notify = true) {
847+
std::string compile_command = "", bool print_notify = true) {
848848
unload();
849849
CHECK_EQUAL(CL_SUCCESS, clGetPlatformIDs(1, &m_platform, 0));
850850
CHECK(acl_platform_is_valid(m_platform));
@@ -853,14 +853,31 @@ MT_TEST_GROUP(from_source) {
853853
&m_device[0], &m_num_devices));
854854
CHECK(m_num_devices > 0);
855855

856+
// Check if there is precompiled binaries, if envvar set, use that instead
857+
const char *envvar_example_binary = "ACL_TEST_EXAMPLE_BINARY";
858+
const char *example_binary_root = acl_getenv(envvar_example_binary);
859+
if (example_binary_root) {
860+
// Precompiled binaries exist, emulate the compile by copying the
861+
// precompiled binaries to the current directory.
862+
#ifdef _WIN32
863+
std::string bin_file =
864+
std::string(example_binary_root) + "/windows/foo.aocr";
865+
#else
866+
std::string bin_file =
867+
std::string(example_binary_root) + "/linux/foo.aocr";
868+
#endif
869+
compile_command = "cp " + bin_file + " ./kernels.aocr && echo ";
870+
}
871+
856872
cl_int status = CL_INVALID_DEVICE;
857873
cl_context_properties props[] = {
858874
CL_CONTEXT_PROGRAM_EXE_LIBRARY_ROOT_INTELFPGA,
859875
(cl_context_properties)m_basedir.c_str(),
860876
CL_CONTEXT_COMPILER_MODE_INTELFPGA,
861877
compiler_mode,
862-
(compile_command ? CL_CONTEXT_COMPILE_COMMAND_INTELFPGA : 0),
863-
(cl_context_properties)compile_command,
878+
(compile_command != "" ? CL_CONTEXT_COMPILE_COMMAND_INTELFPGA : 0),
879+
(cl_context_properties)(compile_command != "" ? compile_command.c_str()
880+
: 0),
864881
0,
865882
0};
866883
m_context =
@@ -949,7 +966,8 @@ MT_TEST(from_source, make_prog_dir_and_build_command) {
949966

950967
// Default arguments, just turning off printing of errors for invalid calls to
951968
// be tested below
952-
load(CL_CONTEXT_COMPILER_MODE_OFFLINE_CREATE_EXE_LIBRARY_INTELFPGA, 0, false);
969+
load(CL_CONTEXT_COMPILER_MODE_OFFLINE_CREATE_EXE_LIBRARY_INTELFPGA, "",
970+
false);
953971
load_program();
954972

955973
// Before build. No executable.
@@ -1082,11 +1100,9 @@ MT_TEST(from_source, online_mode) {
10821100
ACL_LOCKED(CHECK(acl_realpath_existing(check_str) != ""));
10831101
check_str = m_hashdir + std::string("/build.cmd");
10841102
ACL_LOCKED(CHECK(acl_realpath_existing(check_str) != ""));
1085-
// Since we invoked compiler with -rtl, we only get an .aoco and .aocr
1103+
// If we have invoked compiler with -rtl, we should get an .aocr
10861104
check_str = m_hashdir + std::string("/kernels.aocr");
10871105
ACL_LOCKED(CHECK(acl_realpath_existing(check_str) != ""));
1088-
check_str = m_hashdir + std::string("/kernels/kernels.v");
1089-
ACL_LOCKED(CHECK(acl_realpath_existing(check_str) != ""));
10901106

10911107
// Check the build log.
10921108
size_t size_ret;

test/acl_test.cpp

Lines changed: 124 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -218,91 +218,140 @@ const unsigned char *acl_test_get_example_binary(size_t *binary_len) {
218218
}
219219

220220
static void l_load_example_binary(void) {
221-
const char *envvar_offline_device = "CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA";
222-
const char *envvar_program_lib =
223-
"CL_CONTEXT_PROGRAM_EXE_LIBRARY_ROOT_INTELFPGA";
224-
const char *offline_old_value = acl_getenv(envvar_offline_device);
225-
const char *program_lib_old_value = acl_getenv(envvar_program_lib);
226-
int system_ret = -1;
227-
enum { MAX_DEVICES = 100 };
228-
cl_platform_id platform;
229-
cl_device_id device[MAX_DEVICES];
230-
cl_context context;
231-
cl_program program;
232-
cl_int status;
233-
234-
acl_test_setenv(envvar_offline_device, ACLTEST_DEFAULT_BOARD);
235-
acl_test_setenv(envvar_program_lib, ".acltest_builtin_prog");
236-
system_ret = system("rm -rf .acltest_builtin_prog");
237-
assert(system_ret != -1);
238-
239-
ACL_LOCKED(acl_test_setup_generic_system());
240-
241221
// Since this runs before the CppUTest runner is set up, we can't use
242222
// the CHECK* macros.
243223
// Just use asserts.
244224

245-
assert(CL_SUCCESS == clGetPlatformIDs(1, &platform, 0));
246-
assert(CL_SUCCESS == clGetDeviceIDs(platform, CL_DEVICE_TYPE_ACCELERATOR,
247-
MAX_DEVICES, device, 0));
225+
const char *envvar_example_binary = "ACL_TEST_EXAMPLE_BINARY";
226+
const char *example_binary_root = acl_getenv(envvar_example_binary);
227+
if (example_binary_root) {
228+
// Precompiled binaries exist, just read its content
229+
ACL_LOCKED(acl_test_setup_generic_system());
230+
#ifdef _WIN32
231+
std::string bin_file =
232+
std::string(example_binary_root) + "/windows/example.aocr";
233+
#else
234+
std::string bin_file =
235+
std::string(example_binary_root) + "/linux/example.aocr";
236+
#endif
237+
FILE *infile = fopen(bin_file.c_str(), "rb");
238+
assert(infile && "Cannot open example binary example.aocr, make sure "
239+
"ACL_TEST_EXAMPLE_BINARY is set to the correct path");
240+
241+
// Get binary length
242+
assert(fseek(infile, 0, SEEK_END) == 0);
243+
long int position = ftell(infile);
244+
assert(position != -1L);
245+
acl_test_example_binary_len = (size_t)position;
246+
// Return to beginning of file
247+
assert(fseek(infile, 0, SEEK_SET) == 0);
248+
249+
// Read binary
250+
acl_test_example_binary =
251+
(unsigned char *)acl_malloc(acl_test_example_binary_len);
252+
assert(acl_test_example_binary);
253+
assert(fread(acl_test_example_binary, sizeof(char),
254+
acl_test_example_binary_len,
255+
infile) == acl_test_example_binary_len);
256+
assert(fclose(infile) == 0);
257+
} else {
258+
// Precompiled binaries don't exist, do an actual compile with the
259+
// aoc compiler and store the binary as test example binary.
260+
const char *envvar_offline_device = "CL_CONTEXT_OFFLINE_DEVICE_INTELFPGA";
261+
const char *envvar_program_lib =
262+
"CL_CONTEXT_PROGRAM_EXE_LIBRARY_ROOT_INTELFPGA";
263+
const char *offline_old_value = acl_getenv(envvar_offline_device);
264+
const char *program_lib_old_value = acl_getenv(envvar_program_lib);
265+
int system_ret = -1;
266+
enum { MAX_DEVICES = 100 };
267+
cl_platform_id platform;
268+
cl_device_id device[MAX_DEVICES];
269+
cl_context context;
270+
cl_program program;
271+
cl_int status;
272+
273+
acl_test_setenv(envvar_offline_device, ACLTEST_DEFAULT_BOARD);
274+
acl_test_setenv(envvar_program_lib, ".acltest_builtin_prog");
275+
system_ret = system("rm -rf .acltest_builtin_prog");
276+
assert(system_ret != -1);
248277

249-
cl_context_properties props[] = {
250-
CL_CONTEXT_COMPILER_MODE_INTELFPGA,
251-
CL_CONTEXT_COMPILER_MODE_OFFLINE_CREATE_EXE_LIBRARY_INTELFPGA, 0};
252-
context = clCreateContext(props, 1, device, acl_test_notify_print, 0, 0);
253-
assert(context);
254-
255-
const char *src =
256-
"kernel void vecaccum(global int*A, global int*B) {\n"
257-
" size_t gid = get_global_id(0);\n"
258-
" A[gid] += B[gid];\n"
259-
"};\n"
260-
// This one has two constant arguments.
261-
"kernel void vecsum(global int*A, constant int*B, constant int*C) {\n"
262-
" size_t gid = get_global_id(0);\n"
263-
" A[gid] = B[gid] + C[gid];\n"
264-
"};\n"
265-
266-
// This has a printf.
267-
"kernel void printit(global int*A) {\n"
268-
" printf(\"Hello world! %d\\n\", A[0]);\n"
269-
"};\n";
270-
271-
program = clCreateProgramWithSource(context, 1, &src, 0, 0);
272-
assert(program);
273-
274-
status = clBuildProgram(program, 1, device, "-cl-kernel-arg-info", 0, 0);
275-
if (status != CL_SUCCESS) {
276-
printf("Compilation failed. Kernel source is:\n-----\n%s\n----\n", src);
278+
ACL_LOCKED(acl_test_setup_generic_system());
279+
280+
assert(CL_SUCCESS == clGetPlatformIDs(1, &platform, 0));
281+
assert(CL_SUCCESS == clGetDeviceIDs(platform, CL_DEVICE_TYPE_ACCELERATOR,
282+
MAX_DEVICES, device, 0));
283+
284+
cl_context_properties props[] = {
285+
CL_CONTEXT_COMPILER_MODE_INTELFPGA,
286+
CL_CONTEXT_COMPILER_MODE_OFFLINE_CREATE_EXE_LIBRARY_INTELFPGA, 0};
287+
context = clCreateContext(props, 1, device, acl_test_notify_print, 0, 0);
288+
assert(context);
289+
290+
const char *src =
291+
"kernel void vecaccum(global int*A, global int*B) {\n"
292+
" size_t gid = get_global_id(0);\n"
293+
" A[gid] += B[gid];\n"
294+
"};\n"
295+
// This one has two constant arguments.
296+
"kernel void vecsum(global int*A, constant int*B, constant int*C) {\n"
297+
" size_t gid = get_global_id(0);\n"
298+
" A[gid] = B[gid] + C[gid];\n"
299+
"};\n"
300+
301+
// This has a printf.
302+
"kernel void printit(global int*A) {\n"
303+
" printf(\"Hello world! %d\\n\", A[0]);\n"
304+
"};\n";
305+
306+
program = clCreateProgramWithSource(context, 1, &src, 0, 0);
307+
assert(program);
308+
309+
status = clBuildProgram(program, 1, device, "-cl-kernel-arg-info", 0, 0);
310+
if (status != CL_SUCCESS) {
311+
printf("Compilation failed. Kernel source is:\n-----\n%s\n----\n", src);
312+
size_t log_size = 0;
313+
clGetProgramBuildInfo(program, device[0], CL_PROGRAM_BUILD_LOG, 0, 0,
314+
&log_size);
315+
char *log = (char *)acl_malloc(log_size);
316+
clGetProgramBuildInfo(program, device[0], CL_PROGRAM_BUILD_LOG, log_size,
317+
log, 0);
318+
if (log)
319+
printf("Build log is:\n-----\n%s\n----\n", log);
320+
exit(1);
321+
}
322+
323+
// The build log should not be empty
277324
size_t log_size = 0;
325+
size_t empty_log_size = 1;
278326
clGetProgramBuildInfo(program, device[0], CL_PROGRAM_BUILD_LOG, 0, 0,
279327
&log_size);
280-
char *log = (char *)acl_malloc(log_size);
281-
clGetProgramBuildInfo(program, device[0], CL_PROGRAM_BUILD_LOG, log_size,
282-
log, 0);
283-
if (log)
284-
printf("Build log is:\n-----\n%s\n----\n", log);
285-
exit(1);
328+
assert(log_size > empty_log_size);
329+
330+
acl_test_example_binary_len = 0;
331+
assert(CL_SUCCESS == clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES,
332+
sizeof(size_t),
333+
&acl_test_example_binary_len, 0));
334+
acl_test_example_binary =
335+
(unsigned char *)acl_malloc(acl_test_example_binary_len);
336+
assert(acl_test_example_binary);
337+
assert(CL_SUCCESS == clGetProgramInfo(program, CL_PROGRAM_BINARIES,
338+
sizeof(acl_test_example_binary),
339+
&acl_test_example_binary, 0));
340+
341+
// Don't leak
342+
clReleaseProgram(program);
343+
clReleaseContext(context);
344+
345+
acl_test_unsetenv(envvar_offline_device);
346+
if (offline_old_value) {
347+
acl_test_setenv(envvar_offline_device, offline_old_value);
348+
}
349+
acl_test_unsetenv(envvar_program_lib);
350+
if (program_lib_old_value) {
351+
acl_test_setenv(envvar_program_lib, program_lib_old_value);
352+
}
286353
}
287354

288-
// The build log should not be empty
289-
size_t log_size = 0;
290-
size_t empty_log_size = 1;
291-
clGetProgramBuildInfo(program, device[0], CL_PROGRAM_BUILD_LOG, 0, 0,
292-
&log_size);
293-
assert(log_size > empty_log_size);
294-
295-
acl_test_example_binary_len = 0;
296-
assert(CL_SUCCESS == clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES,
297-
sizeof(size_t),
298-
&acl_test_example_binary_len, 0));
299-
acl_test_example_binary =
300-
(unsigned char *)acl_malloc(acl_test_example_binary_len);
301-
assert(acl_test_example_binary);
302-
assert(CL_SUCCESS == clGetProgramInfo(program, CL_PROGRAM_BINARIES,
303-
sizeof(acl_test_example_binary),
304-
&acl_test_example_binary, 0));
305-
306355
// Save the derived sysdef for later tests.
307356
{
308357
acl_pkg_file_t pkg;
@@ -334,19 +383,6 @@ static void l_load_example_binary(void) {
334383
acl_pkg_close_file(pkg);
335384
}
336385

337-
// Don't leak
338-
clReleaseProgram(program);
339-
clReleaseContext(context);
340-
341-
acl_test_unsetenv(envvar_offline_device);
342-
if (offline_old_value) {
343-
acl_test_setenv(envvar_offline_device, offline_old_value);
344-
}
345-
acl_test_unsetenv(envvar_program_lib);
346-
if (program_lib_old_value) {
347-
acl_test_setenv(envvar_program_lib, program_lib_old_value);
348-
}
349-
350386
ACL_LOCKED(acl_test_teardown_generic_system());
351387
}
352388

test/example_binary/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Precompiled Binaries for Runtime Unit Tests
2+
3+
This directory contains precompiled binaries that the runtime unit tests could use.
4+
5+
When the environment variable `ACL_TEST_EXAMPLE_BINARY` is set, precompiled binaries
6+
will be used for the unit tests, instead of compiling with aoc in-time. The environment
7+
variable is set to this directory by default by the unit test CMake configuration.
8+
9+
## Unit Tests Using AOC compiler
10+
11+
During setup, the runtime loads an example binary that may be obtained and used by
12+
any runtime unit tests. The loading is done in the function `l_load_example_binary`
13+
of acl_test.cpp, and the loaded binary can be obtained by calling the function
14+
`acl_test_get_example_binary`.
15+
16+
Other than this, the program `from_source` test group contains two tests that either
17+
requires the aoc compiler, or the precompiled binaries to be present:
18+
19+
- `make_prog_dir_and_build_command`
20+
- `online_mode`
21+
22+
## Overriding the Binaries to be Used
23+
24+
To use precompiled binaries contained in another directory, set `ACL_TEST_EXAMPLE_BINARY`
25+
to the root of that directory, and make sure there is a `linux` subdirectory for linux
26+
precompiled binaries and a `windows` subdirectory for windows precompile binaries.
27+
28+
## Updating the Binaries
29+
30+
In case binaries have to be updated, make sure the aoc compiler is available, and
31+
run the compile scripts contained in each of the corresponding OS subdirectories:
32+
33+
```
34+
# On Linux
35+
sh linux/compile_aocr.sh
36+
# On Windows
37+
windows\compile_aocr.sh
38+
```
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
# Copyright (C) 2021 Intel Corporation
3+
# SPDX-License-Identifier: BSD-3-Clause
4+
5+
set -eux -o pipefail
6+
7+
if ! command -v aoc &> /dev/null
8+
then
9+
echo "Error: aoc could not be found on PATH"
10+
exit 1
11+
fi
12+
13+
scripthome=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
14+
AOCL_BOARD_PACKAGE_ROOT=$(readlink -f "$scripthome/../../board/a10_ref")
15+
export AOCL_BOARD_PACKAGE_ROOT
16+
17+
# First compile example.cl
18+
kernel='example'
19+
board='a10_ref_small'
20+
compile_arg='-cl-kernel-arg-info'
21+
compute_hash='f3effd06c681436a828f7e11c6c1b037807ddba0'
22+
src=$(readlink -f "$scripthome/../src/$kernel.cl")
23+
dest="$scripthome/$kernel.aocr"
24+
25+
aoc -rtl -tidy -board="$board" -hash="$compute_hash" "$src" "$compile_arg" -o "$dest"
26+
27+
# Then compile foo.cl
28+
kernel='foo'
29+
board='a10_ref_small'
30+
compile_arg=''
31+
compute_hash='7128ac1c937694f5b54a12229f19e4ca3a494c16'
32+
src=$(readlink -f "$scripthome/../src/$kernel.cl")
33+
dest="$scripthome/$kernel.aocr"
34+
35+
aoc -rtl -tidy -board="$board" -hash="$compute_hash" "$src" "$compile_arg" -o "$dest"
36+
37+
# Clean up
38+
rm -rf "$scripthome"/*.temp "$scripthome"/*.bc
575 KB
Binary file not shown.

test/example_binary/linux/foo.aocr

201 KB
Binary file not shown.

0 commit comments

Comments
 (0)