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