From 97c0c997147487096b86549f48215284413dd245 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Tue, 1 Nov 2022 10:33:51 +0000 Subject: [PATCH] [SYCL] Fix use-after-move bug in building for multiple devices (#7237) The cache key used while building kernel binaries will have the spec constant data moved to it to avoid repeated copies of a potentially large data structure. However, when building for multiple devices the spec constant data is moved each time a the cache key is created, which can corrupt the cache key. This commit fixes this by creating the cache key once and mutating it for each insertion, preserving common parts of they key and preventing use-after-move. Signed-off-by: Larsen, Steffen --- .../detail/program_manager/program_manager.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sycl/source/detail/program_manager/program_manager.cpp b/sycl/source/detail/program_manager/program_manager.cpp index 2e7eee59b8e1f..193c187ccf345 100644 --- a/sycl/source/detail/program_manager/program_manager.cpp +++ b/sycl/source/detail/program_manager/program_manager.cpp @@ -1998,12 +1998,12 @@ device_image_plain ProgramManager::build(const device_image_plain &DeviceImage, uint32_t ImgId = Img.getImageID(); const RT::PiDevice PiDevice = getRawSyclObjImpl(Devs[0])->getHandleRef(); + auto CacheKey = + std::make_pair(std::make_pair(std::move(SpecConsts), ImgId), + std::make_pair(PiDevice, CompileOpts + LinkOpts)); // TODO: Throw SYCL2020 style exception auto BuildResult = getOrBuild( - Cache, - std::make_pair(std::make_pair(std::move(SpecConsts), ImgId), - std::make_pair(PiDevice, CompileOpts + LinkOpts)), - AcquireF, GetF, BuildF); + Cache, CacheKey, AcquireF, GetF, BuildF); // getOrBuild is not supposed to return nullptr assert(BuildResult != nullptr && "Invalid build result"); @@ -2024,11 +2024,10 @@ device_image_plain ProgramManager::build(const device_image_plain &DeviceImage, const RT::PiDevice PiDeviceAdd = getRawSyclObjImpl(Devs[Idx])->getHandleRef(); - getOrBuild( - Cache, - std::make_pair(std::make_pair(std::move(SpecConsts), ImgId), - std::make_pair(PiDeviceAdd, CompileOpts + LinkOpts)), - AcquireF, GetF, CacheOtherDevices); + // Change device in the cache key to reduce copying of spec const data. + CacheKey.second.first = PiDeviceAdd; + getOrBuild(Cache, CacheKey, AcquireF, + GetF, CacheOtherDevices); // getOrBuild is not supposed to return nullptr assert(BuildResult != nullptr && "Invalid build result"); }