Skip to content

Commit 3b401b0

Browse files
authored
[SYCL] Allow clang-offload-wrapper to accept multiple table files (#11951)
Remove restriction that prevented clang-offload-wrapper from accepting multiple table files. --------- Signed-off-by: Lu, John <[email protected]>
1 parent caaad39 commit 3b401b0

File tree

3 files changed

+289
-19
lines changed

3 files changed

+289
-19
lines changed
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
///////////////////////////////////////////////////////////////////////////////////////////
2+
// Test that clang-offload-wrapper in "-batch" mode can accept multiple batch/table files
3+
///////////////////////////////////////////////////////////////////////////////////////////
4+
5+
///////////////////////////////////////////////////////////////////////////////////////////
6+
// Generate input and table for target 0
7+
///////////////////////////////////////////////////////////////////////////////////////////
8+
9+
// Generate image files
10+
// RUN: echo 't0-A' > %t.0A.bin
11+
// RUN: echo 't0-B' > %t.0B.bin
12+
// RUN: echo 't0-C' > %t.0C.bin
13+
14+
// Generate property files
15+
// RUN: echo '[testProp-GroupA]' > %t.0-A.prop
16+
// RUN: echo 'testProp-name2=1|0' >> %t.0-A.prop
17+
18+
// RUN: echo '[testProp-GroupB]' > %t.0-B.prop
19+
// RUN: echo 'testProp-name3=1|0' >> %t.0-B.prop
20+
21+
// RUN: echo '[testProp-GroupC]' > %t.0-C.prop
22+
// RUN: echo 'testProp-name5=1|0' >> %t.0-C.prop
23+
24+
// Generate sym files
25+
// RUN: echo '_entry_targ_0_A' > %t.0-A.sym
26+
// RUN: echo '_entry_targ_0_B' > %t.0-B.sym
27+
// RUN: echo '_entry_targ_0_C' > %t.0-C.sym
28+
29+
// Generate table file
30+
// RUN: echo '[Code|Properties|Symbols]' > %t.0.table
31+
// RUN: echo '%t.0A.bin|%t.0-A.prop|%t.0-A.sym' >> %t.0.table
32+
// RUN: echo '%t.0B.bin|%t.0-B.prop|%t.0-B.sym' >> %t.0.table
33+
// RUN: echo '%t.0C.bin|%t.0-C.prop|%t.0-C.sym' >> %t.0.table
34+
35+
///////////////////////////////////////////////////////////////////////////////////////////
36+
// Generate input and table for target 1
37+
///////////////////////////////////////////////////////////////////////////////////////////
38+
39+
// Generate image files
40+
// RUN: echo 't1-A' > %t.1A.bin
41+
// RUN: echo 't1-B' > %t.1B.bin
42+
// RUN: echo 't1-C' > %t.1C.bin
43+
44+
// Generate property files
45+
// RUN: echo '[testProp-GroupD]' > %t.1-A.prop
46+
// RUN: echo 'testProp-name7=1|0' >> %t.1-A.prop
47+
48+
// RUN: echo '[testProp-GroupE]' > %t.1-B.prop
49+
// RUN: echo 'testProp-name11=1|0' >> %t.1-B.prop
50+
51+
// RUN: echo '[testProp-GroupF]' > %t.1-C.prop
52+
// RUN: echo 'testProp-name13=1|0' >> %t.1-C.prop
53+
54+
// Generate sym files
55+
// RUN: echo '_entry_targ_1_AA' > %t.1-A.sym
56+
// RUN: echo '_entry_targ_1_BB' > %t.1-B.sym
57+
// RUN: echo '_entry_targ_1_CC' > %t.1-C.sym
58+
59+
// Generate table file
60+
// RUN: echo '[Code|Properties|Symbols]' > %t.1.table
61+
// RUN: echo '%t.1A.bin|%t.1-A.prop|%t.1-A.sym' >> %t.1.table
62+
// RUN: echo '%t.1B.bin|%t.1-B.prop|%t.1-B.sym' >> %t.1.table
63+
// RUN: echo '%t.1C.bin|%t.1-C.prop|%t.1-C.sym' >> %t.1.table
64+
65+
///////////////////////////////////////////////////////////////////////////////////////////
66+
// Generate input and table for target 2
67+
///////////////////////////////////////////////////////////////////////////////////////////
68+
69+
// Generate image files
70+
// RUN: echo 't2-A' > %t.2A.bin
71+
// RUN: echo 't2-B' > %t.2B.bin
72+
// RUN: echo 't2-C' > %t.2C.bin
73+
74+
// Generate property files
75+
// RUN: echo '[testProp-GroupG]' > %t.2-A.prop
76+
// RUN: echo 'testProp-name17=1|0' >> %t.2-A.prop
77+
78+
// RUN: echo '[testProp-GroupH]' > %t.2-B.prop
79+
// RUN: echo 'testProp-name19=1|0' >> %t.2-B.prop
80+
81+
// RUN: echo '[testProp-GroupI]' > %t.2-C.prop
82+
// RUN: echo 'testProp-name23=1|0' >> %t.2-C.prop
83+
84+
// Generate sym files
85+
// RUN: echo '_entry_targ_2_AAA' > %t.2-A.sym
86+
// RUN: echo '_entry_targ_2_BBB' > %t.2-B.sym
87+
// RUN: echo '_entry_targ_2_CCC' > %t.2-C.sym
88+
89+
// Generate table file
90+
// RUN: echo '[Code|Properties|Symbols]' > %t.2.table
91+
// RUN: echo '%t.2A.bin|%t.2-A.prop|%t.2-A.sym' >> %t.2.table
92+
// RUN: echo '%t.2B.bin|%t.2-B.prop|%t.2-B.sym' >> %t.2.table
93+
// RUN: echo '%t.2C.bin|%t.2-C.prop|%t.2-C.sym' >> %t.2.table
94+
95+
///////////////////////////////////////////////////////////////////////////////////////////
96+
// Generate wrapped BC file with multiple targets using multiple batch (i.e. table) files
97+
// and generate executable
98+
///////////////////////////////////////////////////////////////////////////////////////////
99+
// RUN: clang-offload-wrapper "-o=%t.wrapped.bc" \
100+
// RUN: -kind=sycl -target=target-zero -batch %t.0.table \
101+
// RUN: -kind=sycl -target=target-one -batch %t.1.table \
102+
// RUN: -kind=sycl -target=target-two -batch %t.2.table
103+
// RUN: %clang %s %t.wrapped.bc -o %t.fat.bin
104+
105+
///////////////////////////////////////////////////////////////////////////////////////////
106+
// Check that resulting executable has all target images and entry points and properties
107+
// are correct
108+
///////////////////////////////////////////////////////////////////////////////////////////
109+
110+
// Extract images
111+
//
112+
// RUN: clang-offload-extract --stem=%t.extracted %t.fat.bin | FileCheck %s --check-prefix CHECK-EXTRACT
113+
// CHECK-EXTRACT: Section {{.*}}: Image 1'-> File
114+
// CHECK-EXTRACT: Section {{.*}}: Image 2'-> File
115+
// CHECK-EXTRACT: Section {{.*}}: Image 3'-> File
116+
// CHECK-EXTRACT: Section {{.*}}: Image 4'-> File
117+
// CHECK-EXTRACT: Section {{.*}}: Image 5'-> File
118+
// CHECK-EXTRACT: Section {{.*}}: Image 6'-> File
119+
// CHECK-EXTRACT: Section {{.*}}: Image 7'-> File
120+
// CHECK-EXTRACT: Section {{.*}}: Image 8'-> File
121+
// CHECK-EXTRACT: Section {{.*}}: Image 9'-> File
122+
123+
//
124+
// Check that extracted contents match the original images.
125+
//
126+
// RUN: diff %t.extracted.0 %t.0A.bin
127+
// RUN: diff %t.extracted.1 %t.0B.bin
128+
// RUN: diff %t.extracted.2 %t.0C.bin
129+
// RUN: diff %t.extracted.3 %t.1A.bin
130+
// RUN: diff %t.extracted.4 %t.1B.bin
131+
// RUN: diff %t.extracted.5 %t.1C.bin
132+
// RUN: diff %t.extracted.6 %t.2A.bin
133+
// RUN: diff %t.extracted.7 %t.2B.bin
134+
// RUN: diff %t.extracted.8 %t.2C.bin
135+
136+
// Check disassembly
137+
//
138+
// RUN: llvm-dis %t.wrapped.bc
139+
// RUN: FileCheck %s --check-prefix CHECK-DISASM < %t.wrapped.ll
140+
141+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
142+
// CHECK-DISASM-SAME: target-zero
143+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
144+
// CHECK-DISASM-SAME: testProp-name2
145+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
146+
// CHECK-DISASM-SAME: testProp-GroupA
147+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
148+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-zero
149+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
150+
// CHECK-DISASM-SAME: _entry_targ_0_A
151+
152+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
153+
// CHECK-DISASM-SAME: target-zero
154+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
155+
// CHECK-DISASM-SAME: testProp-name3
156+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
157+
// CHECK-DISASM-SAME: testProp-GroupB
158+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
159+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-zero
160+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
161+
// CHECK-DISASM-SAME: _entry_targ_0_B
162+
163+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
164+
// CHECK-DISASM-SAME: target-zero
165+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
166+
// CHECK-DISASM-SAME: testProp-name5
167+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
168+
// CHECK-DISASM-SAME: testProp-GroupC
169+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
170+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-zero
171+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
172+
// CHECK-DISASM-SAME: _entry_targ_0_C
173+
174+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
175+
// CHECK-DISASM-SAME: target-one
176+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
177+
// CHECK-DISASM-SAME: testProp-name7
178+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
179+
// CHECK-DISASM-SAME: testProp-GroupD
180+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
181+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-one
182+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
183+
// CHECK-DISASM-SAME: _entry_targ_1_AA
184+
185+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
186+
// CHECK-DISASM-SAME: target-one
187+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
188+
// CHECK-DISASM-SAME: testProp-name11
189+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
190+
// CHECK-DISASM-SAME: testProp-GroupE
191+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
192+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-one
193+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
194+
// CHECK-DISASM-SAME: _entry_targ_1_BB
195+
196+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
197+
// CHECK-DISASM-SAME: target-one
198+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
199+
// CHECK-DISASM-SAME: testProp-name13
200+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
201+
// CHECK-DISASM-SAME: testProp-GroupF
202+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
203+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-one
204+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
205+
// CHECK-DISASM-SAME: _entry_targ_1_CC
206+
207+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
208+
// CHECK-DISASM-SAME: target-two
209+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
210+
// CHECK-DISASM-SAME: testProp-name17
211+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
212+
// CHECK-DISASM-SAME: testProp-GroupG
213+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
214+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-two
215+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
216+
// CHECK-DISASM-SAME: _entry_targ_2_AAA
217+
218+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
219+
// CHECK-DISASM-SAME: target-two
220+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
221+
// CHECK-DISASM-SAME: testProp-name19
222+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
223+
// CHECK-DISASM-SAME: testProp-GroupH
224+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
225+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-two
226+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
227+
// CHECK-DISASM-SAME: _entry_targ_2_BBB
228+
229+
// CHECK-DISASM: @.sycl_offloading.target.{{.*}} = internal unnamed_addr constant
230+
// CHECK-DISASM-SAME: target-two
231+
// CHECK-DISASM: @prop{{.*}} = internal unnamed_addr constant
232+
// CHECK-DISASM-SAME: testProp-name23
233+
// CHECK-DISASM: @SYCL_PropSetName{{.*}} = internal unnamed_addr constant
234+
// CHECK-DISASM-SAME: testProp-GroupI
235+
// CHECK-DISASM: @.sycl_offloading.{{.*}}.data = internal unnamed_addr constant
236+
// CHECK-DISASM-SAME: __CLANG_OFFLOAD_BUNDLE__sycl-target-two
237+
// CHECK-DISASM: __sycl_offload_entry_name{{.*}} = internal unnamed_addr constant
238+
// CHECK-DISASM-SAME: _entry_targ_2_CCC
239+
240+
///////////////////////////////////////////////////////////////////////////////////////////
241+
// Generate the same wrapped BC file with a single "-batch" option. This shows that
242+
// "-batch" is a mode setting for all input, not an option to introduce a batch/table file.
243+
// Note that "-batch" even affects prior input (e.g. %t.0.table).
244+
///////////////////////////////////////////////////////////////////////////////////////////
245+
// RUN: clang-offload-wrapper "-o=%t.wrapped2.bc" \
246+
// RUN: -kind=sycl -target=target-zero %t.0.table \
247+
// RUN: -kind=sycl -target=target-one %t.1.table \
248+
// RUN: -kind=sycl -target=target-two -batch %t.2.table
249+
250+
// Check that single "-batch" produces the same result as multi "-batch".
251+
// RUN: cmp %t.wrapped.bc %t.wrapped2.bc
252+
253+
///////////////////////////////////////////////////////////////////////////////////////////
254+
// Some code so that we can build an offload executable from this file.
255+
///////////////////////////////////////////////////////////////////////////////////////////
256+
257+
void __sycl_register_lib(void* desc) {}
258+
void __sycl_unregister_lib(void* desc) {}
259+
260+
int main(void) {
261+
return 0;
262+
}

clang/test/Driver/clang-offload-wrapper.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,17 @@
5858
// CHECK-HELP: --help-list - Display list of available options (--help-list-hidden for more)
5959
// CHECK-HELP: --version - Display the version of this program
6060
// CHECK-HELP: clang-offload-wrapper options:
61-
// CHECK-HELP: --batch - All input files are provided as cells in a file table file,
62-
// CHECK-HELP: other command-line input files are not allowed.
63-
// CHECK-HELP: Example input file table in batch mode:
64-
// CHECK-HELP: [Code|Symbols|Properties|Manifest]
65-
// CHECK-HELP: a_0.bc|a_0.sym|a_0.props|a_0.mnf
66-
// CHECK-HELP: a_1.bin|||
61+
// CHECK-HELP: --batch - All input files are treated as a table file. One table file per target.
62+
// CHECK-HELP: Table files consist of a table of filenames that provide
63+
// CHECK-HELP: Code, Symbols, Properties, etc.
64+
// CHECK-HELP: Example input table file in batch mode:
65+
// CHECK-HELP: [Code|Symbols|Properties|Manifest]
66+
// CHECK-HELP: a_0.bc|a_0.sym|a_0.props|a_0.mnf
67+
// CHECK-HELP: a_1.bin|||
68+
// CHECK-HELP: Example usage:
69+
// CHECK-HELP: clang-offload-wrapper -batch -host=x86_64-unknown-linux-gnu
70+
// CHECK-HELP: -kind=openmp -target=spir64_gen table1.txt
71+
// CHECK-HELP: -kind=openmp -target=spir64 table2.txt
6772
// CHECK-HELP: --compile-opts=<string> - compile options passed to the offload runtime
6873
// CHECK-HELP: --desc-name=<name> - Specifies offload descriptor symbol name: '.<offload kind>.<name>',
6974
// CHECK-HELP: and makes it globally visible

clang/tools/clang-offload-wrapper/ClangOffloadWrapper.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,25 @@ static cl::opt<std::string> DescriptorName(
216216
"and makes it globally visible"),
217217
cl::value_desc("name"), cl::cat(ClangOffloadWrapperCategory));
218218

219-
/// batch mode - all input files are grouped in file table files
219+
// clang-format off
220+
/// batch mode - All input files are treated as a table file. One table file per target.
221+
/// - Table files consist of a table of filenames that provide
222+
/// - Code, Symbols, Properties, etc.
220223
static cl::opt<bool> BatchMode(
221224
"batch", cl::NotHidden, cl::init(false), cl::Optional,
222-
cl::desc("All input files are provided as cells in a file table file,\n"
223-
"other command-line input files are not allowed.\n"
224-
"Example input file table in batch mode:\n"
225-
"[Code|Symbols|Properties|Manifest]\n"
226-
"a_0.bc|a_0.sym|a_0.props|a_0.mnf\n"
227-
"a_1.bin|||"),
225+
cl::desc("All input files are treated as a table file. One table file per target.\n"
226+
"Table files consist of a table of filenames that provide\n"
227+
"Code, Symbols, Properties, etc.\n"
228+
"Example input table file in batch mode:\n"
229+
" [Code|Symbols|Properties|Manifest]\n"
230+
" a_0.bc|a_0.sym|a_0.props|a_0.mnf\n"
231+
" a_1.bin|||\n"
232+
"Example usage:\n"
233+
" clang-offload-wrapper -batch -host=x86_64-unknown-linux-gnu\n"
234+
" -kind=openmp -target=spir64_gen table1.txt\n"
235+
" -kind=openmp -target=spir64 table2.txt"),
228236
cl::cat(ClangOffloadWrapperCategory));
237+
// clang-format on
229238

230239
static StringRef offloadKindToString(OffloadKind Kind) {
231240
switch (Kind) {
@@ -1728,12 +1737,6 @@ int main(int argc, const char **argv) {
17281737
auto reportError = [argv](Error E) {
17291738
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0]));
17301739
};
1731-
if (BatchMode && Inputs.size() != 1) {
1732-
reportError(
1733-
createStringError(errc::invalid_argument,
1734-
"batch job table file must be the only input file"));
1735-
return 1;
1736-
}
17371740
if (Target.empty()) {
17381741
Target = sys::getProcessTriple();
17391742
if (Verbose)

0 commit comments

Comments
 (0)