Menggunakan lapisan debug DirectML

Lapisan debug DirectML adalah komponen waktu pengembangan opsional yang membantu Anda dalam men-debug kode DirectML Anda. Saat diaktifkan, lapisan debug DirectML membungkus panggilan API DirectML, dan menyediakan validasi dan pesan tambahan kepada Anda sebagai pengembang. Lapisan debug diimplementasikan dalam pustaka terpisah, DirectML.Debug.dll, yang dimuat secara kondisional saat runtime oleh pustaka inti DirectML.dll.

Kami sangat menyarankan Agar Anda mengaktifkan lapisan debug saat mengembangkan aplikasi menggunakan DirectML, karena dapat memberikan informasi yang tidak ternilai jika terjadi penggunaan API yang tidak valid.

Gambaran umum pesan lapisan debug

Contoh kode di bawah ini menggambarkan bagaimana lapisan debug dapat membantu dalam mendiagnosis penggunaan API yang salah. Kode ini mencoba membangun operasi identitas DirectML; sehingga tensor input dan output harus memiliki bentuk dan jenis data yang sama. Namun, dalam contoh ini kami mengilustrasikan kesalahan dalam parameter tensor output.

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

Tanpa lapisan debug DirectML, baris akhir untuk membuat operator gagal dan mengembalikan E_INVALIDARG (0x80070057). THROW_IF_FAILED Makro (untuk detail selengkapnya, lihat WIL) menerjemahkan kode kesalahan tersebut ke dalam pesan generik "parameter salah", dan mencetaknya ke jendela output debugger.

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

Tetapi ketika lapisan debug DirectML diaktifkan, Anda akan melihat informasi tambahan untuk mempersempit penyebabnya:

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.

Perhatikan bahwa informasi yang diperluas dimulai dengan ERROR D3D12. Ketika lapisan debug DirectML mendeteksi masalah, ia akan selalu mengirim pesan kesalahan ke ID3D12InfoQueue yang terkait dengan ID3D12Device yang diteruskan selama proses pembuatan perangkat DirectML. Pesan kesalahan dalam antrean info selalu diawali dengan KESALAHAN D3D12, seperti yang ditunjukkan di atas; dan mereka juga dapat diakses secara terprogram menggunakan panggilan balik pesan lapisan debug Direct3D 12 (lihat posting blog D3D12 debug layer message callback).

ID3D12InfoQueue hanya tersedia ketika lapisan debug Direct3D 12 diaktifkan dengan ID3D12Debug::EnableDebugLayer. Meskipun selalu lebih disukai untuk mengaktifkan (atau menonaktifkan) lapisan debug Direct3D 12 dan DirectML bersama-sama, versi DirectML yang lebih baru mendukung validasi parameter dasar tanpa lapisan debug Direct3D 12. Jika Anda membuat perangkat DirectML dengan DML_CREATE_DEVICE_FLAG_DEBUG sementara lapisan debug Direct3D 12 belum diaktifkan, pesan kesalahan dicetak menggunakan 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.

Seperti yang disarankan oleh pesan peringatan, yang terbaik adalah mengaktifkan lapisan debug Direct3D 12 saat juga menggunakan lapisan debug DirectML. Beberapa jenis validasi hanya dimungkinkan ketika kedua lapisan debug diaktifkan.

Menginstal lapisan debug DirectML dan Direct3D 12 (komponen sistem)

Saat menggunakan DirectML sebagai komponen sistem (lihat riwayat versi DirectML), lapisan debug adalah bagian dari paket Alat Grafis terpisah, didistribusikan sebagai fitur sesuai permintaan (FOD) (lihat Fitur Sesuai Permintaan). Alat Grafis FOD harus ditambahkan ke sistem Anda agar dapat menggunakan layer debug dengan DirectML versi sistem. FOD juga berisi lapisan debug Direct3D 12, yang juga berguna (tetapi tidak diperlukan) untuk men-debug aplikasi DirectML.

Tambahkan paket FOD Alat Grafis opsional dengan menjalankan perintah berikut di jendela perintah Powershell dengan hak admin.

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

Atau, Anda dapat menambahkan paket Alat Grafis dari dalam Pengaturan Windows. Pada Windows 10 22H2 dan Windows 11, navigasikan ke Pengaturan>Fitur> opsionalSistem>Tambahkan fitur opsional, lalu cari Alat Grafis. Pada versi yang lebih lama dari Windows 10 22H2, navigasikan ke Pengaturan>Aplikasi>dan fitur>Fitur opsional>Tambahkan fitur opsional sebagai gantinya.

Menginstal lapisan debug DirectML (dapat didistribusikan ulang mandiri)

Saat menggunakan DirectML sebagai pustaka yang dapat didistribusikan ulang mandiri (lihat Microsoft.AI.DirectML), lapisan debug DirectML disediakan dalam paket bersama pustaka runtime inti. Tempatkan DirectML.Debug.dll dan DirectML.dll di samping file executable aplikasi Anda.

Jika Anda menggunakan Visual Studio untuk menambahkan Microsoft.AI.DirectML sebagai dependensi paket NuGet, proyek akan menunjukkan opsi pada halaman konfigurasi proyek untuk menyalin atau mengabaikan penyalinan pustaka runtime core dan lapisan debug. Secara default, paket DirectML NuGet dikonfigurasi untuk selalu menyalin kedua DLL ke folder output proyek Anda. Namun, Anda mungkin ingin melewati penyalinan lapisan debug dalam build rilis jika lapisan debug tidak digunakan.

Lapisan Debug yang Dapat Didistribusikan Ulang di Visual Studio

Mengaktifkan Lapisan Debug Direct3D 12

Lapisan debug untuk Direct3D 12 (d3d12sdklayers.dll) independen dari lapisan debug DirectML (DirectML.Debug.dll): lapisan debug DirectML menyediakan validasi yang ditingkatkan untuk penggunaan API DirectML, dan lapisan debug Direct3D 12 mencakup penggunaan API Direct3D 12. Namun, dalam praktiknya, yang terbaik adalah mengaktifkan kedua lapisan debug saat mengembangkan aplikasi DirectML. Lapisan debug Direct3D 12 dipasang sebagai bagian dari FOD Peralatan Grafik, yang dijelaskan di atas. Lihat ID3D12Debug::EnableDebugLayer untuk contoh cara mengaktifkan lapisan debug Direct3D 12.

Penting

Anda harus terlebih dahulu mengaktifkan lapisan debug Direct3D 12. Lalu aktifkan lapisan debug DirectML dengan memanggil DMLCreateDevice.

Mengaktifkan lapisan debug DirectML

Anda dapat mengaktifkan lapisan debug DirectML dengan menyediakan DML_CREATE_DEVICE_FLAG_DEBUG saat Anda memanggil DMLCreateDevice.

Setelah Anda mengaktifkan lapisan debug DirectML, kesalahan DirectML atau panggilan API yang tidak valid akan menyebabkan informasi debug dikeluarkan sebagai keluaran debug. Berikut adalah contohnya.

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

Hingga DML_FEATURE_LEVEL_5_2, ini adalah persyaratan untuk mengaktifkan lapisan debug Direct3D 12 untuk mengaktifkan lapisan debug DirectML. Dalam versi DirectML sebelumnya, jika bendera DML_CREATE_DEVICE_FLAG_DEBUG ditentukan dalam bendera dan lapisan debug tidak diinstal, maka DMLCreateDevice mengembalikan DXGI_ERROR_SDK_COMPONENT_MISSING. Dalam versi DirectML yang lebih baru, pesan dikirim ke OutputDebugStringA saat ID3D12InfoQueue tidak tersedia.

Contoh kode

Kode berikut menggambarkan cara mengaktifkan lapisan-lapisan debug Direct3D 12 dan DirectML hanya untuk build debug.

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

Lihat juga