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