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