Skip to content

[SYCL] Link SYCL device libraries by default. #2400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 73 additions & 6 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2714,6 +2714,14 @@ static SmallVector<const char *, 16> getLinkerArgs(Compilation &C,
return LibArgs;
}

static bool IsSYCLDeviceLibObj(std::string ObjFilePath) {
StringRef ObjFileName = llvm::sys::path::filename(ObjFilePath);
bool Ret = (ObjFileName.startswith("libsycl-") && ObjFileName.endswith(".o"))
? true
: false;
return Ret;
}

// Goes through all of the arguments, including inputs expected for the
// linker directly, to determine if we need to perform additional work for
// static offload libraries.
Expand Down Expand Up @@ -3789,7 +3797,10 @@ class OffloadingActionBuilder final {
if (IA->getType() == types::TY_Object) {
if (!isObjectFile(FileName))
return ABRT_Inactive;
if (Args.hasArg(options::OPT_fintelfpga))
// For SYCL device libraries, don't need to add them to
// FPGAObjectInputs as there is no fpga dep files inside.
if (Args.hasArg(options::OPT_fintelfpga) &&
!IsSYCLDeviceLibObj(FileName))
FPGAObjectInputs.push_back(IA);
}
// When creating FPGA device fat objects, all host objects are
Expand Down Expand Up @@ -3853,6 +3864,53 @@ class OffloadingActionBuilder final {
SYCLDeviceActions.clear();
}

void addSYCLDeviceLibs(const ToolChain *TC, ActionList &DeviceLinkObjects,
bool isSpirvAOT, bool isMSVCEnv) {
enum SYCLDeviceLibType {
sycl_devicelib_wrapper,
sycl_devicelib_fallback
};
StringRef LibLoc, LibSysUtils;
if (isMSVCEnv) {
LibLoc = Args.MakeArgString(TC->getDriver().Dir + "/../bin");
LibSysUtils = "libsycl-msvc";
} else {
LibLoc = Args.MakeArgString(TC->getDriver().Dir + "/../lib");
LibSysUtils = "libsycl-glibc";
}
SmallVector<StringRef, 4> sycl_device_wrapper_libs = {
LibSysUtils, "libsycl-complex", "libsycl-complex-fp64",
"libsycl-cmath", "libsycl-cmath-fp64"};
// For AOT compilation, we need to link sycl_device_fallback_libs as
// default too.
SmallVector<StringRef, 4> sycl_device_fallback_libs = {
"libsycl-fallback-cassert", "libsycl-fallback-complex",
"libsycl-fallback-complex-fp64", "libsycl-fallback-cmath",
"libsycl-fallback-cmath-fp64"};
auto addInputs = [&](SYCLDeviceLibType t) {
auto sycl_libs = (t == sycl_devicelib_wrapper)
? sycl_device_wrapper_libs
: sycl_device_fallback_libs;
for (const StringRef &Lib : sycl_libs) {
SmallString<128> LibName(LibLoc);
llvm::sys::path::append(LibName, Lib);
llvm::sys::path::replace_extension(LibName, ".o");
Arg *InputArg = MakeInputArg(Args, C.getDriver().getOpts(),
Args.MakeArgString(LibName));
auto *SYCLDeviceLibsInputAction =
C.MakeAction<InputAction>(*InputArg, types::TY_Object);
auto *SYCLDeviceLibsUnbundleAction =
C.MakeAction<OffloadUnbundlingJobAction>(
SYCLDeviceLibsInputAction);
addDeviceDepences(SYCLDeviceLibsUnbundleAction);
DeviceLinkObjects.push_back(SYCLDeviceLibsUnbundleAction);
}
};
addInputs(sycl_devicelib_wrapper);
if (isSpirvAOT)
addInputs(sycl_devicelib_fallback);
}

void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {
assert(ToolChains.size() == DeviceLinkerInputs.size() &&
"Toolchains and linker inputs sizes do not match.");
Expand Down Expand Up @@ -3932,13 +3990,27 @@ class OffloadingActionBuilder final {
}
ActionList DeviceLibObjects;
ActionList LinkObjects;
auto TT = SYCLTripleList[I];
auto isNVPTX = (*TC)->getTriple().isNVPTX();
bool isSpirvAOT = TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
TT.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
TT.getSubArch() == llvm::Triple::SPIRSubArch_x86_64;
for (const auto &Input : LI) {
// FPGA aoco does not go through the link, everything else does.
if (Input->getType() == types::TY_FPGA_AOCO)
DeviceLibObjects.push_back(Input);
else
LinkObjects.push_back(Input);
}
// FIXME: Link all wrapper and fallback device libraries as default,
// When spv online link is supported by all backends, the fallback
// device libraries are only needed when current toolchain is using
// AOT compilation.
if (!isNVPTX) {
addSYCLDeviceLibs(
*TC, LinkObjects, true,
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment());
}
// The linkage actions subgraph leading to the offload wrapper.
// [cond] Means incoming/outgoing dependence is created only when cond
// is true. A function of:
Expand Down Expand Up @@ -3993,7 +4065,6 @@ class OffloadingActionBuilder final {
Action *DeviceLinkAction =
C.MakeAction<LinkJobAction>(LinkObjects, types::TY_LLVM_BC);
// setup some flags upfront
auto isNVPTX = (*TC)->getTriple().isNVPTX();

if (isNVPTX && DeviceCodeSplit) {
// TODO Temporary limitation, need to support code splitting for PTX
Expand All @@ -4005,10 +4076,6 @@ class OffloadingActionBuilder final {
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< OptName << (*TC)->getTriple().str();
}
auto TT = SYCLTripleList[I];
bool isSpirvAOT = TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
TT.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
TT.getSubArch() == llvm::Triple::SPIRSubArch_x86_64;
// reflects whether current target is ahead-of-time and can't support
// runtime setting of specialization constants
bool isAOT = isNVPTX || isSpirvAOT;
Expand Down
7 changes: 5 additions & 2 deletions sycl/source/detail/program_manager/program_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,12 @@ RT::PiProgram ProgramManager::getBuiltPIProgram(OSModuleHandle M,
// If device image is not SPIR-V, DeviceLibReqMask will be 0 which means
// no fallback device library will be linked.
uint32_t DeviceLibReqMask = 0;
if (Img.getFormat() == PI_DEVICE_BINARY_TYPE_SPIRV &&
// FIXME: disable the fallback device libraries online link as not all
// backend supports spv online link. Need to enable it when all backends
// support spv online link.
/* if (Img.getFormat() == PI_DEVICE_BINARY_TYPE_SPIRV &&
!SYCLConfig<SYCL_DEVICELIB_NO_FALLBACK>::get())
DeviceLibReqMask = getDeviceLibReqMask(Img);
DeviceLibReqMask = getDeviceLibReqMask(Img); */

ProgramPtr BuiltProgram =
build(std::move(ProgramManaged), ContextImpl, Img.getCompileOptions(),
Expand Down
2 changes: 1 addition & 1 deletion sycl/test/devicelib/assert-aot.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// REQUIRES: opencl-aot, cpu, linux

// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/assert.cpp %sycl_libs_dir/libsycl-glibc.o %sycl_libs_dir/libsycl-fallback-cassert.o -o %t.aot.out
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/assert.cpp -o %t.aot.out
// RUN: %CPU_RUN_PLACEHOLDER %t.aot.out >%t.aot.msg
// RUN: FileCheck %S/assert.cpp --input-file %t.aot.msg --check-prefixes=CHECK-MESSAGE
3 changes: 1 addition & 2 deletions sycl/test/devicelib/assert-windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
// Disable the test until the fix reaches SYCL test infrastructure.
// XFAIL: *
//
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/../bin/libsycl-msvc.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
//
// MSVC implementation of assert does not call an unreachable built-in, so the
// program doesn't terminate when fallback is used.
Expand Down
3 changes: 1 addition & 2 deletions sycl/test/devicelib/assert.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// REQUIRES: cpu,linux
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-glibc.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// (see the other RUN lines below; it is a bit complicated)
//
// assert() call in device code guarantees nothing: on some devices it behaves
Expand Down
8 changes: 4 additions & 4 deletions sycl/test/devicelib/cmath-aot.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// REQUIRES: opencl-aot, cpu
// UNSUPPORTED: windows

// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/cmath_test.cpp %sycl_libs_dir/libsycl-cmath.o %sycl_libs_dir/libsycl-fallback-cmath.o -o %t.cmath.out
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/cmath_test.cpp -o %t.cmath.out
// RUN: %CPU_RUN_PLACEHOLDER %t.cmath.out

// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/cmath_fp64_test.cpp %sycl_libs_dir/libsycl-cmath-fp64.o %sycl_libs_dir/libsycl-fallback-cmath-fp64.o -o %t.cmath.fp64.out
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/cmath_fp64_test.cpp -o %t.cmath.fp64.out
// RUN: %CPU_RUN_PLACEHOLDER %t.cmath.fp64.out

// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/std_complex_math_test.cpp %sycl_libs_dir/libsycl-complex.o %sycl_libs_dir/libsycl-cmath.o %sycl_libs_dir/libsycl-fallback-complex.o %sycl_libs_dir/libsycl-fallback-cmath.o -o %t.complex.out
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/std_complex_math_test.cpp -o %t.complex.out
// RUN: %CPU_RUN_PLACEHOLDER %t.complex.out

// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/std_complex_math_fp64_test.cpp %sycl_libs_dir/libsycl-complex-fp64.o %sycl_libs_dir/libsycl-cmath-fp64.o %sycl_libs_dir/libsycl-fallback-complex-fp64.o %sycl_libs_dir/libsycl-fallback-cmath-fp64.o -o %t.complex.fp64.out
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64-unknown-unknown-sycldevice %S/std_complex_math_fp64_test.cpp -o %t.complex.fp64.out
// RUN: %CPU_RUN_PLACEHOLDER %t.complex.fp64.out
3 changes: 1 addition & 2 deletions sycl/test/devicelib/cmath_fp64_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// UNSUPPORTED: windows
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-cmath-fp64.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Expand Down
3 changes: 1 addition & 2 deletions sycl/test/devicelib/cmath_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// UNSUPPORTED: windows
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-cmath.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Expand Down
15 changes: 15 additions & 0 deletions sycl/test/devicelib/complex-fpga.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//==----- accelerator.cpp - AOT compilation for fpga devices using aoc ----==//
//
// 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

// RUN: %clangxx -fsycl -fsycl-targets=spir64_fpga-unknown-unknown-sycldevice %S/std_complex_math_test.cpp -o %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out

// RUN: %clangxx -fsycl -fintelfpga %S/std_complex_math_test.cpp -o %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
3 changes: 1 addition & 2 deletions sycl/test/devicelib/math_fp64_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// REQUIRES: cpu, linux
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-cmath-fp64.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Expand Down
3 changes: 1 addition & 2 deletions sycl/test/devicelib/math_fp64_windows_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// REQUIRES: cpu, windows
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/../bin/libsycl-cmath-fp64.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Expand Down
6 changes: 3 additions & 3 deletions sycl/test/devicelib/math_override_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// UNSUPPORTED: windows
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-cmath.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out -fno-builtin
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
#include <CL/sycl.hpp>
#include <iostream>
Expand All @@ -16,6 +15,8 @@ constexpr s::access::mode sycl_write = s::access::mode::write;
SYCL_EXTERNAL
extern "C" float sinf(float x) { return x + 100.f; }

SYCL_EXTERNAL
extern "C" float cosf(float x);
class DeviceTest;

void device_test() {
Expand All @@ -37,7 +38,6 @@ void device_test() {
});
});
}

assert(approx_equal_fp(result_sin, 100.f) && approx_equal_fp(result_cos, 1.f));
}

Expand Down
3 changes: 1 addition & 2 deletions sycl/test/devicelib/math_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// REQUIRES: cpu, linux
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-cmath.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Expand Down
3 changes: 1 addition & 2 deletions sycl/test/devicelib/math_windows_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// REQUIRES: cpu, windows
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/../bin/libsycl-cmath.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Expand Down
3 changes: 1 addition & 2 deletions sycl/test/devicelib/std_complex_math_fp64_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// UNSUPPORTED: windows
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-complex-fp64.o %sycl_libs_dir/libsycl-cmath-fp64.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Expand Down
3 changes: 1 addition & 2 deletions sycl/test/devicelib/std_complex_math_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// UNSUPPORTED: windows
// RUN: %clangxx -fsycl -c %s -o %t.o
// RUN: %clangxx -fsycl %t.o %sycl_libs_dir/libsycl-complex.o %sycl_libs_dir/libsycl-cmath.o -o %t.out
// RUN: %clangxx -fsycl %s -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Expand Down