歡迎關注我的公眾號 [極智視界],獲取我的更多筆記分享
O_o
>_<
o_O
O_o
~_~
o_O
本文介紹一下寒武紀 BANG C 的程式設計方式。
相信接觸過 CUDA C 的同學比較多, 但接觸過 BANG C 的同學會少很多,這主要源於 GPU 的使用人群量是 MLU 不可比擬的,不過多學習一些異構程式設計方面的東西還是好的。這裡分享一下寒武紀 BANG C 的程式設計方式,看起來和 CUDA C 會比較類似。我們知道一般的異構程式設計會分為 Host 端和 Device 端,在 Host 端做邏輯判斷,在 Device 端做平行計算。在 BANG C 程式設計中也是一樣,分為 Host 端和 MLU 端,下面從這兩端程式設計方式分別進行介紹。
1、Host 端
Host 端呼叫 CNRT 介面,CNRT 是 MLU 的推理執行時庫,需要包 cnrt。h 頭:
#include “cnrt。h”
進行裝置初始化:
cnrtInit(0);cnrtDev_t dev;cnrtGetDeviceHandle(&dev, 0);cnrtSetCurrentDevice(dev);
建立 Queue:
cnrtQueue_t queue;cnrtCreateQueue(&queue);
指定任務規模和排程型別:
cnrtDim3_t dim; dim。x = 1;dim。y = 1;dim。z = 1;cnrtFunctionType_t func_type = CNRT_FUNC_TYPE_BLOCK;
準備 Kernel 的引數:
cnrtKernelParamsBuffer_t params;cnrtKernelInitParam_t init_param;cnrtCreateKernelInitParam(&init_param);cnrtInitKernelMemory(kernel, init_param);。。。uint32_t param1 = SIZE_INPUT;cnrtGetKernelParamsBuffer(¶ms);cnrtKernelParamsBufferAddParam(params, ¶m1, sizeof(uint32_t));。。。
在 GDRAM 上為輸入資料分配記憶體:
half *ptr_mlu_input;cnrtMalloc((void **)&ptr_mlu_input, N * sizeof(half));
輸入資料拷入 GDRAM:
cnrtMemcpy(&ptr_mlu_input prt_host_input, CNRT_MEM_TRANS_DIR_HOST2DEV);
啟動 Kernel,並繫結到 Queue:
cnrtInvokeKernel_V3((void *)&kernel, init_param, dim, params, func_type, queue, NULL);
同步 Queue:
cnrtSyncQueue(queue);
資料拷出:
cnrtMemcpy(ptr_host_output, ptr_mlu_output, SIZE_OUTPUT, CNRT_MEM_TRANS_DIR_DEV2HOST);
資源釋放:
cnrtDestroyQueue(queue);cnrtDestoryKernelParamsBuffer(params);cnrtDestroy();
2、MLU 端
MLU 端的程式碼就是基於 BANG C 來寫的了,類似 CUDA C,是基於 C 語言的擴充套件,其檔名字尾為 。mlu。
MLU 端程式需要包含 mlu。h 頭:
#inlcude “mlu。h”
再包含一些其他需要的頭:
#include “macro。h”#define s1 N1#define s2 N2
BANG C Kernel 的入口函式需要用
__mlu_entry__
標記,類似於 CUDA C 中的
__global__
:
__mlu__entry__ void kernel(uint32_t size1, uint32_t size2, half* c, half* a, half* b){ /// __nram__ 是標記 NRAM 空間的變數 __nram__ half a_tmp[s1]; __nram__ half b_tmp[s2]; __nram__ half c_tmp[s3]; /// 將資料從 GRAM 複製到 NRAM 上 __memcpy(a_tmp, a, s1 * sizeof(half), GDRAM2NRAM); __memcpy(b_tmp, b, s2 * sizeof(half), GDRAM2NRAM); /// 將 NRAM 上資料進行迴圈 add 計算 __bang_cycle_add(c_tmp, b_tmp, a_tmp, size2, size1); /// 將計算結果從 NRAM 複製到 GDRAM,HOST端可以從 RDRAM 拿資料 __memcpy(c, c_tmp, s2 * sizeof(half), NRAM2GDRAM);}
以上分享了一下 BANG C 異構程式設計的方式,關於什麼是 NRAM、GDRAM 這些,下次我再寫一篇關於寒武紀架構的文章說明一下。
好了,收工~
【公眾號傳送】
《【程式設計藝術】寒武紀 BANG C 異構程式設計方式》