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