Skip to content

Commit f117aa4

Browse files
mdtoguchiArtem Gindinsonsergey-semenov
authored
[Driver][SYCL][FPGA] Improve expected triple and link behaviors for AOCX files (#1549)
When performing -fsycl-link=image behaviors on Windows, there was a mismatch of triples being used when checking for existence of the AOCX binary. This caused a problem when using clang-cl as the triples do not properly match. We also do not want to do any additional unbundling of any AOCX archive, which was causing a conflict of expected FPGA archives. Signed-off-by: Michael D Toguchi <[email protected]> Co-authored-by: Artem Gindinson <[email protected]> Co-authored-by: Sergey Semenov <[email protected]>
1 parent cf77e41 commit f117aa4

File tree

7 files changed

+105
-48
lines changed

7 files changed

+105
-48
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,12 +2534,18 @@ static bool runBundler(const SmallVectorImpl<StringRef> &BundlerArgs,
25342534

25352535
bool hasFPGABinary(Compilation &C, std::string Object, types::ID Type) {
25362536
assert(types::isFPGA(Type) && "unexpected Type for FPGA binary check");
2537+
// Do not do the check if the file doesn't exist
2538+
if (!llvm::sys::fs::exists(Object))
2539+
return false;
2540+
25372541
// Temporary names for the output.
25382542
llvm::Triple TT;
25392543
TT.setArchName(types::getTypeName(Type));
25402544
TT.setVendorName("intel");
25412545
TT.setOS(llvm::Triple::UnknownOS);
25422546
TT.setEnvironment(llvm::Triple::SYCLDevice);
2547+
if (C.getDriver().IsCLMode())
2548+
TT.setObjectFormat(llvm::Triple::COFF);
25432549

25442550
// Checking uses -check-section option with the input file, no output
25452551
// file and the target triple being looked for.
@@ -4794,6 +4800,10 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
47944800
// archive unbundling for Windows.
47954801
if (!isStaticArchiveFile(LA))
47964802
continue;
4803+
// FPGA AOCX files are archives, but we do not want to unbundle them here
4804+
// as they have already been unbundled and processed for linking.
4805+
if (hasFPGABinary(C, LA.str(), types::TY_FPGA_AOCX))
4806+
continue;
47974807
// In MSVC environment offload-static-libs are handled slightly different
47984808
// because of missing support for partial linking in the linker. We add an
47994809
// unbundling action for each static archive which produces list files with

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7282,6 +7282,8 @@ void OffloadBundler::ConstructJobMultipleOutputs(
72827282
TT.setVendorName("intel");
72837283
TT.setOS(getToolChain().getTriple().getOS());
72847284
TT.setEnvironment(llvm::Triple::SYCLDevice);
7285+
if (C.getDriver().IsCLMode())
7286+
TT.setObjectFormat(llvm::Triple::COFF);
72857287
Triples += "sycl-";
72867288
Triples += TT.normalize();
72877289
} else if (getToolChain().getTriple().getSubArch() !=

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

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,12 @@
126126
// RUN: clang-offload-wrapper -o %t-aocx.bc -host=x86_64-unknown-linux-gnu -kind=sycl -target=fpga_aocx-intel-unknown-sycldevice %t.aocx
127127
// RUN: llc -filetype=obj -o %t-aocx.o %t-aocx.bc
128128
// RUN: llvm-ar crv %t_aocx.a %t.o %t-aocx.o
129+
// RUN: clang-offload-wrapper -o %t-aocx_cl.bc -host=x86_64-unknown-linux-gnu -kind=sycl -target=fpga_aocx-intel-unknown-sycldevice-coff %t.aocx
130+
// RUN: llc -filetype=obj -o %t-aocx_cl.o %t-aocx_cl.bc
131+
// RUN: llvm-ar crv %t_aocx_cl.a %t.o %t-aocx_cl.o
129132
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t_aocx.a -ccc-print-phases 2>&1 \
130133
// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-PHASES %s
131-
// RUN: %clang_cl -fsycl -fintelfpga %t_aocx.a -ccc-print-phases 2>&1 \
134+
// RUN: %clang_cl -fsycl -fintelfpga %t_aocx_cl.a -ccc-print-phases 2>&1 \
132135
// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-PHASES %s
133136
// CHK-FPGA-AOCX-PHASES: 0: input, "{{.*}}", fpga_aocx, (host-sycl)
134137
// CHK-FPGA-AOCX-PHASES: 1: linker, {0}, image, (host-sycl)
@@ -138,21 +141,24 @@
138141

139142
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t_aocx.a -### 2>&1 \
140143
// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX,CHK-FPGA-AOCX-LIN %s
141-
// RUN: %clang_cl -fsycl -fintelfpga %t_aocx.a -### 2>&1 \
144+
// RUN: %clang_cl -fsycl -fintelfpga %t_aocx_cl.a -### 2>&1 \
142145
// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX,CHK-FPGA-AOCX-WIN %s
143-
// CHK-FPGA-AOCX: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
146+
// CHK-FPGA-AOCX-LIN: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
147+
// CHK-FPGA-AOCX-WIN: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice-coff" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
144148
// CHK-FPGA-AOCX: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]"
145149
// CHK-FPGA-AOCX-LIN: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.o]]" "[[WRAPOUT]]"
146150
// CHK-FPGA-AOCX-WIN: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT2:.+\.obj]]" "[[WRAPOUT]]"
151+
// CHK-FPGA-AOCX-NOT: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice{{(-coff)?}}"
147152
// CHK-FPGA-AOCX-LIN: ld{{.*}} "[[LIBINPUT]]" "[[LLCOUT]]"
148153
// CHK-FPGA-AOCX-WIN: link{{.*}} "[[LIBINPUT]]" "[[LLCOUT2]]"
149154

150155
/// AOCX with source
151156
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %s %t_aocx.a -### 2>&1 \
152157
// 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 \
158+
// RUN: %clang_cl -fsycl -fintelfpga %s %t_aocx_cl.a -### 2>&1 \
154159
// 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"
160+
// CHK-FPGA-AOCX-SRC-LIN: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
161+
// CHK-FPGA-AOCX-SRC-WIN: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice-coff" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
156162
// CHK-FPGA-AOCX-SRC: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]"
157163
// CHK-FPGA-AOCX-SRC: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.(o|obj)]]" "[[WRAPOUT]]"
158164
// CHK-FPGA-AOCX-SRC: clang{{.*}} "-cc1" {{.*}} "-fsycl-is-device" {{.*}} "-o" "[[DEVICEBC:.+\.bc]]"
@@ -168,9 +174,10 @@
168174
// RUN: touch %t.o
169175
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t.o %t_aocx.a -### 2>&1 \
170176
// 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 \
177+
// RUN: %clang_cl -fsycl -fintelfpga %t.o %t_aocx_cl.a -### 2>&1 \
172178
// 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"
179+
// CHK-FPGA-AOCX-OBJ-LIN: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
180+
// CHK-FPGA-AOCX-OBJ-WIN: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice-coff" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle"
174181
// CHK-FPGA-AOCX-OBJ: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]"
175182
// CHK-FPGA-AOCX-OBJ: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.(o|obj)]]" "[[WRAPOUT]]"
176183
// CHK-FPGA-AOCX-OBJ: clang-offload-bundler{{.*}} "-type=o" {{.*}} "-outputs=[[HOSTOBJ:.+\.(o|obj)]],[[DEVICEOBJ:.+\.(o|obj)]]" "-unbundle"
@@ -332,8 +339,10 @@
332339
// RUN: %clang_cl -fsycl -c -o %t2_cl.o %t2.c
333340
// RUN: clang-offload-wrapper -o %t-aoco.bc -host=x86_64-unknown-linux-gnu -kind=sycl -target=fpga_aoco-intel-unknown-sycldevice %t.aoco
334341
// RUN: llc -filetype=obj -o %t-aoco.o %t-aoco.bc
342+
// RUN: clang-offload-wrapper -o %t-aoco_cl.bc -host=x86_64-unknown-linux-gnu -kind=sycl -target=fpga_aoco-intel-unknown-sycldevice-coff %t.aoco
343+
// RUN: llc -filetype=obj -o %t-aoco_cl.o %t-aoco_cl.bc
335344
// RUN: llvm-ar crv %t_aoco.a %t.o %t2.o %t-aoco.o
336-
// RUN: llvm-ar crv %t_aoco_cl.a %t.o %t2_cl.o %t-aoco.o
345+
// RUN: llvm-ar crv %t_aoco_cl.a %t.o %t2_cl.o %t-aoco_cl.o
337346
// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -foffload-static-lib=%t_aoco.a %s -### -ccc-print-phases 2>&1 \
338347
// RUN: | FileCheck -check-prefix=CHK-FPGA-AOCO-PHASES %s
339348
// CHK-FPGA-AOCO-PHASES: 0: input, "[[INPUTA:.+\.a]]", object, (host-sycl)
@@ -403,7 +412,8 @@
403412
// CHK-FPGA-AOCO: llvm-link{{.*}} "@{{.*}}" "-o" "[[LINKEDBC:.+\.bc]]"
404413
// CHK-FPGA-AOCO: sycl-post-link{{.*}} "-ir-output-only" "-spec-const=default" "-o" "[[PLINKEDBC:.+\.bc]]" "[[LINKEDBC]]"
405414
// CHK-FPGA-AOCO: llvm-spirv{{.*}} "-o" "[[TARGSPV:.+\.spv]]" {{.*}} "[[PLINKEDBC]]"
406-
// CHK-FPGA-AOCO: clang-offload-bundler{{.*}} "-type=aoo" "-targets=sycl-fpga_aoco-intel-unknown-sycldevice" "-inputs=[[INPUTLIB]]" "-outputs=[[AOCOLIST:.+\.txt]]" "-unbundle"
415+
// CHK-FPGA-AOCO-LIN: clang-offload-bundler{{.*}} "-type=aoo" "-targets=sycl-fpga_aoco-intel-unknown-sycldevice" "-inputs=[[INPUTLIB]]" "-outputs=[[AOCOLIST:.+\.txt]]" "-unbundle"
416+
// CHK-FPGA-AOCO-WIN: clang-offload-bundler{{.*}} "-type=aoo" "-targets=sycl-fpga_aoco-intel-unknown-sycldevice-coff" "-inputs=[[INPUTLIB]]" "-outputs=[[AOCOLIST:.+\.txt]]" "-unbundle"
407417
// CHK-FPGA-AOCO: aoc{{.*}} "-o" "[[AOCXOUT:.+\.aocx]]" "[[TARGSPV]]" "-library-list=[[AOCOLIST]]" "-sycl"
408418
// CHK-FPGA-AOCO: clang-offload-wrapper{{.*}} "-o=[[FINALBC:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[AOCXOUT]]"
409419
// CHK-FPGA-AOCO-LIN: llc{{.*}} "-filetype=obj" "-o" "[[FINALOBJL:.+\.o]]" "[[FINALBC]]"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//==--------------- fpga_device.cpp - AOT compilation for fpga -------------==//
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+
#include "CL/sycl.hpp"
10+
11+
using namespace cl::sycl;
12+
13+
const double big[] = {3, 2, 1, 5, 6, 7};
14+
void foo(double &result, queue q, int x) {
15+
buffer<double> buf(&result, 1);
16+
buffer<double, 1> big_buf(big, sizeof(big) / sizeof(double));
17+
q.submit([&](handler &cgh) {
18+
auto acc = buf.get_access<access::mode::discard_write>(cgh);
19+
auto big_acc = big_buf.get_access<access::mode::read>(cgh);
20+
cgh.single_task<class test>([=]() {
21+
acc[0] = big_acc[x];
22+
});
23+
});
24+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//==--------------- fpga_host.cpp - AOT compilation for fpga ---------------==//
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+
#include "CL/sycl.hpp"
10+
#include <cassert>
11+
12+
using namespace cl::sycl;
13+
14+
void foo(double &, queue q, int x);
15+
16+
int main(void) {
17+
queue q(accelerator_selector{});
18+
19+
double result;
20+
foo(result, q, 3);
21+
assert(result == 5);
22+
return 0;
23+
}

sycl/test/fpga_tests/fpga_aocx.cpp

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,50 +10,14 @@
1010

1111
/// E2E test for AOCX creation/use/run for FPGA
1212
// Produce an archive with device (AOCX) image
13-
// RUN: %clangxx -fsycl -fintelfpga -fsycl-link=image -DDEVICE_PART %s -o %t_image.a
13+
// RUN: %clangxx -fsycl -fintelfpga -fsycl-link=image %S/Inputs/fpga_device.cpp -o %t_image.a
1414
// Produce a host object
15-
// RUN: %clangxx -fsycl -fintelfpga -DHOST_PART %s -c -o %t.o
15+
// RUN: %clangxx -fsycl -fintelfpga %S/Inputs/fpga_host.cpp -c -o %t.o
1616

1717
// AOCX with source
18-
// RUN: %clangxx -fsycl -fintelfpga -DHOST_PART %s %t_image.a -o %t_aocx_src.out
18+
// RUN: %clangxx -fsycl -fintelfpga %S/Inputs/fpga_host.cpp %t_image.a -o %t_aocx_src.out
1919
// AOCX with object
2020
// RUN: %clangxx -fsycl -fintelfpga %t.o %t_image.a -o %t_aocx_obj.out
2121
//
2222
// RUN: env SYCL_DEVICE_TYPE=ACC %t_aocx_src.out
2323
// 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
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//==--- fpga_aocx_win.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+
// REQUIRES: system-windows
11+
12+
/// E2E test for AOCX creation/use/run for FPGA
13+
// Produce an archive with device (AOCX) image
14+
// RUN: %clang_cl -fsycl -fintelfpga -fsycl-link=image %S/Inputs/fpga_device.cpp -o %t_image.lib
15+
// Produce a host object
16+
// RUN: %clang_cl -fsycl -fintelfpga -DHOST_PART %S/Inputs/fpga_host.cpp -c -o %t.obj
17+
18+
// AOCX with source
19+
// RUN: %clang_cl -fsycl -fintelfpga -DHOST_PART %S/Inputs/fpga_host.cpp %t_image.lib -o %t_aocx_src.out
20+
// AOCX with object
21+
// RUN: %clang_cl -fsycl -fintelfpga %t.obj %t_image.lib -o %t_aocx_obj.out
22+
//
23+
// RUN: env SYCL_DEVICE_TYPE=ACC %t_aocx_src.out
24+
// RUN: env SYCL_DEVICE_TYPE=ACC %t_aocx_obj.out

0 commit comments

Comments
 (0)