Skip to content

Commit 0457819

Browse files
committed
Merge remote-tracking branch 'origin/sycl' into attach_annotation_to_get
2 parents 246b1ef + 5cfd64d commit 0457819

File tree

49 files changed

+2681
-680
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2681
-680
lines changed

.github/workflows/sycl_post_commit.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,33 @@ jobs:
4646
- name: Intel Arc A-Series Graphics with Level Zero
4747
runner: '["Linux", "arc"]'
4848
extra_lit_opts: --param matrix-xmx8=True --param gpu-intel-dg2=True
49+
# Performance tests below. Specifics:
50+
# - only run performance tests (use LIT_FILTER env)
51+
# - ask llvm-lit to show all the output, even for PASS (-a)
52+
# - run in single thread (-j 1)
53+
# - enable the tests in LIT (--param enable-perf-tests=True)
54+
# - run on all available devices.
55+
- name: Perf tests on Intel GEN12 Graphics system
56+
runner: '["Linux", "gen12"]'
57+
env: '{"LIT_FILTER":"PerformanceTests/"}'
58+
extra_lit_opts: -a -j 1 --param enable-perf-tests=True
59+
target_devices: all
60+
- name: Perf tests on Intel Arc A-Series Graphics system
61+
runner: '["Linux", "arc"]'
62+
env: '{"LIT_FILTER":"PerformanceTests/"}'
63+
extra_lit_opts: -a -j 1 --param enable-perf-tests=True
64+
target_devices: all
4965
uses: ./.github/workflows/sycl_linux_run_tests.yml
5066
with:
5167
name: ${{ matrix.name }}
5268
runner: ${{ matrix. runner }}
5369
image: ghcr.io/intel/llvm/ubuntu2204_intel_drivers:latest
5470
image_options: -u 1001 --device=/dev/dri --privileged --cap-add SYS_ADMIN
55-
target_devices: ext_oneapi_level_zero:gpu
71+
target_devices: ${{ matrix.target_devices || 'ext_oneapi_level_zero:gpu' }}
5672
reset_gpu: true
5773

5874
extra_lit_opts: ${{ matrix.extra_lit_opts }}
75+
env: ${{ matrix.env || '{}' }}
5976

6077
ref: ${{ github.sha }}
6178
merge_ref: ''

clang/test/Driver/linker-wrapper-sycl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
// CHK-CMDS-NEXT: "{{.*}}llvm-link" -only-needed [[FIRSTLLVMLINKOUT]].bc [[FIRSTUNBUNDLEDLIB]].bc [[SECONDUNBUNDLEDLIB]].bc -o [[SECONDLLVMLINKOUT:.*]].bc --suppress-warnings
99
// CHK-CMDS-NEXT: "{{.*}}sycl-post-link" SYCL_POST_LINK_OPTIONS -o [[SYCLPOSTLINKOUT:.*]].table [[SECONDLLVMLINKOUT]].bc
1010
// LLVM-SPIRV is not called in dry-run
11-
// CHK-CMDS-NEXT: "{{.*}}clang-offload-wrapper" -o=[[WRAPPEROUT:.*]].bc -host=x86_64-unknown-linux-gnu -target=spir64 -kind=sycl -batch [[LLVMSPIRVOUT:.*]].table
11+
// CHK-CMDS-NEXT: offload-wrapper: input: [[LLVMSPIRVOUT:.*]].table, output: [[WRAPPEROUT:.*]].bc
1212
// CHK-CMDS-NEXT: "{{.*}}llc" -filetype=obj -o [[LLCOUT:.*]].o [[WRAPPEROUT]].bc
1313
// CHK-CMDS-NEXT: "{{.*}}/ld" HOST_LINKER_FLAGS -dynamic-linker HOST_DYN_LIB -o a.out [[LLCOUT]].o HOST_LIB_PATH HOST_STAT_LIB {{.*}}test-sycl.o
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// REQUIRES: system-linux
2+
// This test check wrapping of SYCL binaries in clang-linker-wrapper.
3+
4+
// RUN: %clang -cc1 -fsycl-is-device -disable-llvm-passes -triple=spir64-unknown-unknown %s -emit-llvm-bc -o %t.device.bc
5+
// RUN: clang-offload-packager -o %t.fat --image=file=%t.device.bc,kind=sycl,triple=spir64-unknown-unknown
6+
// RUN: %clang -cc1 %s -triple=x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.fat
7+
// RUN: clang-linker-wrapper --print-wrapped-module --host-triple=x86_64-unknown-linux-gnu --triple=spir64 \
8+
// RUN: -sycl-device-library-location=%S/Inputs -sycl-post-link-options="-split=auto -symbols" \
9+
// RUN: %t.o -o %t.out 2>&1 --linker-path="/usr/bin/ld" | FileCheck %s
10+
11+
template <typename t, typename Func>
12+
__attribute__((sycl_kernel)) void kernel(const Func &func) {
13+
func();
14+
}
15+
16+
extern "C" {
17+
// symbols so that linker find them and doesn't fail.
18+
void __sycl_register_lib(void *) {}
19+
void __sycl_unregister_lib(void *) {}
20+
}
21+
22+
int main() {
23+
kernel<class fake_kernel>([](){});
24+
}
25+
26+
//#endif
27+
28+
// CHECK-DAG: %_pi_device_binary_property_struct = type { ptr, ptr, i32, i64 }
29+
// CHECK-DAG: %_pi_device_binary_property_set_struct = type { ptr, ptr, ptr }
30+
// CHECK-DAG: %struct.__tgt_offload_entry = type { ptr, ptr, i64, i32, i32 }
31+
// CHECK-DAG: %__sycl.tgt_device_image = type { i16, i8, i8, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }
32+
// CHECK-DAG: %__sycl.tgt_bin_desc = type { i16, i16, ptr, ptr, ptr }
33+
34+
// CHECK-DAG: @.sycl_offloading.target.0 = internal unnamed_addr constant [23 x i8] c"spir64-unknown-unknown\00"
35+
// CHECK-DAG: @.sycl_offloading.opts.compile.0 = internal unnamed_addr constant [1 x i8] zeroinitializer
36+
// CHECK-DAG: @.sycl_offloading.opts.link.0 = internal unnamed_addr constant [1 x i8] zeroinitializer
37+
// CHECK-DAG: @prop = internal unnamed_addr constant [17 x i8] c"DeviceLibReqMask\00"
38+
// CHECK-DAG: @__sycl_offload_prop_sets_arr = internal constant [1 x %_pi_device_binary_property_struct] [%_pi_device_binary_property_struct { ptr @prop, ptr null, i32 1, i64 0 }]
39+
// CHECK-DAG: @SYCL_PropSetName = internal unnamed_addr constant [24 x i8] c"SYCL/devicelib req mask\00"
40+
// CHECK-DAG: @prop.1 = internal unnamed_addr constant [8 x i8] c"aspects\00"
41+
// CHECK-DAG: @prop_val = internal unnamed_addr constant [8 x i8] zeroinitializer
42+
// CHECK-DAG: @__sycl_offload_prop_sets_arr.2 = internal constant [1 x %_pi_device_binary_property_struct] [%_pi_device_binary_property_struct { ptr @prop.1, ptr @prop_val, i32 2, i64 8 }]
43+
// CHECK-DAG: @SYCL_PropSetName.3 = internal unnamed_addr constant [25 x i8] c"SYCL/device requirements\00"
44+
// CHECK-DAG: @__sycl_offload_prop_sets_arr.4 = internal constant [2 x %_pi_device_binary_property_set_struct] [%_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName, ptr @__sycl_offload_prop_sets_arr, ptr getelementptr inbounds ([1 x %_pi_device_binary_property_struct], ptr @__sycl_offload_prop_sets_arr, i64 1, i64 0) }, %_pi_device_binary_property_set_struct { ptr @SYCL_PropSetName.3, ptr @__sycl_offload_prop_sets_arr.2, ptr getelementptr inbounds ([1 x %_pi_device_binary_property_struct], ptr @__sycl_offload_prop_sets_arr.2, i64 1, i64 0) }]
45+
// CHECK-DAG: @.sycl_offloading.0.data = internal unnamed_addr constant [740 x i8]
46+
// CHECK-DAG: @__sycl_offload_entry_name = internal unnamed_addr constant [25 x i8] c"_ZTSZ4mainE11fake_kernel\00"
47+
// CHECK-DAG: @__sycl_offload_entries_arr = internal constant [1 x %struct.__tgt_offload_entry] [%struct.__tgt_offload_entry { ptr null, ptr @__sycl_offload_entry_name, i64 0, i32 0, i32 0 }]
48+
// CHECK-DAG: @.sycl_offloading.0.info = internal local_unnamed_addr constant [2 x i64] [i64 ptrtoint (ptr @.sycl_offloading.0.data to i64), i64 740], section ".tgtimg", align 16
49+
// CHECK-DAG: @llvm.used = appending global [1 x ptr] [ptr @.sycl_offloading.0.info], section "llvm.metadata"
50+
// CHECK-DAG: @.sycl_offloading.device_images = internal unnamed_addr constant [1 x %__sycl.tgt_device_image] [%__sycl.tgt_device_image { i16 2, i8 4, i8 0, ptr @.sycl_offloading.target.0, ptr @.sycl_offloading.opts.compile.0, ptr @.sycl_offloading.opts.link.0, ptr null, ptr null, ptr @.sycl_offloading.0.data, ptr getelementptr inbounds ([740 x i8], ptr @.sycl_offloading.0.data, i64 1, i64 0), ptr @__sycl_offload_entries_arr, ptr getelementptr inbounds ([1 x %struct.__tgt_offload_entry], ptr @__sycl_offload_entries_arr, i64 1, i64 0), ptr @__sycl_offload_prop_sets_arr.4, ptr getelementptr inbounds ([2 x %_pi_device_binary_property_set_struct], ptr @__sycl_offload_prop_sets_arr.4, i64 1, i64 0) }]
51+
// CHECK-DAG: @.sycl_offloading.descriptor = internal constant %__sycl.tgt_bin_desc { i16 1, i16 1, ptr @.sycl_offloading.device_images, ptr null, ptr null }
52+
// CHECK-DAG: @llvm.global_ctors = {{.*}} { i32 1, ptr @sycl.descriptor_reg, ptr null }]
53+
// CHECK-DAG: @llvm.global_dtors = {{.*}} { i32 1, ptr @sycl.descriptor_unreg, ptr null }]
54+
55+
// CHECK: define internal void @sycl.descriptor_reg() section ".text.startup" {
56+
// CHECK-NEXT: entry:
57+
// CHECK-NEXT: call void @__sycl_register_lib(ptr @.sycl_offloading.descriptor)
58+
// CHECK-NEXT: ret void
59+
// CHECK-NEXT: }
60+
61+
// CHECK: define internal void @sycl.descriptor_unreg() section ".text.startup" {
62+
// CHECK-NEXT: entry:
63+
// CHECK-NEXT: call void @__sycl_unregister_lib(ptr @.sycl_offloading.descriptor)
64+
// CHECK-NEXT: ret void
65+
// CHECK-NEXT: }

clang/tools/clang-linker-wrapper/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ endif()
2929
add_clang_tool(clang-linker-wrapper
3030
ClangLinkerWrapper.cpp
3131
OffloadWrapper.cpp
32+
SYCLOffloadWrapper.cpp
3233

3334
DEPENDS
3435
${tablegen_deps}

clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Lines changed: 137 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//===---------------------------------------------------------------------===//
1616

1717
#include "OffloadWrapper.h"
18+
#include "SYCLOffloadWrapper.h"
1819
#include "clang/Basic/Version.h"
1920
#include "llvm/BinaryFormat/Magic.h"
2021
#include "llvm/Bitcode/BitcodeWriter.h"
@@ -46,6 +47,7 @@
4647
#include "llvm/Support/Path.h"
4748
#include "llvm/Support/Program.h"
4849
#include "llvm/Support/Signals.h"
50+
#include "llvm/Support/SimpleTable.h"
4951
#include "llvm/Support/SourceMgr.h"
5052
#include "llvm/Support/StringSaver.h"
5153
#include "llvm/Support/TargetSelect.h"
@@ -633,37 +635,142 @@ static Expected<StringRef> runLLVMToSPIRVTranslation(StringRef InputTable,
633635
return *Output;
634636
}
635637

636-
// Run clang-offload-wrapper
637-
static Expected<StringRef> runWrapper(StringRef &InputFile,
638-
const ArgList &Args) {
639-
// Create a new file to write the wrapped file to.
640-
auto TempFileOrErr =
641-
createOutputFile(sys::path::filename(ExecutableName), "bc");
642-
if (!TempFileOrErr)
643-
return TempFileOrErr.takeError();
644-
Expected<std::string> ClangOffloadWrapperPath = findProgram(
645-
"clang-offload-wrapper", {getMainExecutable("clang-offload-wrapper")});
646-
if (!ClangOffloadWrapperPath)
647-
return ClangOffloadWrapperPath.takeError();
638+
Expected<std::vector<char>> readBinaryFile(StringRef File) {
639+
auto MBOrErr = MemoryBuffer::getFile(File, /*IsText*/ false,
640+
/*RequiresNullTerminator */ false);
641+
if (!MBOrErr)
642+
return createFileError(File, MBOrErr.getError());
648643

649-
BumpPtrAllocator Alloc;
650-
StringSaver Saver(Alloc);
644+
auto &MB = *MBOrErr;
645+
return std::vector<char>(MB->getBufferStart(), MB->getBufferEnd());
646+
}
651647

652-
SmallVector<StringRef, 8> CmdArgs;
653-
CmdArgs.push_back(*ClangOffloadWrapperPath);
654-
CmdArgs.push_back(Saver.save("-o=" + *TempFileOrErr));
655-
llvm::Triple HostTriple(
648+
Expected<std::string> readTextFile(StringRef File) {
649+
auto MBOrErr = MemoryBuffer::getFile(File, /*IsText*/ true,
650+
/*RequiresNullTerminator */ true);
651+
if (!MBOrErr)
652+
return createFileError(File, MBOrErr.getError());
653+
654+
auto &MB = *MBOrErr;
655+
return std::string(MB->getBufferStart(), MB->getBufferEnd());
656+
}
657+
658+
Expected<std::unique_ptr<util::PropertySetRegistry>>
659+
readPropertyRegistryFromFile(StringRef File) {
660+
auto MBOrErr = MemoryBuffer::getFile(File, /*IsText*/ true);
661+
if (!MBOrErr)
662+
return createFileError(File, MBOrErr.getError());
663+
664+
auto &MB = *MBOrErr;
665+
return util::PropertySetRegistry::read(&*MB);
666+
}
667+
668+
// The table format is the following:
669+
// [Code|Properties|Symbols]
670+
// a_0.bin|a_0.prop|a_0.sym
671+
// .
672+
// a_n.bin|a_n.prop|a_n.sym
673+
//
674+
// .bin extension might be a bc, spv or other native extension.
675+
Expected<SmallVector<SYCLImage>> readSYCLImagesFromTable(StringRef TableFile,
676+
const ArgList &Args) {
677+
auto TableOrErr = util::SimpleTable::read(TableFile);
678+
if (!TableOrErr)
679+
return TableOrErr.takeError();
680+
681+
std::unique_ptr<util::SimpleTable> Table = std::move(*TableOrErr);
682+
int CodeIndex = Table->getColumnId("Code");
683+
int PropertiesIndex = Table->getColumnId("Properties");
684+
int SymbolsIndex = Table->getColumnId("Symbols");
685+
if (CodeIndex == -1 || PropertiesIndex == -1 || SymbolsIndex == -1)
686+
return createStringError(
687+
inconvertibleErrorCode(),
688+
"expected columns in the table: Code, Properties and Symbols");
689+
690+
SmallVector<SYCLImage> Images;
691+
for (const util::SimpleTable::Row &row : Table->rows()) {
692+
auto ImageOrErr = readBinaryFile(row.getCell("Code"));
693+
if (!ImageOrErr)
694+
return ImageOrErr.takeError();
695+
696+
auto PropertiesOrErr =
697+
readPropertyRegistryFromFile(row.getCell("Properties"));
698+
if (!PropertiesOrErr)
699+
return PropertiesOrErr.takeError();
700+
701+
auto SymbolsOrErr = readTextFile(row.getCell("Symbols"));
702+
if (!SymbolsOrErr)
703+
return SymbolsOrErr.takeError();
704+
705+
SYCLImage Image;
706+
Image.Image = std::move(*ImageOrErr);
707+
Image.PropertyRegistry = std::move(**PropertiesOrErr);
708+
Image.Entries = std::move(*SymbolsOrErr);
709+
Images.push_back(std::move(Image));
710+
}
711+
712+
return Images;
713+
}
714+
715+
/// Reads device images from the given \p InputFile and wraps them
716+
/// in one LLVM IR Module as a constant data.
717+
///
718+
/// \returns A path to the LLVM Module that contains wrapped images.
719+
Expected<StringRef> wrapSYCLBinariesFromFile(StringRef InputFile,
720+
const ArgList &Args) {
721+
auto OutputFileOrErr = createOutputFile(
722+
sys::path::filename(ExecutableName) + ".sycl.image.wrapper", "bc");
723+
if (!OutputFileOrErr)
724+
return OutputFileOrErr.takeError();
725+
726+
StringRef OutputFilePath = *OutputFileOrErr;
727+
if (Verbose || DryRun) {
728+
errs() << formatv(" offload-wrapper: input: {0}, output: {1}\n", InputFile,
729+
OutputFilePath);
730+
if (DryRun)
731+
return OutputFilePath;
732+
}
733+
734+
auto ImagesOrErr = readSYCLImagesFromTable(InputFile, Args);
735+
if (!ImagesOrErr)
736+
return ImagesOrErr.takeError();
737+
738+
auto &Images = *ImagesOrErr;
739+
StringRef Target = Args.getLastArgValue(OPT_triple_EQ);
740+
if (Target.empty())
741+
return createStringError(
742+
inconvertibleErrorCode(),
743+
"can't wrap SYCL image. -triple argument is missed.");
744+
745+
for (SYCLImage &Image : Images)
746+
Image.Target = Target;
747+
748+
LLVMContext C;
749+
Module M("offload.wrapper.object", C);
750+
M.setTargetTriple(
656751
Args.getLastArgValue(OPT_host_triple_EQ, sys::getDefaultTargetTriple()));
657-
CmdArgs.push_back(Saver.save("-host=" + HostTriple.str()));
658-
const llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ));
659-
SmallString<128> TargetTripleOpt = Triple.getArchName();
660-
CmdArgs.push_back(Saver.save("-target=" + TargetTripleOpt));
661-
CmdArgs.push_back("-kind=sycl");
662-
CmdArgs.push_back("-batch");
663-
CmdArgs.push_back(InputFile);
664-
if (Error Err = executeCommands(*ClangOffloadWrapperPath, CmdArgs))
665-
return std::move(Err);
666-
return *TempFileOrErr;
752+
753+
StringRef CompileOptions =
754+
Args.getLastArgValue(OPT_sycl_backend_compile_options_EQ);
755+
StringRef LinkOptions = Args.getLastArgValue(OPT_sycl_target_link_options_EQ);
756+
SYCLWrappingOptions WrappingOptions;
757+
WrappingOptions.CompileOptions = CompileOptions;
758+
WrappingOptions.LinkOptions = LinkOptions;
759+
if (Error E = wrapSYCLBinaries(M, Images, WrappingOptions))
760+
return E;
761+
762+
if (Args.hasArg(OPT_print_wrapped_module))
763+
errs() << M;
764+
765+
// TODO: Once "llc tool->runCompile" migration is finished we need to remove
766+
// this scope and use community flow.
767+
int FD = -1;
768+
if (std::error_code EC = sys::fs::openFileForWrite(OutputFilePath, FD))
769+
return errorCodeToError(EC);
770+
771+
raw_fd_ostream OS(FD, true);
772+
WriteBitcodeToFile(M, OS);
773+
return OutputFilePath;
667774
}
668775

669776
// Run llc
@@ -691,11 +798,10 @@ static Expected<StringRef> runCompile(StringRef &InputFile,
691798
return *OutputFileOrErr;
692799
}
693800

694-
// Run clang-offload-wrapper and llc
801+
// Run wrapping library and llc
695802
static Expected<StringRef> runWrapperAndCompile(StringRef &InputFile,
696803
const ArgList &Args) {
697-
// call to clang-offload-wrapper
698-
auto OutputFile = sycl::runWrapper(InputFile, Args);
804+
auto OutputFile = sycl::wrapSYCLBinariesFromFile(InputFile, Args);
699805
if (!OutputFile)
700806
return OutputFile.takeError();
701807
// call to llc

clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ def sycl_device_library_location_EQ : Joined<["-"],
140140
"sycl-device-library-location=">, Flags<[WrapperOnlyOption]>,
141141
HelpText<"Location of SYCL device library files">;
142142

143+
// Options for SYCL backends and linker options for shared libraries.
144+
def sycl_backend_compile_options_EQ :
145+
Joined<["-"], "sycl-backend-compile-options">,
146+
Flags<[WrapperOnlyOption]>,
147+
HelpText<"Options that are passed to the backend of target device compiler">;
148+
def sycl_target_link_options_EQ :
149+
Joined<["-"], "sycl-target-link-options">,
150+
Flags<[WrapperOnlyOption]>,
151+
HelpText<"Options that are passed to target linker during a linking of shared device code.">;
152+
143153
// Special option to pass in sycl-post-link options
144154
def sycl_post_link_options_EQ : Joined<["-"], "sycl-post-link-options=">,
145155
Flags<[WrapperOnlyOption]>,

0 commit comments

Comments
 (0)