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)並將塊狀佈局傳播到下一個原語。

子圖最佳化透過以下步驟實現這一點。

  1. 解析 ONNX Runtime 圖並建立子圖的內部表示。
  2. 子圖運算子 (DnnlFunKernel) 遍歷 DNNL 節點並建立向量 DNNL 核。
  3. DnnlFunKernel 的計算函式遍歷並將資料繫結到向量中的 DNNL 原語,然後提交向量進行執行。

子圖(IR)內部表示

DnnlExecutionProvider::GetCapability() 解析 ONNX 模型圖並建立 DNNL 運算元子圖的 IR(內部表示)。每個子圖包含一個 DnnlNodes 向量、輸入、輸出及其所有 DnnlNodes 的屬性。可能存在同名屬性,因此我們將屬性名稱加上節點名稱及其索引作為字首。子圖的唯一 ID 被設定為一個屬性。

DnnlNode 具有指向其輸入和輸出的索引以及指向其父節點的指標。DnnlNode 直接從其父節點讀取塊狀記憶體以避免資料重排序。

MKL-DNN Node

子圖類

DnnlConv、DnnlPool 等原語均派生自 DnnlKernel 基類。

以下 UML 圖展示了子圖類。

MKL-DNN subgraph

子圖執行

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

其他資源