OpenCL kernel 在 Vulkan 上的使用
OpenCL 自 2008 年底釋出 1.0 至今過了十個年頭,在 GPGPU 面向上也累積了相當的開發者社群,
儘管 Desktop 上熱烈程度不如 Nvidia CUDA,
而 Mobile 上因 Google 的錯誤決定去強推 RenderScript,
造成手機商在配置與否的態度不一
這樣的情況造成 OpenCL 的使用程度上既不熱烈,
然而許多情況下又是唯一方案
在 Vulkan 的推出後,
由於其基於 SPIR-V 標準的特性, 讓許多應用能夠依附於此之上
其中之一即為 OpenCL kernel 的使用
透過預先以 compiler 將 OpenCL kernel 轉為 SPIR-V binary
再搭配 Vulkan 載入與使用 Compute Shader 的方式, 得以間接的使用 OpenCL 語法
所需的第一個工具為:
https://github.com/google/clspv
clspv 為將 OpenCL kernel 編譯出 SPIR-V 的 Compiler
再來即為 Vulkan 對應 OpenCL Host Code 的使用流程
網路上可以找到下列三篇提及 OpenCL Host => Vulkan 流程轉換的 Blog 文
OpenCL -> Vulkan: A Porting Guide Part I
OpenCL -> Vulkan: A Porting Guide Part II
OpenCL -> Vulkan: A Porting Guide Part III
以及該系列文作者於 Khronos Munich 2017 的簡報: OpenCL to Vulkan: A Porting Guide
若跳過對 OpenCL 與 Vulkan 的對應, 想直接切入 Vulkan Compute Shader 流程
該作者的 A simple Vulkan Compute example 一文以及 GitHub gist 幫助就相當大
個人透過上述幾篇, 實作了上述 Compute Example 等義的 CL kernel
並整合開源放上 https://github.com/champyen/vkcl
以 Intel HD Graphics 500 搭配 Mesa Vulkan 實作, 能正確執行
儘管因此能夠撰寫 OpenCL kernel 來在 Vulkan 環境中使用, 然而並不代表沒有任何限制
相關限制都在 clspv 的 OpenCLCOnVulkan 文件中
Kernel
- argument 非 buffer/image 型別, 會透過整合到一個 buffer 方式傳入
- WorkGroupSize 無法透過 host 指定, 似乎只能以 __attribute__ ((reqd_work_group_size(x, y, z))) 方式指定
- 無法呼叫其他 Kernel
- 不能使用 local 作為 argument
- 不能使用 half 作為 argument
Types
- boolean 無法作為 global, constant, 而 sizeof 為未定義行為
- 8-bit, 64-bit, event_t 型別無法使用
- 沒有長度為 8, 16 的向量 (也就是儘支援向量長度 2, 3, 4)
- pointer 的限制很多
這部分相當的多, 都是無法使用, 簡短提示如下:
- atomic: atomic_xchg()
- common: step(), smooth_step()
- conversion: 俱備 rounding, saturation 都不可使用
- math, integer, rational: 這部分特定的 function 無法使用, 請參考說明
- async, shuffle, printf, vload/vstore: 請直接當不存在 ...
Vulkan GLSL Compute Shader
OpenCL kernel 在 Vulkan 1.0 上運作需要兩個 extension:- SPV_KHR_variable_pointers
- SPV_KHR_storage_buffer_storage_class
若考量 Vulkan 1.0 裝置的相容性, 那麼採用 GLSL Compute Shader 方式撰寫是不錯的選擇
此外 Vulkan GLSL compute shader 的相關範例也並不多, 以下是看到覺得不錯的
https://github.com/Erkaman/vulkan_minimal_compute
https://github.com/alexhultman/libvc
https://arm-software.github.io/vulkan-sdk/basic_compute.html
撰寫 Vulkan GLSL compute shader 也需要 compiler 產生 SPIR-V
這時 LunarG 的 Vulkan Toolchain 能夠直接下載使用
https://vulkan.lunarg.com/sdk/home
update: 值得一提的是與 OpenGL GLSL compute shader 的不同, OpenGL GLSL compute shader 制定時, 能使用的 builtins 受限於既有 GLSL 部分, Vulkan 制定的時候對其做了擴充, 能使用的函式較接近原有的 OpenCL:
https://www.khronos.org/registry/spir-v/specs/unified1/GLSL.std.450.mobile.html
1 則留言:
藉由留言來更新一下, 近年的新 project - CLVK
主要是實作 OpenCL Host API over Vulkan
其目標也是與 clspv 搭配
https://github.com/kpet/clvk
張貼留言