Compartilhar via


Usando a camada de depuração do DirectML

A camada de depuração do DirectML é um componente opcional de tempo de desenvolvimento que ajuda você a depurar seu código DirectML. Quando habilitada, a camada de depuração do DirectML encapsula as chamadas à API do DirectML e fornece validação e mensagens adicionais para você como desenvolvedor. A camada de depuração é implementada em uma biblioteca separada, DirectML.Debug.dll, que é carregada condicionalmente em tempo de execução pela biblioteca principal de tempo de execução DirectML.dll.

Recomendamos que você habilite a camada de depuração ao desenvolver aplicativos usando o DirectML, pois ela pode fornecer informações inestimáveis no caso de uso inválido da API.

Visão geral das mensagens da camada de depuração

O exemplo de código a seguir ilustra como a camada de depuração pode ajudar a diagnosticar o uso incorreto da API. Esse código tenta construir uma operação de identidade DirectML; portanto, os tensores de entrada e saída devem ter a mesma forma e tipo de dados. No entanto, neste exemplo, ilustramos um erro nos parâmetros tensor de saída.

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

Sem a camada de depuração DirectML, a linha final para criar o operador falha e retorna E_INVALIDARG (0x80070057). A THROW_IF_FAILED macro (para obter mais detalhes, consulte WIL) converte esse código de erro na mensagem genérica "o parâmetro está incorreto" e o imprime na janela de saída do depurador.

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

Mas quando a camada de depuração DirectML estiver habilitada, você verá informações adicionais para restringir a 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 como as informações estendidas começam com ERRO D3D12. Quando a camada de depuração do DirectML detecta um problema, ela sempre prefere enviar mensagens de erro para a ID3D12InfoQueue associada à ID3D12Device passadas durante a criação do dispositivo DirectML. As mensagens de erro na fila de informações são sempre prefixadas com ERRO D3D12, conforme mostrado acima; e também podem ser acessadas programaticamente usando um retorno de chamada de mensagem de camada de depuração do Direct3D 12 (consulte a postagem de blog retorno de chamada da camada de depuração D3D12).

O ID3D12InfoQueue está disponível somente quando a camada de depuração direct3D 12 está habilitada com ID3D12Debug::EnableDebugLayer. Embora seja sempre preferível habilitar (ou desabilitar) as camadas de depuração Direct3D 12 e DirectML juntas, versões mais recentes do DirectML dão suporte à validação básica de parâmetro sem a camada de depuração Direct3D 12. Se você criar um dispositivo DirectML com DML_CREATE_DEVICE_FLAG_DEBUG enquanto a camada de depuração direct3D 12 não tiver sido habilitada, as mensagens de erro serão impressas usando 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 a mensagem de aviso sugere, é melhor habilitar a camada de depuração direct3D 12 ao usar também a camada de depuração DirectML. Alguns tipos de validação só são possíveis quando ambas as camadas de depuração estão habilitadas.

Instalando as camadas de depuração DirectML e Direct3D 12 (componente do sistema)

Ao usar o DirectML como um componente do sistema (consulte o histórico de versão do DirectML), a camada de depuração faz parte de um pacote de Ferramentas Gráficas separado, distribuído como um FOD (recurso sob demanda) (consulte Recursos sob Demanda). O FOD das Ferramentas de Gráficos deve ser adicionado ao sistema para usar a camada de depuração com a versão do sistema do DirectML. O FOD também contém a camada de depuração Direct3D 12, que também é útil (mas não necessária) para depurar aplicativos DirectML.

Para adicionar o pacote FOD opcional das Ferramentas Gráficas, execute o comando a seguir em um prompt do PowerShell do administrador.

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

Como alternativa, você pode adicionar o pacote de Ferramentas Gráficas de dentro das Configurações do Windows. No Windows 10 22H2 e no Windows 11, navegue até Configurações>Sistema>Recursos opcionais>, Adicionar um recurso opcional, então pesquise Ferramentas Gráficas. Em versões anteriores ao Windows 10 22H2, navegue até Configurações>Aplicativos>Aplicativos e recursos>Recursos opcionais>Adicionar um recurso opcional.

Instalando a camada de depuração do DirectML (redistribuível autônomo)

Ao usar o DirectML como uma biblioteca redistribuível autônoma (consulte Microsoft.AI.DirectML), a camada de depuração do DirectML é fornecida no pacote junto com a biblioteca de runtime principal. Coloque ambos DirectML.Debug.dll e DirectML.dll ao lado do executável do aplicativo.

Se você usar o Visual Studio para adicionar Microsoft.AI.DirectML como uma dependência de pacote NuGet, o projeto mostrará opções na página de configuração do projeto para copiar ou ignorar a cópia do runtime principal e das bibliotecas de camadas de depuração. Por padrão, o pacote NuGet DirectML é configurado para sempre copiar ambas as DLLs para a pasta de saída do projeto. No entanto, talvez você queira ignorar a cópia da camada de depuração em builds de versão se a camada de depuração não for usada.

Camada de depuração redistribuível no Visual Studio

Habilitando a camada de depuração do Direct3D 12

A camada de depuração para Direct3D 12 (d3d12sdklayers.dll) é independente da camada de depuração DirectML (DirectML.Debug.dll): a camada de depuração DirectML fornece validação aprimorada para uso da API DirectML e a camada de depuração Direct3D 12 abrange o uso da API Direct3D 12. Na prática, no entanto, é melhor habilitar ambas as camadas de depuração ao desenvolver aplicativos DirectML. A camada de depuração do Direct3D 12 é instalada como parte do FOD das Ferramentas Gráficas, que é explicado acima. Consulte ID3D12Debug::EnableDebugLayer para obter um exemplo de como ativar a camada de depuração do Direct3D 12.

Importante

Primeiro, você deve habilitar a camada de depuração do Direct3D 12. Em seguida, habilite a camada de depuração DirectML chamando DMLCreateDevice.

Habilitando a camada de depuração do DirectML

Você pode habilitar a camada de depuração do DirectML fornecendo DML_CREATE_DEVICE_FLAG_DEBUG ao chamar DMLCreateDevice.

Depois de habilitar a camada de depuração do DirectML, quaisquer erros de DirectML ou chamadas à API inválidas farão com que as informações de depuração sejam emitidas como saída de depuração. Aqui está um exemplo.

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

Até DML_FEATURE_LEVEL_5_2, é um requisito habilitar a camada de depuração do Direct3D 12 para habilitar a camada de depuração do DirectML. Nas versões anteriores do DirectML, se o sinalizador DML_CREATE_DEVICE_FLAG_DEBUG for especificado em sinalizadores e as camadas de depuração não estiverem instaladas, DMLCreateDevice retornará DXGI_ERROR_SDK_COMPONENT_MISSING. Nas versões mais recentes do DirectML, as mensagens são enviadas para OutputDebugStringA quando ID3D12InfoQueue não está disponível.

Exemplo de código

O código a seguir ilustra a habilitação das camadas de depuração Direct3D 12 e DirectML somente para builds de depuração.

// 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 também