@@ -378,11 +378,13 @@ class kernel_bundle_impl {
378378
379379 // oneapi_ext_kernel_compiler
380380 // program manager integration, only for sycl_jit language
381- kernel_bundle_impl (context Ctx, std::vector<device> Devs,
382- const std::vector<kernel_id> &KernelIDs,
383- std::vector<std::string> KNames,
384- sycl_device_binaries Binaries, std::string Pfx,
385- syclex::source_language Lang)
381+ kernel_bundle_impl (
382+ context Ctx, std::vector<device> Devs,
383+ const std::vector<kernel_id> &KernelIDs,
384+ std::vector<std::string> &&KernelNames,
385+ std::unordered_map<std::string, std::string> &&MangledKernelNames,
386+ sycl_device_binaries Binaries, std::string &&Prefix,
387+ syclex::source_language Lang)
386388 : kernel_bundle_impl(std::move(Ctx), std::move(Devs), KernelIDs,
387389 bundle_state::executable) {
388390 assert (Lang == syclex::source_language::sycl_jit);
@@ -392,9 +394,10 @@ class kernel_bundle_impl {
392394 // loaded via the program manager have `kernel_id`s, they can't be looked up
393395 // from the (unprefixed) kernel name.
394396 MIsInterop = true ;
395- MKernelNames = std::move (KNames);
397+ MKernelNames = std::move (KernelNames);
398+ MMangledKernelNames = std::move (MangledKernelNames);
396399 MDeviceBinaries = Binaries;
397- MPrefix = std::move (Pfx );
400+ MPrefix = std::move (Prefix );
398401 MLanguage = Lang;
399402 }
400403
@@ -499,27 +502,70 @@ class kernel_bundle_impl {
499502 if (MLanguage == syclex::source_language::sycl_jit) {
500503 // Build device images via the program manager.
501504 const std::string &SourceStr = std::get<std::string>(MSource);
505+ std::ostringstream SourceExt;
506+ if (!RegisteredKernelNames.empty ()) {
507+ SourceExt << SourceStr << ' \n ' ;
508+
509+ auto EmitEntry =
510+ [&SourceExt](const std::string &Name) -> std::ostringstream & {
511+ SourceExt << " {\" " << Name << " \" , " << Name << " }" ;
512+ return SourceExt;
513+ };
514+
515+ SourceExt << " [[__sycl_detail__::__registered_kernels__(\n " ;
516+ for (auto It = RegisteredKernelNames.begin (),
517+ SecondToLast = RegisteredKernelNames.end () - 1 ;
518+ It != SecondToLast; ++It) {
519+ EmitEntry (*It) << " ,\n " ;
520+ }
521+ EmitEntry (RegisteredKernelNames.back ()) << " \n " ;
522+ SourceExt << " )]];\n " ;
523+ }
524+
502525 auto [Binaries, Prefix] = syclex::detail::SYCL_JIT_to_SPIRV (
503- SourceStr, MIncludePairs, BuildOptions, LogPtr ,
504- RegisteredKernelNames );
526+ RegisteredKernelNames. empty () ? SourceStr : SourceExt. str () ,
527+ MIncludePairs, BuildOptions, LogPtr );
505528
506529 auto &PM = detail::ProgramManager::getInstance ();
507530 PM.addImages (Binaries);
508531
509532 std::vector<kernel_id> KernelIDs;
510533 std::vector<std::string> KernelNames;
534+ std::unordered_map<std::string, std::string> MangledKernelNames;
511535 for (const auto &KernelID : PM.getAllSYCLKernelIDs ()) {
512536 std::string_view KernelName{KernelID.get_name ()};
513537 if (KernelName.find (Prefix) == 0 ) {
514538 KernelIDs.push_back (KernelID);
515539 KernelName.remove_prefix (Prefix.length ());
516540 KernelNames.emplace_back (KernelName);
541+ static constexpr std::string_view SYCLKernelMarker{" __sycl_kernel_" };
542+ if (KernelName.find (SYCLKernelMarker) == 0 ) {
543+ // extern "C" declaration, implicitly register kernel without the
544+ // marker.
545+ std::string_view KernelNameWithoutMarker{KernelName};
546+ KernelNameWithoutMarker.remove_prefix (SYCLKernelMarker.length ());
547+ MangledKernelNames.emplace (KernelNameWithoutMarker, KernelName);
548+ }
517549 }
518550 }
519551
520- return std::make_shared<kernel_bundle_impl>(MContext, MDevices, KernelIDs,
521- KernelNames, Binaries, Prefix,
522- MLanguage);
552+ // Apply frontend information.
553+ for (const auto *RawImg : PM.getRawDeviceImages (KernelIDs)) {
554+ for (const sycl_device_binary_property &RKProp :
555+ RawImg->getRegisteredKernels ()) {
556+
557+ auto BA = DeviceBinaryProperty (RKProp).asByteArray ();
558+ auto MangledNameLen = BA.consume <uint64_t >() / 8 /* bits in a byte*/ ;
559+ std::string_view MangledName{
560+ reinterpret_cast <const char *>(BA.begin ()), MangledNameLen};
561+ MangledKernelNames.emplace (RKProp->Name , MangledName);
562+ }
563+ }
564+
565+ return std::make_shared<kernel_bundle_impl>(
566+ MContext, MDevices, KernelIDs, std::move (KernelNames),
567+ std::move (MangledKernelNames), Binaries, std::move (Prefix),
568+ MLanguage);
523569 }
524570
525571 ur_program_handle_t UrProgram = nullptr ;
@@ -625,21 +671,27 @@ class kernel_bundle_impl {
625671 KernelNames, MLanguage);
626672 }
627673
628- std::string adjust_kernel_name (const std::string &Name,
629- syclex::source_language Lang) {
630- // Once name demangling support is in, we won't need this.
631- if (Lang != syclex::source_language::sycl &&
632- Lang != syclex::source_language::sycl_jit)
633- return Name;
674+ std::string adjust_kernel_name (const std::string &Name) {
675+ if (MLanguage == syclex::source_language::sycl_jit) {
676+ auto It = MMangledKernelNames.find (Name);
677+ return It == MMangledKernelNames.end () ? Name : It->second ;
678+ }
634679
635- bool isMangled = Name.find (" __sycl_kernel_" ) != std::string::npos;
636- return isMangled ? Name : " __sycl_kernel_" + Name;
680+ if (MLanguage == syclex::source_language::sycl) {
681+ bool isMangled = Name.find (" __sycl_kernel_" ) != std::string::npos;
682+ return isMangled ? Name : " __sycl_kernel_" + Name;
683+ }
684+
685+ return Name;
686+ }
687+
688+ bool is_kernel_name (const std::string &Name) {
689+ return std::find (MKernelNames.begin (), MKernelNames.end (), Name) !=
690+ MKernelNames.end ();
637691 }
638692
639693 bool ext_oneapi_has_kernel (const std::string &Name) {
640- auto it = std::find (MKernelNames.begin (), MKernelNames.end (),
641- adjust_kernel_name (Name, MLanguage));
642- return it != MKernelNames.end ();
694+ return is_kernel_name (adjust_kernel_name (Name));
643695 }
644696
645697 kernel
@@ -649,13 +701,12 @@ class kernel_bundle_impl {
649701 throw sycl::exception (make_error_code (errc::invalid),
650702 " 'ext_oneapi_get_kernel' is only available in "
651703 " kernel_bundles successfully built from "
652- " kernel_bundle<bundle_state:ext_oneapi_source>." );
704+ " kernel_bundle<bundle_state:: ext_oneapi_source>." );
653705
654- std::string AdjustedName = adjust_kernel_name (Name, MLanguage );
655- if (!ext_oneapi_has_kernel (Name ))
706+ std::string AdjustedName = adjust_kernel_name (Name);
707+ if (!is_kernel_name (AdjustedName ))
656708 throw sycl::exception (make_error_code (errc::invalid),
657- " kernel '" + AdjustedName +
658- " ' not found in kernel_bundle" );
709+ " kernel '" + Name + " ' not found in kernel_bundle" );
659710
660711 if (MLanguage == syclex::source_language::sycl_jit) {
661712 auto &PM = ProgramManager::getInstance ();
@@ -697,6 +748,22 @@ class kernel_bundle_impl {
697748 return detail::createSyclObjFromImpl<kernel>(KernelImpl);
698749 }
699750
751+ std::string ext_oneapi_get_raw_kernel_name (const std::string &Name) {
752+ if (MKernelNames.empty ())
753+ throw sycl::exception (
754+ make_error_code (errc::invalid),
755+ " 'ext_oneapi_get_raw_kernel_name' is only available in "
756+ " kernel_bundles successfully built from "
757+ " kernel_bundle<bundle_state::ext_oneapi_source>." );
758+
759+ std::string AdjustedName = adjust_kernel_name (Name);
760+ if (!is_kernel_name (AdjustedName))
761+ throw sycl::exception (make_error_code (errc::invalid),
762+ " kernel '" + Name + " ' not found in kernel_bundle" );
763+
764+ return AdjustedName;
765+ }
766+
700767 bool empty () const noexcept { return MDeviceImages.empty (); }
701768
702769 backend get_backend () const noexcept {
@@ -872,12 +939,11 @@ class kernel_bundle_impl {
872939 }
873940
874941 bool is_specialization_constant_set (const char *SpecName) const noexcept {
875- bool SetInDevImg =
876- std::any_of (begin (), end (),
877- [SpecName](const device_image_plain &DeviceImage) {
878- return getSyclObjImpl (DeviceImage)
879- ->is_specialization_constant_set (SpecName);
880- });
942+ bool SetInDevImg = std::any_of (
943+ begin (), end (), [SpecName](const device_image_plain &DeviceImage) {
944+ return getSyclObjImpl (DeviceImage)
945+ ->is_specialization_constant_set (SpecName);
946+ });
881947 return SetInDevImg || MSpecConstValues.count (std::string{SpecName}) != 0 ;
882948 }
883949
@@ -968,6 +1034,7 @@ class kernel_bundle_impl {
9681034 const std::variant<std::string, std::vector<std::byte>> MSource;
9691035 // only kernel_bundles created from source have KernelNames member.
9701036 std::vector<std::string> MKernelNames;
1037+ std::unordered_map<std::string, std::string> MMangledKernelNames;
9711038 sycl_device_binaries MDeviceBinaries = nullptr ;
9721039 std::string MPrefix;
9731040 include_pairs_t MIncludePairs;
0 commit comments