From dad672eeeeedee1e86ecaba1e31860ebaf5ae11c Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Tue, 24 Mar 2020 15:56:55 -0700 Subject: [PATCH 1/5] [Driver][SYCL][FPGA] Adjust device and AOCX link order for FPGA 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 --- clang/lib/Driver/Driver.cpp | 9 +++++- clang/test/Driver/sycl-offload-intelfpga.cpp | 34 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index c08e54d5a54e5..42e554a7ee578 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3714,7 +3714,12 @@ class OffloadingActionBuilder final { auto *DeviceCheckAction = C.MakeAction(I, types::TY_Object); DeviceObjects.push_back(DeviceCheckAction); - } else { + continue; + } + // We want to move the AOCX/AOCR binary to the front of the objects + // allowing it to be picked up before the other device objects at + // runtime. + if (types::isFPGA(I->getType())) { // Do not perform a device link and only pass the aocr // file to the offline compilation before wrapping. Just // wrap an aocx file. @@ -3729,7 +3734,9 @@ class OffloadingActionBuilder final { C.MakeAction(I, types::TY_Object); DA.add(*DeviceWrappingAction, **TC, /*BoundArch=*/nullptr, Action::OFK_SYCL); + continue; } + DeviceObjects.push_back(I); } if (!DeviceObjects.empty()) { // When aocx or aocr is found, there is an expectation that none of diff --git a/clang/test/Driver/sycl-offload-intelfpga.cpp b/clang/test/Driver/sycl-offload-intelfpga.cpp index 254bf5552e4e6..478ecdc96723d 100644 --- a/clang/test/Driver/sycl-offload-intelfpga.cpp +++ b/clang/test/Driver/sycl-offload-intelfpga.cpp @@ -145,6 +145,40 @@ // CHK-FPGA-AOCX-LIN: ld{{.*}} "[[LIBINPUT]]" "[[LLCOUT]]" // CHK-FPGA-AOCX-WIN: link{{.*}} "[[LIBINPUT]]" "[[LLCOUT2]]" +/// AOCX with source +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %s %t_aocx.a -### 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-SRC,CHK-FPGA-AOCX-SRC-LIN %s +// RUN: %clang_cl -fsycl -fintelfpga %s %t_aocx.a -### 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-SRC,CHK-FPGA-AOCX-SRC-WIN %s +// CHK-FPGA-AOCX-SRC: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle" +// CHK-FPGA-AOCX-SRC: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]" +// CHK-FPGA-AOCX-SRC: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.(o|obj)]]" "[[WRAPOUT]]" +// CHK-FPGA-AOCX-SRC: llvm-link{{.*}} "-o" "[[LLVMLINKOUT:.+\.bc]]" "--suppress-warnings" +// CHK-FPGA-AOCX-SRC: llvm-spirv{{.*}} "-o" "[[LLVMSPVOUT:.+\.spv]]" {{.*}} "[[LLVMLINKOUT]]" +// CHK-FPGA-AOCX-SRC: clang-offload-wrapper{{.*}} "-o=[[WRAPOUTSRC:.+.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[LLVMSPVOUT]]" +// CHK-FPGA-AOCX-SRC: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUTSRC:.+\.(o|obj)]]" "[[WRAPOUTSRC]]" +// CHK-FPGA-AOCX-SRC: clang{{.*}} "-fsycl-is-host" {{.*}} "-o" "[[HOSTOBJ:.+\.(o|obj)]]" +// CHK-FPGA-AOCX-SRC-LIN: ld{{.*}} "[[HOSTOBJ]]" "[[LIBINPUT]]" "[[LLCOUT]]" "[[LLCOUTSRC]]" +// CHK-FPGA-AOCX-SRC-WIN: link{{.*}} "[[HOSTOBJ]]" "[[LIBINPUT]]" "[[LLCOUT]]" "[[LLCOUTSRC]]" + +/// AOCX with object +// RUN: touch %t.o +// RUN: %clangxx -target x86_64-unknown-linux-gnu -fsycl -fintelfpga %t.o %t_aocx.a -### 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-OBJ,CHK-FPGA-AOCX-OBJ-LIN %s +// RUN: %clang_cl -fsycl -fintelfpga %t.o %t_aocx.a -### 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHK-FPGA-AOCX-OBJ,CHK-FPGA-AOCX-OBJ-WIN %s +// CHK-FPGA-AOCX-OBJ: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle" +// CHK-FPGA-AOCX-OBJ: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]" +// CHK-FPGA-AOCX-OBJ: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.(o|obj)]]" "[[WRAPOUT]]" +// CHK-FPGA-AOCX-OBJ: clang-offload-bundler{{.*}} "-type=o" {{.*}} "-outputs=[[HOSTOBJ:.+\.(o|obj)]],[[DEVICEOBJ:.+\.(o|obj)]]" "-unbundle" + // CHK-FPGA-AOCX-OBJ: llvm-no-spir-kernel{{.*}} "[[DEVICEOBJ]]" "-o" "[[CHECKOUT:.+\.(o|obj)]]" +// CHK-FPGA-AOCX-OBJ: llvm-link{{.*}} "[[CHECKOUT]]" "-o" "[[LLVMLINKOUT:.+\.bc]]" "--suppress-warnings" +// CHK-FPGA-AOCX-OBJ: llvm-spirv{{.*}} "-o" "[[LLVMSPVOUT:.+\.spv]]" {{.*}} "[[LLVMLINKOUT]]" +// CHK-FPGA-AOCX-OBJ: clang-offload-wrapper{{.*}} "-o=[[WRAPOUTSRC:.+.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[LLVMSPVOUT]]" +// CHK-FPGA-AOCX-OBJ: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUTSRC:.+\.(o|obj)]]" "[[WRAPOUTSRC]]" +// CHK-FPGA-AOCX-OBJ-LIN: ld{{.*}} "[[HOSTOBJ]]" "[[LIBINPUT]]" "[[LLCOUT]]" "[[LLCOUTSRC]]" +// CHK-FPGA-AOCX-OBJ-WIN: link{{.*}} "[[HOSTOBJ]]" "[[LIBINPUT]]" "[[LLCOUT]]" "[[LLCOUTSRC]]" + /// -fintelfpga -fsycl-link from source // RUN: touch %t.cpp // RUN: %clangxx -### -target x86_64-unknown-linux-gnu -fsycl -fintelfpga -fsycl-link=early %t.cpp -ccc-print-phases 2>&1 \ From 90cee2923d4a798fdb5a4d551c2695eb49998c6e Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Tue, 24 Mar 2020 16:04:33 -0700 Subject: [PATCH 2/5] [NFC] whitespace cleanup Signed-off-by: Michael D Toguchi --- clang/test/Driver/sycl-offload-intelfpga.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Driver/sycl-offload-intelfpga.cpp b/clang/test/Driver/sycl-offload-intelfpga.cpp index 478ecdc96723d..60abc654cd401 100644 --- a/clang/test/Driver/sycl-offload-intelfpga.cpp +++ b/clang/test/Driver/sycl-offload-intelfpga.cpp @@ -171,7 +171,7 @@ // CHK-FPGA-AOCX-OBJ: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]" // CHK-FPGA-AOCX-OBJ: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.(o|obj)]]" "[[WRAPOUT]]" // CHK-FPGA-AOCX-OBJ: clang-offload-bundler{{.*}} "-type=o" {{.*}} "-outputs=[[HOSTOBJ:.+\.(o|obj)]],[[DEVICEOBJ:.+\.(o|obj)]]" "-unbundle" - // CHK-FPGA-AOCX-OBJ: llvm-no-spir-kernel{{.*}} "[[DEVICEOBJ]]" "-o" "[[CHECKOUT:.+\.(o|obj)]]" +// CHK-FPGA-AOCX-OBJ: llvm-no-spir-kernel{{.*}} "[[DEVICEOBJ]]" "-o" "[[CHECKOUT:.+\.(o|obj)]]" // CHK-FPGA-AOCX-OBJ: llvm-link{{.*}} "[[CHECKOUT]]" "-o" "[[LLVMLINKOUT:.+\.bc]]" "--suppress-warnings" // CHK-FPGA-AOCX-OBJ: llvm-spirv{{.*}} "-o" "[[LLVMSPVOUT:.+\.spv]]" {{.*}} "[[LLVMLINKOUT]]" // CHK-FPGA-AOCX-OBJ: clang-offload-wrapper{{.*}} "-o=[[WRAPOUTSRC:.+.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[LLVMSPVOUT]]" From 4f31cad5ea2d44be155ce2435c104bfa571c8be2 Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Wed, 25 Mar 2020 11:39:24 -0700 Subject: [PATCH 3/5] [NFC] Update src test to be more clear, amend comment Signed-off-by: Michael D Toguchi --- clang/lib/Driver/Driver.cpp | 7 +++++-- clang/test/Driver/sycl-offload-intelfpga.cpp | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 42e554a7ee578..03a775e1b5b3f 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3717,8 +3717,11 @@ class OffloadingActionBuilder final { continue; } // We want to move the AOCX/AOCR binary to the front of the objects - // allowing it to be picked up before the other device objects at - // runtime. + // allowing it to be picked up instead of the other device objects + // at runtime. + // TODO: In the presense of existing FPGA Device binaries (AOCX) + // we do not need to perform/add the SPIR-V generated device + // binaries from sources or objects. if (types::isFPGA(I->getType())) { // Do not perform a device link and only pass the aocr // file to the offline compilation before wrapping. Just diff --git a/clang/test/Driver/sycl-offload-intelfpga.cpp b/clang/test/Driver/sycl-offload-intelfpga.cpp index 60abc654cd401..28c15c227fd75 100644 --- a/clang/test/Driver/sycl-offload-intelfpga.cpp +++ b/clang/test/Driver/sycl-offload-intelfpga.cpp @@ -153,7 +153,8 @@ // CHK-FPGA-AOCX-SRC: clang-offload-bundler{{.*}} "-type=ao" "-targets=sycl-fpga_aocx-intel-unknown-sycldevice" "-inputs=[[LIBINPUT:.+\.a]]" "-outputs=[[BUNDLEOUT:.+\.aocx]]" "-unbundle" // CHK-FPGA-AOCX-SRC: clang-offload-wrapper{{.*}} "-o=[[WRAPOUT:.+\.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[BUNDLEOUT]]" // CHK-FPGA-AOCX-SRC: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUT:.+\.(o|obj)]]" "[[WRAPOUT]]" -// CHK-FPGA-AOCX-SRC: llvm-link{{.*}} "-o" "[[LLVMLINKOUT:.+\.bc]]" "--suppress-warnings" +// CHK-FPGA-AOCX-SRC: clang{{.*}} "-cc1" {{.*}} "-fsycl-is-device" {{.*}} "-o" "[[DEVICEBC:.+\.bc]]" +// CHK-FPGA-AOCX-SRC: llvm-link{{.*}} "[[DEVICEBC]]" "-o" "[[LLVMLINKOUT:.+\.bc]]" "--suppress-warnings" // CHK-FPGA-AOCX-SRC: llvm-spirv{{.*}} "-o" "[[LLVMSPVOUT:.+\.spv]]" {{.*}} "[[LLVMLINKOUT]]" // CHK-FPGA-AOCX-SRC: clang-offload-wrapper{{.*}} "-o=[[WRAPOUTSRC:.+.bc]]" {{.*}} "-target=spir64_fpga" "-kind=sycl" "[[LLVMSPVOUT]]" // CHK-FPGA-AOCX-SRC: llc{{.*}} "-filetype=obj" "-o" "[[LLCOUTSRC:.+\.(o|obj)]]" "[[WRAPOUTSRC]]" From 4c08106182216c5fe10de4e8b3d5332950df5b9d Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Fri, 27 Mar 2020 17:34:52 -0700 Subject: [PATCH 4/5] [NFC] Additional E2E test for aocx Signed-off-by: Michael D Toguchi --- sycl/test/fpga_tests/fpga_aocx.cpp | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 sycl/test/fpga_tests/fpga_aocx.cpp diff --git a/sycl/test/fpga_tests/fpga_aocx.cpp b/sycl/test/fpga_tests/fpga_aocx.cpp new file mode 100644 index 0000000000000..4711fd9668ad6 --- /dev/null +++ b/sycl/test/fpga_tests/fpga_aocx.cpp @@ -0,0 +1,59 @@ +//==----- fpga_aocx.cpp - AOT compilation for fpga using aoc with aocx -----==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: aoc, accelerator + +/// E2E test for AOCX creation/use/run for FPGA +// Produce an archive with device (AOCX) image +// RUN: %clangxx -fsycl -fintelfpga -fsycl-link=image -DDEVICE_PART %s -o %t_image.a +// Produce a host object +// RUN: %clangxx -fsycl -fintelfpga -DHOST_PART %s -c -o %t.o + +// AOCX with source +// RUN: %clangxx -fsycl -fintelfpga -DHOST_PART %s %t_image.a -o %t_aocx_src.out +// AOCX with object +// RUN: %clangxx -fsycl -fintelfpga %t.o %t_image.a -o %t_aocx_obj.out +// +// RUN: env SYCL_DEVICE_TYPE=ACC %t_aocx_src.out +// RUN: env SYCL_DEVICE_TYPE=ACC %t_aocx_obj.out + +#include "CL/sycl.hpp" +#include + +using namespace cl::sycl; + +#ifdef DEVICE_PART + +const double big[] = {3, 2, 1, 5, 6,7}; +void foo(double &result, queue q, int x) { + buffer buf(&result, 1); + buffer big_buf(big, sizeof(big) / sizeof(double)); + q.submit([&](handler& cgh) { + auto acc = buf.get_access(cgh); + auto big_acc = big_buf.get_access(cgh); + cgh.single_task([=]() { + acc[0] = big_acc[x]; + }); + }); +} + +#endif // DEVICE_PART + +#ifdef HOST_PART + +void foo(double &, queue q, int x); + +int main(void) { + queue q(accelerator_selector{});; + + double result; + foo(result, q, 3); + std::cout << "Result: " << result << "\n"; +} + +#endif // HOST_PART From 336de4de2785332e6836aed88e947308694b73a1 Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Fri, 27 Mar 2020 17:40:11 -0700 Subject: [PATCH 5/5] [NFC] formatting update Signed-off-by: Michael D Toguchi --- sycl/test/fpga_tests/fpga_aocx.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sycl/test/fpga_tests/fpga_aocx.cpp b/sycl/test/fpga_tests/fpga_aocx.cpp index 4711fd9668ad6..b3293eeb10997 100644 --- a/sycl/test/fpga_tests/fpga_aocx.cpp +++ b/sycl/test/fpga_tests/fpga_aocx.cpp @@ -29,15 +29,15 @@ using namespace cl::sycl; #ifdef DEVICE_PART -const double big[] = {3, 2, 1, 5, 6,7}; +const double big[] = {3, 2, 1, 5, 6, 7}; void foo(double &result, queue q, int x) { buffer buf(&result, 1); buffer big_buf(big, sizeof(big) / sizeof(double)); - q.submit([&](handler& cgh) { + q.submit([&](handler &cgh) { auto acc = buf.get_access(cgh); auto big_acc = big_buf.get_access(cgh); cgh.single_task([=]() { - acc[0] = big_acc[x]; + acc[0] = big_acc[x]; }); }); } @@ -49,7 +49,7 @@ void foo(double &result, queue q, int x) { void foo(double &, queue q, int x); int main(void) { - queue q(accelerator_selector{});; + queue q(accelerator_selector{}); double result; foo(result, q, 3);