Utilisation de la couche de débogage DirectML

La couche de débogage DirectML est un composant facultatif pendant le développement qui vous aide à déboguer votre code DirectML. Lorsque cette option est activée, la couche de débogage DirectML encapsule les appels d’API DirectML et fournit des messages et validation supplémentaires au développeur. La couche de débogage est implémentée dans une bibliothèque distincte, DirectML.Debug.dll, qui est chargée conditionnellement au moment de l’exécution par la bibliothèque runtime principale DirectML.dll.

Nous vous recommandons fortement d’activer la couche de débogage lors du développement d’applications à l’aide de DirectML, car elle peut fournir des informations précieuses en cas d’utilisation d’API non valide.

Vue d’ensemble des messages de la couche de débogage

L’exemple de code ci-dessous montre comment la couche de débogage peut aider à diagnostiquer l’utilisation incorrecte d’API. Ce code tente de construire une opération d’identité DirectML. Ainsi, les tenseurs d’entrée et de sortie doivent avoir le même type de forme et de données. Toutefois, dans cet exemple, nous expliquons une erreur dans les paramètres de tenseur de sortie.

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

Sans la couche de débogage DirectML, la ligne finale pour créer l’opérateur échoue et retourne E_INVALIDARG (0x80070057). La macro THROW_IF_FAILED (pour plus d’informations, voir WIL) traduit ce code d’erreur dans le message générique « le paramètre est incorrect » et l’affiche dans la fenêtre de sortie du débogueur.

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

Toutefois, lorsque la couche de débogage DirectML est activée, vous verrez des informations supplémentaires pour affiner la cause :

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.

Remarquez comment les informations étendues commencent par ERREUR D3D12. Lorsque la couche de débogage DirectML détecte un problème, elle préfère toujours envoyer des messages d’erreur à ID3D12InfoQueue associé à ID3D12Device passé lors de la création de l’appareil DirectML. Les messages d’erreur dans la file d’attente d’informations sont toujours précédés de D3D12 ERROR, comme indiqué ci-dessus. Ils sont également accessibles par programmation à l’aide d’un rappel de message de couche de débogage Direct3D 12 (voir le billet de blog rappel de message de couche de débogage D3D12).

ID3D12InfoQueue est disponible uniquement lorsque la couche de débogage Direct3D 12 est activée avec ID3D12Debug::EnableDebugLayer. Bien qu’il soit toujours préférable d’activer (ou de désactiver) les couches de débogage Direct3D 12 et DirectML ensemble, les versions plus récentes de DirectML prennent en charge la validation des paramètres de base sans la couche de débogage Direct3D 12. Si vous créez un appareil DirectML avec DML_CREATE_DEVICE_FLAG_DEBUG alors que la couche de débogage Direct3D 12 n’a pas été activée, les messages d’erreur sont affichés à l’aide de 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.

Comme le suggère le message d’avertissement, il est préférable d’activer la couche de débogage Direct3D 12 lors de l’utilisation de la couche de débogage DirectML. Certains types de validation sont possibles uniquement lorsque les deux couches de débogage sont activées.

Installation des couches de débogage DirectML et Direct3D 12 (composant système)

Lors de l’utilisation de DirectML en tant que composant système (voir Historique des versions DirectML), la couche de débogage fait partie d’un package Outils graphiques distinct, distribué en tant que fonctionnalité à la demande (FOD) (voir Fonctionnalités à la demande). La FOD Outils graphiques doit être ajouté à votre système pour utiliser la couche de débogage avec la version système de DirectML. La FOD contient également la couche de débogage Direct3D 12, ce qui est également utile (mais pas obligatoire) pour le débogage d’applications DirectML.

Pour ajouter le package FOD Outils graphiques facultatif, exécutez la commande suivante à partir d’une invite PowerShell avec privilèges d’administrateur.

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

Vous pouvez également ajouter le package Outils graphiques à partir des Paramètres Windows. Sur Windows 10 22H2 et Windows 11, accédez à Paramètres>Système>Fonctionnalités facultatives>Ajouter une fonctionnalité facultative, puis recherchez Outils graphiques. Sur les versions antérieures à Windows 10 22H2, accédez à Paramètres>Applications>Applications et fonctionnalités>Fonctionnalités facultatives>Ajouter une fonctionnalité.

Installation de la couche de débogage DirectML (redistribuable autonome)

Lors de l’utilisation de DirectML en tant que bibliothèque redistribuable autonome (voir Microsoft.AI.DirectML), la couche de débogage DirectML est fournie dans le package en même temps que la bibliothèque de runtime principale. Placez les deux DirectML.Debug.dll et DirectML.dll en regard de l’exécutable de votre application.

Si vous utilisez Visual Studio pour ajouter Microsoft.AI.DirectML en tant que dépendance de package NuGet, le projet affiche les options de la page de configuration du projet pour copier ou ignorer la copie des bibliothèques de couches principales de runtime et de débogage. Par défaut, le package NuGet DirectML est configuré pour toujours copier les deux DLL dans votre dossier de sortie de projet. Toutefois, vous pouvez ignorer la copie de la couche de débogage dans les générations de mise en production si la couche de débogage n’est pas utilisée.

Redistributable Debug Layer in Visual Studio

Activation de la couche de débogage Direct3D 12

La couche de débogage pour Direct3D 12 (d3d12sdklayers.dll) est indépendante de la couche de débogage DirectML (DirectML.Debug.dll) : la couche de débogage DirectML fournit une validation améliorée pour l’utilisation de l’API DirectML, et la couche de débogage Direct3D 12 couvre l’utilisation de l’API Direct3D 12. Toutefois, dans la pratique, il est préférable d’activer les deux couches de débogage lors du développement d’applications DirectML. La couche de débogage Direct3D 12 est installée dans le cadre de la FOD Outils graphiques, qui est expliqué ci-dessus. Reportez-vous à ID3D12Debug::EnableDebugLayer pour obtenir un exemple d’activation de la couche de débogage Direct3D 12.

Important

Vous devez d’abord activer la couche de débogage Direct3D 12. Activez ensuite la couche de débogage DirectML en appelant DMLCreateDevice.

Activation de la couche de débogage DirectML

Vous pouvez activer la couche de débogage DirectML en fournissant DML_CREATE_DEVICE_FLAG_DEBUG lorsque vous appelez DMLCreateDevice.

Une fois que vous avez activé la couche de débogage DirectML, les erreurs DirectML ou les appels d’API non valides entraînent l’émission d’informations de débogage en tant que sortie de débogage. Voici un exemple.

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

Jusqu’à DML_FEATURE_LEVEL_5_2, il est nécessaire d’activer la couche de débogage Direct3D 12 pour activer la couche de débogage DirectML. Dans les versions antérieures de DirectML, si l’indicateur DML_CREATE_DEVICE_FLAG_DEBUG est spécifié dans les indicateurs et que les couches de débogage ne sont pas installées, DMLCreateDevice retourne DXGI_ERROR_SDK_COMPONENT_MISSING. Dans les versions plus récentes de DirectML, les messages sont envoyés à OutputDebugStringA quand ID3D12InfoQueue n’est pas disponible.

Exemple de code

Le code suivant illustre l’activation des couches de débogage Direct3D 12 et DirectML uniquement pour les versions de débogage.

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

Voir aussi