Como usar a camada de depuração do DirectML
A camada de depuração do DirectML é um componente opcional do tempo de desenvolvimento que ajuda você a depurar seu código DirectML. Quando habilitada, a camada de depuração do DirectML encapsula chamadas de 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 no runtime pela biblioteca de runtime DirectML.dll
principal.
É altamente recomendável que você habilite a camada de depuração ao desenvolver aplicativos usando DirectML, pois ela pode fornecer informações importantes no caso do uso inválido da API.
Visão geral das mensagens da camada de depuração
O exemplo de código abaixo ilustra como a camada de depuração pode ajudar no diagnóstico do uso incorreto da API. Esse código tenta construir uma operação de identidade DirectML. Assim, 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 do 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 do DirectML, a linha final para criar o operador falha e retorna E_INVALIDARG
(0x80070057). A macro THROW_IF_FAILED
(para obter mais detalhes, consulte WIL) converte esse código de erro na mensagem genérica "o parâmetro está incorreto" e a 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 do 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 D3D12 ERROR. Quando a camada de depuração do DirectML detecta um problema, ela sempre prefere enviar mensagens de erro para o ID3D12InfoQueue associado ao ID3D12Device, passado durante a criação do dispositivo DirectML. As mensagens de erro na fila de informações são sempre prefixadas com D3D12 ERROR, como mostrado acima, e também podem ser acessadas programaticamente usando um retorno de chamada de mensagem da camada de depuração do Direct3D 12 (consulte a postagem do blog D3D12 debug layer message callback).
O ID3D12InfoQueue estará disponível somente quando a camada de depuração do Direct3D 12 estiver habilitada com ID3D12Debug::EnableDebugLayer. Embora seja sempre melhor habilitar (ou desabilitar) as camadas de depuração do Direct3D 12 e do DirectML juntas, as versões mais recentes do DirectML oferecem suporte à validação de parâmetros básicos sem a camada de depuração do Direct3D 12. Se você criar um dispositivo DirectML com DML_CREATE_DEVICE_FLAG_DEBUG enquanto a camada de depuração do 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 do Direct3D 12 quando também a estiver usando. Alguns tipos de validação só são possíveis quando ambas as camadas de depuração estão habilitadas.
Como instalar as camadas de depuração do DirectML e Direct3D 12 (componente do sistema)
Ao usar o DirectML como um componente do sistema (consulte Histórico de versões do DirectML), a camada de depuração faz parte de um pacote separado de Ferramentas Gráficas, distribuído como um FOD (recurso sob demanda) (consulte Recursos sob demanda). O FOD de Ferramentas Gráficas deve ser adicionado ao seu sistema para usar a camada de depuração com a versão de sistema do DirectML. O FOD também contém a camada de depuração do Direct3D 12, que também é útil (mas não necessária) para depurar aplicativos DirectML.
Para adicionar o pacote FOD das Ferramentas Gráficas opcionais, execute o seguinte comando em um prompt do administrador do Powershell.
Add-WindowsCapability -Online -Name "Tools.Graphics.DirectX~~~~0.0.1.0"
Como alternativa, você pode adicionar o pacote de Ferramentas Gráficas nas Configurações do Windows. No Windows 10 22H2 e no Windows 11, navegue até Configurações>Sistema>Recursos opcionais>Adicione um recurso opcional e procure por Ferramentas Gráficas. Em versões anteriores ao Windows 10 22H2, navegue até Configurações>Aplicativos>Aplicativos e recursos>Recursos opcionais>Adicione um recurso opcional.
Como instalat a camada de depuração DirectML (redistribuível autônoma)
Ao usar o DirectML como uma biblioteca redistribuível autônoma (confira Microsoft.AI.DirectML), a camada de depuração do DirectML é fornecida no pacote junto com a biblioteca de runtime principal. Coloque DirectML.Debug.dll
e DirectML.dll
ao lado do executável do seu 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ções do projeto para copiar ou ignorar a cópia do runtime principal e das bibliotecas da camada de depuração. Por padrão, o pacote NuGet do DirectML é configurado para copiar sempre ambas as DLLs na pasta de saída do projeto. No entanto, convém ignorar a cópia da camada de depuração nas compilações de versão se a camada de depuração não for usada.
Habilitar a camada de depuração do Direct3D 12
A camada de depuração do Direct3D 12 (d3d12sdklayers.dll
) é independente da camada de depuração do DirectML (DirectML.Debug.dll
): essa fornece validação aprimorada para o uso da API do DirectML e a camada de depuração do Direct3D 12 abrange o uso da API do 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, o que é explicado acima. Consulte ID3D12Debug::EnableDebugLayer para obter um exemplo de como ativar a camada de depuração do Direct3D 12.
Importante
Você deve primeiro habilitar a camada de depuração do Direct3D 12. E, em seguida, habilite a camada de depuração do DirectML chamando o DMLCreateDevice.
Habilitar a camada de depuração do Direct3D
Você pode habilitar a camada de depuração do DirectML fornecendo o DML_CREATE_DEVICE_FLAG_DEBUG ao chamar DMLCreateDevice.
Após habilitar a camada de depuração do DirectML, todos os erros do DirectML ou as chamadas de API inválidas emitirão as informações de depuração como saída de depuração. Veja 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. Em 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, o DMLCreateDevice retornará o erro DXGI_ERROR_SDK_COMPONENT_MISSING. Em versões mais recentes do DirectML, as mensagens serão enviadas para OutputDebugStringA quando ID3D12InfoQueue não estiver 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 as compilações 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));