@@ -755,7 +755,8 @@ setSpecializationConstants(const std::shared_ptr<device_image_impl> &InputImpl,
755755 }
756756}
757757
758- static inline void CheckAndDecompressImage ([[maybe_unused]] RTDeviceBinaryImage *Img) {
758+ static inline void
759+ CheckAndDecompressImage ([[maybe_unused]] RTDeviceBinaryImage *Img) {
759760#ifndef SYCL_RT_ZSTD_NOT_AVAIABLE
760761 if (auto CompImg = dynamic_cast <CompressedRTDeviceBinaryImage *>(Img))
761762 if (CompImg->IsCompressed ())
@@ -844,26 +845,26 @@ ur_program_handle_t ProgramManager::getBuiltURProgram(
844845 programReleaseInfo.getFuncPtrFromModule (ur::getURLoaderLibrary ());
845846 ProgramPtr ProgramManaged (NativePrg, programRelease);
846847
848+ std::vector<const RTDeviceBinaryImage *> ImagesVec;
847849 // Link a fallback implementation of device libraries if they are not
848850 // supported by a device compiler.
849851 // Pre-compiled programs (after AOT compilation or read from persitent
850852 // cache) are supposed to be already linked.
851853 // If device image is not SPIR-V, DeviceLibReqMask will be 0 which means
852854 // no fallback device library will be linked.
853- uint32_t DeviceLibReqMask = 0 ;
854855 bool UseDeviceLibs = !DeviceCodeWasInCache &&
855856 Img.getFormat () == SYCL_DEVICE_BINARY_TYPE_SPIRV &&
856857 !SYCLConfig<SYCL_DEVICELIB_NO_FALLBACK>::get ();
857858 if (UseDeviceLibs)
858- DeviceLibReqMask = getDeviceLibReqMask ( Img);
859+ ImagesVec. push_back (& Img);
859860
860861 std::vector<ur_program_handle_t > ProgramsToLink;
861862 // If we had a program in cache, then it should have been the fully linked
862863 // program already.
863864 if (!DeviceCodeWasInCache) {
864865 for (RTDeviceBinaryImage *BinImg : DeviceImagesToLink) {
865866 if (UseDeviceLibs)
866- DeviceLibReqMask |= getDeviceLibReqMask (* BinImg);
867+ ImagesVec. push_back ( BinImg);
867868 device_image_plain DevImagePlain =
868869 getDeviceImageFromBinaryImage (BinImg, Context, Device);
869870 const std::shared_ptr<detail::device_image_impl> &DeviceImageImpl =
@@ -883,10 +884,10 @@ ur_program_handle_t ProgramManager::getBuiltURProgram(
883884 }
884885 std::vector<ur_device_handle_t > Devs = {
885886 getSyclObjImpl (Device).get ()->getHandleRef ()};
886- ;
887+
887888 ProgramPtr BuiltProgram = build (
888889 std::move (ProgramManaged), ContextImpl, CompileOpts, LinkOpts, Devs,
889- DeviceLibReqMask , ProgramsToLink,
890+ ImagesVec , ProgramsToLink,
890891 /* CreatedFromBinary*/ Img.getFormat () != SYCL_DEVICE_BINARY_TYPE_SPIRV);
891892 // Those extra programs won't be used anymore, just the final linked result
892893 for (ur_program_handle_t Prg : ProgramsToLink)
@@ -1505,9 +1506,9 @@ static bool isDeviceLibRequired(DeviceLibExt Ext, uint32_t DeviceLibReqMask) {
15051506}
15061507
15071508static std::vector<ur_program_handle_t >
1508- getDeviceLibPrograms (const ContextImplPtr Context,
1509- std::vector<ur_device_handle_t > &Devices,
1510- uint32_t DeviceLibReqMask) {
1509+ getDeviceLibProgramsLegacy (const ContextImplPtr Context,
1510+ std::vector<ur_device_handle_t > &Devices,
1511+ uint32_t DeviceLibReqMask) {
15111512 std::vector<ur_program_handle_t > Programs;
15121513
15131514 std::pair<DeviceLibExt, bool > RequiredDeviceLibExt[] = {
@@ -1590,6 +1591,57 @@ getDeviceLibPrograms(const ContextImplPtr Context,
15901591 return Programs;
15911592}
15921593
1594+ static std::vector<ur_program_handle_t >
1595+ getDeviceLibPrograms (const ContextImplPtr Context,
1596+ std::vector<ur_device_handle_t > &Devices,
1597+ const std::vector<const RTDeviceBinaryImage *> &Images) {
1598+ std::vector<ur_program_handle_t > Programs;
1599+ return Programs;
1600+ }
1601+
1602+ static void
1603+ checkDeviceLibsLinkMode (const std::vector<const RTDeviceBinaryImage *> &Images,
1604+ bool &LinkDeviceLib, bool &LegacyLinkMode) {
1605+ bool ReqMaskAvailable = false , ReqBinsAvailable = false ;
1606+ for (auto Img : Images) {
1607+ const RTDeviceBinaryImage::PropertyRange &LegacyRange =
1608+ Img->getDeviceLibReqMask ();
1609+ if (LegacyRange.isAvailable ()) {
1610+ ReqMaskAvailable = true ;
1611+ continue ;
1612+ }
1613+
1614+ const RTDeviceBinaryImage::PropertyRange &NewRange =
1615+ Img->getDeviceLibReqBins ();
1616+ if (NewRange.isAvailable ())
1617+ ReqBinsAvailable = true ;
1618+ }
1619+
1620+ // If both ReqBins and ReqMask are available, it means user's device image
1621+ // and the images in cache are built with different version compiler, we
1622+ // don't support such scenario.
1623+ if ((!ReqMaskAvailable && !ReqBinsAvailable) ||
1624+ (ReqMaskAvailable && ReqBinsAvailable)) {
1625+ LinkDeviceLib = false ;
1626+ return ;
1627+ }
1628+
1629+ LinkDeviceLib = true ;
1630+ LegacyLinkMode = ReqMaskAvailable;
1631+ }
1632+
1633+ static uint32_t getDeviceLibReqMaskFromImages (
1634+ const std::vector<const RTDeviceBinaryImage *> &Images) {
1635+ uint32_t DeviceLibReqMask = 0 ;
1636+ for (auto Img : Images) {
1637+ const RTDeviceBinaryImage::PropertyRange &ReqMaskRange =
1638+ Img->getDeviceLibReqMask ();
1639+ if (ReqMaskRange.isAvailable ())
1640+ DeviceLibReqMask |= DeviceBinaryProperty (*(ReqMaskRange.begin ())).asUint32 ();
1641+ }
1642+ return DeviceLibReqMask;
1643+ }
1644+
15931645// Check if device image is compressed.
15941646static inline bool isDeviceImageCompressed (sycl_device_binary Bin) {
15951647
@@ -1600,19 +1652,25 @@ static inline bool isDeviceImageCompressed(sycl_device_binary Bin) {
16001652ProgramManager::ProgramPtr ProgramManager::build (
16011653 ProgramPtr Program, const ContextImplPtr Context,
16021654 const std::string &CompileOptions, const std::string &LinkOptions,
1603- std::vector<ur_device_handle_t > &Devices, uint32_t DeviceLibReqMask,
1655+ std::vector<ur_device_handle_t > &Devices,
1656+ const std::vector<const RTDeviceBinaryImage *> &Images,
16041657 const std::vector<ur_program_handle_t > &ExtraProgramsToLink,
16051658 bool CreatedFromBinary) {
16061659
16071660 if constexpr (DbgProgMgr > 0 ) {
16081661 std::cerr << " >>> ProgramManager::build(" << Program.get () << " , "
16091662 << CompileOptions << " , " << LinkOptions << " , "
1610- << VecToString (Devices) << " , " << std::hex << DeviceLibReqMask
1611- << std::dec << " , " << VecToString (ExtraProgramsToLink) << " , "
1612- << CreatedFromBinary << " )\n " ;
1663+ << VecToString (Devices) << " , " << std::dec << " , "
1664+ << VecToString (ExtraProgramsToLink) << " , " << CreatedFromBinary
1665+ << " )\n " ;
16131666 }
16141667
1615- bool LinkDeviceLibs = (DeviceLibReqMask != 0 );
1668+ bool LinkDeviceLibs = false ;
1669+ bool LegacyDeviceLibLinkMode = false ;
1670+ if (Images.size () == 0 )
1671+ LinkDeviceLibs = false ;
1672+ else
1673+ checkDeviceLibsLinkMode (Images, LinkDeviceLibs, LegacyDeviceLibLinkMode);
16161674
16171675 // TODO: this is a temporary workaround for GPU tests for ESIMD compiler.
16181676 // We do not link with other device libraries, because it may fail
@@ -1623,7 +1681,13 @@ ProgramManager::ProgramPtr ProgramManager::build(
16231681
16241682 std::vector<ur_program_handle_t > LinkPrograms;
16251683 if (LinkDeviceLibs) {
1626- LinkPrograms = getDeviceLibPrograms (Context, Devices, DeviceLibReqMask);
1684+ if (LegacyDeviceLibLinkMode) {
1685+ uint32_t DeviceLibReqMask = getDeviceLibReqMaskFromImages (Images);
1686+ LinkPrograms =
1687+ getDeviceLibProgramsLegacy (Context, Devices, DeviceLibReqMask);
1688+ } else {
1689+ LinkPrograms = getDeviceLibPrograms (Context, Devices, Images);
1690+ }
16271691 }
16281692
16291693 static const char *ForceLinkEnv = std::getenv (" SYCL_FORCE_LINK" );
@@ -1939,15 +2003,6 @@ void ProgramManager::dumpImage(const RTDeviceBinaryImage &Img,
19392003 F.close ();
19402004}
19412005
1942- uint32_t ProgramManager::getDeviceLibReqMask (const RTDeviceBinaryImage &Img) {
1943- const RTDeviceBinaryImage::PropertyRange &DLMRange =
1944- Img.getDeviceLibReqMask ();
1945- if (DLMRange.isAvailable ())
1946- return DeviceBinaryProperty (*(DLMRange.begin ())).asUint32 ();
1947- else
1948- return 0x0 ;
1949- }
1950-
19512006const KernelArgMask *
19522007ProgramManager::getEliminatedKernelArgMask (ur_program_handle_t NativePrg,
19532008 const std::string &KernelName) {
@@ -2640,10 +2695,10 @@ device_image_plain ProgramManager::build(const device_image_plain &DeviceImage,
26402695 // Pre-compiled programs are supposed to be already linked.
26412696 // If device image is not SPIR-V, DeviceLibReqMask will be 0 which means
26422697 // no fallback device library will be linked.
2643- uint32_t DeviceLibReqMask = 0 ;
2698+ std::vector< const RTDeviceBinaryImage *> ImagesVec ;
26442699 if (Img.getFormat () == SYCL_DEVICE_BINARY_TYPE_SPIRV &&
26452700 !SYCLConfig<SYCL_DEVICELIB_NO_FALLBACK>::get ())
2646- DeviceLibReqMask = getDeviceLibReqMask ( Img);
2701+ ImagesVec. push_back (& Img);
26472702
26482703 // TODO: Add support for dynamic linking with kernel bundles
26492704 std::vector<ur_program_handle_t > ExtraProgramsToLink;
@@ -2653,7 +2708,7 @@ device_image_plain ProgramManager::build(const device_image_plain &DeviceImage,
26532708 }
26542709 ProgramPtr BuiltProgram =
26552710 build (std::move (ProgramManaged), ContextImpl, CompileOpts, LinkOpts,
2656- URDevices, DeviceLibReqMask , ExtraProgramsToLink);
2711+ URDevices, ImagesVec , ExtraProgramsToLink);
26572712
26582713 emitBuiltProgramInfo (BuiltProgram.get (), ContextImpl);
26592714
@@ -2869,10 +2924,13 @@ ur_kernel_handle_t ProgramManager::getOrCreateMaterializedKernel(
28692924 // No linking of extra programs reqruired.
28702925 std::vector<ur_program_handle_t > ExtraProgramsToLink;
28712926 std::vector<ur_device_handle_t > Devs = {DeviceImpl->getHandleRef ()};
2927+ std::vector<const RTDeviceBinaryImage *> ImagesVec;
2928+ // For non-spirv target, we don't need to link any fallback device library.
2929+ // An empty images vector will skip linking fallback device libraries.
28722930 auto BuildProgram =
28732931 build (std::move (ProgramManaged), detail::getSyclObjImpl (Context),
28742932 CompileOpts, LinkOpts, Devs,
2875- /* For non SPIR-V devices DeviceLibReqdMask is always 0 */ 0 ,
2933+ ImagesVec ,
28762934 ExtraProgramsToLink);
28772935 ur_kernel_handle_t UrKernel{nullptr };
28782936 Adapter->call <errc::kernel_not_supported, UrApiKind::urKernelCreate>(
0 commit comments