From e39af42137fd86d826c47facf2869318b76e38dc Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Tue, 3 Nov 2020 11:13:26 +0100 Subject: [PATCH] Allow sub devices to reuse build status from root device create DeviceBuildInfo struct for per-device info in program Related-To: NEO-5001 Change-Id: I4048f3dd34240a4f937cc4a05935cba4f40a1872 Signed-off-by: Mateusz Jablonski --- opencl/source/program/build.cpp | 10 ++++---- opencl/source/program/compile.cpp | 10 ++++---- opencl/source/program/create.inl | 2 +- opencl/source/program/get_info.cpp | 2 +- opencl/source/program/link.cpp | 10 ++++---- opencl/source/program/program.cpp | 22 +++++++++++++++--- opencl/source/program/program.h | 10 ++++++-- .../api/cl_get_program_build_info_tests.inl | 23 +++++++++++++++---- 8 files changed, 60 insertions(+), 29 deletions(-) diff --git a/opencl/source/program/build.cpp b/opencl/source/program/build.cpp index d33d9f6fde..5cb825f69a 100644 --- a/opencl/source/program/build.cpp +++ b/opencl/source/program/build.cpp @@ -54,14 +54,14 @@ cl_int Program::build( } do { // check to see if a previous build request is in progress - if (std::any_of(deviceVector.begin(), deviceVector.end(), [&](auto device) { return CL_BUILD_IN_PROGRESS == buildStatuses[device]; })) { + if (std::any_of(deviceVector.begin(), deviceVector.end(), [&](auto device) { return CL_BUILD_IN_PROGRESS == deviceBuildInfos[device].buildStatus; })) { retVal = CL_INVALID_OPERATION; break; } if (isCreatedFromBinary == false) { for (const auto &device : deviceVector) { - buildStatuses[device] = CL_BUILD_IN_PROGRESS; + deviceBuildInfos[device].buildStatus = CL_BUILD_IN_PROGRESS; } if (nullptr != buildOptions) { @@ -199,13 +199,11 @@ cl_int Program::build( if (retVal != CL_SUCCESS) { for (const auto &device : deviceVector) { - buildStatuses[device] = CL_BUILD_ERROR; + deviceBuildInfos[device].buildStatus = CL_BUILD_ERROR; } programBinaryType = CL_PROGRAM_BINARY_TYPE_NONE; } else { - for (const auto &device : deviceVector) { - buildStatuses[device] = CL_BUILD_SUCCESS; - } + setBuildStatusSuccess(deviceVector); programBinaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE; } diff --git a/opencl/source/program/compile.cpp b/opencl/source/program/compile.cpp index 49dd25bbaa..8af5a8b875 100644 --- a/opencl/source/program/compile.cpp +++ b/opencl/source/program/compile.cpp @@ -52,7 +52,7 @@ cl_int Program::compile( } } - if (std::any_of(deviceVector.begin(), deviceVector.end(), [&](auto device) { return CL_BUILD_IN_PROGRESS == buildStatuses[device]; })) { + if (std::any_of(deviceVector.begin(), deviceVector.end(), [&](auto device) { return CL_BUILD_IN_PROGRESS == deviceBuildInfos[device].buildStatus; })) { retVal = CL_INVALID_OPERATION; break; } @@ -63,7 +63,7 @@ cl_int Program::compile( } for (const auto &device : deviceVector) { sourceLevelDebuggerNotified[device->getRootDeviceIndex()] = false; - buildStatuses[device] = CL_BUILD_IN_PROGRESS; + deviceBuildInfos[device].buildStatus = CL_BUILD_IN_PROGRESS; } options = (buildOptions != nullptr) ? buildOptions : ""; @@ -165,13 +165,11 @@ cl_int Program::compile( if (retVal != CL_SUCCESS) { for (const auto &device : deviceVector) { - buildStatuses[device] = CL_BUILD_ERROR; + deviceBuildInfos[device].buildStatus = CL_BUILD_ERROR; } programBinaryType = CL_PROGRAM_BINARY_TYPE_NONE; } else { - for (const auto &device : deviceVector) { - buildStatuses[device] = CL_BUILD_SUCCESS; - } + setBuildStatusSuccess(deviceVector); programBinaryType = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT; } diff --git a/opencl/source/program/create.inl b/opencl/source/program/create.inl index edf8dd9d74..8276be3ef4 100644 --- a/opencl/source/program/create.inl +++ b/opencl/source/program/create.inl @@ -129,7 +129,7 @@ T *Program::createBuiltInFromGenBinary( if (program->buildInfos[device->getRootDeviceIndex()].packedDeviceBinarySize == 0) { program->replaceDeviceBinary(makeCopy(binary, size), size, device->getRootDeviceIndex()); } - program->buildStatuses[device] = CL_BUILD_SUCCESS; + program->deviceBuildInfos[device].buildStatus = CL_BUILD_SUCCESS; } program->isCreatedFromBinary = true; program->programBinaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE; diff --git a/opencl/source/program/get_info.cpp b/opencl/source/program/get_info.cpp index d4ceac937a..23a86bc4e2 100644 --- a/opencl/source/program/get_info.cpp +++ b/opencl/source/program/get_info.cpp @@ -187,7 +187,7 @@ cl_int Program::getBuildInfo(cl_device_id device, cl_program_build_info paramNam switch (paramName) { case CL_PROGRAM_BUILD_STATUS: srcSize = retSize = sizeof(cl_build_status); - pSrc = &buildStatuses.at(pClDev); + pSrc = &deviceBuildInfos.at(pClDev).buildStatus; break; case CL_PROGRAM_BUILD_OPTIONS: diff --git a/opencl/source/program/link.cpp b/opencl/source/program/link.cpp index 669532ce41..77e8869fbb 100644 --- a/opencl/source/program/link.cpp +++ b/opencl/source/program/link.cpp @@ -48,7 +48,7 @@ cl_int Program::link( break; } - if (std::any_of(deviceVector.begin(), deviceVector.end(), [&](auto device) { return CL_BUILD_IN_PROGRESS == buildStatuses[device]; })) { + if (std::any_of(deviceVector.begin(), deviceVector.end(), [&](auto device) { return CL_BUILD_IN_PROGRESS == deviceBuildInfos[device].buildStatus; })) { retVal = CL_INVALID_OPERATION; break; } @@ -56,7 +56,7 @@ cl_int Program::link( for (const auto &device : deviceVector) { kernelDebugDataNotified[device->getRootDeviceIndex()] = false; debugOptionsAppended[device->getRootDeviceIndex()] = false; - buildStatuses[device] = CL_BUILD_IN_PROGRESS; + deviceBuildInfos[device].buildStatus = CL_BUILD_IN_PROGRESS; } options = (buildOptions != nullptr) ? buildOptions : ""; @@ -208,13 +208,11 @@ cl_int Program::link( if (retVal != CL_SUCCESS) { for (const auto &device : deviceVector) { - buildStatuses[device] = CL_BUILD_ERROR; + deviceBuildInfos[device].buildStatus = CL_BUILD_ERROR; } programBinaryType = CL_PROGRAM_BINARY_TYPE_NONE; } else { - for (const auto &device : deviceVector) { - buildStatuses[device] = CL_BUILD_SUCCESS; - } + setBuildStatusSuccess(deviceVector); } return retVal; diff --git a/opencl/source/program/program.cpp b/opencl/source/program/program.cpp index 2937455441..27e2303efe 100644 --- a/opencl/source/program/program.cpp +++ b/opencl/source/program/program.cpp @@ -55,7 +55,15 @@ Program::Program(Context *context, bool isBuiltIn, const ClDeviceVector &clDevic if (device->getRootDeviceIndex() > maxRootDeviceIndex) { maxRootDeviceIndex = device->getRootDeviceIndex(); } - buildStatuses[device] = CL_BUILD_NONE; + deviceBuildInfos[device] = {}; + if (device->getNumAvailableDevices() > 1) { + for (auto i = 0u; i < device->getNumAvailableDevices(); i++) { + auto subDevice = device->getDeviceById(i); + if (isDeviceAssociated(*subDevice)) { + deviceBuildInfos[device].associatedSubDevices.push_back(subDevice); + } + } + } } buildInfos.resize(maxRootDeviceIndex + 1); @@ -484,8 +492,16 @@ cl_int Program::packDeviceBinary(uint32_t rootDeviceIndex) { } void Program::setBuildStatus(cl_build_status status) { - for (auto &buildStatusPair : buildStatuses) { - buildStatusPair.second = status; + for (auto &deviceBuildInfo : deviceBuildInfos) { + deviceBuildInfo.second.buildStatus = status; + } +} +void Program::setBuildStatusSuccess(const ClDeviceVector &deviceVector) { + for (const auto &device : deviceVector) { + deviceBuildInfos[device].buildStatus = CL_BUILD_SUCCESS; + for (const auto &subDevice : deviceBuildInfos[device].associatedSubDevices) { + deviceBuildInfos[subDevice].buildStatus = CL_BUILD_SUCCESS; + } } } diff --git a/opencl/source/program/program.h b/opencl/source/program/program.h index 8c4a8deac2..30fbbfb47e 100644 --- a/opencl/source/program/program.h +++ b/opencl/source/program/program.h @@ -155,7 +155,7 @@ class Program : public BaseObject<_cl_program> { size_t paramValueSize, void *paramValue, size_t *paramValueSizeRet) const; bool isBuilt() const { - return std::all_of(this->buildStatuses.begin(), this->buildStatuses.end(), [](auto pair) { return pair.second == CL_SUCCESS; }); + return std::all_of(this->deviceBuildInfos.begin(), this->deviceBuildInfos.end(), [](auto deviceBuildInfo) { return deviceBuildInfo.second.buildStatus == CL_SUCCESS; }); } Context &getContext() const { @@ -288,6 +288,7 @@ class Program : public BaseObject<_cl_program> { void notifyDebuggerWithSourceCode(ClDevice &clDevice, std::string &filename); void setBuildStatus(cl_build_status status); + void setBuildStatusSuccess(const ClDeviceVector &deviceVector); cl_program_binary_type programBinaryType = CL_PROGRAM_BINARY_TYPE_NONE; bool isSpirV = false; @@ -304,7 +305,12 @@ class Program : public BaseObject<_cl_program> { std::vector parentKernelInfoArray; std::vector subgroupKernelInfoArray; - std::unordered_map buildStatuses; + struct DeviceBuildInfo { + StackVec associatedSubDevices; + cl_build_status buildStatus = CL_BUILD_NONE; + }; + + std::unordered_map deviceBuildInfos; bool isCreatedFromBinary = false; std::string sourceCode; diff --git a/opencl/test/unit_test/api/cl_get_program_build_info_tests.inl b/opencl/test/unit_test/api/cl_get_program_build_info_tests.inl index 669ae69479..acdc82027d 100644 --- a/opencl/test/unit_test/api/cl_get_program_build_info_tests.inl +++ b/opencl/test/unit_test/api/cl_get_program_build_info_tests.inl @@ -98,7 +98,7 @@ TEST_F(clGetProgramBuildInfoTests, givenSourceWhenclGetProgramBuildInfoIsCalledT EXPECT_EQ(CL_SUCCESS, retVal); } -TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenCompilingForSpecificDevicesThenOnlySpecificDevicesReportBuildStatus) { +TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenCompilingForSpecificDevicesThenOnlySpecificDevicesAndTheirSubDevicesReportBuildStatus) { cl_program pProgram = nullptr; std::unique_ptr pSource = nullptr; size_t sourceSize = 0; @@ -139,7 +139,8 @@ TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenCompilingForSpecificD } cl_device_id devicesForCompilation[] = {context.getDevice(1), context.getDevice(3)}; - cl_device_id devicesNotForCompilation[] = {context.getDevice(0), context.getDevice(2), context.getDevice(4), context.getDevice(5)}; + cl_device_id associatedSubDevices[] = {context.getDevice(4), context.getDevice(5)}; + cl_device_id devicesNotForCompilation[] = {context.getDevice(0), context.getDevice(2)}; retVal = clCompileProgram( pProgram, @@ -164,6 +165,11 @@ TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenCompilingForSpecificD EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_BUILD_SUCCESS, buildStatus); } + for (const auto &device : associatedSubDevices) { + retVal = clGetProgramBuildInfo(pProgram, device, CL_PROGRAM_BUILD_STATUS, sizeof(buildStatus), &buildStatus, NULL); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(CL_BUILD_SUCCESS, buildStatus); + } retVal = clReleaseProgram(pProgram); EXPECT_EQ(CL_SUCCESS, retVal); @@ -452,7 +458,7 @@ TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenLinkingWithoutInputDe EXPECT_EQ(CL_SUCCESS, retVal); } -TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenBuildingForSpecificDevicesThenOnlySpecificDevicesReportBuildStatus) { +TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenBuildingForSpecificDevicesThenOnlySpecificDevicesAndTheirSubDevicesReportBuildStatus) { MockProgram *pProgram = nullptr; std::unique_ptr pSource = nullptr; size_t sourceSize = 0; @@ -495,7 +501,8 @@ TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenBuildingForSpecificDe } cl_device_id devicesForBuild[] = {context.getDevice(1), context.getDevice(3)}; - cl_device_id devicesNotForBuild[] = {context.getDevice(0), context.getDevice(2), context.getDevice(4), context.getDevice(5)}; + cl_device_id associatedSubDevices[] = {context.getDevice(4), context.getDevice(5)}; + cl_device_id devicesNotForBuild[] = {context.getDevice(0), context.getDevice(2)}; retVal = clBuildProgram( pProgram, @@ -515,6 +522,14 @@ TEST(clGetProgramBuildInfoTest, givenMultiDeviceProgramWhenBuildingForSpecificDe EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(expectedBinaryType, binaryType); } + for (const auto &device : associatedSubDevices) { + retVal = clGetProgramBuildInfo(pProgram, device, CL_PROGRAM_BUILD_STATUS, sizeof(buildStatus), &buildStatus, NULL); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(CL_BUILD_SUCCESS, buildStatus); + retVal = clGetProgramBuildInfo(pProgram, device, CL_PROGRAM_BINARY_TYPE, sizeof(binaryType), &binaryType, NULL); + EXPECT_EQ(CL_SUCCESS, retVal); + EXPECT_EQ(expectedBinaryType, binaryType); + } for (const auto &device : devicesNotForBuild) { retVal = clGetProgramBuildInfo(pProgram, device, CL_PROGRAM_BUILD_STATUS, sizeof(buildStatus), &buildStatus, NULL); EXPECT_EQ(CL_SUCCESS, retVal);