Uso de la capa de depuración de DirectML

La capa de depuración de DirectML es un componente opcional en tiempo de desarrollo que le ayuda a depurar el código de DirectML. Cuando está habilitada, la capa de depuración de DirectML ajusta las llamadas a la API de DirectML y proporciona mensajes y validación adicionales para usted como desarrollador. La capa de depuración se implementa en una biblioteca independiente, DirectML.Debug.dll, que se carga condicionalmente en tiempo de ejecución mediante la biblioteca principal en tiempo de ejecución DirectML.dll.

Se recomienda encarecidamente habilitar la capa de depuración al desarrollar aplicaciones mediante DirectML, ya que puede proporcionar información valiosa en caso de un uso de la API no válido.

Información general sobre los mensajes de capa de depuración

En el ejemplo de código siguiente se muestra cómo la capa de depuración puede ayudar a diagnosticar el uso incorrecto de la API. Este código intenta construir una operación de identidad de DirectML; por lo tanto, los tensores de entrada y salida deben tener la misma forma y tipo de datos. Sin embargo, en este ejemplo se muestra un error en los parámetros del tensor de salida.

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

Sin la capa de depuración de DirectML, se produce un error en la línea final para crear el operador y se devuelve E_INVALIDARG (0x80070057). La macro THROW_IF_FAILED (para obtener más detalles, consulte WIL) convierte ese código de error en el mensaje genérico "el parámetro es incorrecto" y lo imprime en la ventana de salida del depurador.

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

Pero cuando la capa de depuración de DirectML esté habilitada, verá información adicional para restringir la causa:

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.

Observe cómo comienza la información extendida con el ERROR D3D12. Cuando la capa de depuración de DirectML detecta un problema, siempre prefiere enviar mensajes de error a la cola ID3D12InfoQueue asociada pasando el valor id3D12Device durante la creación del dispositivo DirectML. Los mensajes de error de la cola de información siempre tienen el prefijo D3D12 ERROR, como se muestra anteriormente; y también son accesibles mediante programación mediante una devolución de llamada de mensaje de capa de depuración de Direct3D 12 (consulte la entrada de blog D3D12 debug layer message callback).

La cola Id3D12InfoQueue solo está disponible cuando la capa de depuración de Direct3D 12 está habilitada con ID3D12Debug::EnableDebugLayer. Aunque siempre es preferible habilitar (o deshabilitar) las capas de depuración de Direct3D 12 y DirectML a la vez, las versiones más recientes de DirectML admiten la validación básica de parámetros sin la capa de depuración de Direct3D 12. Si crea un dispositivo DirectML con DML_CREATE_DEVICE_FLAG_DEBUG y la capa de depuración de Direct3D 12 no está habilitada, se imprimen mensajes de error en su lugar mediante 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.

Como sugiere el mensaje de advertencia, es mejor habilitar la capa de depuración de Direct3D 12 al usar también la capa de depuración de DirectML. Algunos tipos de validación solo son posibles cuando ambas capas de depuración están habilitadas.

Instalación de las capas de depuración de DirectML y Direct3D 12 (componente del sistema)

Cuando se usa DirectML como componente del sistema (consulte el historial de versiones de DirectML), la capa de depuración forma parte de un paquete de Herramientas de gráficos independiente, distribuido como característica a petición (FOD) (consulte Características a petición). Las herramientas de gráficos FOD deben agregarse al sistema para poder usar la capa de depuración con la versión del sistema de DirectML. La característica a petición contiene la capa de depuración de Direct3D 12, que también es útil (pero no necesaria) para depurar aplicaciones DirectML.

Para agregar el paquete FOD opcional de Herramientas de gráficos, ejecute el siguiente comando desde un símbolo del sistema de PowerShell de administrador.

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

Como alternativa, puede agregar el paquete Herramientas de gráficos desde la configuración de Windows. En Windows 10 22H2 y Windows 11, vaya a Configuración>Características>opcionales del sistema>Agregar una característica opcional y, a continuación, busque Herramientas de gráficos. En las versiones de Windows 10 anteriores a 22H2, vaya a Configuración>Aplicaciones>Aplicaciones y características>Características opcionales>Agregar una característica opcional.

Instalación de la capa de depuración de DirectML (redistribución independiente)

Cuando se usa DirectML como una biblioteca redistribuible independiente (consulte Microsoft.AI.DirectML), la capa de depuración de DirectML se incluye en el paquete junto con la biblioteca principal en tiempo de ejecución. Coloque tanto DirectML.Debug.dll como DirectML.dll junto al ejecutable de la aplicación.

Si usa Visual Studio para agregar Microsoft.AI.DirectML como dependencia de paquete NuGet, el proyecto mostrará opciones en la página de configuración del proyecto para copiar o omitir la copia del entorno de ejecución principal y las bibliotecas de capas de depuración. De forma predeterminada, el paquete NuGet de DirectML está configurado para copiar siempre ambos archivos DLL en la carpeta de salida del proyecto. Sin embargo, es posible que quiera omitir la copia de la capa de depuración en las compilaciones de la versión si no se usa la capa de depuración.

Redistributable Debug Layer in Visual Studio

Habilitación de la capa de depuración de Direct3D 12

La capa de depuración de Direct3D 12 (d3d12sdklayers.dll) es independiente de la capa de depuración de DirectML (DirectML.Debug.dll): la capa de depuración de DirectML proporciona una validación mejorada para el uso de la API de DirectML y la capa de depuración de Direct3D 12 cubre el uso de la API de Direct3D 12. Sin embargo, en la práctica, es mejor habilitar ambas capas de depuración al desarrollar aplicaciones de DirectML. La capa de depuración de Direct3D 12 se instala como parte de la característica a petición Herramientas de gráficos, que se explica anteriormente. Consulte ID3D12Debug::EnableDebugLayer para obtener un ejemplo de cómo activar la capa de depuración de Direct3D 12.

Importante

Primero debe habilitar la capa de depuración de Direct3D 12. A continuación, habilite la capa de depuración de DirectML llamando a DMLCreateDevice.

Habilitación de la capa de depuración de DirectML

Puede habilitar la capa de depuración de DirectML proporcionando DML_CREATE_DEVICE_FLAG_DEBUG al llamar a DMLCreateDevice.

Una vez que haya habilitado la capa de depuración de DirectML, los errores de DirectML o las llamadas API no válidas harán que la información de depuración se emita como salida de depuración. Este es un ejemplo.

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

Hasta DML_FEATURE_LEVEL_5_2, es un requisito habilitar la capa de depuración de Direct3D 12 para habilitar la capa de depuración de DirectML. En versiones anteriores de DirectML, si la marca DML_CREATE_DEVICE_FLAG_DEBUG se especifica en marcas y las capas de depuración no están instaladas, DMLCreateDevice devuelve DXGI_ERROR_SDK_COMPONENT_MISSING. En versiones más recientes de DirectML, se envían mensajes a OutputDebugStringA cuando ID3D12InfoQueue no está disponible.

Ejemplo de código

En el código siguiente se muestra cómo habilitar las capas de depuración de Direct3D 12 y DirectML solo para las compilaciones de depuración.

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

Consulte también