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