From 2b8acba2f10ded40a97ab5fd58e6531124945902 Mon Sep 17 00:00:00 2001 From: Aleksandra Nizio Date: Mon, 29 Sep 2025 15:19:56 +0000 Subject: [PATCH] feature: Adding support to clCreateProgramWithIL Related-To: NEO-15701 Signed-off-by: Aleksandra Nizio --- opencl/source/program/CMakeLists.txt | 3 +- opencl/source/program/build.cpp | 4 ++- opencl/source/program/create_ext.cpp | 14 +++++++++ opencl/source/program/program.cpp | 6 +++- opencl/source/program/program.h | 2 ++ opencl/test/unit_test/api/CMakeLists.txt | 1 + .../cl_create_program_with_binary_tests.cpp | 30 +++++++++++++++++++ .../cl_create_program_with_binary_tests.inl | 16 ---------- opencl/test/unit_test/mocks/mock_program.h | 3 ++ opencl/test/unit_test/program/CMakeLists.txt | 4 +-- .../program/process_elf_binary_tests.cpp | 2 +- 11 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 opencl/source/program/create_ext.cpp create mode 100644 opencl/test/unit_test/api/cl_create_program_with_binary_tests.cpp diff --git a/opencl/source/program/CMakeLists.txt b/opencl/source/program/CMakeLists.txt index 45f45948ad..d4bb8ede6c 100644 --- a/opencl/source/program/CMakeLists.txt +++ b/opencl/source/program/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2018-2022 Intel Corporation +# Copyright (C) 2018-2025 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -9,6 +9,7 @@ set(RUNTIME_SRCS_PROGRAM ${CMAKE_CURRENT_SOURCE_DIR}/build.cpp ${CMAKE_CURRENT_SOURCE_DIR}/compile.cpp ${CMAKE_CURRENT_SOURCE_DIR}/create.cpp + ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}create_ext.cpp ${CMAKE_CURRENT_SOURCE_DIR}/create.inl ${CMAKE_CURRENT_SOURCE_DIR}/get_info.cpp ${CMAKE_CURRENT_SOURCE_DIR}/link.cpp diff --git a/opencl/source/program/build.cpp b/opencl/source/program/build.cpp index 2e73abb5b2..8a03a5e690 100644 --- a/opencl/source/program/build.cpp +++ b/opencl/source/program/build.cpp @@ -69,7 +69,9 @@ cl_int Program::build( TranslationInput inputArgs = {IGC::CodeType::oclC, IGC::CodeType::oclGenBin}; if (createdFrom != CreatedFrom::source) { - inputArgs.srcType = isSpirV ? IGC::CodeType::spirV : IGC::CodeType::llvmBc; + inputArgs.srcType = (intermediateRepresentation != IGC::CodeType::invalid) + ? intermediateRepresentation + : (isSpirV ? IGC::CodeType::spirV : IGC::CodeType::llvmBc); inputArgs.src = ArrayRef(irBinary.get(), irBinarySize); } else { inputArgs.src = ArrayRef(sourceCode.c_str(), sourceCode.size()); diff --git a/opencl/source/program/create_ext.cpp b/opencl/source/program/create_ext.cpp new file mode 100644 index 0000000000..36f7620b54 --- /dev/null +++ b/opencl/source/program/create_ext.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "opencl/source/program/program.h" + +namespace NEO { +cl_int Program::createFromILExt(Context *context, const void *il, size_t length) { + return CL_INVALID_BINARY; +} +} // namespace NEO diff --git a/opencl/source/program/program.cpp b/opencl/source/program/program.cpp index c62f83ed82..61c235a669 100644 --- a/opencl/source/program/program.cpp +++ b/opencl/source/program/program.cpp @@ -176,7 +176,9 @@ cl_int Program::createProgramFromBinary( auto rootDeviceIndex = clDevice.getRootDeviceIndex(); cl_int retVal = CL_INVALID_BINARY; - + if (pBinary == nullptr) { + return retVal; + } this->irBinary.reset(); this->irBinarySize = 0U; this->isSpirV = false; @@ -280,6 +282,8 @@ cl_int Program::createProgramFromBinary( break; } } + } else { + retVal = this->createFromILExt(context, pBinary, binarySize); } return retVal; diff --git a/opencl/source/program/program.h b/opencl/source/program/program.h index faba7d93e9..8bafca70e7 100644 --- a/opencl/source/program/program.h +++ b/opencl/source/program/program.h @@ -276,6 +276,7 @@ class Program : public BaseObject<_cl_program> { Zebin::Debug::Segments getZebinSegments(uint32_t rootDeviceIndex); MOCKABLE_VIRTUAL void callPopulateZebinExtendedArgsMetadataOnce(uint32_t rootDeviceIndex); MOCKABLE_VIRTUAL void callGenerateDefaultExtendedArgsMetadataOnce(uint32_t rootDeviceIndex); + MOCKABLE_VIRTUAL cl_int createFromILExt(Context *context, const void *il, size_t length); protected: MOCKABLE_VIRTUAL cl_int createProgramFromBinary(const void *pBinary, size_t binarySize, ClDevice &clDevice); @@ -388,6 +389,7 @@ class Program : public BaseObject<_cl_program> { std::string decodeErrors; std::string decodeWarnings; } decodedSingleDeviceBinary; + IGC::CodeType::CodeType_t intermediateRepresentation = IGC::CodeType::invalid; }; static_assert(NEO::NonCopyableAndNonMovable); diff --git a/opencl/test/unit_test/api/CMakeLists.txt b/opencl/test/unit_test/api/CMakeLists.txt index 53f781f4cc..3bf9d14d01 100644 --- a/opencl/test/unit_test/api/CMakeLists.txt +++ b/opencl/test/unit_test/api/CMakeLists.txt @@ -27,6 +27,7 @@ set(IGDRCL_SRCS_tests_api ${CMAKE_CURRENT_SOURCE_DIR}/cl_create_perf_counters_command_queue_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/cl_create_pipe_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/cl_create_program_with_binary_tests.inl + ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}cl_create_program_with_binary_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/cl_create_program_with_built_in_kernels_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/cl_create_sampler_tests.inl ${CMAKE_CURRENT_SOURCE_DIR}/cl_create_sampler_with_properties_tests.inl diff --git a/opencl/test/unit_test/api/cl_create_program_with_binary_tests.cpp b/opencl/test/unit_test/api/cl_create_program_with_binary_tests.cpp new file mode 100644 index 0000000000..5b80d39dce --- /dev/null +++ b/opencl/test/unit_test/api/cl_create_program_with_binary_tests.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2025 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "opencl/test/unit_test/api/cl_api_tests.h" + +using namespace NEO; + +using ClCreateProgramWithILTests = ApiTests; + +namespace ULT { +TEST_F(ClCreateProgramWithILTests, GivenIncorrectIlWhenCreatingProgramWithIlThenExpectedErrorIsReturned) { + const uint32_t notSpirv[16] = {0xDEADBEEF}; + + cl_int err = CL_SUCCESS; + cl_program prog = clCreateProgramWithIL(pContext, notSpirv, sizeof(notSpirv), &err); + EXPECT_EQ(CL_INVALID_BINARY, err); + EXPECT_EQ(nullptr, prog); +} + +TEST_F(ClCreateProgramWithILTests, GivenIncorrectIlAndNoErrorPointerWhenCreatingProgramWithIlThenExpectedErrorIsReturned) { + const uint32_t notSpirv[16] = {0xDEADBEEF}; + + cl_program prog = clCreateProgramWithIL(pContext, notSpirv, sizeof(notSpirv), nullptr); + EXPECT_EQ(nullptr, prog); +} +} // namespace ULT \ No newline at end of file diff --git a/opencl/test/unit_test/api/cl_create_program_with_binary_tests.inl b/opencl/test/unit_test/api/cl_create_program_with_binary_tests.inl index 6f6b73f64a..6f2f22c83c 100644 --- a/opencl/test/unit_test/api/cl_create_program_with_binary_tests.inl +++ b/opencl/test/unit_test/api/cl_create_program_with_binary_tests.inl @@ -163,22 +163,6 @@ TEST_F(ClCreateProgramWithILTests, GivenIncorrectIlSizeWhenCreatingProgramWithIl EXPECT_EQ(nullptr, prog); } -TEST_F(ClCreateProgramWithILTests, GivenIncorrectIlWhenCreatingProgramWithIlThenInvalidBinaryErrorIsReturned) { - const uint32_t notSpirv[16] = {0xDEADBEEF}; - - cl_int err = CL_SUCCESS; - cl_program prog = clCreateProgramWithIL(pContext, notSpirv, sizeof(notSpirv), &err); - EXPECT_EQ(CL_INVALID_BINARY, err); - EXPECT_EQ(nullptr, prog); -} - -TEST_F(ClCreateProgramWithILTests, GivenIncorrectIlAndNoErrorPointerWhenCreatingProgramWithIlThenInvalidBinaryErrorIsReturned) { - const uint32_t notSpirv[16] = {0xDEADBEEF}; - - cl_program prog = clCreateProgramWithIL(pContext, notSpirv, sizeof(notSpirv), nullptr); - EXPECT_EQ(nullptr, prog); -} - TEST_F(ClCreateProgramWithILKHRTests, GivenCorrectParametersWhenCreatingProgramWithIlkhrThenProgramIsCreatedAndSuccessIsReturned) { const uint32_t spirv[16] = {0x03022307}; diff --git a/opencl/test/unit_test/mocks/mock_program.h b/opencl/test/unit_test/mocks/mock_program.h index e35b06dbf1..d6fae34682 100644 --- a/opencl/test/unit_test/mocks/mock_program.h +++ b/opencl/test/unit_test/mocks/mock_program.h @@ -256,6 +256,9 @@ class MockProgram : public Program { bool wasDebuggerNotified = false; bool wasPopulateZebinExtendedArgsMetadataOnceCalled = false; bool callBasePopulateZebinExtendedArgsMetadataOnce = false; + auto getIntermediateRepresentation() const { return this->intermediateRepresentation; } + auto getIsGeneratedByIgc() const { return this->isGeneratedByIgc; } + auto &getBuildInfos() { return this->buildInfos; } }; } // namespace NEO diff --git a/opencl/test/unit_test/program/CMakeLists.txt b/opencl/test/unit_test/program/CMakeLists.txt index 7f0337297a..6ebf243606 100644 --- a/opencl/test/unit_test/program/CMakeLists.txt +++ b/opencl/test/unit_test/program/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2018-2023 Intel Corporation +# Copyright (C) 2018-2025 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -12,7 +12,7 @@ set(IGDRCL_SRCS_tests_program ${CMAKE_CURRENT_SOURCE_DIR}/kernel_info_from_patchtokens_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/printf_handler_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/process_debug_data_tests.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/process_elf_binary_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}process_elf_binary_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/process_spir_binary_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/program_data_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/program_from_binary.h diff --git a/opencl/test/unit_test/program/process_elf_binary_tests.cpp b/opencl/test/unit_test/program/process_elf_binary_tests.cpp index 857109e0bd..85e66c960c 100644 --- a/opencl/test/unit_test/program/process_elf_binary_tests.cpp +++ b/opencl/test/unit_test/program/process_elf_binary_tests.cpp @@ -40,7 +40,7 @@ TEST_F(ProcessElfBinaryTests, GivenNullWhenCreatingProgramFromBinaryThenInvalidB EXPECT_EQ(CL_INVALID_BINARY, retVal); } -TEST_F(ProcessElfBinaryTests, GivenInvalidBinaryWhenCreatingProgramFromBinaryThenInvalidBinaryErrorIsReturned) { +TEST_F(ProcessElfBinaryTests, GivenInvalidBinaryWhenCreatingProgramFromBinaryThenExpectedErrorIsReturned) { char pBinary[] = "thisistotallyinvalid\0"; size_t binarySize = strnlen_s(pBinary, 21); cl_int retVal = program->createProgramFromBinary(pBinary, binarySize, *device);