Verwenden der DirectML-Debugebene

Die DirectML-Debug-Ebene ist eine optionale Entwicklungszeitkomponente, die Sie beim Debuggen ihres DirectML-Codes unterstützt. Wenn diese Option aktiviert ist, umschließt die DirectML-Debugebene DirectML-API-Aufrufe und stellt zusätzliche Überprüfungs- und Meldungen für Sie als Fachkraft in der Entwicklung bereit. Die Debugebene wird in einer separaten Bibliothek implementiert, DirectML.Debug.dlldie zur Laufzeit durch die Kernlaufzeitbibliothek DirectML.dllbedingt geladen wird.

Es wird dringend empfohlen, die Debugebene beim Entwickeln von Anwendungen mit DirectML zu aktivieren, da sie bei ungültiger API-Verwendung unschätzbare Informationen bereitstellen kann.

Übersicht über Debug-Ebenenmeldungen

Im folgenden Codebeispiel wird veranschaulicht, wie die Debugebene bei der Diagnose einer falschen API-Verwendung helfen kann. Dieser Code versucht, einen DirectML-Identitätsvorgang zu erstellen; damit die Eingabe- und Ausgabe-Tensoren dieselbe Form und denselben Datentyp aufweisen sollten. In diesem Beispiel veranschaulichen wir jedoch einen Fehler in den Ausgabe-Tensorparametern.

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)));

Ohne die DirectML-Debugebene schlägt die letzte Position zum Erstellen des Operators fehl und gibt (0x80070057) zurück E_INVALIDARG . Das THROW_IF_FAILED Makro (weitere Details finden Sie unter WIL) übersetzt diesen Fehlercode in die generische Meldung „der Parameter ist falsch“, und druckt ihn in das Ausgabefenster des Debugger.

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

Wenn die DirectML-Debugebene jedoch aktiviert ist , werden zusätzliche Informationen angezeigt, um die Ursache einzugrenzen:

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.

Beachten Sie, wie die erweiterten Informationen mit D3D12 ERROR beginnen. Wenn die DirectML-Debugebene ein Problem erkennt, bevorzugt es immer, Fehlermeldungen an die ID3D12InfoQueue zu senden, die mit ID3D12Device verknüpft ist, die während der DirectML-Geräteerstellung übergeben wurde. Fehlermeldungen in der Infowarteschlange werden immer mit dem Präfix D3D12 ERROR versehen, wie oben gezeigt. Außerdem können sie programmgesteuert über einen Direct3D 12 Debug Ebenen-Nachrichtenrückruf aufgerufen werden (siehe Blogbeitrag D3D12 Debug Layer Message Callback).

Die ID3D12InfoQueue ist nur verfügbar, wenn die Direct3D 12-Debugebene mit ID3D12Debug::EnableDebugLayer aktiviert ist. Obwohl es immer vorzuziehen ist, sowohl die Direct3D 12- als auch DirectML-Debugebenen zu aktivieren (oder zu deaktivieren), unterstützen neuere Versionen von DirectML die grundlegende Parameterüberprüfung ohne die Direct3D 12-Debugebene. Wenn Sie ein DirectML-Gerät mit DML_CREATE_DEVICE_FLAG_DEBUG erstellen, während die Direct3D 12-Debugebene nicht aktiviert wurde, werden Fehlermeldungen stattdessen mithilfe von OutputDebugStringA gedruckt:

[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.

Wie die Warnmeldung sagt, empfiehlt es sich, die Direct3D 12-Debugebene zu aktivieren, wenn auch die DirectML-Debugebene verwendet wird. Einige Überprüfungstypen sind nur möglich, wenn beide Debugebenen aktiviert sind.

Installieren der DirectML- und Direct3D 12-Debugebenen (Systemkomponente)

Bei Verwendung von DirectML als Systemkomponente (siehe DirectML-Versionsverlauf) ist die Debugebene Teil eines separaten Grafiktools-Pakets, das als Feature-on-Demand (FOD) verteilt wird (siehe Features on Demand). Die Grafiktools-FOD müssen Ihrem System hinzugefügt werden, um die Debugebene mit der Systemversion von DirectML zu verwenden. Das FOD enthält auch die Direct3D 12-Debugebene, die auch für das Debuggen von DirectML-Anwendungen nützlich (aber nicht erforderlich) ist.

Um das optionale FOD-Paket für Grafiktools hinzuzufügen, führen Sie den folgenden Befehl an einer PowerShell-Eingabeaufforderung des Administrators aus.

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

Alternativ können Sie das Grafiktools-Paket in Windows Einstellungen hinzufügen. Navigieren Sie unter Windows 10 22H2 und Windows 11 zu Einstellungen> System>Optionale Features>Hinzufügen eines optionalen Features, und suchen Sie dann nach Grafiktools. Bei Versionen, die älter als Windows 10 22H2 sind, navigieren Sie stattdessen zu >Apps>Apps & Funktionen>Optionale Funktionen>Eine optionale Funktion hinzufügen.

Installieren der DirectML-Debugebene (eigenständige verteilbare)

Bei Verwendung von DirectML als eigenständige verteilbare Bibliothek (siehe Microsoft.AI.DirectML) wird die DirectML-Debugebene zusammen mit der Kernlaufzeitbibliothek im Paket bereitgestellt. Platzieren Sie sowohl DirectML.Debug.dll als auch DirectML.dll neben der ausführbaren Datei Ihrer Anwendung.

Wenn Sie Visual Studio zum Hinzufügen von Microsoft.AI.DirectML als NuGet-Paketabhängigkeit verwenden, zeigt das Projekt Optionen auf der Projektkonfigurationsseite an, um das Kopieren oder Überspringen des Kopierens der Kernlaufzeit- und Debug-Ebenenbibliotheken zu überspringen. Standardmäßig ist das DirectML NuGet-Paket so konfiguriert, dass beide DLLs immer in den Projektausgabeordner kopiert werden. Möglicherweise möchten Sie jedoch das Kopieren der Debugebene in Releasebuilds überspringen, wenn die Debugebene nicht verwendet wird.

Redistributable Debug Layer in Visual Studio

Aktivieren der Direct3D 12-Debugebene

Die Debugebene für Direct3D 12 (d3d12sdklayers.dll) ist unabhängig von der DirectML-Debugebene (DirectML.Debug.dll): Die DirectML-Debugebene bietet eine erweiterte Überprüfung für die DirectML-API-Verwendung, und die Direct3D 12-Debugebene deckt die Direct3D 12-API-Verwendung ab. In der Praxis empfiehlt es sich jedoch, beide Debugebenen beim Entwickeln von DirectML-Anwendungen zu aktivieren. Die Direct3D 12-Debugebene wird als Teil der Grafiktools-FOD installiert, die oben erläutert wird. Ein Beispiel zum Aktivieren der Direct3D 12-Debugebene finden Sie unter ID3D12Debug::EnableDebugLayer.

Wichtig

Sie müssen zuerst die Direct3D 12-Debugebene aktivieren. Aktivieren Sie dann die DirectML-Debugebene, indem Sie DMLCreateDevice aufrufen.

Verwenden der DirectML-Debugebene

Sie können die DirectML-Debugebene aktivieren, indem Sie DML_CREATE_DEVICE_FLAG_DEBUG angeben, wenn Sie DMLCreateDevice aufrufen.

Nachdem Sie die DirectML-Debugebene aktiviert haben, werden alle DirectML-Fehler oder ungültigen API-Aufrufe dazu führen, dass Debuginformationen als Debugausgabe ausgegeben werden. Im Folgenden sehen Sie ein Beispiel.

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

Bis DML_FEATURE_LEVEL_5_2 ist es eine Anforderung, die Direct3D 12-Debugebene zu aktivieren, um die DirectML-Debugebene zu aktivieren. Wenn in früheren Versionen von DirectML das DML_CREATE_DEVICE_FLAG_DEBUG Flag in Flags angegeben ist und die Debugebenen nicht installiert sind, gibt DMLCreateDevice DXGI_ERROR_SDK_COMPONENT_MISSING zurück. In neueren Versionen von DirectML werden Nachrichten an OutputDebugStringA gesendet, wenn ID3D12InfoQueue nicht verfügbar ist.

Code-Beispiel

Der folgende Code veranschaulicht die Aktivierung der Direct3D 12- und DirectML-Debugebenen nur für Debugbuilds.

// 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));

Weitere Informationen