目錄
- 前言
- 一、介紹
- 二、統一編譯
- 三、使用統一后端
- 四、切換后端
- 五、案例
- 六、注意事項
前言
在《玩轉 ArrayFire:07 陣列和矩陣操作》中,我們已經了解到 ArrayFire 的陣列和矩陣操作,在這一篇中,我們將繼續了解 ArrayFire 的后端,
一、介紹
ArrayFire 的統一后端是在版本 3.2 中引入的,雖然這不是一個獨立的后端,但它允許用戶在運行時可以在不同的 ArrayFire 后端(CPU、CUDA和OpenCL)切換,
二、統一編譯
使用統一后端進行編譯的步驟與使用任何其他后端進行編譯的步驟相同,唯一的區別是可執行檔案需要鏈接到 af 庫(如 Linux 的 libaf.so、OSX的 libaf.dylib、Windows 的 af.lib 等),如果想要與 CMake 一起使用,請使用 ArrayFire_Unified_LIBRARIES 變數,
三、使用統一后端
統一后端將動態地加載后端庫,后端優先級為 CUDA -> OpenCL -> CPU ,這里需要注意的最重要的一點是,ArrayFire 庫所依賴的所有庫都需要位于環境路徑中,
- LD_LIBRARY_PATH -> Linux, Unix, OSX
- DYLD_LIBRARY_PATH -> OSX
- PATH -> Windows
如果缺少任何庫,那么 ArrayFire 庫將無法加載,后端也將被標記為不可用,如果該路徑不在系統路徑中,那么 ArrayFire 庫可能會出現在 AF_PATH 或 AF_BUILD_PATH 環境變數中,這些路徑被視為備用路徑,以防在系統路徑中找不到這些檔案,但是,ArrayFire 庫的所有其他上游庫必須出現在上面所示的系統路徑變數中,
四、切換后端
af_backend 列舉存盤可能的后端,要選擇后端,呼叫 af::setBackend 函式,如下所示:
af::setBackend(AF_BACKEND_CUDA); // Sets CUDA as current backend
可以呼叫 af::getBackendCount 函式來獲取后端可用的數量(成功加載 libaf* 后端庫的數量),
五、案例
#include <arrayfire.h>
void testBackend()
{
af::info();
af_print(af::randu(5, 4));
}
int main()
{
try {
printf("Trying CPU Backend\n");
af::setBackend(AF_BACKEND_CPU);
testBackend();
} catch (af::exception& e) {
printf("Caught exception when trying CPU backend\n");
fprintf(stderr, "%s\n", e.what());
}
try {
printf("Trying CUDA Backend\n");
af::setBackend(AF_BACKEND_CUDA);
testBackend();
} catch (af::exception& e) {
printf("Caught exception when trying CUDA backend\n");
fprintf(stderr, "%s\n", e.what());
}
try {
printf("Trying OpenCL Backend\n");
af::setBackend(AF_BACKEND_OPENCL);
testBackend();
} catch (af::exception& e) {
printf("Caught exception when trying OpenCL backend\n");
fprintf(stderr, "%s\n", e.what());
}
return 0;
}
輸出結果,如下所示:
Trying CPU Backend
ArrayFire v3.2.0 (CPU, 64-bit Linux, build fc7630f)
[0] Intel: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz Max threads(8)
af::randu(5, 4)
[5 4 1 1]
0.0000 0.2190 0.3835 0.5297
0.1315 0.0470 0.5194 0.6711
0.7556 0.6789 0.8310 0.0077
0.4587 0.6793 0.0346 0.3834
0.5328 0.9347 0.0535 0.0668
Trying CUDA Backend
ArrayFire v3.2.0 (CUDA, 64-bit Linux, build fc7630f)
Platform: CUDA Toolkit 7.5, Driver: 355.11
[0] Quadro K5000, 4093 MB, CUDA Compute 3.0
af::randu(5, 4)
[5 4 1 1]
0.7402 0.4464 0.7762 0.2920
0.9210 0.6673 0.2948 0.3194
0.0390 0.1099 0.7140 0.8109
0.9690 0.4702 0.3585 0.1541
0.9251 0.5132 0.6814 0.4452
Trying OpenCL Backend
ArrayFire v3.2.0 (OpenCL, 64-bit Linux, build fc7630f)
[0] NVIDIA : Quadro K5000
-1- INTEL : Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz
af::randu(5, 4)
[5 4 1 1]
0.4107 0.0081 0.6600 0.1046
0.8224 0.3775 0.0764 0.8827
0.9518 0.3027 0.0901 0.1647
0.1794 0.6456 0.5933 0.8060
0.4198 0.5591 0.1098 0.5938
六、注意事項
如果不小心切換后端,很容易遇到例外,
- 不要在不同的后端之間使用 array
ArrayFire 檢查輸入到函式的陣列是否與活動后端匹配,如果在一個后端創建陣列,但在另一個后端使用,則拋出代碼為 503 (AF_ERR_ARR_BKND_MISMATCH)的例外,
#include <arrayfire.h>
int main()
{
try {
af::setBackend(AF_BACKEND_CUDA);
af::array A = af::randu(5, 5);
af::setBackend(AF_BACKEND_OPENCL);
af::array B = af::constant(10, 5, 5);
af::array C = af::matmul(A, B); // This will throw an exception
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
return 0;
}
- 使用命名方案來跟蹤 array 和后端
我們建議您使用一種技術來跟蹤后端上的陣列,一種建議是在陣列名中使用 _cpu, _cuda, _opencl 后綴,因此,在 CUDA 后端創建的陣列將被命名為 myarray_cuda ,如果你還沒有在你的代碼中使用過 af::setBackend 函式,那么你就不用擔心這個問題,因為所有的陣列都是在相同的默認后端創建的,
- 不能同時使用自定義內核(CUDA/OpenCL)與統一后端
不建議使用帶有統一后端的自定義內核,這主要是因為統一后端意味著超級可移植,應該只使用 ArrayFire 和本地 CPU 代碼,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/257856.html
標籤:區塊鏈
下一篇:vue專案 前端實作列印功能
