Skip to content

Commit ba404be

Browse files
authored
[Driver][SYCL][FPGA] Adjust device and AOCX link order for FPGA (#1389)
When compiling with -fintelfpga, a user can provide an -fsycl-link=image created aocx based binary/archive. When linked in, this archive should get precedence over any other device object that is extracted from object or generated from source to ensure the proper binary is grabbed at runtime. Signed-off-by: Michael D Toguchi <michael.d.toguchi@intel.com>
1 parent 8845263 commit ba404be

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3714,7 +3714,15 @@ class OffloadingActionBuilder final {
37143714
auto *DeviceCheckAction =
37153715
C.MakeAction<SPIRCheckJobAction>(I, types::TY_Object);
37163716
DeviceObjects.push_back(DeviceCheckAction);
3717-
} else {
3717+
continue;
3718+
}
3719+
// We want to move the AOCX/AOCR binary to the front of the objects
3720+
// allowing it to be picked up instead of the other device objects
3721+
// at runtime.
3722+
// TODO: In the presense of existing FPGA Device binaries (AOCX)
3723+
// we do not need to perform/add the SPIR-V generated device
3724+
// binaries from sources or objects.
3725+
if (types::isFPGA(I->getType())) {
37183726
// Do not perform a device link and only pass the aocr
37193727
// file to the offline compilation before wrapping. Just
37203728
// wrap an aocx file.
@@ -3729,7 +3737,9 @@ class OffloadingActionBuilder final {
37293737
C.MakeAction<OffloadWrapperJobAction>(I, types::TY_Object);
37303738
DA.add(*DeviceWrappingAction, **TC, /*BoundArch=*/nullptr,
37313739
Action::OFK_SYCL);
3740+
continue;
37323741
}
3742+
DeviceObjects.push_back(I);
37333743
}
37343744
if (!DeviceObjects.empty()) {
37353745
// When aocx or aocr is found, there is an expectation that none of

clang/test/Driver/sycl-offload-intelfpga.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,41 @@
147147
// CHK-FPGA-AOCX-LIN: ld{{.*}} "[[LIBINPUT]]" "[[LLCOUT]]"
148148
// CHK-FPGA-AOCX-WIN: link{{.*}} "[[LIBINPUT]]" "[[LLCOUT2]]"
149149

150+
/// AOCX with source
151+
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %s %t_aocx.a -### 2>&1 \
152+
// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-SRC,CHK-FPGA-AOCX-SRC-LIN %s
153+
// RUN: %clang_cl -fsycl -fintelfpga %s %t_aocx.a -### 2>&1 \
154+
// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-SRC,CHK-FPGA-AOCX-SRC-WIN %s
155+
// CHK-FPGA-AOCX-SRC: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
156+
// CHK-FPGA-AOCX-SRC: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]"
157+
// CHK-FPGA-AOCX-SRC: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.(o|obj)]]" "[[WRAPOUT]]"
158+
// CHK-FPGA-AOCX-SRC: clang{{.*}} "-cc1" {{.*}} "-fsycl-is-device" {{.*}} "-o" "[[DEVICEBC:.+\.bc]]"
159+
// CHK-FPGA-AOCX-SRC: llvm-link{{.*}} "[[DEVICEBC]]" "-o" "[[LLVMLINKOUT:.+\.bc]]" "--suppress-warnings"
160+
// CHK-FPGA-AOCX-SRC: llvm-spirv{{.*}} "-o" "[[LLVMSPVOUT:.+\.spv]]" {{.*}} "[[LLVMLINKOUT]]"
161+
// CHK-FPGA-AOCX-SRC: clang-offload-wrapper{{.*}} "-o=[[WRAPOUTSRC:.+.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[LLVMSPVOUT]]"
162+
// CHK-FPGA-AOCX-SRC: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUTSRC:.+\.(o|obj)]]" "[[WRAPOUTSRC]]"
163+
// CHK-FPGA-AOCX-SRC: clang{{.*}} "-fsycl-is-host" {{.*}} "-o" "[[HOSTOBJ:.+\.(o|obj)]]"
164+
// CHK-FPGA-AOCX-SRC-LIN: ld{{.*}} "[[HOSTOBJ]]" "[[LIBINPUT]]" "[[LLCOUT]]" "[[LLCOUTSRC]]"
165+
// CHK-FPGA-AOCX-SRC-WIN: link{{.*}} "[[HOSTOBJ]]" "[[LIBINPUT]]" "[[LLCOUT]]" "[[LLCOUTSRC]]"
166+
167+
/// AOCX with object
168+
// RUN: touch %t.o
169+
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t.o %t_aocx.a -### 2>&1 \
170+
// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-OBJ,CHK-FPGA-AOCX-OBJ-LIN %s
171+
// RUN: %clang_cl -fsycl -fintelfpga %t.o %t_aocx.a -### 2>&1 \
172+
// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-OBJ,CHK-FPGA-AOCX-OBJ-WIN %s
173+
// CHK-FPGA-AOCX-OBJ: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
174+
// CHK-FPGA-AOCX-OBJ: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]"
175+
// CHK-FPGA-AOCX-OBJ: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.(o|obj)]]" "[[WRAPOUT]]"
176+
// CHK-FPGA-AOCX-OBJ: clang-offload-bundler{{.*}} "-type=o" {{.*}} "-outputs=[[HOSTOBJ:.+\.(o|obj)]],[[DEVICEOBJ:.+\.(o|obj)]]" "-unbundle"
177+
// CHK-FPGA-AOCX-OBJ: llvm-no-spir-kernel{{.*}} "[[DEVICEOBJ]]" "-o" "[[CHECKOUT:.+\.(o|obj)]]"
178+
// CHK-FPGA-AOCX-OBJ: llvm-link{{.*}} "[[CHECKOUT]]" "-o" "[[LLVMLINKOUT:.+\.bc]]" "--suppress-warnings"
179+
// CHK-FPGA-AOCX-OBJ: llvm-spirv{{.*}} "-o" "[[LLVMSPVOUT:.+\.spv]]" {{.*}} "[[LLVMLINKOUT]]"
180+
// CHK-FPGA-AOCX-OBJ: clang-offload-wrapper{{.*}} "-o=[[WRAPOUTSRC:.+.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[LLVMSPVOUT]]"
181+
// CHK-FPGA-AOCX-OBJ: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUTSRC:.+\.(o|obj)]]" "[[WRAPOUTSRC]]"
182+
// CHK-FPGA-AOCX-OBJ-LIN: ld{{.*}} "[[HOSTOBJ]]" "[[LIBINPUT]]" "[[LLCOUT]]" "[[LLCOUTSRC]]"
183+
// CHK-FPGA-AOCX-OBJ-WIN: link{{.*}} "[[HOSTOBJ]]" "[[LIBINPUT]]" "[[LLCOUT]]" "[[LLCOUTSRC]]"
184+
150185
/// -fintelfpga -fsycl-link from source
151186
// RUN: touch %t.cpp
152187
// RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \

sycl/test/fpga_tests/fpga_aocx.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//==----- fpga_aocx.cpp - AOT compilation for fpga using aoc with aocx -----==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// REQUIRES: aoc, accelerator
10+
11+
/// E2E test for AOCX creation/use/run for FPGA
12+
// Produce an archive with device (AOCX) image
13+
// RUN: %clangxx -fsycl -fintelfpga -fsycl-link=image -DDEVICE_PART %s -o %t_image.a
14+
// Produce a host object
15+
// RUN: %clangxx -fsycl -fintelfpga -DHOST_PART %s -c -o %t.o
16+
17+
// AOCX with source
18+
// RUN: %clangxx -fsycl -fintelfpga -DHOST_PART %s %t_image.a -o %t_aocx_src.out
19+
// AOCX with object
20+
// RUN: %clangxx -fsycl -fintelfpga %t.o %t_image.a -o %t_aocx_obj.out
21+
//
22+
// RUN: env SYCL_DEVICE_TYPE=ACC %t_aocx_src.out
23+
// RUN: env SYCL_DEVICE_TYPE=ACC %t_aocx_obj.out
24+
25+
#include "CL/sycl.hpp"
26+
#include <iostream>
27+
28+
using namespace cl::sycl;
29+
30+
#ifdef DEVICE_PART
31+
32+
const double big[] = {3, 2, 1, 5, 6, 7};
33+
void foo(double &result, queue q, int x) {
34+
buffer<double> buf(&result, 1);
35+
buffer<double, 1> big_buf(big, sizeof(big) / sizeof(double));
36+
q.submit([&](handler &cgh) {
37+
auto acc = buf.get_access<access::mode::discard_write>(cgh);
38+
auto big_acc = big_buf.get_access<access::mode::read>(cgh);
39+
cgh.single_task<class test>([=]() {
40+
acc[0] = big_acc[x];
41+
});
42+
});
43+
}
44+
45+
#endif // DEVICE_PART
46+
47+
#ifdef HOST_PART
48+
49+
void foo(double &, queue q, int x);
50+
51+
int main(void) {
52+
queue q(accelerator_selector{});
53+
54+
double result;
55+
foo(result, q, 3);
56+
std::cout << "Result: " << result << "\n";
57+
}
58+
59+
#endif // HOST_PART

0 commit comments

Comments
 (0)