Udostępnij przez


Korzystanie z warstwy debugowania DirectML

Warstwa debugowania DirectML to opcjonalny komponent, który pomaga w debugowaniu kodu DirectML podczas procesu tworzenia oprogramowania. Po włączeniu warstwa debugowania DirectML opakowuje wywołania interfejsu API DirectML i zapewnia dodatkową walidację oraz komunikaty dla Ciebie jako programisty. Warstwa debugowania jest implementowana w oddzielnej bibliotece DirectML.Debug.dll, która jest warunkowo ładowana w czasie wykonywania przez podstawową bibliotekę DirectML.dll.

Zdecydowanie zalecamy włączenie warstwy debugowania podczas opracowywania aplikacji przy użyciu języka DirectML, ponieważ może on dostarczać nieocenione informacje w przypadku nieprawidłowego użycia interfejsu API.

Omówienie komunikatów warstwy debugowania

Poniższy przykład kodu ilustruje, jak warstwa debugowania może pomóc w diagnozowaniu nieprawidłowego użycia interfejsu API. Ten kod próbuje skonstruować operację tożsamości DirectML; dlatego tensor danych wejściowych i wyjściowych powinien mieć ten sam kształt i typ danych. Jednak w tym przykładzie zilustrujemy błąd w parametrach tensor wyjściowych.

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

Bez warstwy debugowania DirectML ostatni wiersz umożliwiający utworzenie operatora kończy się niepowodzeniem i zwraca wartość E_INVALIDARG (0x80070057). Makro THROW_IF_FAILED (aby uzyskać więcej szczegółów, zobacz WIL) tłumaczy ten kod błędu na ogólny komunikat "parametr jest niepoprawny" i wyświetla go w oknie danych wyjściowych debugera.

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

Jednak po włączeniu warstwy debugowania DirectML zobaczysz dodatkowe informacje, aby zawęzić przyczynę:

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.

Zwróć uwagę, że informacje rozszerzone zaczynają się od błędu D3D12. Gdy warstwa debugowania DirectML wykryje problem, zawsze woli wysyłać komunikaty o błędach do kolejki ID3D12InfoQueue skojarzonej z identyfikatorem ID3D12Device przekazanym podczas tworzenia urządzenia DirectML. Komunikaty o błędach w kolejce informacji są zawsze poprzedzone komunikatem D3D12 ERROR, jak pokazano powyżej; są one również dostępne programowo przy użyciu wywołania zwrotnego komunikatu warstwy debugowania Direct3D 12 (zobacz wpis w blogu D3D12 wywołanie zwrotne komunikatu warstwy debugowania).

Kolejka ID3D12InfoQueue jest dostępna tylko wtedy, gdy warstwa debug Direct3D 12 jest włączona poprzez funkcję ID3D12Debug::EnableDebugLayer. Chociaż zawsze zaleca się włączenie (lub wyłączenie) warstw debugowania Direct3D 12 i DirectML, nowsze wersje directML obsługują podstawową walidację parametrów bez warstwy debugowania Direct3D 12. Jeśli tworzysz urządzenie DirectML z użyciem DML_CREATE_DEVICE_FLAG_DEBUG, podczas gdy warstwa debugowania Direct3D 12 nie została włączona, komunikaty o błędach są zamiast tego drukowane przy użyciu 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.

Jak sugeruje komunikat ostrzegawczy, najlepiej włączyć warstwę debugowania Direct3D 12 również w przypadku korzystania z warstwy debugowania DirectML. Niektóre typy weryfikacji są możliwe tylko wtedy, gdy obie warstwy debugowania są włączone.

Instalowanie warstw debugowania DirectML i Direct3D 12 (składnik systemu)

W przypadku używania języka DirectML jako składnika systemu (zobacz historia wersji directML) warstwa debugowania jest częścią oddzielnego pakietu narzędzi graficznych dystrybuowanych jako funkcja na żądanie (FOD) (zobacz Funkcje na żądanie). Narzędzia graficzne FOD należy dodać do systemu, aby można było używać warstwy debugowania z systemową wersją języka DirectML. FoD zawiera również warstwę debugowania Direct3D 12, która jest również przydatna (ale nie jest wymagana) do debugowania aplikacji DirectML.

Aby dodać opcjonalny pakiet FOD narzędzi graficznych, uruchom następujące polecenie w wierszu polecenia administratora programu PowerShell.

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

Alternatywnie możesz dodać pakiet Narzędzi graficznych z poziomu ustawień systemu Windows. W systemach Windows 10 22H2 i Windows 11 przejdź do pozycji Ustawienia>Opcjonalne funkcje>systemowe>Dodaj funkcję opcjonalną, a następnie wyszukaj pozycję Narzędzia graficzne. W wersjach starszych niż Windows 10 22H2 przejdź do pozycji Ustawienia>Aplikacje i>funkcje>Opcjonalne funkcje>Dodaj opcjonalną funkcję .

Instalowanie warstwy debugowania DirectML (autonomiczny pakiet redystrybucyjny)

W przypadku korzystania z języka DirectML jako autonomicznej biblioteki redystrybucyjnej (zobacz Microsoft.AI.DirectML), warstwa debugowania DirectML jest udostępniana w pakiecie wraz z podstawową biblioteką środowiska uruchomieniowego. Umieść zarówno DirectML.Debug.dll, jak i DirectML.dll obok pliku wykonywalnego aplikacji.

Jeśli używasz programu Visual Studio do dodawania Microsoft.AI.DirectML jako zależności pakietu NuGet, projekt wyświetli opcje na stronie konfiguracji projektu w celu skopiowania lub pominięcia kopiowania podstawowych bibliotek środowiska uruchomieniowego i bibliotek warstwy debugowania. Domyślnie pakiet NuGet directML jest skonfigurowany tak, aby zawsze kopiować obie biblioteki DLL do folderu wyjściowego projektu. Możesz jednak pominąć kopiowanie warstwy debug w wersjach produkcyjnych, jeśli warstwa debug nie jest używana.

Warstwa debugowania redystrybucyjnego w programie Visual Studio

Włączanie warstwy debugowania Direct3D 12

Warstwa debugowania direct3D 12 (d3d12sdklayers.dll) jest niezależna od warstwy debugowania DirectML (DirectML.Debug.dll): warstwa debugowania DirectML zapewnia rozszerzoną walidację użycia interfejsu API DirectML, a warstwa debugowania Direct3D 12 obejmuje użycie interfejsu API Direct3D 12. W praktyce najlepiej jednak włączyć obie warstwy debugowania podczas tworzenia aplikacji DirectML. Warstwa debugowania Direct3D 12 jest instalowana w ramach narzędzia graficznego FOD, co zostało wyjaśnione powyżej. Odniesienie się do ID3D12Debug::EnableDebugLayer aby dowiedzieć się, jak aktywować warstwę debugowania Direct3D 12.

Ważne

Najpierw należy włączyć warstwę debugowania Direct3D 12. Następnie włącz warstwę debugowania DirectML, wywołując funkcję DMLCreateDevice.

Włączanie warstwy debugowania DirectML

Warstwę debugowania DirectML można włączyć, podając DML_CREATE_DEVICE_FLAG_DEBUG podczas wywoływania funkcji DMLCreateDevice.

Po włączeniu warstwy debugowania DirectML wszelkie błędy języka DirectML lub nieprawidłowe wywołania interfejsu API spowodują emitowanie informacji debugowania jako danych wyjściowych debugowania. Oto przykład.

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

Do momentu DML_FEATURE_LEVEL_5_2 wymagane jest włączenie warstwy debugowania Direct3D 12, aby włączyć warstwę debugowania DirectML. Jeśli we wcześniejszych wersjach języka DirectML flaga DML_CREATE_DEVICE_FLAG_DEBUG jest określona w flagach , a warstwy debugowania nie są zainstalowane, funkcja DMLCreateDevice zwraca DXGI_ERROR_SDK_COMPONENT_MISSING. W nowszych wersjach DirectML komunikaty są wysyłane do OutputDebugStringA, gdy ID3D12InfoQueue nie jest dostępne.

Przykład kodu

Poniższy kod ilustruje włączenie warstw debugowych Direct3D 12 i DirectML tylko dla kompilacji debugowych.

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

Zobacz także