Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11486,6 +11486,12 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_fsycl_embed_ir))
CmdArgs.push_back(Args.MakeArgString("-sycl-embed-ir"));

if (Args.hasFlag(options::OPT_fsycl_allow_device_image_dependencies,
options::OPT_fno_sycl_allow_device_image_dependencies,
false))
CmdArgs.push_back(
Args.MakeArgString("-sycl-allow-device-image-dependencies"));

// Formulate and add any offload-wrapper and AOT specific options. These
// are additional options passed in via -Xsycl-target-linker and
// -Xsycl-target-backend.
Expand Down
16 changes: 16 additions & 0 deletions clang/test/Driver/sycl-offload-new-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,19 @@
// RUN: --offload-new-driver 2>&1 \
// RUN: | FileCheck -check-prefix NVPTX_CUDA_PATH %s
// NVPTX_CUDA_PATH: clang-linker-wrapper{{.*}} "--cuda-path={{.*}}Inputs/CUDA_80/usr/local/cuda"

/// Check for -sycl-allow-device-image-dependencies transmission to clang-linker-wrapper tool
// RUN: %clangxx -fsycl -### --offload-new-driver \
// RUN: -fsycl-allow-device-image-dependencies %s 2>&1 \
// RUN: | FileCheck -check-prefix CHECK_DYNAMIC_LINKING %s
// CHECK_DYNAMIC_LINKING: clang-linker-wrapper{{.*}} "-sycl-allow-device-image-dependencies"

/// Check that -sycl-allow-device-image-dependencies is not passed to clang-linker-wrapper tool
// RUN: %clangxx -fsycl -### --offload-new-driver \
// RUN: -fno-sycl-allow-device-image-dependencies %s 2>&1 \
// RUN: | FileCheck -check-prefix CHECK_NO_DYNAMIC_LINKING %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you double check and make sure this will actual fail if the arg appears for this case and the below one? if not we might want to use implicit-check-not instead of a check-prefix


/// Check that -sycl-allow-device-image-dependencies is not passed to clang-linker-wrapper tool
// RUN: %clangxx -fsycl -### --offload-new-driver %s 2>&1 \
// RUN: | FileCheck -check-prefix CHECK_NO_DYNAMIC_LINKING %s
// CHECK_NO_DYNAMIC_LINKING-NOT: clang-linker-wrapper{{.*}} "-sycl-allow-device-image-dependencies"
1 change: 1 addition & 0 deletions clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ getTripleBasedSYCLPostLinkOpts(const ArgList &Args,
if ((!Args.hasFlag(OPT_no_sycl_remove_unused_external_funcs,
OPT_sycl_remove_unused_external_funcs, false) &&
!SYCLNativeCPU) &&
!Args.hasArg(OPT_sycl_allow_device_image_dependencies) &&
!Triple.isNVPTX() && !Triple.isAMDGPU())
PostLinkArgs.push_back("-emit-only-kernels-as-entry-points");

Expand Down
5 changes: 5 additions & 0 deletions clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,8 @@ Flags<[WrapperOnlyOption]>, HelpText<"Embed LLVM IR for runtime kernel fusion">
def sycl_dump_device_code_EQ : Joined<["--", "-"], "sycl-dump-device-code=">,
Flags<[WrapperOnlyOption]>,
HelpText<"Path to the folder where the tool dumps SPIR-V device code. Other formats aren't dumped.">;

// Options to enable/disable device dynamic linking.
def sycl_allow_device_image_dependencies : Flag<["--", "-"], "sycl-allow-device-image-dependencies">,
Flags<[WrapperOnlyOption, HelpHidden]>,
HelpText<"Allow dependencies between device code images">;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#define A_EXPORT
#include "a.hpp"
#include "b.hpp"
#include <iostream>

A_DECLSPEC SYCL_EXTERNAL int levelA(int val) {
#ifndef __SYCL_DEVICE_ONLY__
std::cerr << "Host symbol used" << std::endl;
val ^= 0x1234;
#endif
val = levelB(val);
return val |= (0xA << 0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <sycl/detail/core.hpp>

#if defined(MAKE_DLL)
#ifdef A_EXPORT
#define A_DECLSPEC __declspec(dllexport)
#else
#define A_DECLSPEC __declspec(dllimport)
#endif
#else
#define A_DECLSPEC
#endif

A_DECLSPEC SYCL_EXTERNAL int levelA(int val);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#define B_EXPORT
#include "b.hpp"
#include "c.hpp"
#include <iostream>

B_DECLSPEC SYCL_EXTERNAL int levelB(int val) {
#ifndef __SYCL_DEVICE_ONLY__
std::cerr << "Host symbol used" << std::endl;
val ^= 0x2345;
#endif
val = levelC(val);
return val |= (0xB << 4);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <sycl/detail/core.hpp>

#if defined(MAKE_DLL)
#ifdef B_EXPORT
#define B_DECLSPEC __declspec(dllexport)
#else
#define B_DECLSPEC __declspec(dllimport)
#endif
#else
#define B_DECLSPEC
#endif

B_DECLSPEC SYCL_EXTERNAL int levelB(int val);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#define C_EXPORT
#include "c.hpp"
#include "d.hpp"
#include <iostream>

C_DECLSPEC SYCL_EXTERNAL int levelC(int val) {
#ifndef __SYCL_DEVICE_ONLY__
std::cerr << "Host symbol used" << std::endl;
val ^= 0x3456;
#endif
val = levelD(val);
return val |= (0xC << 8);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <sycl/detail/core.hpp>

#if defined(MAKE_DLL)
#ifdef C_EXPORT
#define C_DECLSPEC __declspec(dllexport)
#else
#define C_DECLSPEC __declspec(dllimport)
#endif
#else
#define C_DECLSPEC
#endif

C_DECLSPEC SYCL_EXTERNAL int levelC(int val);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#define D_EXPORT
#include "d.hpp"
#include <iostream>

D_DECLSPEC SYCL_EXTERNAL int levelD(int val) {
#ifndef __SYCL_DEVICE_ONLY__
std::cerr << "Host symbol used" << std::endl;
val ^= 0x4567;
#endif
return val |= (0xD << 12);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <sycl/detail/core.hpp>

#if defined(MAKE_DLL)
#ifdef D_EXPORT
#define D_DECLSPEC __declspec(dllexport)
#else
#define D_DECLSPEC __declspec(dllimport)
#endif
#else
#define D_DECLSPEC
#endif

D_DECLSPEC SYCL_EXTERNAL int levelD(int val);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "a.hpp"
#include <iostream>
#include <sycl/detail/core.hpp>
#define EXPORT
#include "wrapper.hpp"

using namespace sycl;

class ExeKernel;

int wrapper() {
int val = 0;
{
buffer<int, 1> buf(&val, range<1>(1));
queue q;
q.submit([&](handler &cgh) {
auto acc = buf.get_access(cgh);
cgh.single_task<ExeKernel>([=]() { acc[0] = levelA(acc[0]); });
});
}

std::cout << "val=" << std::hex << val << "\n";
if (val != 0xDCBA)
return (1);
return (0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#if defined(_WIN32)
#ifdef EXPORT
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
#endif
int wrapper();
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Test -fsycl-allow-device-image-dependencies with dynamic libraries.

// UNSUPPORTED: cuda || hip
// UNSUPPORTED-INTENDED: Not implemented yet for Nvidia/AMD backends.

// DEFINE: %{dynamic_lib_options} = -fsycl %fPIC %shared_lib -fsycl-allow-device-image-dependencies -I %S/Inputs %if windows %{-DMAKE_DLL %}
// DEFINE: %{dynamic_lib_suffix} = %if windows %{dll%} %else %{so%}

// RUN: %clangxx --offload-new-driver %{dynamic_lib_options} %S/Inputs/d.cpp -o %T/libdevice_d.%{dynamic_lib_suffix}
// RUN: %clangxx --offload-new-driver %{dynamic_lib_options} %S/Inputs/c.cpp %if windows %{%T/libdevice_d.lib%} -o %T/libdevice_c.%{dynamic_lib_suffix}
// RUN: %clangxx --offload-new-driver %{dynamic_lib_options} %S/Inputs/b.cpp %if windows %{%T/libdevice_c.lib%} -o %T/libdevice_b.%{dynamic_lib_suffix}
// RUN: %clangxx --offload-new-driver %{dynamic_lib_options} %S/Inputs/a.cpp %if windows %{%T/libdevice_b.lib%} -o %T/libdevice_a.%{dynamic_lib_suffix}

// RUN: %{build} --offload-new-driver -fsycl-allow-device-image-dependencies -I %S/Inputs -o %t.out \
// RUN: %if windows \
// RUN: %{%T/libdevice_a.lib%} \
// RUN: %else \
// RUN: %{-L%T -ldevice_a -ldevice_b -ldevice_c -ldevice_d -Wl,-rpath=%T%}

// RUN: %{run} %t.out

#include "a.hpp"
#include <iostream>
#include <sycl/detail/core.hpp>

using namespace sycl;

class ExeKernel;

int main() {
int val = 0;
{
buffer<int, 1> buf(&val, range<1>(1));
queue q;
q.submit([&](handler &cgh) {
auto acc = buf.get_access(cgh);
cgh.single_task<ExeKernel>([=]() { acc[0] = levelA(acc[0]); });
});
}

std::cout << "val=" << std::hex << val << "\n";
if (val != 0xDCBA)
return (1);
return (0);
}
Loading
Loading