Skip to content

Commit 8c050ee

Browse files
feat(ocl): Generate minimal set of args info
Provide minimalistic arg info metada when provided native binary is missing kernels_misc_info section. - For args passed by value and by pointer (-images/samplers), do not specify type name - instead, return an opaque* type name with size. Signed-off-by: Kacper Nowak <[email protected]> Source: a262bff
1 parent 5b1c570 commit 8c050ee

File tree

8 files changed

+249
-11
lines changed

8 files changed

+249
-11
lines changed

opencl/source/kernel/kernel.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,7 @@ cl_int Kernel::getArgInfo(cl_uint argIndex, cl_kernel_arg_info paramName, size_t
486486
}
487487

488488
program->callPopulateZebinExtendedArgsMetadataOnce(clDevice.getRootDeviceIndex());
489-
if (kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.empty()) {
490-
return CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
491-
}
489+
program->callGenerateDefaultExtendedArgsMetadataOnce(clDevice.getRootDeviceIndex());
492490

493491
const auto &argTraits = args[argIndex].getTraits();
494492
const auto &argMetadata = kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata[argIndex];

opencl/source/program/process_device_binary.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,4 +379,98 @@ void Program::callPopulateZebinExtendedArgsMetadataOnce(uint32_t rootDeviceIndex
379379
};
380380
std::call_once(extractAndDecodeMetadataOnce, extractAndDecodeMetadata);
381381
}
382+
383+
void Program::callGenerateDefaultExtendedArgsMetadataOnce(uint32_t rootDeviceIndex) {
384+
auto ensureTypeNone = [](ArgTypeTraits &typeTraits) -> void {
385+
typeTraits.typeQualifiers.constQual = false;
386+
typeTraits.typeQualifiers.pipeQual = false;
387+
typeTraits.typeQualifiers.restrictQual = false;
388+
typeTraits.typeQualifiers.unknownQual = false;
389+
typeTraits.typeQualifiers.volatileQual = false;
390+
};
391+
392+
auto &buildInfo = this->buildInfos[rootDeviceIndex];
393+
auto generateDefaultMetadata = [&]() {
394+
for (const auto &kernelInfo : buildInfo.kernelInfoArray) {
395+
if (false == kernelInfo->kernelDescriptor.explicitArgsExtendedMetadata.empty()) {
396+
continue;
397+
}
398+
size_t argIndex = 0u;
399+
kernelInfo->kernelDescriptor.explicitArgsExtendedMetadata.resize(kernelInfo->kernelDescriptor.payloadMappings.explicitArgs.size());
400+
for (auto &kernelArg : kernelInfo->kernelDescriptor.payloadMappings.explicitArgs) {
401+
ArgTypeMetadataExtended argMetadataExtended;
402+
auto &argTypeTraits = kernelArg.getTraits();
403+
argMetadataExtended.argName = std::string("arg" + std::to_string(argIndex));
404+
405+
if (kernelArg.is<ArgDescriptor::ArgTValue>()) {
406+
const auto &argAsValue = kernelArg.as<ArgDescValue>(false);
407+
uint16_t maxSourceOffset = 0u, elemSize = 0u;
408+
for (const auto &elem : argAsValue.elements) {
409+
if (maxSourceOffset <= elem.sourceOffset) {
410+
maxSourceOffset = elem.sourceOffset;
411+
elemSize = elem.size;
412+
}
413+
}
414+
if (maxSourceOffset != 0u) {
415+
argMetadataExtended.type = std::string("__opaque_var;" + std::to_string(maxSourceOffset + elemSize));
416+
} else {
417+
argMetadataExtended.type = std::string("__opaque;" + std::to_string(elemSize));
418+
}
419+
ensureTypeNone(argTypeTraits);
420+
argTypeTraits.addressQualifier = KernelArgMetadata::AddrPrivate;
421+
argTypeTraits.accessQualifier = KernelArgMetadata::AccessNone;
422+
} else if (kernelArg.is<ArgDescriptor::ArgTPointer>()) {
423+
const auto &argAsPtr = kernelArg.as<ArgDescPointer>(false);
424+
argMetadataExtended.type = std::string("__opaque_ptr;" + std::to_string(argAsPtr.pointerSize));
425+
} else if (kernelArg.is<ArgDescriptor::ArgTImage>()) {
426+
const auto &argAsImage = kernelArg.as<ArgDescImage>(false);
427+
switch (argAsImage.imageType) {
428+
case NEOImageType::ImageTypeBuffer:
429+
argMetadataExtended.type = std::string("image1d_buffer_t");
430+
break;
431+
case NEOImageType::ImageType1D:
432+
argMetadataExtended.type = std::string("image1d_t");
433+
break;
434+
case NEOImageType::ImageType1DArray:
435+
argMetadataExtended.type = std::string("image1d_array_t");
436+
break;
437+
case NEOImageType::ImageType2DArray:
438+
argMetadataExtended.type = std::string("image2d_array_t");
439+
break;
440+
case NEOImageType::ImageType3D:
441+
argMetadataExtended.type = std::string("image3d_t");
442+
break;
443+
case NEOImageType::ImageType2DDepth:
444+
argMetadataExtended.type = std::string("image2d_depth_t");
445+
break;
446+
case NEOImageType::ImageType2DArrayDepth:
447+
argMetadataExtended.type = std::string("image2d_array_depth_t");
448+
break;
449+
case NEOImageType::ImageType2DMSAA:
450+
argMetadataExtended.type = std::string("image2d_msaa_t");
451+
break;
452+
case NEOImageType::ImageType2DMSAADepth:
453+
argMetadataExtended.type = std::string("image2d_msaa_depth_t");
454+
break;
455+
case NEOImageType::ImageType2DArrayMSAA:
456+
argMetadataExtended.type = std::string("image2d_array_msaa_t");
457+
break;
458+
case NEOImageType::ImageType2DArrayMSAADepth:
459+
argMetadataExtended.type = std::string("image2d_array_msaa_depth_t");
460+
break;
461+
default:
462+
argMetadataExtended.type = std::string("image2d_t");
463+
break;
464+
}
465+
} else if (kernelArg.is<ArgDescriptor::ArgTSampler>()) {
466+
argMetadataExtended.type = std::string("sampler_t");
467+
}
468+
kernelInfo->kernelDescriptor.explicitArgsExtendedMetadata.at(argIndex) = std::move(argMetadataExtended);
469+
argIndex++;
470+
}
471+
}
472+
};
473+
std::call_once(generateDefaultMetadataOnce, generateDefaultMetadata);
474+
}
475+
382476
} // namespace NEO

opencl/source/program/program.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ class Program : public BaseObject<_cl_program> {
282282
MOCKABLE_VIRTUAL void createDebugZebin(uint32_t rootDeviceIndex);
283283
Debug::Segments getZebinSegments(uint32_t rootDeviceIndex);
284284
MOCKABLE_VIRTUAL void callPopulateZebinExtendedArgsMetadataOnce(uint32_t rootDeviceIndex);
285+
MOCKABLE_VIRTUAL void callGenerateDefaultExtendedArgsMetadataOnce(uint32_t rootDeviceIndex);
285286

286287
protected:
287288
MOCKABLE_VIRTUAL cl_int createProgramFromBinary(const void *pBinary, size_t binarySize, ClDevice &clDevice);
@@ -376,6 +377,7 @@ class Program : public BaseObject<_cl_program> {
376377
size_t exportedFunctionsKernelId = std::numeric_limits<size_t>::max();
377378

378379
std::once_flag extractAndDecodeMetadataOnce;
380+
std::once_flag generateDefaultMetadataOnce;
379381
};
380382

381383
} // namespace NEO

opencl/test/unit_test/kernel/kernel_arg_info_tests.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,6 @@ TEST_F(KernelArgInfoTest, GivenValidArgIndexThenExplicitArgsMetadataIsPopulated)
6161
EXPECT_TRUE(program->wasPopulateZebinExtendedArgsMetadataOnceCalled);
6262
}
6363

64-
TEST_F(KernelArgInfoTest, GivenEmptyExplicitArgsMetadataThenAppropriateErrorIsReturned) {
65-
kernelDescriptor->explicitArgsExtendedMetadata.resize(0);
66-
auto retVal = kernel->getArgInfo(0, 0, 0, nullptr, nullptr);
67-
EXPECT_EQ(CL_KERNEL_ARG_INFO_NOT_AVAILABLE, retVal);
68-
}
69-
7064
TEST_F(KernelArgInfoTest, GivenInvalidParametersWhenGettingKernelArgInfoThenValueSizeRetIsNotUpdated) {
7165
auto retVal = kernel->getArgInfo(0, 0, 0, nullptr, nullptr);
7266
EXPECT_EQ(CL_INVALID_VALUE, retVal);

opencl/test/unit_test/program/program_tests.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3554,3 +3554,126 @@ TEST(ProgramPopulateZebinExtendedArgsMetadataTests, givenZebinaryFormatWithValid
35543554
buildInfo.kernelInfoArray.clear();
35553555
buildInfo.unpackedDeviceBinary.release();
35563556
}
3557+
3558+
TEST(ProgramGenerateDefaultArgsMetadataTests, givenNativeBinaryWhenCallingGenerateDefaultExtendedArgsMetadataThenGenerateMetadataForEachExplicitArgForEachKernel) {
3559+
MockClDevice device{new MockDevice()};
3560+
MockProgram program(toClDeviceVector(device));
3561+
3562+
const auto &rootDeviceIndex = device.getRootDeviceIndex();
3563+
auto &buildInfo = program.buildInfos[rootDeviceIndex];
3564+
3565+
KernelInfo kernelInfo1, kernelInfo2;
3566+
kernelInfo1.kernelDescriptor.kernelMetadata.kernelName = "some_kernel";
3567+
kernelInfo2.kernelDescriptor.kernelMetadata.kernelName = "another_kernel";
3568+
buildInfo.kernelInfoArray.push_back(&kernelInfo1);
3569+
buildInfo.kernelInfoArray.push_back(&kernelInfo2);
3570+
3571+
kernelInfo1.kernelDescriptor.payloadMappings.explicitArgs.resize(2);
3572+
kernelInfo1.kernelDescriptor.payloadMappings.explicitArgs.at(0).type = ArgDescriptor::ArgTPointer;
3573+
auto &ptr = kernelInfo1.kernelDescriptor.payloadMappings.explicitArgs.at(0).as<ArgDescPointer>();
3574+
ptr.pointerSize = 8u;
3575+
3576+
kernelInfo1.kernelDescriptor.payloadMappings.explicitArgs.at(1).type = ArgDescriptor::ArgTImage;
3577+
auto &img = kernelInfo1.kernelDescriptor.payloadMappings.explicitArgs.at(1).as<ArgDescImage>();
3578+
img.imageType = NEOImageType::ImageType2D;
3579+
3580+
kernelInfo2.kernelDescriptor.payloadMappings.explicitArgs.resize(1);
3581+
kernelInfo2.kernelDescriptor.payloadMappings.explicitArgs.at(0).type = ArgDescriptor::ArgTSampler;
3582+
3583+
program.callGenerateDefaultExtendedArgsMetadataOnce(rootDeviceIndex);
3584+
EXPECT_EQ(2u, kernelInfo1.kernelDescriptor.explicitArgsExtendedMetadata.size());
3585+
EXPECT_EQ(1u, kernelInfo2.kernelDescriptor.explicitArgsExtendedMetadata.size());
3586+
3587+
const auto &argMetadata1 = kernelInfo1.kernelDescriptor.explicitArgsExtendedMetadata[0];
3588+
EXPECT_STREQ("arg0", argMetadata1.argName.c_str());
3589+
auto expectedTypeName = std::string("__opaque_ptr;" + std::to_string(ptr.pointerSize));
3590+
EXPECT_STREQ(expectedTypeName.c_str(), argMetadata1.type.c_str());
3591+
3592+
const auto &argMetadata2 = kernelInfo1.kernelDescriptor.explicitArgsExtendedMetadata[1];
3593+
EXPECT_STREQ("arg1", argMetadata2.argName.c_str());
3594+
EXPECT_STREQ("image2d_t", argMetadata2.type.c_str());
3595+
3596+
const auto &argMetadata3 = kernelInfo2.kernelDescriptor.explicitArgsExtendedMetadata[0];
3597+
EXPECT_STREQ("arg0", argMetadata3.argName.c_str());
3598+
EXPECT_STREQ("sampler_t", argMetadata3.type.c_str());
3599+
3600+
buildInfo.kernelInfoArray.clear();
3601+
buildInfo.unpackedDeviceBinary.release();
3602+
}
3603+
3604+
TEST(ProgramGenerateDefaultArgsMetadataTests, whenGeneratingDefaultMetadataForArgByValueWithManyElementsThenGenerateProperMetadata) {
3605+
MockClDevice device{new MockDevice()};
3606+
MockProgram program(toClDeviceVector(device));
3607+
3608+
const auto &rootDeviceIndex = device.getRootDeviceIndex();
3609+
auto &buildInfo = program.buildInfos[rootDeviceIndex];
3610+
3611+
KernelInfo kernelInfo;
3612+
kernelInfo.kernelDescriptor.kernelMetadata.kernelName = "some_kernel";
3613+
buildInfo.kernelInfoArray.push_back(&kernelInfo);
3614+
3615+
kernelInfo.kernelDescriptor.payloadMappings.explicitArgs.resize(1);
3616+
kernelInfo.kernelDescriptor.payloadMappings.explicitArgs.at(0).type = ArgDescriptor::ArgTValue;
3617+
auto &argAsVal = kernelInfo.kernelDescriptor.payloadMappings.explicitArgs.at(0).as<ArgDescValue>();
3618+
argAsVal.elements.resize(3u);
3619+
3620+
argAsVal.elements[0].sourceOffset = 0u;
3621+
argAsVal.elements[0].size = 8u;
3622+
argAsVal.elements[1].sourceOffset = 16u;
3623+
argAsVal.elements[1].size = 8u;
3624+
argAsVal.elements[2].sourceOffset = 8u;
3625+
argAsVal.elements[2].size = 8u;
3626+
3627+
program.callGenerateDefaultExtendedArgsMetadataOnce(rootDeviceIndex);
3628+
EXPECT_EQ(1u, kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.size());
3629+
3630+
const auto &argMetadata = kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata[0];
3631+
EXPECT_STREQ("arg0", argMetadata.argName.c_str());
3632+
3633+
auto expectedSize = argAsVal.elements[1].sourceOffset + argAsVal.elements[1].size;
3634+
auto expectedTypeName = std::string("__opaque_var;" + std::to_string(expectedSize));
3635+
EXPECT_STREQ(expectedTypeName.c_str(), argMetadata.type.c_str());
3636+
3637+
const auto &argTypeTraits = kernelInfo.kernelDescriptor.payloadMappings.explicitArgs.at(0).getTraits();
3638+
EXPECT_EQ(KernelArgMetadata::AddrPrivate, argTypeTraits.addressQualifier);
3639+
EXPECT_EQ(KernelArgMetadata::AccessNone, argTypeTraits.accessQualifier);
3640+
EXPECT_TRUE(argTypeTraits.typeQualifiers.empty());
3641+
3642+
buildInfo.kernelInfoArray.clear();
3643+
buildInfo.unpackedDeviceBinary.release();
3644+
}
3645+
3646+
TEST(ProgramGenerateDefaultArgsMetadataTests, whenGeneratingDefaultMetadataForArgByValueWithSingleElementEachThenGenerateProperMetadata) {
3647+
MockClDevice device{new MockDevice()};
3648+
MockProgram program(toClDeviceVector(device));
3649+
3650+
const auto &rootDeviceIndex = device.getRootDeviceIndex();
3651+
auto &buildInfo = program.buildInfos[rootDeviceIndex];
3652+
3653+
KernelInfo kernelInfo;
3654+
kernelInfo.kernelDescriptor.kernelMetadata.kernelName = "some_kernel";
3655+
buildInfo.kernelInfoArray.push_back(&kernelInfo);
3656+
3657+
kernelInfo.kernelDescriptor.payloadMappings.explicitArgs.resize(1);
3658+
kernelInfo.kernelDescriptor.payloadMappings.explicitArgs.at(0).type = ArgDescriptor::ArgTValue;
3659+
auto &argAsVal = kernelInfo.kernelDescriptor.payloadMappings.explicitArgs.at(0).as<ArgDescValue>();
3660+
argAsVal.elements.resize(1u);
3661+
argAsVal.elements[0].size = 16u;
3662+
3663+
program.callGenerateDefaultExtendedArgsMetadataOnce(rootDeviceIndex);
3664+
EXPECT_EQ(1u, kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata.size());
3665+
3666+
const auto &argMetadata = kernelInfo.kernelDescriptor.explicitArgsExtendedMetadata[0];
3667+
EXPECT_STREQ("arg0", argMetadata.argName.c_str());
3668+
3669+
auto expectedTypeName = std::string("__opaque;" + std::to_string(argAsVal.elements[0].size));
3670+
EXPECT_STREQ(expectedTypeName.c_str(), argMetadata.type.c_str());
3671+
3672+
const auto &argTypeTraits = kernelInfo.kernelDescriptor.payloadMappings.explicitArgs.at(0).getTraits();
3673+
EXPECT_EQ(KernelArgMetadata::AddrPrivate, argTypeTraits.addressQualifier);
3674+
EXPECT_EQ(KernelArgMetadata::AccessNone, argTypeTraits.accessQualifier);
3675+
EXPECT_TRUE(argTypeTraits.typeQualifiers.empty());
3676+
3677+
buildInfo.kernelInfoArray.clear();
3678+
buildInfo.unpackedDeviceBinary.release();
3679+
}

shared/source/device_binary_format/zebin_decoder.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,11 @@ NEO::DecodeError populateArgDescriptor(const NEO::Elf::ZebinKernelMetadata::Type
848848
dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescPointer>(true);
849849
break;
850850
case NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::AddressSpaceImage: {
851-
dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescImage>(true);
851+
auto &argAsImage = dst.payloadMappings.explicitArgs[src.argIndex].as<ArgDescImage>(true);
852+
if (src.imageType != NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::ImageTypeMax) {
853+
argAsImage.imageType = static_cast<NEOImageType>(src.imageType);
854+
}
855+
852856
auto &extendedInfo = dst.payloadMappings.explicitArgs[src.argIndex].getExtendedTypeInfo();
853857
extendedInfo.isMediaImage = (src.imageType == NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::ImageType::ImageType2DMedia);
854858
extendedInfo.isMediaBlockImage = (src.imageType == NEO::Elf::ZebinKernelMetadata::Types::Kernel::PayloadArgument::ImageType::ImageType2DMediaBlock);

shared/source/kernel/kernel_arg_descriptor.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,26 @@ struct ArgDescPointer final {
4545
}
4646
};
4747

48+
enum class NEOImageType : uint8_t {
49+
ImageTypeUnknown,
50+
ImageTypeBuffer,
51+
ImageType1D,
52+
ImageType1DArray,
53+
ImageType2D,
54+
ImageType2DArray,
55+
ImageType3D,
56+
ImageTypeCube,
57+
ImageTypeCubeArray,
58+
ImageType2DDepth,
59+
ImageType2DArrayDepth,
60+
ImageType2DMSAA,
61+
ImageType2DMSAADepth,
62+
ImageType2DArrayMSAA,
63+
ImageType2DArrayMSAADepth,
64+
ImageType2DMedia,
65+
ImageType2DMediaBlock,
66+
};
67+
4868
struct ArgDescImage final {
4969
SurfaceStateHeapOffset bindful = undefined<SurfaceStateHeapOffset>; // stateful with BTI
5070
CrossThreadDataOffset bindless = undefined<CrossThreadDataOffset>;
@@ -64,6 +84,7 @@ struct ArgDescImage final {
6484
CrossThreadDataOffset flatHeight = undefined<CrossThreadDataOffset>;
6585
CrossThreadDataOffset flatPitch = undefined<CrossThreadDataOffset>;
6686
} metadataPayload;
87+
NEOImageType imageType;
6788
};
6889

6990
struct ArgDescSampler final {
@@ -182,7 +203,7 @@ struct ArgDescriptor final {
182203

183204
namespace {
184205
constexpr auto ArgSize = sizeof(ArgDescriptor);
185-
static_assert(ArgSize <= 64, "Keep it small");
206+
static_assert(ArgSize <= 72, "Keep it small");
186207
} // namespace
187208

188209
template <>

shared/test/unit_test/device_binary_format/zebin_decoder_tests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5909,10 +5909,12 @@ TEST(PopulateArgDescriptorCrossthreadPayload, GivenValidImageArgumentWithImageMe
59095909
EXPECT_EQ(64U, args[0].as<ArgDescImage>().bindful);
59105910
EXPECT_TRUE(args[0].getExtendedTypeInfo().isMediaImage);
59115911
EXPECT_TRUE(args[0].getExtendedTypeInfo().isTransformable);
5912+
EXPECT_EQ(NEOImageType::ImageType2DMedia, args[0].as<ArgDescImage>().imageType);
59125913

59135914
EXPECT_EQ(128U, args[1].as<ArgDescImage>().bindful);
59145915
EXPECT_TRUE(args[1].getExtendedTypeInfo().isMediaBlockImage);
59155916
EXPECT_FALSE(args[1].getExtendedTypeInfo().isTransformable);
5917+
EXPECT_EQ(NEOImageType::ImageType2DMediaBlock, args[1].as<ArgDescImage>().imageType);
59165918
const auto &imgMetadata = args[1].as<ArgDescImage>().metadataPayload;
59175919
EXPECT_EQ(0U, imgMetadata.imgHeight);
59185920
EXPECT_EQ(4U, imgMetadata.imgWidth);

0 commit comments

Comments
 (0)