@@ -523,26 +523,55 @@ void program_impl::flush_spec_constants(const RTDeviceBinaryImage &Img,
523
523
RT::PiProgram NativePrg) const {
524
524
// iterate via all specialization constants the program's image depends on,
525
525
// and set each to current runtime value (if any)
526
- const pi::DeviceBinaryImage::PropertyRange &SCRange = Img.getSpecConstants ();
526
+ const pi::DeviceBinaryImage::PropertyRange &ScalarSCRange =
527
+ Img.getScalarSpecConstants ();
528
+ const pi::DeviceBinaryImage::PropertyRange &CompositeSCRange =
529
+ Img.getCompositeSpecConstants ();
527
530
ContextImplPtr Ctx = getSyclObjImpl (get_context ());
528
531
using SCItTy = pi::DeviceBinaryImage::PropertyRange::ConstIterator;
529
532
530
533
auto LockGuard = Ctx->getKernelProgramCache ().acquireCachedPrograms ();
534
+ NativePrg = NativePrg ? NativePrg : getHandleRef ();
531
535
532
- for (SCItTy SCIt : SCRange) {
533
- const char *SCName = (*SCIt)->Name ;
534
- auto SCEntry = SpecConstRegistry.find (SCName);
536
+ for (SCItTy SCIt : ScalarSCRange) {
537
+ auto SCEntry = SpecConstRegistry.find ((*SCIt)->Name );
535
538
if (SCEntry == SpecConstRegistry.end ())
536
539
// spec constant has not been set in user code - SPIR-V will use default
537
540
continue ;
538
541
const spec_constant_impl &SC = SCEntry->second ;
539
542
assert (SC.isSet () && " uninitialized spec constant" );
540
- pi_device_binary_property SCProp = *SCIt;
541
- pi_uint32 ID = pi::DeviceBinaryProperty (SCProp).asUint32 ();
542
- NativePrg = NativePrg ? NativePrg : getHandleRef ();
543
+ pi_uint32 ID = pi::DeviceBinaryProperty (*SCIt).asUint32 ();
543
544
Ctx->getPlugin ().call <PiApiKind::piextProgramSetSpecializationConstant>(
544
545
NativePrg, ID, SC.getSize (), SC.getValuePtr ());
545
546
}
547
+
548
+ for (SCItTy SCIt : CompositeSCRange) {
549
+ auto SCEntry = SpecConstRegistry.find ((*SCIt)->Name );
550
+ if (SCEntry == SpecConstRegistry.end ())
551
+ // spec constant has not been set in user code - SPIR-V will use default
552
+ continue ;
553
+ const spec_constant_impl &SC = SCEntry->second ;
554
+ assert (SC.isSet () && " uninitialized spec constant" );
555
+ pi::ByteArray Descriptors = pi::DeviceBinaryProperty (*SCIt).asByteArray ();
556
+ // First 8 bytes are consumed by size of the property
557
+ assert (Descriptors.size () > 8 && " Unexpected property size" );
558
+ // Expected layout is vector of 3-component tuples (flattened into a vector
559
+ // of scalars), where each tuple consists of: ID of a scalar spec constant,
560
+ // which is a member of the composite; offset, which is used to calculate
561
+ // location of scalar member within the composite; size of a scalar member
562
+ // of the composite.
563
+ assert (((Descriptors.size () - 8 ) / sizeof (std::uint32_t )) % 3 == 0 &&
564
+ " unexpected layout of composite spec const descriptors" );
565
+ auto *It = reinterpret_cast <const std::uint32_t *>(&Descriptors[8 ]);
566
+ auto *End = reinterpret_cast <const std::uint32_t *>(&Descriptors[0 ] +
567
+ Descriptors.size ());
568
+ while (It != End) {
569
+ Ctx->getPlugin ().call <PiApiKind::piextProgramSetSpecializationConstant>(
570
+ NativePrg, /* ID */ It[0 ], /* Size */ It[2 ],
571
+ SC.getValuePtr () + /* Offset */ It[1 ]);
572
+ It += 3 ;
573
+ }
574
+ }
546
575
}
547
576
548
577
pi_native_handle program_impl::getNative () const {
0 commit comments