Skip to content

Commit 86bf5fd

Browse files
authored
[UR] Add dynamic shared mem support for cooperative group count suggestion (#22964)
Add dynamic shared memory support for cooperative group count suggestion fixes: #22936
1 parent 62a4610 commit 86bf5fd

5 files changed

Lines changed: 75 additions & 4 deletions

File tree

unified-runtime/source/adapters/level_zero/common/helpers/kernel_helpers.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,32 @@ ur_result_t getSuggestedLocalWorkSize(ur_device_handle_t hDevice,
6262
return UR_RESULT_SUCCESS;
6363
}
6464

65+
uint32_t getMaxCooperativeGroupCountWithDynamicSharedMemory(
66+
uint32_t suggestedGroupCount, uint32_t computeUnitCount,
67+
uint32_t maxSharedLocalMemory, uint32_t staticSharedLocalMemory,
68+
size_t dynamicSharedLocalMemory) {
69+
70+
if (dynamicSharedLocalMemory == 0)
71+
return suggestedGroupCount;
72+
73+
// Reject a per-group allocation that cannot fit on one compute unit
74+
// and avoid overflowing the combined allocation size.
75+
if (staticSharedLocalMemory > maxSharedLocalMemory ||
76+
dynamicSharedLocalMemory > maxSharedLocalMemory - staticSharedLocalMemory)
77+
return 0;
78+
79+
const size_t sharedLocalMemoryPerGroup =
80+
staticSharedLocalMemory + dynamicSharedLocalMemory;
81+
82+
// Cap the driver's estimate by the number of groups that can reside given
83+
// the requested local memory per group.
84+
const uint64_t sharedLocalMemoryGroupCount =
85+
(uint64_t)computeUnitCount *
86+
(maxSharedLocalMemory / sharedLocalMemoryPerGroup);
87+
return static_cast<uint32_t>(
88+
std::min((uint64_t)suggestedGroupCount, sharedLocalMemoryGroupCount));
89+
}
90+
6591
ur_result_t setKernelGlobalOffset(ur_context_handle_t Context,
6692
ze_kernel_handle_t Kernel, uint32_t WorkDim,
6793
const size_t *GlobalWorkOffset) {

unified-runtime/source/adapters/level_zero/common/helpers/kernel_helpers.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ ur_result_t getSuggestedLocalWorkSize(ur_device_handle_t hDevice,
5959
size_t GlobalWorkSize3D[3],
6060
uint32_t SuggestedLocalWorkSize3D[3]);
6161

62+
uint32_t getMaxCooperativeGroupCountWithDynamicSharedMemory(
63+
uint32_t suggestedGroupCount, uint32_t computeUnitCount,
64+
uint32_t maxSharedLocalMemory, uint32_t staticSharedLocalMemory,
65+
size_t dynamicSharedLocalMemory);
66+
6267
/**
6368
* Handle uncommon conditions after kernel submission.
6469
* Resets the offset to {0, 0, 0} if one was supplied.

unified-runtime/source/adapters/level_zero/kernel.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,6 @@ ur_result_t urKernelSuggestMaxCooperativeGroupCount(
10941094
size_t dynamicSharedMemorySize, uint32_t *pGroupCountRet) {
10951095
auto hKernel = v1_cast(hKernelOpque);
10961096
auto hDevice = common_cast(hDeviceOpque);
1097-
(void)dynamicSharedMemorySize;
10981097
std::shared_lock<ur_shared_mutex> Guard(hKernel->Mutex);
10991098

11001099
ze_kernel_handle_t ZeKernel = nullptr;
@@ -1109,7 +1108,12 @@ ur_result_t urKernelSuggestMaxCooperativeGroupCount(
11091108
uint32_t TotalGroupCount = 0;
11101109
ZE2UR_CALL(zeKernelSuggestMaxCooperativeGroupCount,
11111110
(ZeKernel, &TotalGroupCount));
1112-
*pGroupCountRet = TotalGroupCount;
1111+
*pGroupCountRet = getMaxCooperativeGroupCountWithDynamicSharedMemory(
1112+
TotalGroupCount,
1113+
hDevice->ZeDeviceProperties->numSubslicesPerSlice *
1114+
hDevice->ZeDeviceProperties->numSlices,
1115+
hDevice->ZeDeviceComputeProperties->maxSharedLocalMemory,
1116+
hKernel->ZeKernelProperties->localMemSize, dynamicSharedMemorySize);
11131117
return UR_RESULT_SUCCESS;
11141118
}
11151119

unified-runtime/source/adapters/level_zero/v2/kernel.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,6 @@ ur_result_t urKernelSuggestMaxCooperativeGroupCount(
666666
size_t dynamicSharedMemorySize, uint32_t *pGroupCountRet) {
667667
auto hKernel = v2_cast(hKernelOpque);
668668
auto hDevice = common_cast(hDeviceOpque);
669-
(void)dynamicSharedMemorySize;
670669

671670
uint32_t wg[3];
672671
wg[0] = ur_cast<uint32_t>(pLocalWorkSize[0]);
@@ -678,7 +677,12 @@ ur_result_t urKernelSuggestMaxCooperativeGroupCount(
678677
uint32_t totalGroupCount = 0;
679678
ZE2UR_CALL(zeKernelSuggestMaxCooperativeGroupCount,
680679
(hKernel->getZeHandle(hDevice), &totalGroupCount));
681-
*pGroupCountRet = totalGroupCount;
680+
*pGroupCountRet = getMaxCooperativeGroupCountWithDynamicSharedMemory(
681+
totalGroupCount,
682+
hDevice->ZeDeviceProperties->numSubslicesPerSlice *
683+
hDevice->ZeDeviceProperties->numSlices,
684+
hDevice->ZeDeviceComputeProperties->maxSharedLocalMemory,
685+
hKernel->getProperties(hDevice).localMemSize, dynamicSharedMemorySize);
682686
return UR_RESULT_SUCCESS;
683687
}
684688

unified-runtime/test/conformance/kernel/urKernelSuggestMaxCooperativeGroupCount.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
#include <uur/fixtures.h>
77

8+
#include <array>
9+
810
struct urKernelSuggestMaxCooperativeGroupCountTest
911
: uur::urKernelExecutionTest {
1012
void SetUp() override {
@@ -36,6 +38,36 @@ TEST_P(urKernelSuggestMaxCooperativeGroupCountTest, Success) {
3638
ASSERT_GE(suggested_work_groups, 0);
3739
}
3840

41+
TEST_P(urKernelSuggestMaxCooperativeGroupCountTest, DynamicSharedMemory) {
42+
uint64_t local_memory_size = 0;
43+
ASSERT_SUCCESS(urDeviceGetInfo(device, UR_DEVICE_INFO_LOCAL_MEM_SIZE,
44+
sizeof(local_memory_size), &local_memory_size,
45+
nullptr));
46+
uint32_t compute_unit_count = 0;
47+
ASSERT_SUCCESS(urDeviceGetInfo(device, UR_DEVICE_INFO_NUM_COMPUTE_UNITS,
48+
sizeof(compute_unit_count),
49+
&compute_unit_count, nullptr));
50+
51+
ASSERT_SUCCESS(urKernelSuggestMaxCooperativeGroupCount(
52+
kernel, device, n_dimensions, &local_size, 0, &suggested_work_groups));
53+
54+
// Check that increasing the dynamic shared memory size reduces
55+
// the number of suggested work groups.
56+
constexpr std::array<uint32_t, 4> divs = {8, 4, 2, 1};
57+
uint32_t previous_suggested_work_groups = suggested_work_groups;
58+
for (const uint32_t i : divs) {
59+
const size_t dynamic_shared_memory_size = local_memory_size / i;
60+
ASSERT_SUCCESS(urKernelSuggestMaxCooperativeGroupCount(
61+
kernel, device, n_dimensions, &local_size, dynamic_shared_memory_size,
62+
&suggested_work_groups));
63+
64+
ASSERT_LE(suggested_work_groups, previous_suggested_work_groups);
65+
ASSERT_LE((uint64_t)suggested_work_groups,
66+
(uint64_t)(compute_unit_count)*i);
67+
previous_suggested_work_groups = suggested_work_groups;
68+
}
69+
}
70+
3971
TEST_P(urKernelSuggestMaxCooperativeGroupCountTest, InvalidNullHandleKernel) {
4072
ASSERT_EQ_RESULT(urKernelSuggestMaxCooperativeGroupCount(
4173
nullptr, device, n_dimensions, &local_size, 0,

0 commit comments

Comments
 (0)