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