mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
feature: 2d-block-load-transpose query
Implemented device property query API for determining support capabilities regarding 2d-block-load-tranpose features for which not all Intel devices support. Related-To: NEO-11592 Signed-off-by: Jack Myers <jack.myers@intel.com>
This commit is contained in:

committed by
Compute-Runtime-Automation

parent
b1a50104a8
commit
f5d00b2616
@ -1060,6 +1060,12 @@ ze_result_t DeviceImp::getProperties(ze_device_properties_t *pDeviceProperties)
|
||||
auto deviceMediaProperties = reinterpret_cast<ze_intel_device_media_exp_properties_t *>(extendedProperties);
|
||||
deviceMediaProperties->numDecoderCores = 0;
|
||||
deviceMediaProperties->numEncoderCores = 0;
|
||||
} else if (extendedProperties->stype == ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES) {
|
||||
ze_intel_device_block_array_exp_flags_t supportMatrix{0};
|
||||
supportMatrix |= getProductHelper().supports2DBlockStore() ? ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_STORE : 0;
|
||||
supportMatrix |= getProductHelper().supports2DBlockLoad() ? ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_LOAD : 0;
|
||||
auto blockTransposeProps = reinterpret_cast<ze_intel_device_block_array_exp_properties_t *>(extendedProperties);
|
||||
blockTransposeProps->flags = supportMatrix;
|
||||
}
|
||||
getAdditionalExtProperties(extendedProperties);
|
||||
extendedProperties = static_cast<ze_base_properties_t *>(extendedProperties->pNext);
|
||||
|
@ -6117,5 +6117,91 @@ TEST(ExtensionLookupTest, givenLookupMapWhenAskingForZeIntelGetDriverVersionStri
|
||||
EXPECT_NE(nullptr, ExtensionFunctionAddressHelper::getExtensionFunctionAddress("zeIntelGetDriverVersionString"));
|
||||
}
|
||||
|
||||
template <bool BlockLoad, bool BlockStore>
|
||||
class Mock2DTransposeProductHelper : public MockProductHelperHw<IGFX_UNKNOWN> {
|
||||
public:
|
||||
bool supports2DBlockLoad() const override {
|
||||
return BlockLoad;
|
||||
}
|
||||
bool supports2DBlockStore() const override {
|
||||
return BlockStore;
|
||||
}
|
||||
};
|
||||
|
||||
template <bool BlockLoad, bool BlockStore>
|
||||
class Mock2DTransposeDevice : public MockDeviceImp {
|
||||
public:
|
||||
using mockProductHelperType = Mock2DTransposeProductHelper<BlockLoad, BlockStore>;
|
||||
|
||||
using MockDeviceImp::MockDeviceImp;
|
||||
|
||||
const ProductHelper &getProductHelper() override {
|
||||
return *mockProductHelper;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<mockProductHelperType> mockProductHelper = std::make_unique<mockProductHelperType>();
|
||||
};
|
||||
|
||||
TEST(ExtensionLookupTest, given2DBlockLoadFalseAnd2DBlockStoreFalseThenFlagsIndicateSupportsNeither) {
|
||||
auto *neoMockDevice = NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(defaultHwInfo.get(), 0);
|
||||
Mock2DTransposeDevice<false, false> deviceImp(neoMockDevice, neoMockDevice->getExecutionEnvironment());
|
||||
|
||||
ze_device_properties_t deviceProps = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
|
||||
ze_intel_device_block_array_exp_properties_t blockArrayProps = {ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES};
|
||||
deviceProps.pNext = &blockArrayProps;
|
||||
|
||||
auto success = L0::Device::fromHandle(static_cast<ze_device_handle_t>(&deviceImp))->getProperties(&deviceProps);
|
||||
ASSERT_EQ(success, ZE_RESULT_SUCCESS);
|
||||
|
||||
ASSERT_FALSE(static_cast<bool>(blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_LOAD));
|
||||
ASSERT_FALSE(static_cast<bool>(blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_STORE));
|
||||
}
|
||||
|
||||
TEST(ExtensionLookupTest, given2DBlockLoadTrueAnd2DBlockStoreFalseThenFlagsIndicateSupportLoad) {
|
||||
auto *neoMockDevice = NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(defaultHwInfo.get(), 0);
|
||||
Mock2DTransposeDevice<true, false> deviceImp(neoMockDevice, neoMockDevice->getExecutionEnvironment());
|
||||
|
||||
ze_device_properties_t deviceProps = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
|
||||
ze_intel_device_block_array_exp_properties_t blockArrayProps = {ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES};
|
||||
deviceProps.pNext = &blockArrayProps;
|
||||
|
||||
auto success = L0::Device::fromHandle(static_cast<ze_device_handle_t>(&deviceImp))->getProperties(&deviceProps);
|
||||
ASSERT_EQ(success, ZE_RESULT_SUCCESS);
|
||||
|
||||
ASSERT_TRUE(static_cast<bool>(blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_LOAD));
|
||||
ASSERT_FALSE(static_cast<bool>(blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_STORE));
|
||||
}
|
||||
|
||||
TEST(ExtensionLookupTest, given2DBlockLoadFalseAnd2DBlockStoreTrueThenFlagsIndicateSupportStore) {
|
||||
auto *neoMockDevice = NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(defaultHwInfo.get(), 0);
|
||||
Mock2DTransposeDevice<false, true> deviceImp(neoMockDevice, neoMockDevice->getExecutionEnvironment());
|
||||
|
||||
ze_device_properties_t deviceProps = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
|
||||
ze_intel_device_block_array_exp_properties_t blockArrayProps = {ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES};
|
||||
deviceProps.pNext = &blockArrayProps;
|
||||
|
||||
auto success = L0::Device::fromHandle(static_cast<ze_device_handle_t>(&deviceImp))->getProperties(&deviceProps);
|
||||
ASSERT_EQ(success, ZE_RESULT_SUCCESS);
|
||||
|
||||
ASSERT_FALSE(static_cast<bool>(blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_LOAD));
|
||||
ASSERT_TRUE(static_cast<bool>(blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_STORE));
|
||||
}
|
||||
|
||||
TEST(ExtensionLookupTest, given2DBlockLoadTrueAnd2DBlockStoreTrueThenFlagsIndicateSupportBoth) {
|
||||
auto *neoMockDevice = NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(defaultHwInfo.get(), 0);
|
||||
Mock2DTransposeDevice<true, true> deviceImp(neoMockDevice, neoMockDevice->getExecutionEnvironment());
|
||||
|
||||
ze_device_properties_t deviceProps = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
|
||||
ze_intel_device_block_array_exp_properties_t blockArrayProps = {ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES};
|
||||
deviceProps.pNext = &blockArrayProps;
|
||||
|
||||
auto success = L0::Device::fromHandle(static_cast<ze_device_handle_t>(&deviceImp))->getProperties(&deviceProps);
|
||||
ASSERT_EQ(success, ZE_RESULT_SUCCESS);
|
||||
|
||||
ASSERT_TRUE(static_cast<bool>(blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_LOAD));
|
||||
ASSERT_TRUE(static_cast<bool>(blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_STORE));
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace L0
|
||||
|
79
level_zero/doc/experimental_extensions/2D_BLOCK_TRANSPOSE.md
Normal file
79
level_zero/doc/experimental_extensions/2D_BLOCK_TRANSPOSE.md
Normal file
@ -0,0 +1,79 @@
|
||||
<!---
|
||||
|
||||
Copyright (C) 2024 Intel Corporation
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
-->
|
||||
|
||||
# 2D Block Array Transpose Properties Extension
|
||||
|
||||
* [Overview](#Overview)
|
||||
* [Definitions](#Definitions)
|
||||
* [Known Issues and Limitations](#Known-Issues-and-Limitations)
|
||||
|
||||
# Overview
|
||||
|
||||
Some key framework optimization replies on 2D-block-load transpose feature of GPU product, but this feature is absent in some Intel GPU products.
|
||||
This extension allows for users to query the 2D-block-load transpose capabilities of a device.
|
||||
|
||||
# Definitions
|
||||
|
||||
## Interfaces
|
||||
|
||||
```cpp
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Supported 2D Block Array flags
|
||||
typedef uint32_t ze_intel_device_block_array_exp_flags_t;
|
||||
typedef enum _ze_intel_device_block_array_exp_flag_t {
|
||||
ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_STORE = ZE_BIT(0), ///< Supports store operation
|
||||
ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_LOAD = ZE_BIT(1), ///< Supports load operation
|
||||
ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_intel_device_block_array_exp_flag_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_NAME
|
||||
/// @brief Device 2D block array properties driver extension name
|
||||
#define ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_NAME "ZE_intel_experimental_device_block_array_properties"
|
||||
#endif // ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_NAME
|
||||
|
||||
/// @brief Device 2D block array properties queried using
|
||||
/// ::zeDeviceGetProperties
|
||||
///
|
||||
/// @details
|
||||
/// - This structure may be passed to ::zeDeviceGetProperties, via
|
||||
/// `pNext` member of ::ze_device_properties_t.
|
||||
/// @brief Device 2D block array properties
|
||||
#define ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES (ze_structure_type_t)0x00030007
|
||||
|
||||
typedef struct _ze_intel_device_block_array_exp_properties_t {
|
||||
ze_structure_type_t stype = ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES; ///< [in] type of this structure
|
||||
void *pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific
|
||||
///< structure (i.e. contains sType and pNext).
|
||||
ze_intel_device_block_array_exp_flags_t flags; ///< [out] 0 (none) or a valid combination of ::ze_intel_device_block_array_exp_flag_t
|
||||
} ze_intel_device_block_array_exp_properties_t;
|
||||
```
|
||||
|
||||
## Programming example
|
||||
|
||||
```cpp
|
||||
|
||||
ze_device_roperties_t deviceProps = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
|
||||
ze_intel_device_block_array_exp_properties_t blockArrayProps = {ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES};
|
||||
deviceProps.pNext = &blockArrayProps;
|
||||
|
||||
SUCCESS_OR_TERMINATE(zeDeviceGetProperties(device, &deviceProps));
|
||||
|
||||
if (blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_STORE) {
|
||||
printf("2D block store supported\n");
|
||||
}
|
||||
|
||||
if (blockArrayProps.flags & ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_LOAD) {
|
||||
printf("2D block load supported\n");
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
# Known Issues and Limitations
|
||||
|
@ -187,6 +187,38 @@ typedef enum _ze_intel_get_driver_version_string_exp_version_t {
|
||||
ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_VERSION_FORCE_UINT32 = 0x7fffffff
|
||||
} ze_intel_get_driver_version_string_exp_version_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Supported 2D Block Array flags
|
||||
typedef uint32_t ze_intel_device_block_array_exp_flags_t;
|
||||
typedef enum _ze_intel_device_block_array_exp_flag_t {
|
||||
ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_STORE = ZE_BIT(0), ///< Supports store operation
|
||||
ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_LOAD = ZE_BIT(1), ///< Supports load operation
|
||||
ZE_INTEL_DEVICE_EXP_FLAG_2D_BLOCK_FORCE_UINT32 = 0x7fffffff
|
||||
|
||||
} ze_intel_device_block_array_exp_flag_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_NAME
|
||||
/// @brief Device 2D block array properties driver extension name
|
||||
#define ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_NAME "ZE_intel_experimental_device_block_array_properties"
|
||||
#endif // ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_NAME
|
||||
|
||||
/// @brief Device 2D block array properties queried using
|
||||
/// ::zeDeviceGetProperties
|
||||
///
|
||||
/// @details
|
||||
/// - This structure may be passed to ::zeDeviceGetProperties, via
|
||||
/// `pNext` member of ::ze_device_properties_t.
|
||||
/// @brief Device 2D block array properties
|
||||
#define ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES (ze_structure_type_t)0x00030007
|
||||
|
||||
typedef struct _ze_intel_device_block_array_exp_properties_t {
|
||||
ze_structure_type_t stype = ZE_INTEL_DEVICE_BLOCK_ARRAY_EXP_PROPERTIES; ///< [in] type of this structure
|
||||
void *pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific
|
||||
///< structure (i.e. contains sType and pNext).
|
||||
ze_intel_device_block_array_exp_flags_t flags; ///< [out] 0 (none) or a valid combination of ::ze_intel_device_block_array_exp_flag_t
|
||||
} ze_intel_device_block_array_exp_properties_t;
|
||||
|
||||
/// @brief Query to read the Intel Level Zero Driver Version String
|
||||
///
|
||||
/// @details
|
||||
|
@ -241,6 +241,8 @@ class ProductHelper {
|
||||
virtual std::optional<bool> isCoherentAllocation(uint64_t patIndex) const = 0;
|
||||
virtual bool isStagingBuffersEnabled() const = 0;
|
||||
virtual uint32_t getCacheLineSize() const = 0;
|
||||
virtual bool supports2DBlockStore() const = 0;
|
||||
virtual bool supports2DBlockLoad() const = 0;
|
||||
|
||||
virtual ~ProductHelper() = default;
|
||||
|
||||
|
@ -909,4 +909,14 @@ uint32_t ProductHelperHw<gfxProduct>::getCacheLineSize() const {
|
||||
return GfxProduct::cacheLineSize;
|
||||
}
|
||||
|
||||
template <PRODUCT_FAMILY gfxProduct>
|
||||
bool ProductHelperHw<gfxProduct>::supports2DBlockLoad() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <PRODUCT_FAMILY gfxProduct>
|
||||
bool ProductHelperHw<gfxProduct>::supports2DBlockStore() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
@ -185,6 +185,8 @@ class ProductHelperHw : public ProductHelper {
|
||||
std::optional<bool> isCoherentAllocation(uint64_t patIndex) const override;
|
||||
bool isStagingBuffersEnabled() const override;
|
||||
uint32_t getCacheLineSize() const override;
|
||||
bool supports2DBlockStore() const override;
|
||||
bool supports2DBlockLoad() const override;
|
||||
|
||||
~ProductHelperHw() override = default;
|
||||
|
||||
|
@ -1011,3 +1011,13 @@ TEST_F(ProductHelperTest, whenGettingMaxSubSliceSpaceThenValueIsNotSmallerThanMa
|
||||
}
|
||||
EXPECT_EQ(maxSupportedSubSlices, productHelper->computeMaxNeededSubSliceSpace(hwInfo));
|
||||
}
|
||||
|
||||
HWTEST_F(ProductHelperTest, givenDefaultProductHelperWhenQuery2DBlockLoadThenReturnFalse) {
|
||||
|
||||
EXPECT_FALSE(productHelper->supports2DBlockLoad());
|
||||
}
|
||||
|
||||
HWTEST_F(ProductHelperTest, givenDefaultProductHelperWhenQuery2DBlockStoreThenReturnFalse) {
|
||||
|
||||
EXPECT_FALSE(productHelper->supports2DBlockStore());
|
||||
}
|
||||
|
Reference in New Issue
Block a user