OpenCL（Open Computing Language，開放計算語言）是一個為異構平臺編寫程式的框架，此異構平臺可由 CPU、GPU、DSP、FPGA 或其他型別的處理器與硬體加速器所組成。OpenCL 由一門用於編寫 kernels（在 OpenCL 裝置上執行的函式）的語言（基於 C99）和一組用於定義並控制平臺的 API 組成。OpenCL 提供了基於任務分割和資料分割的平行計算機制。 OpenCL 類似於另外兩個開放的工業標準 OpenGL 和 OpenAL，這兩個標準分別用於三維圖形和計算機音訊方面。OpenCL 擴充了 GPU 圖形生成之外的能力。OpenCL 由非盈利性技術組織 Khronos Group 掌管。 歷史 OpenCL 最初由蘋果公司開發，擁有其商標權，並在與 AMD，IBM，Intel 和 NVIDIA 技術團隊的合作之下初步完善。隨後，蘋果將這一草案提交至 Khronos Group。2008 年 6 月 16 日，Khronos 的通用計算工作小組成立。5 個月後的 2008 年 11 月 18 日，該工作組完成了 OpenCL 10 規範的技術細節。該技術規範在由 Khronos 成員進行審查之後，於 2008 年 12 月 8 日公開發表。 2010 年 6 月 14 日，OpenCL 11 釋出。2011 年 11 月 15 日，OpenCL 12 釋出。2013 年 11 月 18 日，OpenCL 20 釋出。2015 年 11 月 16 日，OpenCL 21 釋出。2017 年 5 月 16 日，OpenCL 22 釋出。 路線圖 在 2017 年 5 月發行 OpenCL 22 之時，Khronos Group 宣佈 OpenCL 將盡可能的匯合於 Vulkan，以確使 OpenCL 軟體在這兩種 API 上靈活部署。這已經由 Adobe 的 Premiere Rush 展示出來，它使用 clspv 開源編譯器，編譯了大量 OpenCL C 核心程式碼，使其在部署於 Android 的 Vulkan 執行時系統上執行。 OpenCL 擁有獨立於 Vulkan 的前瞻性路線圖，即曾意圖在 2020 年發行的 OpenCL Next，它可以集成於擴充套件諸如 VulkanOpenCL 互操作、ScratchPad 記憶體管理、擴充套件子組、SPIRV 14 攝入和 SPIRV 擴充套件除錯資訊；OpenCL 還在考慮類似 Vulkan 的裝載器和分層以及 靈活配置，以便在多種加速型別上靈活部署。 OpenCL 30 在 2020 年 8 月 30 日，發行了最終的 OpenCL 30 規範。OpenCL 12 功能已經成為強制性基準，而所有 OpenCL 2x 和 OpenCL 30 特徵變為可選項。這個規範保留了 OpenCL C 語言，並廢棄了版本 21 介入的 OpenCL C 核心語言，將其替代為 C for OpenCL 語言，它基於了 ClangLLVM 編譯器，實現了 C17 的子集和中間程式碼。C for OpenCL 版本 10 的官方文件在 2020 年 12 月發表，它後向兼容於 OpenCL C 20。 在 21 上釋出的 OpenCL 307，提出了 C for OpenCL 的新版本和一些 Khronos openCL 擴充套件。在 2021 年 12 月，發行了 C for OpenCL 版本 2021，它完全兼容於 OpenCL 30 標準。NVIDIA 密切協作於 Khronos OpenCL 工作組，透過訊號量和記憶體共享改進了 Vulkan 互操作。小更新 3014 版本，具有缺陷修正和針對多裝置的一個新擴充套件。 範例 快速傅立葉變換 一個快速傅立葉變換的式子： create a compute context with GPU device context clCreateContextFromType NULL CL_DEVICE_TYPE_GPU NULL NULL NULL create a command queue queue clCreateCommandQueue context NULL 0 NULL allocate the buffer memory objects memobjs 0 clCreateBuffer context CL_MEM_READ_ONLY CL_MEM_COPY_HOST_PTR sizeof float2num_entries srcA NULL memobjs 1 clCreateBuffer context CL_MEM_READ_WRITE sizeof float2num_entries NULL NULL create the compute program program clCreateProgramWithSource context 1 fft1D_1024_kernel_src NULL NULL build the compute program executable clBuildProgram program 0 NULL NULL NULL NULL create the compute kernel kernel clCreateKernel program fft1D_1024 NULL set the args values clSetKernelArg kernel 0 sizeof cl_memvoid memobjs 0 clSetKernelArg kernel 1 sizeof cl_memvoid memobjs 1 clSetKernelArg kernel 2 sizeof floatlocal_work_size 0116 NULL clSetKernelArg kernel 3 sizeof floatlocal_work_size 0116 NULL create ND range object with workitem dimensions and execute kernel global_work_size 0 num_entries local_work_size 0 64 clEnqueueNDRangeKernel queue kernel 1 NULL global_work_size local_work_size 0 NULL NULL 真正的運算：（基於 Fitting FFT onto the G80 Architecture） This kernel computes FFT of length 1024 The 1024 length FFT is decomposed into calls to a radix 16 function another radix 16 function and then a radix 4 function __kernel void fft1D_1024 __global float2 in __global float2 out __local float sMemx __local float sMemyint tid get_local_id 0 int blockIdx get_group_id 0 1024 tid float2 data 16 starting index of data tofrom global memory in in blockIdx out out blockIdx globalLoads data in 64 coalesced global reads fftRadix16Pass data inplace radix16 pass twiddleFactorMul data tid 1024 0 local shuffle using local memory localShuffle data sMemx sMemy tid tid 15 65 tid 4 fftRadix16Pass data inplace radix16 pass twiddleFactorMul data tid 64 4 twiddle factor multiplication localShuffle data sMemx sMemy tid tid 4 64 tid 15 four radix4 function calls fftRadix4Pass data radix4 function number 1 fftRadix4Pass data 4 radix4 function number 2 fftRadix4Pass data 8 radix4 function number 3 fftRadix4Pass data 12 radix4 function number 4 coalesced global writes globalStores data out 64 Apple 的網站上可以發現傅立葉變換的例子 平行合併排序法 使用 Python 3x 搭配 PyOpenCL 與 NumPy import io import random import numpy as np import pyopencl as cl def dump_step data chunk_size 顯示排序過程 msg ioStringIO div ioStringIO for idx item in enumerate data if idx chunk_size 0 if idx 0 msgwrite divwrite divwrite else msgwrite divwrite msgwrite 2dformat item out msggetvalue if chunk_size 1 print len out 1 print out print divgetvalue msgclose divclose def cl_merge_sort_sbs data_in 平行合併排序 OpenCL kernel 函式程式碼 CL_CODE kernel void merge int chunk_size int size global long data global long buff 取得分組編號 const int gid get_global_id 0 根據分組編號計算責任範圍 const int offset gid chunk_size const int real_size min offset chunk_size size offset global long data_part data offset global long buff_part buff offset 設定合併前的初始狀態 int r_beg chunk_size 1 int b_ptr 0 int l_ptr 0 int r_ptr r_beg 進行合併 while b_ptr real_size if r_ptr real_size 若右側沒有資料，取左側資料堆入緩衝區 buff_part b_ptr data_part l_ptr else if l_ptr r_beg 若左側沒有資料，取右側資料堆入緩衝區 buff_part b_ptr data_part r_ptr else 若兩側都有資料，取較小資料堆入緩衝區 if data_part l_ptr data_part r_ptr buff_part b_ptr data_part l_ptr else buff_part b_ptr data_part r_ptr b_ptr 配置計算資源，編譯 OpenCL 程式 ctx clContext dev_typecldevice_typeGPU prg clProgram ctx CL_CODEbuild queue clCommandQueue ctx mf clmem_flags 資料轉換成 numpy 形式以利轉換為 OpenCL Buffer data_np npint64 data_in buff_np npempty_like data_np 建立緩衝區，並且複製數值到緩衝區 data clBuffer ctx mfREAD_WRITE mfCOPY_HOST_PTR hostbufdata_np buff clBuffer ctx mfREAD_WRITE mfCOPY_HOST_PTR hostbufbuff_np 設定合併前初始狀態 data_len npint32 len data_np chunk_size npint32 1 dump_step data_np chunk_size while chunk_size data_len 更新分組大小，每一回合變兩倍 chunk_size 1 換算平行作業組數 group_size data_len 1 chunk_size 1 進行分組合併作業 prgmerge queue group_size 1 chunk_size data_len data buff 將合併結果作為下一回合的原始資料 temp data data buff buff temp 顯示此回合狀態 clenqueue_copy queue data_np data dump_step data_np chunk_size queuefinish datarelease buffrelease def main n randomrandint 5 16 data for i in range n dataappend randomrandint 1 99 cl_merge_sort_sbs data if __name__ __main__ main 執行結果： 85 41 64 40 90 29 38 41 64 17 20 41 16 65 83 41 85 40 64 29 90 38 41 17 64 20 41 16 65 83 40 41 64 85 29 38 41 90 17 20 41 64 16 65 83 29 38 40 41 41 64 85 90 16 17 20 41 64 65 83 16 17 20 29 38 40 41 41 41 64 64 65 83 85 90 參見 GPGPU CUDA DirectCompute C AMP 參考文獻 外部連結 支援 OpenCL 的產品 開源 GPU 社群 CategoryC 語言家族 Category 應用程式介面 CategoryGPGPU OpenCL Category 平行計算 Category 跨平臺軟體