次の方法で共有


DirectML デバッグ レイヤーの使用

DirectML デバッグ レイヤーは、DirectML コードのデバッグに役立つオプションの開発時コンポーネントです。 有効にすると、DirectML デバッグ レイヤーは DirectML API 呼び出しをラップし、開発者として追加の検証とメッセージを提供します。 デバッグ レイヤーは別のライブラリ ( DirectML.Debug.dll) に実装され、コア ランタイム ライブラリ DirectML.dllによって実行時に条件付きで読み込まれます。

無効な API の使用が発生した場合に貴重な情報を提供できるため、DirectML を使用してアプリケーションを開発するときにデバッグ レイヤーを有効にすることを強くお勧めします。

デバッグ レイヤー メッセージの概要

次のコード例は、デバッグ レイヤーが不適切な API 使用状況の診断にどのように役立つかを示しています。 このコードは、DirectML ID 操作の構築を試みます。そのため、入力テンソルと出力テンソルの形状とデータ型は同じである必要があります。 ただし、この例では、出力テンソル パラメーターの間違いを示しています。

uint32_t sizes[] = { 1 };

DML_BUFFER_TENSOR_DESC inputBufferDesc = {};
inputBufferDesc.DataType = DML_TENSOR_DATA_TYPE_FLOAT32;
inputBufferDesc.DimensionCount = ARRAYSIZE(sizes);
inputBufferDesc.Sizes = sizes;
inputBufferDesc.TotalTensorSizeInBytes = 256;

DML_BUFFER_TENSOR_DESC outputBufferDesc = {};
outputBufferDesc.DataType = DML_TENSOR_DATA_TYPE_FLOAT16; // Invalid: doesn't match input type!
outputBufferDesc.DimensionCount = ARRAYSIZE(sizes);
outputBufferDesc.Sizes = sizes;
outputBufferDesc.TotalTensorSizeInBytes = 256;

DML_TENSOR_DESC inputDesc = { DML_TENSOR_TYPE_BUFFER, &inputBufferDesc };
DML_TENSOR_DESC outputDesc = { DML_TENSOR_TYPE_BUFFER, &outputBufferDesc };

DML_ELEMENT_WISE_IDENTITY_OPERATOR_DESC identityDesc = {};
identityDesc.InputTensor = &inputDesc;
identityDesc.OutputTensor = &outputDesc;

DML_OPERATOR_DESC opDesc = { DML_OPERATOR_ELEMENT_WISE_IDENTITY, &identityDesc };

Microsoft::WRL::ComPtr<IDMLOperator> op;
THROW_IF_FAILED(dmlDevice->CreateOperator(&opDesc, IID_PPV_ARGS(&op)));

DirectML デバッグ レイヤーがないと、演算子を作成する最後の行が失敗し、 E_INVALIDARG (0x80070057) が返されます。 THROW_IF_FAILED マクロ (詳細については、WIL を参照) は、そのエラー コードを汎用メッセージ "パラメーターが正しくありません" に変換し、デバッガーの出力ウィンドウに出力します。

TensorValidator.h(203)\DirectML.dll!00007FF83D25ADC9: (caller: 00007FF83D267523) Exception(1) tid(3b54) 80070057 The parameter is incorrect.

ただし、DirectML デバッグ レイヤー が有効になっている場合は 、原因を絞り込むための追加情報が表示されます。

D3D12 ERROR: Mismatched tensor data types. Tensor 'Output' has DataType of DML_TENSOR_DATA_TYPE_FLOAT16, while tensor 'Input' has DataType of DML_TENSOR_DATA_TYPE_FLOAT32. Both tensors are expected to have the same DataType. [ UNKNOWN ERROR #1: STRING_FROM_APPLICATION]

TensorValidator.h(203)\DirectML.Debug.dll!00007FF86DF66ADA: (caller: 00007FF86DF81646) Exception(1) tid(9f34) 80070057 The parameter is incorrect.

拡張情報が D3D12 ERROR で始まる方法に注目してください。 DirectML デバッグ レイヤーで問題が検出されると、DirectML デバイスの作成時に渡された ID3D12Device に関連付けられている ID3D12InfoQueue にエラー メッセージを送信することを常に優先します。 上記のように、情報キュー内のエラー メッセージには常に D3D12 ERROR がプレフィックスとして付けられます。また、Direct3D 12 デバッグ レイヤー メッセージ コールバックを使用してプログラムからアクセスすることもできます ( ブログ投稿 D3D12 デバッグ レイヤー メッセージ コールバックを参照)。

ID3D12InfoQueue は、Direct3D 12 デバッグ レイヤーが ID3D12Debug::EnableDebugLayer で有効になっている場合にのみ使用できます。 Direct3D 12 と DirectML の両方のデバッグ レイヤーを一緒に有効 (または無効) にすることは常に望ましいですが、DirectML の新しいバージョンでは、Direct3D 12 デバッグ レイヤーなしで基本的なパラメーター検証がサポートされます。 Direct3D 12 デバッグ レイヤーが有効になっていないときに DML_CREATE_DEVICE_FLAG_DEBUG を使用して DirectML デバイスを作成すると、 代わりに OutputDebugStringA を使用してエラー メッセージが出力されます。

[DIRECTML WARNING]: enable the D3D debug layer for enhanced validation with DML_CREATE_DEVICE_FLAG_DEBUG.

[DIRECTML ERROR]: Mismatched tensor data types. Tensor 'Output' has DataType of DML_TENSOR_DATA_TYPE_FLOAT16, while tensor 'Input' has DataType of DML_TENSOR_DATA_TYPE_FLOAT32. Both tensors are expected to have the same DataType.

TensorValidator.h(218)\DirectML.Debug.dll!00007FF820C43AFB: (caller: 00007FF820C01CD1) Exception(1) tid(5df8) 80070057 The parameter is incorrect.

警告メッセージが示すように、DirectML デバッグ レイヤーも使用する場合は、Direct3D 12 デバッグ レイヤーを有効にすることをお勧めします。 一部の種類の検証は、両方のデバッグ レイヤーが有効になっている場合にのみ可能です。

DirectML および Direct3D 12 デバッグ レイヤーのインストール (システム コンポーネント)

DirectML をシステム コンポーネントとして使用する場合 ( DirectML バージョン履歴を参照)、デバッグ レイヤーは個別のグラフィックス ツール パッケージの一部であり、オンデマンド機能 (FOD) として配布されます (オンデマンド 機能を参照)。 DirectML のシステム バージョンでデバッグ レイヤーを使用するには、グラフィックス ツール FOD をシステムに追加する必要があります。 FOD には Direct3D 12 デバッグ レイヤーも含まれています。これは DirectML アプリケーションのデバッグにも役立ちます (ただし、必須ではありません)。

オプションのグラフィックス ツール FOD パッケージを追加するには、管理者の Powershell プロンプトから次のコマンドを実行します。

Add-WindowsCapability -Online -Name "Tools.Graphics.DirectX~~~~0.0.1.0"

または、Windows 設定内からグラフィックス ツール パッケージを追加することもできます。 Windows 10 22H2 および Windows 11 で、[設定]>システム>オプションの機能>オプション機能を追加し、グラフィックス ツールを検索します。 Windows 10 22H2 より前のバージョンでは、[設定]、[アプリ&機能]、[オプション機能] の オプション機能の追加 に移動します。

DirectML デバッグ レイヤーのインストール (スタンドアロン再頒布可能パッケージ)

スタンドアロンの再頒布可能ライブラリとして DirectML を使用する場合 ( Microsoft.AI.DirectML を参照)、DirectML デバッグ レイヤーはコア ランタイム ライブラリと共にパッケージに提供されます。 アプリケーションの実行可能ファイルの横に DirectML.Debug.dllDirectML.dll の両方を配置します。

Visual Studio を使用して nuGet パッケージの依存関係として Microsoft.AI.DirectML を追加すると、プロジェクトの構成ページに、コア ランタイム ライブラリとデバッグ レイヤー ライブラリのコピーまたはスキップのオプションが表示されます。 既定では、DirectML NuGet パッケージは、常に両方の DLL をプロジェクト出力フォルダーにコピーするように構成されます。 ただし、デバッグ レイヤーが使用されていない場合は、リリース ビルドでデバッグ レイヤーのコピーをスキップすることをお勧めします。

Visual Studio の再頒布可能デバッグ レイヤー

Direct3D 12 デバッグ レイヤーの有効化

は DirectML デバッグ レイヤー (d3d12sdklayers.dll) に依存しません。DirectML デバッグ レイヤーは DirectML API の使用に対して強化された検証を提供し、Direct3D 12 デバッグ レイヤーは Direct3D 12 API の使用を対象とします。 ただし、実際には、DirectML アプリケーションを開発するときに 両方 のデバッグ レイヤーを有効にすることをお勧めします。 Direct3D 12 デバッグ レイヤーは、上で説明したグラフィックス ツール FOD の一部としてインストールされます。 Direct3D 12 デバッグ レイヤーをアクティブ化する方法の例については、 ID3D12Debug::EnableDebugLayer を参照してください。

重要

最初に Direct3D 12 デバッグ レイヤーを有効にする必要があります。 次にDMLCreateDevice を呼び出して DirectML デバッグ レイヤーを有効にします。

DirectML デバッグ レイヤーの有効化

DMLCreateDevice を呼び出すときにDML_CREATE_DEVICE_FLAG_DEBUGを指定することで、DirectML デバッグ レイヤーを有効にすることができます。

DirectML デバッグ レイヤーを有効にすると、DirectML エラーまたは無効な API 呼び出しが発生すると、デバッグ情報がデバッグ出力として出力されます。 例を次に示します。

DML_OPERATOR_CONVOLUTION: invalid D3D12_HEAP_TYPE. DirectML requires all bound buffers to be D3D12_HEAP_TYPE_DEFAULT.

DML_FEATURE_LEVEL_5_2までは、DirectML デバッグ レイヤーを有効にするために Direct3D 12 デバッグ レイヤーを有効にする必要があります。 DirectML の以前のバージョンでは、 DML_CREATE_DEVICE_FLAG_DEBUG フラグが フラグ で指定されていて、デバッグ レイヤーがインストールされていない場合、 DMLCreateDeviceDXGI_ERROR_SDK_COMPONENT_MISSINGを返します。 DirectML の新しいバージョンでは、ID3D12InfoQueue が使用できない場合、メッセージは OutputDebugStringA に送信されます。

コード例

次のコードは、デバッグ ビルドに対してのみ Direct3D 12 と DirectML の両方のデバッグ レイヤーを有効にする方法を示しています。

// By default, disable the DirectML debug layer.
DML_CREATE_DEVICE_FLAGS dmlCreateDeviceFlags = DML_CREATE_DEVICE_FLAG_NONE;

#if defined(_DEBUG)
// If the project is in a debug build, then enable the Direct3D 12 debug layer.
// This is optional (starting in DML_FEATURE_LEVEL_5_2) but strongly recommended!
Microsoft::WRL::ComPtr<ID3D12Debug> debugController;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
{
    debugController->EnableDebugLayer();
}

// If the project is in a debug build, then enable debugging via DirectML debug layers with this flag.
dmlCreateDeviceFlags |= DML_CREATE_DEVICE_FLAG_DEBUG;
#endif

// Create the DirectML device.
Microsoft::WRL::ComPtr<IDMLDevice> dmlDevice;
THROW_IF_FAILED(DMLCreateDevice(
    d3D12Device.Get(),
    dmlCreateDeviceFlags,
    IID_PPV_ARGS(&dmlDevice));

こちらも参照ください