oneDNN 執行提供程式
前身為“DNNL”
使用英特爾 oneDNN 執行提供程式,利用英特爾® 深度神經網路數學核心庫 (Intel® DNNL) 最佳化的原語來加速 ONNX Runtime 的效能。
Intel® oneAPI 深度神經網路庫是一個用於深度學習應用程式的開源效能庫。該庫在英特爾® 架構和英特爾® 處理器圖形架構上加速深度學習應用程式和框架。Intel DNNL 包含向量化和執行緒化的構建模組,可用於透過 C 和 C++ 介面實現深度神經網路 (DNN)。
ONNX Runtime 的 oneDNN 執行提供程式 (EP) 由英特爾和微軟合作開發。
目錄
構建
有關構建說明,請參閱構建頁面。
用法
C/C++
DNNLExecutionProvider 執行提供程式需要向 ONNX Runtime 註冊才能在推理會話中啟用。
Ort::Env env = Ort::Env{ORT_LOGGING_LEVEL_ERROR, "Default"};
Ort::SessionOptions sf;
bool enable_cpu_mem_arena = true;
Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_Dnnl(sf, enable_cpu_mem_arena));
C API 詳情請見此處。
Python
當使用帶有 DNNL 執行提供程式構建的 ONNX Runtime 的 Python wheel 時,它將自動優先於 CPU 執行提供程式。Python API 詳情請見此處。
子圖最佳化
DNNL 使用塊狀佈局(例如:通道被 16 阻斷的 nhwc – nChw16c)來利用 AVX512 的向量操作。為獲得最佳效能,我們避免重排序(例如:Nchw16c 到 nchw)並將塊狀佈局傳播到下一個原語。
子圖最佳化透過以下步驟實現這一點。
- 解析 ONNX Runtime 圖並建立子圖的內部表示。
- 子圖運算子 (DnnlFunKernel) 遍歷 DNNL 節點並建立向量 DNNL 核。
- DnnlFunKernel 的計算函式遍歷並將資料繫結到向量中的 DNNL 原語,然後提交向量進行執行。
子圖(IR)內部表示
DnnlExecutionProvider::GetCapability() 解析 ONNX 模型圖並建立 DNNL 運算元子圖的 IR(內部表示)。每個子圖包含一個 DnnlNodes 向量、輸入、輸出及其所有 DnnlNodes 的屬性。可能存在同名屬性,因此我們將屬性名稱加上節點名稱及其索引作為字首。子圖的唯一 ID 被設定為一個屬性。
DnnlNode 具有指向其輸入和輸出的索引以及指向其父節點的指標。DnnlNode 直接從其父節點讀取塊狀記憶體以避免資料重排序。

子圖類
DnnlConv、DnnlPool 等原語均派生自 DnnlKernel 基類。
以下 UML 圖展示了子圖類。

子圖執行
DnnlExecutionProvicer::Compute() 函式建立 DnnlFuncKernel 並呼叫其 Compute 函式。
DnnlFuncKernel::Compute 函式建立 SubgraphPrimitve 池並將物件新增到對映中。
SubgraphPrimitve 建構函式呼叫以下成員函式
SubgraphPrimitve::CreatePrimitives()
for (auto& mklnode : mklnodes) {
if (mklnode.name == "Conv") {
kernel.reset(new DnnlConv());
kernels.push_back(kernel);
} else if (mklnode.name == "BatchNormalization-Relu") {
kernel.reset(new DnnlBatchNorm());
context_.kernels.push_back(kernel);
} else if (mklnode.name == "MaxPool") {
kernel.reset(new DnnlPool());
context_.kernels.push_back(kernel);
}
.
.
.
在 CreatePrimitives 方法中,我們遍歷 DnnlNodes 並建立 DnnlKernel 物件,將 DNNL 原語新增到向量中。它還讀取屬性。這隻在第一次迭代時執行一次。
SubgraphPrimitve::Compute()
for (auto& kernel : kernels) {
kernel->Bind(input_tensors, output_tensors);
}
stream->submit(net);
在 SubgraphPrimitve::Compute() 方法中,我們遍歷 DNNL 核並繫結輸入資料。然後我們將原語向量提交到 DNNL 流。
支援範圍
支援的作業系統
- Ubuntu 16.04
- Windows 10
- Mac OS X
支援的後端
- CPU