onnxruntime/winml/lib/Common/CommonDeviceHelpers.cpp
raoanag 424107a82a
Merge main to WindowsAI (#18122)
### Description
Merge main to WindowsAI



### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->

---------

Signed-off-by: Nash <george.nash@intel.com>
Signed-off-by: Yiming Hu <yiming.hu@amd.com>
Signed-off-by: Liqun Fu <liqfu@microsoft.com>
Co-authored-by: Kaz Nishimura <kazssym@linuxfront.com>
Co-authored-by: Tianlei Wu <tlwu@microsoft.com>
Co-authored-by: Nat Kershaw (MSFT) <nakersha@microsoft.com>
Co-authored-by: Yulong Wang <7679871+fs-eire@users.noreply.github.com>
Co-authored-by: Changming Sun <chasun@microsoft.com>
Co-authored-by: zesongw <zesong.wang@intel.com>
Co-authored-by: Yi Zhang <zhanyi@microsoft.com>
Co-authored-by: Dmitri Smirnov <yuslepukhin@users.noreply.github.com>
Co-authored-by: Yifan Li <109183385+yf711@users.noreply.github.com>
Co-authored-by: simonjub <78098752+simonjub@users.noreply.github.com>
Co-authored-by: PeixuanZuo <94887879+PeixuanZuo@users.noreply.github.com>
Co-authored-by: Adrian Lizarraga <adlizarraga@microsoft.com>
Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com>
Co-authored-by: Arthur Islamov <arthur@islamov.ai>
Co-authored-by: Jambay Kinley <jambaykinley@microsoft.com>
Co-authored-by: Justin Chu <justinchuby@users.noreply.github.com>
Co-authored-by: Wei-Sheng Chin <wschin@outlook.com>
Co-authored-by: Bowen Bao <bowbao@microsoft.com>
Co-authored-by: Hariharan Seshadri <shariharan91@gmail.com>
Co-authored-by: Numfor Tiapo <numsmt2@gmail.com>
Co-authored-by: Vincent Wang <wangwchpku@outlook.com>
Co-authored-by: Pranav Sharma <prs@microsoft.com>
Co-authored-by: George Nash <george.nash@intel.com>
Co-authored-by: Abhishek Jindal <abjindal@microsoft.com>
Co-authored-by: pengwa <pengwa@microsoft.com>
Co-authored-by: Yiming Hu <woinck@users.noreply.github.com>
Co-authored-by: Jiajia Qin <jiajia.qin@intel.com>
Co-authored-by: Lukas Berbuer <36054362+lukasberbuer@users.noreply.github.com>
Co-authored-by: Wanming Lin <wanming.lin@intel.com>
Co-authored-by: Xavier Dupré <xadupre@users.noreply.github.com>
Co-authored-by: aimilefth <60664743+aimilefth@users.noreply.github.com>
Co-authored-by: Baiju Meswani <bmeswani@microsoft.com>
Co-authored-by: Adam Pocock <adam.pocock@oracle.com>
Co-authored-by: Chi Lo <54722500+chilo-ms@users.noreply.github.com>
Co-authored-by: RandySheriffH <48490400+RandySheriffH@users.noreply.github.com>
Co-authored-by: Randy Shuai <rashuai@microsoft.com>
Co-authored-by: Vadym Stupakov <vadim.stupakov@gmail.com>
Co-authored-by: Jian Chen <cjian@microsoft.com>
Co-authored-by: Brian Lambert <98757707+brian-pieces@users.noreply.github.com>
Co-authored-by: Nicolò Lucchesi <nicolo.lucchesi@gmail.com>
Co-authored-by: liqun Fu <liqfu@microsoft.com>
Co-authored-by: trajep <trajepl@gmail.com>
Co-authored-by: Scott McKay <skottmckay@gmail.com>
Co-authored-by: Mustafa Ateş Uzun <mustafauzun0@gmail.com>
Co-authored-by: MistEO <mistereo@hotmail.com>
Co-authored-by: satyajandhyala <satya.k.jandhyala@gmail.com>
Co-authored-by: shaahji <96227573+shaahji@users.noreply.github.com>
Co-authored-by: Rachel Guo <35738743+YUNQIUGUO@users.noreply.github.com>
Co-authored-by: rachguo <rachguo@rachguos-Mini.attlocal.net>
Co-authored-by: Caroline Zhu <wolfivyaura@gmail.com>
Co-authored-by: Caroline Zhu <carolinezhu@microsoft.com>
Co-authored-by: Guenther Schmuelling <guschmue@microsoft.com>
Co-authored-by: xhcao <xinghua.cao@intel.com>
Co-authored-by: Ella Charlaix <80481427+echarlaix@users.noreply.github.com>
Co-authored-by: Xu Xing <xing.xu@intel.com>
Co-authored-by: Hector Li <hecli@microsoft.com>
Co-authored-by: Ye Wang <52801275+wangyems@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Benedikt Hilmes <benedikt.hilmes@rwth-aachen.de>
Co-authored-by: rachguo <rachguo@rachguos-Mac-mini.local>
Co-authored-by: George Wu <jywu@microsoft.com>
Co-authored-by: JiCheng <wejoncy@163.com>
Co-authored-by: Sheil Kumar <smk2007@gmail.com>
Co-authored-by: Sheil Kumar <sheilk@microsoft.com>
Co-authored-by: cloudhan <guangyunhan@microsoft.com>
Co-authored-by: kyoshisuki <143475866+kyoshisuki@users.noreply.github.com>
Co-authored-by: aciddelgado <139922440+aciddelgado@users.noreply.github.com>
Co-authored-by: tlwu@microsoft.com <tlwu@a100.crj0ad2y1kku1j4yxl4sj10o4e.gx.internal.cloudapp.net>
Co-authored-by: Maximilian Müller <44298237+gedoensmax@users.noreply.github.com>
Co-authored-by: Tang, Cheng <souptc@gmail.com>
Co-authored-by: Cheng Tang <chenta@microsoft.com@orttrainingdev9.d32nl1ml4oruzj4qz3bqlggovf.px.internal.cloudapp.net>
Co-authored-by: Cheng Tang <chenta@microsoft.com>
Co-authored-by: Jeff Daily <jeff.daily@amd.com>
Co-authored-by: cloudhan <cloudhan@outlook.com>
Co-authored-by: Yufeng Li <liyufeng1987@gmail.com>
Co-authored-by: Zhang Lei <zhang.huanning@hotmail.com>
Co-authored-by: Dwayne Robinson <fdwr@hotmail.com>
Co-authored-by: Zhipeng Han <zhipeng.han@outlook.com>
Co-authored-by: Thiago Crepaldi <thiago.crepaldi@microsoft.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Patrice Vignola <vignola.patrice@gmail.com>
Co-authored-by: kunal-vaishnavi <115581922+kunal-vaishnavi@users.noreply.github.com>
Co-authored-by: snadampal <87143774+snadampal@users.noreply.github.com>
Co-authored-by: Sumit Agarwal <sumitagarwal330@gmail.com>
Co-authored-by: Ashwini Khade <askhade@microsoft.com>
Co-authored-by: Yang Gu <yang.gu@intel.com>
Co-authored-by: Cheng Tang <chenta@a100.crj0ad2y1kku1j4yxl4sj10o4e.gx.internal.cloudapp.net>
Co-authored-by: mindest <30493312+mindest@users.noreply.github.com>
Co-authored-by: Scott McKay <Scott.McKay@microsoft.com>
Co-authored-by: Xavier Dupre <xadupre@microsoft.com@orttrainingdev9.d32nl1ml4oruzj4qz3bqlggovf.px.internal.cloudapp.net>
Co-authored-by: guyang3532 <62738430+guyang3532@users.noreply.github.com>
Co-authored-by: Carson M <carson@pyke.io>
Co-authored-by: sophies927 <107952697+sophies927@users.noreply.github.com>
2023-10-27 17:08:01 -07:00

210 lines
7.4 KiB
C++

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "lib/Common/inc/pch.h"
#if USE_DML
#include <DirectML.h>
#endif USE_DML
#include "inc/CommonDeviceHelpers.h"
#include <d3d11on12.h>
#include <wil/winrt.h>
#include "LearningModelDevice.h"
namespace {
constexpr uint32_t c_intelVendorId = 0x8086;
constexpr uint32_t c_nvidiaVendorId = 0x10DE;
constexpr uint32_t c_amdVendorId = 0x1002;
bool CheckAdapterFP16Blocked(bool isMcdmAdapter, uint32_t vendorId, uint32_t majorVersion, uint32_t minorVersion) {
switch (vendorId) {
case c_intelVendorId: {
if (isMcdmAdapter) {
return false;
}
// Check Intel GPU driver version
return (majorVersion < 25) || (majorVersion == 25 && minorVersion < 6574) ||
(majorVersion == 26 && minorVersion < 6572);
}
}
return false;
}
void ParseDriverVersion(LARGE_INTEGER& version, uint32_t& majorVersion, uint32_t& minorVersion) {
majorVersion = HIWORD(version.HighPart);
minorVersion = LOWORD(version.LowPart);
}
HRESULT
GetDXGIAdapterMetadata(ID3D12Device& device, uint32_t& vendorId, uint32_t& majorVersion, uint32_t& minorVersion) {
winrt::com_ptr<IDXGIFactory4> spFactory;
RETURN_IF_FAILED(CreateDXGIFactory1(IID_PPV_ARGS(spFactory.put())));
winrt::com_ptr<IDXGIAdapter> spAdapter;
RETURN_IF_FAILED(spFactory->EnumAdapterByLuid(device.GetAdapterLuid(), IID_PPV_ARGS(spAdapter.put())));
DXGI_ADAPTER_DESC adapterDesc = {};
RETURN_IF_FAILED(spAdapter->GetDesc(&adapterDesc));
LARGE_INTEGER driverVersion;
RETURN_IF_FAILED(spAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &driverVersion));
vendorId = adapterDesc.VendorId;
ParseDriverVersion(driverVersion, majorVersion, minorVersion);
return S_OK;
}
#ifdef ENABLE_DXCORE
HRESULT GetDXCoreAdapterMetadata(
ID3D12Device& device, bool& isMcdmAdapter, uint32_t& vendorId, uint32_t& majorVersion, uint32_t& minorVersion
) {
winrt::com_ptr<IDXCoreAdapterFactory> spFactory;
RETURN_IF_FAILED(DXCoreCreateAdapterFactory(IID_PPV_ARGS(spFactory.put())));
winrt::com_ptr<IDXCoreAdapter> spAdapter;
RETURN_IF_FAILED(spFactory->GetAdapterByLuid(device.GetAdapterLuid(), IID_PPV_ARGS(spAdapter.put())));
if (spAdapter->IsAttributeSupported(DXCORE_ADAPTER_ATTRIBUTE_D3D12_CORE_COMPUTE) &&
(!(spAdapter->IsAttributeSupported(DXCORE_ADAPTER_ATTRIBUTE_D3D12_GRAPHICS) ||
spAdapter->IsAttributeSupported(DXCORE_ADAPTER_ATTRIBUTE_D3D11_GRAPHICS)))) {
isMcdmAdapter = true;
} else {
isMcdmAdapter = false;
}
DXCoreHardwareID hardwareId;
RETURN_IF_FAILED(spAdapter->GetProperty(DXCoreAdapterProperty::HardwareID, &hardwareId));
vendorId = hardwareId.vendorID;
uint64_t rawDriverVersion;
RETURN_IF_FAILED(spAdapter->GetProperty(DXCoreAdapterProperty::DriverVersion, &rawDriverVersion));
LARGE_INTEGER driverVersion;
driverVersion.QuadPart = static_cast<LONGLONG>(rawDriverVersion);
ParseDriverVersion(driverVersion, majorVersion, minorVersion);
return S_OK;
}
#endif
HRESULT GetD3D12Device(const winml::LearningModelDevice& device, ID3D12Device** outDevice) {
_LUID id;
id.LowPart = device.AdapterId().LowPart;
id.HighPart = device.AdapterId().HighPart;
CommonDeviceHelpers::AdapterEnumerationSupport support;
RETURN_IF_FAILED(GetAdapterEnumerationSupport(&support));
if (support.has_dxgi) {
winrt::com_ptr<IDXGIFactory4> spFactory;
RETURN_IF_FAILED(CreateDXGIFactory1(IID_PPV_ARGS(spFactory.put())));
winrt::com_ptr<IDXGIAdapter1> spAdapter;
RETURN_IF_FAILED(spFactory->EnumAdapterByLuid(id, IID_PPV_ARGS(spAdapter.put())));
RETURN_IF_FAILED(D3D12CreateDevice(spAdapter.get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(outDevice)));
}
#ifdef ENABLE_DXCORE
if (support.has_dxgi == false) {
winrt::com_ptr<IDXCoreAdapterFactory> spFactory;
RETURN_IF_FAILED(DXCoreCreateAdapterFactory(IID_PPV_ARGS(spFactory.put())));
winrt::com_ptr<IDXCoreAdapter> spAdapter;
RETURN_IF_FAILED(spFactory->GetAdapterByLuid(id, IID_PPV_ARGS(spAdapter.put())));
RETURN_IF_FAILED(D3D12CreateDevice(spAdapter.get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(outDevice)));
}
#endif
return S_OK;
}
HRESULT IsFloat16Blocked(ID3D12Device& device, bool* isBlocked) {
uint32_t vendorId;
uint32_t majorVersion;
uint32_t minorVersion;
bool isMcdmAdapter;
*isBlocked = true;
CommonDeviceHelpers::AdapterEnumerationSupport support;
RETURN_IF_FAILED(CommonDeviceHelpers::GetAdapterEnumerationSupport(&support));
#ifdef ENABLE_DXCORE
if (support.has_dxcore) {
RETURN_IF_FAILED(GetDXCoreAdapterMetadata(device, isMcdmAdapter, vendorId, majorVersion, minorVersion));
*isBlocked = CheckAdapterFP16Blocked(isMcdmAdapter, vendorId, majorVersion, minorVersion);
return S_OK;
}
#endif
RETURN_IF_FAILED(GetDXGIAdapterMetadata(device, vendorId, majorVersion, minorVersion));
isMcdmAdapter = false;
*isBlocked = CheckAdapterFP16Blocked(isMcdmAdapter, vendorId, majorVersion, minorVersion);
return S_OK;
}
} // namespace
namespace CommonDeviceHelpers {
constexpr uint32_t c_intelVendorId = 0x8086;
constexpr uint32_t c_nvidiaVendorId = 0x10DE;
constexpr uint32_t c_amdVendorId = 0x1002;
bool IsFloat16Supported(const winml::LearningModelDevice& device) {
auto adapterId = device.AdapterId();
if (!adapterId.HighPart && !adapterId.LowPart) {
// CPU device
return true;
}
winrt::com_ptr<ID3D12Device> d3d12Device;
if (FAILED(GetD3D12Device(device, d3d12Device.put()))) {
return false;
}
return IsFloat16Supported(d3d12Device.get());
}
bool IsFloat16Supported(ID3D12Device* device) {
#ifndef USE_DML
throw winrt::hresult_error(E_NOTIMPL, L"IsFloat16Supported is not implemented for WinML only build.");
#else
bool isBlocked;
if (FAILED(IsFloat16Blocked(*device, &isBlocked)) || isBlocked) {
return false;
}
winrt::com_ptr<IDMLDevice> dmlDevice;
winrt::check_hresult(DMLCreateDevice(device, DML_CREATE_DEVICE_FLAG_NONE, IID_PPV_ARGS(dmlDevice.put())));
DML_FEATURE_QUERY_TENSOR_DATA_TYPE_SUPPORT float16Query = {DML_TENSOR_DATA_TYPE_FLOAT16};
DML_FEATURE_DATA_TENSOR_DATA_TYPE_SUPPORT float16Data = {};
winrt::check_hresult(dmlDevice->CheckFeatureSupport(
DML_FEATURE_TENSOR_DATA_TYPE_SUPPORT, sizeof(float16Query), &float16Query, sizeof(float16Data), &float16Data
));
return float16Data.IsSupported;
#endif
}
HRESULT GetAdapterEnumerationSupport(AdapterEnumerationSupport* support) {
static std::optional<AdapterEnumerationSupport> s_adapterEnumerationSupport;
if (!s_adapterEnumerationSupport.has_value()) {
// check for support, starting with DXGI
winrt::com_ptr<IDXGIFactory4> dxgiFactory;
#ifdef ENABLE_DXCORE
winrt::com_ptr<IDXCoreAdapterFactory> dxcoreFactory;
// necessary because DXCoreCreateAdapterFactory is overloaded
HRESULT(WINAPI * pDxCoreTestFunc)
(REFIID, void**) = DXCoreCreateAdapterFactory;
#endif
AdapterEnumerationSupport adapterEnumerationSupport = {};
if (SUCCEEDED(RunDelayLoadedApi(CreateDXGIFactory1, IID_PPV_ARGS(dxgiFactory.put())))) {
adapterEnumerationSupport.has_dxgi = true;
}
#ifdef ENABLE_DXCORE
if (SUCCEEDED(RunDelayLoadedApi(pDxCoreTestFunc, IID_PPV_ARGS(dxcoreFactory.put())))) {
adapterEnumerationSupport.has_dxcore = true;
}
#endif
s_adapterEnumerationSupport = adapterEnumerationSupport;
if (!(adapterEnumerationSupport.has_dxgi || adapterEnumerationSupport.has_dxcore)) {
return TYPE_E_CANTLOADLIBRARY;
}
}
*support = s_adapterEnumerationSupport.value();
return S_OK;
}
} // namespace CommonDeviceHelpers