diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index c08e54d5a54e5..03a775e1b5b3f 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3714,7 +3714,15 @@ 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 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 // wrap an aocx file. @@ -3729,7 +3737,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..28c15c227fd75 100644 --- a/clang/test/Driver/sycl-offload-intelfpga.cpp +++ b/clang/test/Driver/sycl-offload-intelfpga.cpp @@ -145,6 +145,41 @@ // 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: 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]]" +// 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 \ diff --git a/sycl/test/fpga_tests/fpga_aocx.cpp b/sycl/test/fpga_tests/fpga_aocx.cpp new file mode 100644 index 0000000000000..b3293eeb10997 --- /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