@@ -378,11 +378,13 @@ class kernel_bundle_impl {
378
378
379
379
// oneapi_ext_kernel_compiler
380
380
// 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)
386
388
: kernel_bundle_impl(std::move(Ctx), std::move(Devs), KernelIDs,
387
389
bundle_state::executable) {
388
390
assert (Lang == syclex::source_language::sycl_jit);
@@ -392,9 +394,10 @@ class kernel_bundle_impl {
392
394
// loaded via the program manager have `kernel_id`s, they can't be looked up
393
395
// from the (unprefixed) kernel name.
394
396
MIsInterop = true ;
395
- MKernelNames = std::move (KNames);
397
+ MKernelNames = std::move (KernelNames);
398
+ MMangledKernelNames = std::move (MangledKernelNames);
396
399
MDeviceBinaries = Binaries;
397
- MPrefix = std::move (Pfx );
400
+ MPrefix = std::move (Prefix );
398
401
MLanguage = Lang;
399
402
}
400
403
@@ -499,27 +502,70 @@ class kernel_bundle_impl {
499
502
if (MLanguage == syclex::source_language::sycl_jit) {
500
503
// Build device images via the program manager.
501
504
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
+
502
525
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 );
505
528
506
529
auto &PM = detail::ProgramManager::getInstance ();
507
530
PM.addImages (Binaries);
508
531
509
532
std::vector<kernel_id> KernelIDs;
510
533
std::vector<std::string> KernelNames;
534
+ std::unordered_map<std::string, std::string> MangledKernelNames;
511
535
for (const auto &KernelID : PM.getAllSYCLKernelIDs ()) {
512
536
std::string_view KernelName{KernelID.get_name ()};
513
537
if (KernelName.find (Prefix) == 0 ) {
514
538
KernelIDs.push_back (KernelID);
515
539
KernelName.remove_prefix (Prefix.length ());
516
540
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
+ }
517
549
}
518
550
}
519
551
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);
523
569
}
524
570
525
571
ur_program_handle_t UrProgram = nullptr ;
@@ -625,21 +671,27 @@ class kernel_bundle_impl {
625
671
KernelNames, MLanguage);
626
672
}
627
673
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
+ }
634
679
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 ();
637
691
}
638
692
639
693
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));
643
695
}
644
696
645
697
kernel
@@ -649,13 +701,12 @@ class kernel_bundle_impl {
649
701
throw sycl::exception (make_error_code (errc::invalid),
650
702
" 'ext_oneapi_get_kernel' is only available in "
651
703
" kernel_bundles successfully built from "
652
- " kernel_bundle<bundle_state:ext_oneapi_source>." );
704
+ " kernel_bundle<bundle_state:: ext_oneapi_source>." );
653
705
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 ))
656
708
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" );
659
710
660
711
if (MLanguage == syclex::source_language::sycl_jit) {
661
712
auto &PM = ProgramManager::getInstance ();
@@ -697,6 +748,22 @@ class kernel_bundle_impl {
697
748
return detail::createSyclObjFromImpl<kernel>(KernelImpl);
698
749
}
699
750
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
+
700
767
bool empty () const noexcept { return MDeviceImages.empty (); }
701
768
702
769
backend get_backend () const noexcept {
@@ -872,12 +939,11 @@ class kernel_bundle_impl {
872
939
}
873
940
874
941
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
+ });
881
947
return SetInDevImg || MSpecConstValues.count (std::string{SpecName}) != 0 ;
882
948
}
883
949
@@ -968,6 +1034,7 @@ class kernel_bundle_impl {
968
1034
const std::variant<std::string, std::vector<std::byte>> MSource;
969
1035
// only kernel_bundles created from source have KernelNames member.
970
1036
std::vector<std::string> MKernelNames;
1037
+ std::unordered_map<std::string, std::string> MMangledKernelNames;
971
1038
sycl_device_binaries MDeviceBinaries = nullptr ;
972
1039
std::string MPrefix;
973
1040
include_pairs_t MIncludePairs;
0 commit comments