Skip to content

Commit e05a19c

Browse files
kbobrovsPennycook
andauthored
[SYCL] Add online compilation extension spec. (#2913)
* [SYCL] Add online compilation extension spec. Signed-off-by: Konstantin S Bobrovsky <[email protected]> Co-authored-by: John Pennycook <[email protected]>
1 parent 70ac47d commit e05a19c

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
= SYCL Intel extension: Online Compilation
2+
Konstantin Bobrovskii <konstantin[email protected]>, John Pennycook <john[email protected]>
3+
v0.1
4+
:source-highlighter: pygments
5+
:icons: font
6+
== Introduction
7+
This document describes an interface for online compilation from high-level languages, such as
8+
OpenCL, to a binary format, such as SPIR-V, loadable by SYCL backends. Unlike SYCL 2020 provisional's
9+
OpenCL backend online compilation interface, this interface is not bound to any particular backend and does
10+
not require available SYCL context for online compilation.
11+
12+
This gives a flexibility to "cross-compile" to SPIR-V or other supported formats without any SYCL
13+
device or context available. The online compilation API uses the `online_compiler` class to access
14+
compilation services. Instances of the class are constructed based on a specification of the desired
15+
compilation target passed to the constructors - such as compiled code format, target architecture,
16+
etc. All the settings are optional, and by default the target is generic SPIR-V.
17+
18+
This API is an Intel SYCL extension.
19+
20+
== Online compilation API
21+
22+
All online compilation API elements reside in the `sycl::INTEL` namespace.
23+
24+
=== Source language specification
25+
26+
Elements of the enum designate the source language:
27+
[source,c++]
28+
-----------------
29+
enum class source_language {
30+
opencl_c, // OpenCL C language
31+
cm // Intel's C-for-Media language
32+
};
33+
-----------------
34+
35+
=== APIs to express compilation target characteristics
36+
37+
The desired format of the compiled code:
38+
[source,c++]
39+
-----------------
40+
enum class compiled_code_format {
41+
spir_v
42+
};
43+
-----------------
44+
45+
Target device architecture:
46+
[source,c++]
47+
-----------------
48+
class device_arch {
49+
public:
50+
static constexpr int any = 0; // designates an unspecified architecture
51+
device_arch(int Val);
52+
53+
// GPU architecture IDs
54+
enum gpu { gpu_any = 1, ... };
55+
// CPU architecture IDs
56+
enum cpu { cpu_any = 1, ... };
57+
// FPGA architecture IDs
58+
enum fpga { fpga_any = 1, ... };
59+
60+
// Converts this architecture representation to an integer.
61+
operator int();
62+
};
63+
-----------------
64+
65+
=== Compiler API
66+
67+
To compile a source, a user program must first construct an instance of the `sycl::INTEL::online_compiler` class. Then pass the source as an `std::string` object to online compiler's `compile` function along with other relevant parameters. The `online_compiler` is templated by the source language, and the `compile` function is a variadic template function. Instantiations of the `online_compiler::compile` for different languages may have different sets of formal parameters. The `compile` function returns a binary blob - an `std::vector<unsigned char>` - with the device code compiled according to the compilation target specification provided at online compiler construction time.
68+
69+
==== Online compiler
70+
[source,c++]
71+
-----------------
72+
template <source_language Lang> class online_compiler;
73+
-----------------
74+
75+
==== Compilation target specification elements.
76+
[cols="40,60",options="header"]
77+
|===
78+
|Element name and type |Description
79+
80+
|`compiled_code_format` OutputFormat
81+
|Compiled code format.
82+
83+
|`std::pair<int, int>` OutputFormatVersion
84+
|Compiled code format version - a pair of "major" and "minor" components.
85+
86+
|`sycl::info::device_type` DeviceType
87+
|Target device type.
88+
89+
|`device_arch` DeviceArch
90+
|Target device architecture.
91+
92+
|`bool` Is64Bit
93+
|Whether the target device architecture is 64-bit.
94+
95+
|`std::string` DeviceStepping
96+
|Target device stepping (implementation defined).
97+
|===
98+
99+
Online compiler construction or source compilation may be unsuccessful, in which case an instance
100+
of `sycl::INTEL::online_compile_error` is thrown. For example, when some of the compilation
101+
target specification elements are not supported by the implementation, or there is a syntax error
102+
in the source program.
103+
104+
105+
==== `sycl::INTEL::online_compiler` constructors.
106+
[cols="40,60",options="header"]
107+
|===
108+
|Constructor |Description
109+
110+
|`online_compiler(compiled_code_format fmt = compiled_code_format::spir_v)`
111+
| Constructs online compiler which can target any device and produces
112+
given compiled code format. Produced device code is 64-bit. OutputFormatVersion is
113+
implementation defined. The created compiler is "optimistic" - it assumes all applicable SYCL
114+
device capabilities are supported by the target device(s).
115+
116+
|`online_compiler(
117+
sycl::info::device_type dev_type,
118+
device_arch arch,
119+
compiled_code_format fmt = compiled_code_format::spir_v)`
120+
| Constructor version which allows to specify target device type and architecture.
121+
122+
|`online_compiler(const sycl::device &dev)`
123+
|Constructs online compiler for the target specified by given SYCL device.
124+
|===
125+
126+
==== The compilation function - `online_compiler::compile`
127+
It compiles given in-memory source to a binary blob. Blob format,
128+
other parameters are set in the constructor. Specialization for each language will provide exact
129+
signatures, which can be different for different languages.Throws `online_compile_error` if
130+
compilation is not successful.
131+
[source,c++]
132+
-----------------
133+
template <typename... Tys>
134+
std::vector<byte> compile(const std::string &src, const Tys&... args);
135+
-----------------
136+
137+
Instantiations of the compilation function:
138+
[source,c++]
139+
-----------------
140+
/// Compiles given OpenCL source. May throw \c online_compile_error.
141+
/// @param src - contents of the source
142+
/// @param options - compilation options (implementation defined); standard
143+
/// OpenCL JIT compiler options must be supported
144+
template <>
145+
template <>
146+
std::vector<byte> online_compiler<source_language::opencl_c>::compile(
147+
const std::string &src, const std::vector<std::string> &options);
148+
149+
/// Compiles given CM source.
150+
template <>
151+
template <>
152+
std::vector<byte> online_compiler<source_language::cm>::compile(
153+
const std::string &src);
154+
155+
/// Compiles given CM source.
156+
/// @param options - compilation options (implementation defined)
157+
template <>
158+
template <>
159+
std::vector<byte> online_compiler<source_language::cm>::compile(
160+
const std::string &src, const std::vector<std::string> &options);
161+
-----------------
162+
163+
== API usage example
164+
This example compiles an OpenCL source to a generic SPIR-V.
165+
[source,c++]
166+
-----------------
167+
#include "CL/sycl/INTEL/online_compiler.hpp"
168+
169+
#include <iostream>
170+
#include <vector>
171+
172+
static const char *kernelSource = R"===(
173+
__kernel void my_kernel(__global int *in, __global int *out) {
174+
size_t i = get_global_id(0);
175+
out[i] = in[i] + 1;
176+
}
177+
)===";
178+
179+
using namespace sycl::INTEL;
180+
181+
int main(int argc, char **argv) {
182+
online_compiler<source_language::opencl_c> compiler;
183+
std::vector<byte> blob;
184+
185+
try {
186+
blob = compiler.compile(
187+
std::string(kernelSource),
188+
std::vector<std::string> {
189+
std::string("-cl-fast-relaxed-math")
190+
}
191+
);
192+
}
193+
catch (online_compile_error &e) {
194+
std::cout << "compilation failed\n";
195+
return 1;
196+
}
197+
return 0;
198+
}
199+
-----------------

0 commit comments

Comments
 (0)