xref: /libCEED/rust/libceed-sys/c-src/backends/sycl/online_compiler.hpp (revision bd882c8a454763a096666645dc9a6229d5263694)
1*bd882c8aSJames Wright //===------- online_compiler.hpp - Online source compilation service ------===//
2*bd882c8aSJames Wright //
3*bd882c8aSJames Wright // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*bd882c8aSJames Wright // See https://llvm.org/LICENSE.txt for license information.
5*bd882c8aSJames Wright // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*bd882c8aSJames Wright //
7*bd882c8aSJames Wright //===----------------------------------------------------------------------===//
8*bd882c8aSJames Wright 
9*bd882c8aSJames Wright #pragma once
10*bd882c8aSJames Wright 
11*bd882c8aSJames Wright #include <sycl/sycl.hpp>
12*bd882c8aSJames Wright 
13*bd882c8aSJames Wright #include <string>
14*bd882c8aSJames Wright #include <vector>
15*bd882c8aSJames Wright 
16*bd882c8aSJames Wright namespace sycl {
17*bd882c8aSJames Wright namespace ext::libceed {
18*bd882c8aSJames Wright 
19*bd882c8aSJames Wright using byte = unsigned char;
20*bd882c8aSJames Wright 
21*bd882c8aSJames Wright enum class compiled_code_format {
22*bd882c8aSJames Wright   spir_v = 0  // the only format supported for now
23*bd882c8aSJames Wright };
24*bd882c8aSJames Wright 
25*bd882c8aSJames Wright class device_arch {
26*bd882c8aSJames Wright  public:
27*bd882c8aSJames Wright   static constexpr int any = 0;
28*bd882c8aSJames Wright 
29*bd882c8aSJames Wright   device_arch(int Val) : Val(Val) {}
30*bd882c8aSJames Wright 
31*bd882c8aSJames Wright   // TODO1: the list must be extended with a bunch of new GPUs available.
32*bd882c8aSJames Wright   // TODO2: the list of supported GPUs grows rapidly.
33*bd882c8aSJames Wright   // The API must allow user to define the target GPU option even if it is
34*bd882c8aSJames Wright   // not listed in this enumerator below.
35*bd882c8aSJames Wright   enum gpu {
36*bd882c8aSJames Wright     gpu_any    = 1,
37*bd882c8aSJames Wright     gpu_gen9   = 2,
38*bd882c8aSJames Wright     gpu_skl    = gpu_gen9,
39*bd882c8aSJames Wright     gpu_gen9_5 = 3,
40*bd882c8aSJames Wright     gpu_kbl    = gpu_gen9_5,
41*bd882c8aSJames Wright     gpu_cfl    = gpu_gen9_5,
42*bd882c8aSJames Wright     gpu_gen11  = 4,
43*bd882c8aSJames Wright     gpu_icl    = gpu_gen11,
44*bd882c8aSJames Wright     gpu_gen12  = 5,
45*bd882c8aSJames Wright     gpu_tgl    = gpu_gen12,
46*bd882c8aSJames Wright     gpu_tgllp  = gpu_gen12
47*bd882c8aSJames Wright   };
48*bd882c8aSJames Wright 
49*bd882c8aSJames Wright   enum cpu {
50*bd882c8aSJames Wright     cpu_any = 1,
51*bd882c8aSJames Wright   };
52*bd882c8aSJames Wright 
53*bd882c8aSJames Wright   enum fpga {
54*bd882c8aSJames Wright     fpga_any = 1,
55*bd882c8aSJames Wright   };
56*bd882c8aSJames Wright 
57*bd882c8aSJames Wright   operator int() { return Val; }
58*bd882c8aSJames Wright 
59*bd882c8aSJames Wright  private:
60*bd882c8aSJames Wright   int Val;
61*bd882c8aSJames Wright };
62*bd882c8aSJames Wright 
63*bd882c8aSJames Wright /// Represents an error happend during online compilation.
64*bd882c8aSJames Wright class online_compile_error : public sycl::exception {
65*bd882c8aSJames Wright  public:
66*bd882c8aSJames Wright   online_compile_error() = default;
67*bd882c8aSJames Wright   online_compile_error(const std::string &Msg) : sycl::exception(Msg) {}
68*bd882c8aSJames Wright };
69*bd882c8aSJames Wright 
70*bd882c8aSJames Wright /// Designates a source language for the online compiler.
71*bd882c8aSJames Wright enum class source_language { opencl_c = 0, cm = 1 };
72*bd882c8aSJames Wright 
73*bd882c8aSJames Wright /// Represents an online compiler for the language given as template
74*bd882c8aSJames Wright /// parameter.
75*bd882c8aSJames Wright template <source_language Lang>
76*bd882c8aSJames Wright class online_compiler {
77*bd882c8aSJames Wright  public:
78*bd882c8aSJames Wright   /// Constructs online compiler which can target any device and produces
79*bd882c8aSJames Wright   /// given compiled code format. Produces 64-bit device code.
80*bd882c8aSJames Wright   /// The created compiler is "optimistic" - it assumes all applicable SYCL
81*bd882c8aSJames Wright   /// device capabilities are supported by the target device(s).
82*bd882c8aSJames Wright   online_compiler(compiled_code_format fmt = compiled_code_format::spir_v)
83*bd882c8aSJames Wright       : OutputFormat(fmt),
84*bd882c8aSJames Wright         OutputFormatVersion({0, 0}),
85*bd882c8aSJames Wright         DeviceType(sycl::info::device_type::all),
86*bd882c8aSJames Wright         DeviceArch(device_arch::any),
87*bd882c8aSJames Wright         Is64Bit(true),
88*bd882c8aSJames Wright         DeviceStepping("") {}
89*bd882c8aSJames Wright 
90*bd882c8aSJames Wright   /// Constructs online compiler which targets given architecture and produces
91*bd882c8aSJames Wright   /// given compiled code format. Produces 64-bit device code.
92*bd882c8aSJames Wright   /// Throws online_compile_error if values of constructor arguments are
93*bd882c8aSJames Wright   /// contradictory or not supported - e.g. if the source language is not
94*bd882c8aSJames Wright   /// supported for given device type.
95*bd882c8aSJames Wright   online_compiler(sycl::info::device_type dev_type, device_arch arch, compiled_code_format fmt = compiled_code_format::spir_v)
96*bd882c8aSJames Wright       : OutputFormat(fmt), OutputFormatVersion({0, 0}), DeviceType(dev_type), DeviceArch(arch), Is64Bit(true), DeviceStepping("") {}
97*bd882c8aSJames Wright 
98*bd882c8aSJames Wright   /// Constructs online compiler for the target specified by given SYCL device.
99*bd882c8aSJames Wright   // TODO: the initial version generates the generic code (SKL now), need
100*bd882c8aSJames Wright   // to do additional device::info calls to determine the device by it's
101*bd882c8aSJames Wright   // features.
102*bd882c8aSJames Wright   online_compiler(const sycl::device &)
103*bd882c8aSJames Wright       : OutputFormat(compiled_code_format::spir_v),
104*bd882c8aSJames Wright         OutputFormatVersion({0, 0}),
105*bd882c8aSJames Wright         DeviceType(sycl::info::device_type::all),
106*bd882c8aSJames Wright         DeviceArch(device_arch::any),
107*bd882c8aSJames Wright         Is64Bit(true),
108*bd882c8aSJames Wright         DeviceStepping("") {}
109*bd882c8aSJames Wright 
110*bd882c8aSJames Wright   /// Compiles given in-memory \c Lang source to a binary blob. Blob format,
111*bd882c8aSJames Wright   /// other parameters are set in the constructor by the compilation target
112*bd882c8aSJames Wright   /// specification parameters.
113*bd882c8aSJames Wright   /// Specialization for each language will provide exact signatures, which
114*bd882c8aSJames Wright   /// can be different for different languages.
115*bd882c8aSJames Wright   /// Throws online_compile_error if compilation is not successful.
116*bd882c8aSJames Wright   template <typename... Tys>
117*bd882c8aSJames Wright   std::vector<byte> compile(const std::string &src, const Tys &...args);
118*bd882c8aSJames Wright 
119*bd882c8aSJames Wright   /// Sets the compiled code format of the compilation target and returns *this.
120*bd882c8aSJames Wright   online_compiler<Lang> &setOutputFormat(compiled_code_format fmt) {
121*bd882c8aSJames Wright     OutputFormat = fmt;
122*bd882c8aSJames Wright     return *this;
123*bd882c8aSJames Wright   }
124*bd882c8aSJames Wright 
125*bd882c8aSJames Wright   /// Sets the compiled code format version of the compilation target and
126*bd882c8aSJames Wright   /// returns *this.
127*bd882c8aSJames Wright   online_compiler<Lang> &setOutputFormatVersion(int major, int minor) {
128*bd882c8aSJames Wright     OutputFormatVersion = {major, minor};
129*bd882c8aSJames Wright     return *this;
130*bd882c8aSJames Wright   }
131*bd882c8aSJames Wright 
132*bd882c8aSJames Wright   /// Sets the device type of the compilation target and returns *this.
133*bd882c8aSJames Wright   online_compiler<Lang> &setTargetDeviceType(sycl::info::device_type type) {
134*bd882c8aSJames Wright     DeviceType = type;
135*bd882c8aSJames Wright     return *this;
136*bd882c8aSJames Wright   }
137*bd882c8aSJames Wright 
138*bd882c8aSJames Wright   /// Sets the device architecture of the compilation target and returns *this.
139*bd882c8aSJames Wright   online_compiler<Lang> &setTargetDeviceArch(device_arch arch) {
140*bd882c8aSJames Wright     DeviceArch = arch;
141*bd882c8aSJames Wright     return *this;
142*bd882c8aSJames Wright   }
143*bd882c8aSJames Wright 
144*bd882c8aSJames Wright   /// Makes the compilation target 32-bit and returns *this.
145*bd882c8aSJames Wright   online_compiler<Lang> &set32bitTarget() {
146*bd882c8aSJames Wright     Is64Bit = false;
147*bd882c8aSJames Wright     return *this;
148*bd882c8aSJames Wright   };
149*bd882c8aSJames Wright 
150*bd882c8aSJames Wright   /// Makes the compilation target 64-bit and returns *this.
151*bd882c8aSJames Wright   online_compiler<Lang> &set64bitTarget() {
152*bd882c8aSJames Wright     Is64Bit = true;
153*bd882c8aSJames Wright     return *this;
154*bd882c8aSJames Wright   };
155*bd882c8aSJames Wright 
156*bd882c8aSJames Wright   /// Sets implementation-defined target device stepping of the compilation
157*bd882c8aSJames Wright   /// target and returns *this.
158*bd882c8aSJames Wright   online_compiler<Lang> &setTargetDeviceStepping(const std::string &id) {
159*bd882c8aSJames Wright     DeviceStepping = id;
160*bd882c8aSJames Wright     return *this;
161*bd882c8aSJames Wright   }
162*bd882c8aSJames Wright 
163*bd882c8aSJames Wright  private:
164*bd882c8aSJames Wright   /// Compiled code format.
165*bd882c8aSJames Wright   compiled_code_format OutputFormat;
166*bd882c8aSJames Wright 
167*bd882c8aSJames Wright   /// Compiled code format version - a pair of "major" and "minor" components
168*bd882c8aSJames Wright   std::pair<int, int> OutputFormatVersion;
169*bd882c8aSJames Wright 
170*bd882c8aSJames Wright   /// Target device type
171*bd882c8aSJames Wright   sycl::info::device_type DeviceType;
172*bd882c8aSJames Wright 
173*bd882c8aSJames Wright   /// Target device architecture
174*bd882c8aSJames Wright   device_arch DeviceArch;
175*bd882c8aSJames Wright 
176*bd882c8aSJames Wright   /// Whether the target device architecture is 64-bit
177*bd882c8aSJames Wright   bool Is64Bit;
178*bd882c8aSJames Wright 
179*bd882c8aSJames Wright   /// Target device stepping (implementation defined)
180*bd882c8aSJames Wright   std::string DeviceStepping;
181*bd882c8aSJames Wright 
182*bd882c8aSJames Wright   /// Handles to helper functions used by the implementation.
183*bd882c8aSJames Wright   void *CompileToSPIRVHandle   = nullptr;
184*bd882c8aSJames Wright   void *FreeSPIRVOutputsHandle = nullptr;
185*bd882c8aSJames Wright };
186*bd882c8aSJames Wright 
187*bd882c8aSJames Wright // Specializations of the online_compiler class and 'compile' function for
188*bd882c8aSJames Wright // particular languages and parameter types.
189*bd882c8aSJames Wright 
190*bd882c8aSJames Wright /// Compiles the given OpenCL source. May throw \c online_compile_error.
191*bd882c8aSJames Wright /// @param src - contents of the source.
192*bd882c8aSJames Wright /// @param options - compilation options (implementation defined); standard
193*bd882c8aSJames Wright ///   OpenCL JIT compiler options must be supported.
194*bd882c8aSJames Wright template <>
195*bd882c8aSJames Wright template <>
196*bd882c8aSJames Wright std::vector<byte> online_compiler<source_language::opencl_c>::compile(const std::string &src, const std::vector<std::string> &options);
197*bd882c8aSJames Wright 
198*bd882c8aSJames Wright /// Compiles the given OpenCL source. May throw \c online_compile_error.
199*bd882c8aSJames Wright /// @param src - contents of the source.
200*bd882c8aSJames Wright // template <>
201*bd882c8aSJames Wright // template <>
202*bd882c8aSJames Wright // std::vector<byte>
203*bd882c8aSJames Wright // online_compiler<source_language::opencl_c>::compile(const std::string &src) {
204*bd882c8aSJames Wright //   return compile(src, std::vector<std::string>{});
205*bd882c8aSJames Wright // }
206*bd882c8aSJames Wright 
207*bd882c8aSJames Wright /// Compiles the given CM source \p src.
208*bd882c8aSJames Wright /// @param src - contents of the source.
209*bd882c8aSJames Wright /// @param options - compilation options (implementation defined).
210*bd882c8aSJames Wright template <>
211*bd882c8aSJames Wright template <>
212*bd882c8aSJames Wright std::vector<byte> online_compiler<source_language::cm>::compile(const std::string &src, const std::vector<std::string> &options);
213*bd882c8aSJames Wright 
214*bd882c8aSJames Wright /// Compiles the given CM source \p src.
215*bd882c8aSJames Wright // template <>
216*bd882c8aSJames Wright // template <>
217*bd882c8aSJames Wright // std::vector<byte> online_compiler<source_language::cm>::compile(const std::string &src) {
218*bd882c8aSJames Wright //   return compile(src, std::vector<std::string>{});
219*bd882c8aSJames Wright // }
220*bd882c8aSJames Wright 
221*bd882c8aSJames Wright }  // namespace ext::libceed
222*bd882c8aSJames Wright }  // namespace sycl
223