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