Skip to content
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

[Clang][SYCL] Introduce clang-sycl-link-wrapper to link SYCL offloading device code #1

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
67 changes: 67 additions & 0 deletions clang/docs/ClangSYCLLinkWrapper.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
====================
Clang SYCL link Wrapper
====================
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

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

Suggested change
====================
Clang SYCL link Wrapper
====================
=======================
Clang SYCL link Wrapper
=======================


.. contents::
:local:

.. _clang-sycl-link-wrapper:

Introduction
============

This tool works as a wrapper around the SYCL device code linking process.
Purpose of this wrapper is to provide an interface to link SYCL device bitcode
Copy link

Choose a reason for hiding this comment

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

Suggested change
Purpose of this wrapper is to provide an interface to link SYCL device bitcode
The purpose of this wrapper is to provide an interface to link SYCL device bitcode

Copy link

Choose a reason for hiding this comment

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

According to my understanding, the purpose of the tool is to provide standard linker interface and be able to link any object file formats 'compile' step is able to produce for SYCL offload mode. So, I would expect this tool to handle linking of fat objects with device code in other IR like SPIR-V as well as native binary format.

in LLVM IR format, run some SYCL-specific finalization steps and then use the
SPIR-V LLVM Translator tool to produce the final output.

Device code linking for SYCL offloading kind has a number of known quirks that
Copy link

Choose a reason for hiding this comment

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

Suggested change
Device code linking for SYCL offloading kind has a number of known quirks that
Device code linking for SYCL offloading has a number of known quirks that

makes it difficult to use in a unified offloading setting. Two of the primary
issues are:
1. Several finalization steps are required to be run on the fully-linked LLVM
IR bitcode to gaurantee conformance to SYCL standards. This step is unique to
Copy link

Choose a reason for hiding this comment

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

Suggested change
IR bitcode to gaurantee conformance to SYCL standards. This step is unique to
IR bitcode to guarantee conformance to SYCL standards. This step is unique to

SYCL offloading compilation flow.
Copy link

Choose a reason for hiding this comment

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

Suggested change
SYCL offloading compilation flow.
the SYCL offloading compilation flow.

2. SPIR-V LLVM Translator tool is an extenal tool and hence SPIR-V IR code
Copy link

Choose a reason for hiding this comment

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

Suggested change
2. SPIR-V LLVM Translator tool is an extenal tool and hence SPIR-V IR code
2. SPIR-V LLVM Translator tool is an external tool and hence SPIR-V IR code

generation cannot be done as part of LTO. This limitation will be lifted once
SPIR-V backend is available as a viable LLVM backend.
Copy link

Choose a reason for hiding this comment

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

Suggested change
SPIR-V backend is available as a viable LLVM backend.
the SPIR-V backend is available as a viable LLVM backend.


This tool works around these issues.

Usage
=====

This tool can be used with the following options. Several of these options will
be passed down to downstrea tools like 'llvm-link', 'llvm-spirv', etc.
Copy link

Choose a reason for hiding this comment

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

Suggested change
be passed down to downstrea tools like 'llvm-link', 'llvm-spirv', etc.
be passed down to downstream tools like 'llvm-link', 'llvm-spirv', etc.

Copy link

Choose a reason for hiding this comment

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

Suggested change
be passed down to downstrea tools like 'llvm-link', 'llvm-spirv', etc.
be passed down to downstrea tools like 'clang', 'llvm-spirv', etc.

We should use clang instead of llvm-link to link llvm bitcode files.


.. code-block:: console

OVERVIEW: A utility that wraps around the SYCl device code linking process.
This enables linking and code generation for SPIR-V JIT targets.
Copy link

Choose a reason for hiding this comment

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

What about AOT targets?


USAGE: clang-sycl-link-wrapper [options]

OPTIONS:
--arch <value> Specify the name of the target architecture.
--dry-run Print generated commands without running.
-g Specify that this was a debug compile.
-help-hidden Display all available options
-help Display available options (--help-hidden for more)
--library-path=<dir> Set the library path for SYCL device libraries
-o <path> Path to file to write output
--save-temps Save intermediate results
--triple <value> Specify the target triple.
--version Display the version number and exit
-v Print verbose information

Example
=======

This tool is intended to be invoked when targeting the SPIR-V toolchain.
When --sycl-link option is passed, clang driver will invoke the linking job of
Copy link

Choose a reason for hiding this comment

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

Suggested change
When --sycl-link option is passed, clang driver will invoke the linking job of
When the `--sycl-link option` is passed, the clang driver will invoke the linking job of

Copy link

Choose a reason for hiding this comment

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

Please, specify that --sycl-link is the clang driver option, not clang-sycl-link-wrapper option.

the SPIR-V toolchain, which in turn will invoke this tool.
This tool can be used to create one or more fully linked SYCL objects that are
Copy link

Choose a reason for hiding this comment

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

Suggested change
This tool can be used to create one or more fully linked SYCL objects that are
This tool can be used to create one or more fully linked device images that are

?

ready to be wrapped and linked with host code to generate the final executable.

.. code-block:: console

clang --target=spirv64 --sycl-link input.bc
1 change: 1 addition & 0 deletions clang/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Using Clang Tools
ClangOffloadBundler
ClangOffloadPackager
ClangRepl
ClangSYCLLinkWrapper

Design Documents
================
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -6728,7 +6728,10 @@ def fsycl : Flag<["-"], "fsycl">,
def fno_sycl : Flag<["-"], "fno-sycl">,
Visibility<[ClangOption, CLOption]>,
Group<sycl_Group>, HelpText<"Disables SYCL kernels compilation for device">;

def sycl_link : Flag<["--"], "sycl-link">, Flags<[HelpHidden]>,
Visibility<[ClangOption, CLOption]>,
Group<sycl_Group>, HelpText<"Perform link through clang-sycl-link-wrapper via the SPIR-V "
Copy link

Choose a reason for hiding this comment

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

given the description, maybe it should be --sycl-spirv-link?

"toolchain.">;
// OS-specific options
let Flags = [TargetSpecific] in {
defm android_pad_segment : BooleanFFlag<"android-pad-segment">, Group<f_Group>;
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4780,6 +4780,12 @@ Action *Driver::ConstructPhaseAction(
if (Phase == phases::Assemble && Input->getType() != types::TY_PP_Asm)
return Input;

// Use of --sycl-link and the SPIR-V target triple will only allow for the
// link phase to occur. This is for all input files.
if (C.getDefaultToolChain().getTriple().isSPIROrSPIRV() &&
Args.hasArg(options::OPT_sycl_link) && Phase != phases::Link)
return Input;

// Build the appropriate action.
switch (Phase) {
case phases::Link:
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Driver/ToolChains/SPIRV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,19 @@ void SPIRV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());

// Use of --sycl-link will call the clang-sycl-link-wrapper instead of
// the default linker (spirv-link).
if (Args.hasArg(options::OPT_sycl_link))
Linker = ToolChain.GetProgramPath("clang-sycl-link-wrapper");
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
Args.MakeArgString(Linker), CmdArgs,
Inputs, Output));
}

SPIRVToolChain::SPIRVToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: ToolChain(D, Triple, Args) {
NativeLLVMSupport = Args.hasArg(options::OPT_sycl_link);
}

bool SPIRVToolChain::HasNativeLLVMSupport() const { return NativeLLVMSupport; }
5 changes: 3 additions & 2 deletions clang/lib/Driver/ToolChains/SPIRV.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVToolChain final : public ToolChain {

public:
SPIRVToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args)
: ToolChain(D, Triple, Args) {}
const llvm::opt::ArgList &Args);

bool useIntegratedAs() const override { return true; }

Expand All @@ -72,6 +71,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVToolChain final : public ToolChain {
}
bool isPICDefaultForced() const override { return false; }
bool SupportsProfiling() const override { return false; }
bool HasNativeLLVMSupport() const override;

clang::driver::Tool *SelectTool(const JobAction &JA) const override;

Expand All @@ -81,6 +81,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRVToolChain final : public ToolChain {

private:
clang::driver::Tool *getTranslator() const;
bool NativeLLVMSupport;
};

} // namespace toolchains
Expand Down
Empty file.
Empty file.
9 changes: 9 additions & 0 deletions clang/test/Driver/clang-sycl-link-wrapper-test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Tests the clang-sycl-link-wrapper tool
//
// Test a simple case without arguments
// RUN: %clangxx -fsycl -emit-llvm -c %s -o %t.bc
// RUN: clang-sycl-link-wrapper --dry-run -triple spirv64 %t.bc --library-path=%S/Inputs -o a.spv 2>&1 \
// RUN: | FileCheck %s --check-prefix=CMDS
// CMDS: "{{.*}}llvm-link{{.*}}" {{.*}}.bc -o [[FIRSTLLVMLINKOUT:.*]].bc --suppress-warnings
// CMDS-NEXT: "{{.*}}llvm-link{{.*}}" -only-needed [[FIRSTLLVMLINKOUT]].bc {{.*}}libsycl-crt.bc {{.*}}libsycl-complex.bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings
// CMDS-NEXT: "{{.*}}llvm-spirv{{.*}}" {{.*}}-o a.spv [[SECONDLLVMLINKOUT]].bc
7 changes: 7 additions & 0 deletions clang/test/Driver/sycl-link-spirv-target.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Tests the driver when linking LLVM IR bitcode files and targeting SPIR-V
// architecture.
//
// RUN: touch %t.bc
// RUN: %clangxx --target=spirv64 --sycl-link -### %t.bc 2>&1 \
// RUN: | FileCheck %s -check-prefix=LINK
// LINK: "{{.*}}clang-sycl-link-wrapper{{.*}}" "{{.*}}.bc" "-o" "a.out"
1 change: 1 addition & 0 deletions clang/tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ add_clang_subdirectory(clang-nvlink-wrapper)
add_clang_subdirectory(clang-offload-packager)
add_clang_subdirectory(clang-offload-bundler)
add_clang_subdirectory(clang-scan-deps)
add_clang_subdirectory(clang-sycl-link-wrapper)
add_clang_subdirectory(clang-installapi)
if(HAVE_CLANG_REPL_SUPPORT)
add_clang_subdirectory(clang-repl)
Expand Down
28 changes: 28 additions & 0 deletions clang/tools/clang-sycl-link-wrapper/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
Option
)

set(LLVM_TARGET_DEFINITIONS SYCLLinkOpts.td)
tablegen(LLVM SYCLLinkOpts.inc -gen-opt-parser-defs)
add_public_tablegen_target(SYCLLinkWrapperOpts)

if(NOT CLANG_BUILT_STANDALONE)
set(tablegen_deps intrinsics_gen SYCLLinkWrapperOpts)
endif()

add_clang_tool(clang-sycl-link-wrapper
ClangSYCLLinkWrapper.cpp

DEPENDS
${tablegen_deps}
)

set(CLANG_SYCL_LINK_WRAPPER_LIB_DEPS
clangBasic
)

target_link_libraries(clang-sycl-link-wrapper
PRIVATE
${CLANG_SYCL_LINK_WRAPPER_LIB_DEPS}
)
Loading