Skip to content

Commit ffeeae2

Browse files
authored
[SYCL][ESIMD] Emulate handling of 64 bit data by accessor version of gather/scatter (#12602)
1 parent 05740cc commit ffeeae2

File tree

10 files changed

+183
-90
lines changed

10 files changed

+183
-90
lines changed

sycl/include/sycl/ext/intel/esimd/memory.hpp

Lines changed: 143 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,32 +2699,40 @@ ESIMD_INLINE ESIMD_NODEBUG std::enable_if_t<
26992699
scatter_impl(AccessorTy acc, simd<T, N> vals, simd<uint32_t, N> offsets,
27002700
uint32_t glob_offset, simd_mask<N> mask) {
27012701

2702-
static_assert(sizeof(T) <= 4 && detail::isPowerOf2(N, 32),
2703-
"Unexpected type or vector length");
2704-
constexpr int TypeSizeLog2 = detail::ElemsPerAddrEncoding<sizeof(T)>();
2705-
// TODO (performance) use hardware-supported scale once BE supports it
2706-
constexpr int16_t scale = 0;
2707-
const auto si = __ESIMD_NS::get_surface_index(acc);
2708-
2709-
if constexpr (sizeof(T) < 4) {
2710-
using Tint = std::conditional_t<std::is_integral_v<T>, T,
2711-
detail::uint_type_t<sizeof(T)>>;
2712-
using Treal = __raw_t<T>;
2713-
simd<Tint, N> vals_int = bitcast<Tint, Treal, N>(std::move(vals).data());
2714-
using PromoT = typename std::conditional_t<std::is_signed<Tint>::value,
2715-
int32_t, uint32_t>;
2716-
const simd<PromoT, N> promo_vals = convert<PromoT>(std::move(vals_int));
2717-
__esimd_scatter_scaled<PromoT, N, decltype(si), TypeSizeLog2, scale>(
2718-
mask.data(), si, glob_offset, offsets.data(), promo_vals.data());
2702+
static_assert(detail::isPowerOf2(N, 32), "Unexpected vector length");
2703+
if constexpr (sizeof(T) == 8) {
2704+
scatter_impl<uint32_t, N>(
2705+
acc, vals.template bit_cast_view<uint32_t>().template select<N, 2>(0),
2706+
offsets, glob_offset, mask);
2707+
scatter_impl<uint32_t, N>(
2708+
acc, vals.template bit_cast_view<uint32_t>().template select<N, 2>(1),
2709+
offsets, glob_offset + sizeof(uint32_t), mask);
27192710
} else {
2720-
using Treal = __raw_t<T>;
2721-
if constexpr (!std::is_same_v<Treal, T>) {
2722-
simd<Treal, N> Values = vals.template bit_cast_view<Treal>();
2723-
__esimd_scatter_scaled<Treal, N, decltype(si), TypeSizeLog2, scale>(
2724-
mask.data(), si, glob_offset, offsets.data(), Values.data());
2711+
constexpr int TypeSizeLog2 = detail::ElemsPerAddrEncoding<sizeof(T)>();
2712+
// TODO (performance) use hardware-supported scale once BE supports it
2713+
constexpr int16_t scale = 0;
2714+
const auto si = __ESIMD_NS::get_surface_index(acc);
2715+
2716+
if constexpr (sizeof(T) < 4) {
2717+
using Tint = std::conditional_t<std::is_integral_v<T>, T,
2718+
detail::uint_type_t<sizeof(T)>>;
2719+
using Treal = __raw_t<T>;
2720+
simd<Tint, N> vals_int = bitcast<Tint, Treal, N>(std::move(vals).data());
2721+
using PromoT = typename std::conditional_t<std::is_signed<Tint>::value,
2722+
int32_t, uint32_t>;
2723+
const simd<PromoT, N> promo_vals = convert<PromoT>(std::move(vals_int));
2724+
__esimd_scatter_scaled<PromoT, N, decltype(si), TypeSizeLog2, scale>(
2725+
mask.data(), si, glob_offset, offsets.data(), promo_vals.data());
27252726
} else {
2726-
__esimd_scatter_scaled<T, N, decltype(si), TypeSizeLog2, scale>(
2727-
mask.data(), si, glob_offset, offsets.data(), vals.data());
2727+
using Treal = __raw_t<T>;
2728+
if constexpr (!std::is_same_v<Treal, T>) {
2729+
simd<Treal, N> Values = vals.template bit_cast_view<Treal>();
2730+
__esimd_scatter_scaled<Treal, N, decltype(si), TypeSizeLog2, scale>(
2731+
mask.data(), si, glob_offset, offsets.data(), Values.data());
2732+
} else {
2733+
__esimd_scatter_scaled<T, N, decltype(si), TypeSizeLog2, scale>(
2734+
mask.data(), si, glob_offset, offsets.data(), vals.data());
2735+
}
27282736
}
27292737
}
27302738
}
@@ -2736,42 +2744,50 @@ __ESIMD_API std::enable_if_t<
27362744
simd<T, N>>
27372745
gather_impl(AccessorTy acc, simd<uint32_t, N> offsets, uint32_t glob_offset,
27382746
simd_mask<N> mask) {
2739-
static_assert(sizeof(T) <= 4 && detail::isPowerOf2(N, 32),
2740-
"Unexpected type or vector length");
2741-
2742-
constexpr int TypeSizeLog2 = detail::ElemsPerAddrEncoding<sizeof(T)>();
2743-
// TODO (performance) use hardware-supported scale once BE supports it
2744-
constexpr uint32_t scale = 0;
2745-
const auto si = get_surface_index(acc);
2746-
2747-
if constexpr (sizeof(T) < 4) {
2748-
using Tint = std::conditional_t<std::is_integral_v<T>, T,
2749-
detail::uint_type_t<sizeof(T)>>;
2750-
using Treal = __raw_t<T>;
2751-
static_assert(std::is_integral<Tint>::value,
2752-
"only integral 1- & 2-byte types are supported");
2753-
using PromoT = typename std::conditional_t<std::is_signed<Tint>::value,
2754-
int32_t, uint32_t>;
2755-
simd<PromoT, N> promo_vals =
2756-
__esimd_gather_masked_scaled2<PromoT, N, decltype(si), TypeSizeLog2,
2757-
scale>(si, glob_offset, offsets.data(),
2758-
mask.data());
2759-
auto Res = convert<Tint>(promo_vals);
2760-
2761-
if constexpr (!std::is_same_v<Tint, T>) {
2762-
return detail::bitcast<Treal, Tint, N>(Res.data());
2763-
} else {
2764-
return Res;
2765-
}
2747+
static_assert(detail::isPowerOf2(N, 32), "Unexpected vector length");
2748+
2749+
if constexpr (sizeof(T) == 8) {
2750+
simd<T, N> Res;
2751+
Res.template bit_cast_view<uint32_t>().template select<N, 2>(0) =
2752+
gather_impl<uint32_t, N>(acc, offsets, glob_offset, mask);
2753+
Res.template bit_cast_view<uint32_t>().template select<N, 2>(1) =
2754+
gather_impl<uint32_t, N>(acc, offsets, glob_offset + sizeof(uint32_t),
2755+
mask);
2756+
return Res;
27662757
} else {
27672758
using Treal = __raw_t<T>;
2768-
simd<Treal, N> Res = __esimd_gather_masked_scaled2<Treal, N, decltype(si),
2769-
TypeSizeLog2, scale>(
2770-
si, glob_offset, offsets.data(), mask.data());
2771-
if constexpr (!std::is_same_v<Treal, T>) {
2772-
return Res.template bit_cast_view<T>();
2759+
constexpr int TypeSizeLog2 = detail::ElemsPerAddrEncoding<sizeof(T)>();
2760+
// TODO (performance) use hardware-supported scale once BE supports it
2761+
constexpr uint32_t scale = 0;
2762+
const auto si = get_surface_index(acc);
2763+
if constexpr (sizeof(T) < 4) {
2764+
using Tint = std::conditional_t<std::is_integral_v<T>, T,
2765+
detail::uint_type_t<sizeof(T)>>;
2766+
2767+
static_assert(std::is_integral<Tint>::value,
2768+
"only integral 1- & 2-byte types are supported");
2769+
using PromoT = typename std::conditional_t<std::is_signed<Tint>::value,
2770+
int32_t, uint32_t>;
2771+
simd<PromoT, N> promo_vals =
2772+
__esimd_gather_masked_scaled2<PromoT, N, decltype(si), TypeSizeLog2,
2773+
scale>(si, glob_offset, offsets.data(),
2774+
mask.data());
2775+
auto Res = convert<Tint>(promo_vals);
2776+
2777+
if constexpr (!std::is_same_v<Tint, T>) {
2778+
return detail::bitcast<Treal, Tint, N>(Res.data());
2779+
} else {
2780+
return Res;
2781+
}
27732782
} else {
2774-
return Res;
2783+
simd<Treal, N> Res = __esimd_gather_masked_scaled2<Treal, N, decltype(si),
2784+
TypeSizeLog2, scale>(
2785+
si, glob_offset, offsets.data(), mask.data());
2786+
if constexpr (!std::is_same_v<Treal, T>) {
2787+
return Res.template bit_cast_view<T>();
2788+
} else {
2789+
return Res;
2790+
}
27752791
}
27762792
}
27772793
}
@@ -2927,7 +2943,7 @@ __ESIMD_API
29272943
return gather<T, N>(__ESIMD_DNS::accessorToPointer<T>(acc, glob_offset),
29282944
byte_offsets, mask);
29292945
#else
2930-
if constexpr (sizeof(T) > 4 || !(detail::isPowerOf2(N, 32))) {
2946+
if constexpr (!detail::isPowerOf2(N, 32)) {
29312947
// Requires DG2 or PVC.
29322948
simd<T, N> PassThru; // Intentionally undefined
29332949
byte_offsets += glob_offset;
@@ -3136,7 +3152,7 @@ gather(AccessorT acc, simd<OffsetT, N / VS> byte_offsets,
31363152
"hint is cache_level::L2 now.");
31373153

31383154
if constexpr (L1Hint != cache_hint::none || L2Hint != cache_hint::none ||
3139-
VS > 1 || sizeof(T) > 4 || !(detail::isPowerOf2(N, 32))) {
3155+
VS > 1 || !(detail::isPowerOf2(N, 32))) {
31403156
simd<T, N> PassThru; // Intentionally undefined
31413157
return detail::gather_impl<T, N, VS, L1Hint, L2Hint,
31423158
detail::lsc_data_size::default_size>(
@@ -3344,13 +3360,13 @@ gather(AccessorT acc, OffsetSimdViewT byte_offsets, PropertyListT props = {}) {
33443360
///
33453361
///
33463362
template <typename T, int N, typename AccessorTy>
3347-
__ESIMD_API std::enable_if_t<
3348-
(sizeof(T) <= 4) && (N == 1 || N == 8 || N == 16 || N == 32) &&
3349-
detail::is_device_accessor_with_v<AccessorTy,
3350-
detail::accessor_mode_cap::can_write>>
3351-
scatter(AccessorTy acc, simd<detail::DeviceAccessorOffsetT, N> offsets,
3352-
simd<T, N> vals, detail::DeviceAccessorOffsetT glob_offset = 0,
3353-
simd_mask<N> mask = 1) {
3363+
__ESIMD_API
3364+
std::enable_if_t<(detail::isPowerOf2(N, 32)) &&
3365+
detail::is_device_accessor_with_v<
3366+
AccessorTy, detail::accessor_mode_cap::can_write>>
3367+
scatter(AccessorTy acc, simd<detail::DeviceAccessorOffsetT, N> offsets,
3368+
simd<T, N> vals, detail::DeviceAccessorOffsetT glob_offset = 0,
3369+
simd_mask<N> mask = 1) {
33543370
#ifdef __ESIMD_FORCE_STATELESS_MEM
33553371
scatter<T, N>(__ESIMD_DNS::accessorToPointer<T>(acc, glob_offset), offsets,
33563372
vals, mask);
@@ -3362,7 +3378,7 @@ scatter(AccessorTy acc, simd<detail::DeviceAccessorOffsetT, N> offsets,
33623378
#ifdef __ESIMD_FORCE_STATELESS_MEM
33633379
template <typename T, int N, typename AccessorTy, typename Toffset>
33643380
__ESIMD_API std::enable_if_t<
3365-
(sizeof(T) <= 4) && (N == 1 || N == 8 || N == 16 || N == 32) &&
3381+
(detail::isPowerOf2(N, 32)) &&
33663382
detail::is_device_accessor_with_v<AccessorTy,
33673383
detail::accessor_mode_cap::can_write> &&
33683384
std::is_integral_v<Toffset> && !std::is_same_v<Toffset, uint64_t>>
@@ -3902,9 +3918,27 @@ slm_gather(simd<uint32_t, N / VS> byte_offsets, simd_mask<N / VS> mask,
39023918
detail::lsc_data_size::default_size>(
39033919
byte_offsets, mask, pass_thru);
39043920
} else {
3905-
using MsgT = detail::__raw_t<T>;
3906-
return __esimd_slm_gather_ld<MsgT, N, Alignment>(
3907-
byte_offsets.data(), mask.data(), pass_thru.data());
3921+
if constexpr (sizeof(T) == 8) {
3922+
simd<T, N> Res;
3923+
Res.template bit_cast_view<uint32_t>().template select<N, 2>(0) =
3924+
__esimd_slm_gather_ld<uint32_t, N, Alignment>(
3925+
byte_offsets.data(), mask.data(),
3926+
(pass_thru.template bit_cast_view<uint32_t>()
3927+
.template select<N, 2>(0))
3928+
.data());
3929+
simd<uint32_t, N / VS> Offset = byte_offsets + sizeof(uint32_t);
3930+
Res.template bit_cast_view<uint32_t>().template select<N, 2>(1) =
3931+
__esimd_slm_gather_ld<uint32_t, N, sizeof(uint32_t)>(
3932+
Offset.data(), mask.data(),
3933+
(pass_thru.template bit_cast_view<uint32_t>()
3934+
.template select<N, 2>(1))
3935+
.data());
3936+
return Res;
3937+
} else {
3938+
using MsgT = detail::__raw_t<T>;
3939+
return __esimd_slm_gather_ld<MsgT, N, Alignment>(
3940+
byte_offsets.data(), mask.data(), pass_thru.data());
3941+
}
39083942
}
39093943
}
39103944

@@ -3943,16 +3977,30 @@ slm_gather(simd<uint32_t, N / VS> byte_offsets, simd_mask<N / VS> mask,
39433977
static_assert(Alignment >= sizeof(T),
39443978
"slm_gather() requires at least element-size alignment");
39453979

3946-
if constexpr (VS > 1 || (!(detail::isPowerOf2(N, 32) && sizeof(T) <= 4) &&
3980+
if constexpr (VS > 1 || (!detail::isPowerOf2(N, 32) &&
39473981
!detail::isMaskedGatherScatterLLVMAvailable())) {
39483982
simd<T, N> PassThru; // Intentionally undefined
39493983
return detail::slm_gather_impl<T, VS, detail::lsc_data_size::default_size>(
39503984
byte_offsets, mask, PassThru);
39513985
} else if constexpr (detail::isMaskedGatherScatterLLVMAvailable()) {
3952-
using MsgT = detail::__raw_t<T>;
3953-
simd<MsgT, N> PassThru; // it is intentionally undefined
3954-
return __esimd_slm_gather_ld<MsgT, N, Alignment>(
3955-
byte_offsets.data(), mask.data(), PassThru.data());
3986+
if constexpr (sizeof(T) == 8) {
3987+
simd<T, N> Res;
3988+
simd<uint32_t, N> PassThru; // it is intentionally undefined
3989+
3990+
Res.template bit_cast_view<uint32_t>().template select<N, 2>(0) =
3991+
__esimd_slm_gather_ld<uint32_t, N, Alignment>(
3992+
byte_offsets.data(), mask.data(), PassThru.data());
3993+
simd<uint32_t, N / VS> Offset = byte_offsets + sizeof(uint32_t);
3994+
Res.template bit_cast_view<uint32_t>().template select<N, 2>(1) =
3995+
__esimd_slm_gather_ld<uint32_t, N, sizeof(uint32_t)>(
3996+
Offset.data(), mask.data(), PassThru.data());
3997+
return Res;
3998+
} else {
3999+
using MsgT = detail::__raw_t<T>;
4000+
simd<MsgT, N> PassThru; // it is intentionally undefined
4001+
return __esimd_slm_gather_ld<MsgT, N, Alignment>(
4002+
byte_offsets.data(), mask.data(), PassThru.data());
4003+
}
39564004
} else {
39574005
detail::LocalAccessorMarker acc;
39584006
return detail::gather_impl<T, N>(acc, byte_offsets, 0, mask);
@@ -4236,15 +4284,30 @@ slm_scatter(simd<uint32_t, N / VS> byte_offsets, simd<T, N> vals,
42364284
"slm_scatter() requires at least element-size alignment");
42374285

42384286
// Use LSC lowering if VS > 1.
4239-
if constexpr (VS > 1 || (!(detail::isPowerOf2(N, 32) && sizeof(T) <= 4) &&
4287+
if constexpr (VS > 1 || (!detail::isPowerOf2(N, 32) &&
42404288
!detail::isMaskedGatherScatterLLVMAvailable())) {
42414289
__ESIMD_DNS::slm_scatter_impl<T, VS, detail::lsc_data_size::default_size>(
42424290
byte_offsets, vals, mask);
42434291
} else if constexpr (detail::isMaskedGatherScatterLLVMAvailable()) {
4244-
using MsgT = detail::__raw_t<T>;
4245-
__esimd_slm_scatter_st<MsgT, N, Alignment>(
4246-
sycl::bit_cast<__ESIMD_DNS::vector_type_t<MsgT, N>>(vals.data()),
4247-
byte_offsets.data(), mask.data());
4292+
if constexpr (sizeof(T) == 8) {
4293+
__esimd_slm_scatter_st<uint32_t, N, Alignment>(
4294+
vals.template bit_cast_view<uint32_t>()
4295+
.template select<N, 2>(0)
4296+
.data(),
4297+
byte_offsets.data(), mask.data());
4298+
simd<uint32_t, N / VS> Offset = byte_offsets + sizeof(uint32_t);
4299+
__esimd_slm_scatter_st<uint32_t, N, sizeof(uint32_t)>(
4300+
vals.template bit_cast_view<uint32_t>()
4301+
.template select<N, 2>(1)
4302+
.data(),
4303+
Offset.data(), mask.data());
4304+
4305+
} else {
4306+
using MsgT = detail::__raw_t<T>;
4307+
__esimd_slm_scatter_st<MsgT, N, Alignment>(
4308+
sycl::bit_cast<__ESIMD_DNS::vector_type_t<MsgT, N>>(vals.data()),
4309+
byte_offsets.data(), mask.data());
4310+
}
42484311
} else {
42494312
detail::LocalAccessorMarker acc;
42504313
detail::scatter_impl<T, N>(acc, vals, byte_offsets, 0, mask);

sycl/test-e2e/ESIMD/api/slm_gather_scatter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,5 +127,13 @@ int main(void) {
127127
passed &= test<half, 32>(q);
128128
}
129129

130+
passed &= test<int64_t, 16>(q);
131+
passed &= test<int64_t, 32>(q);
132+
133+
if (dev.has(sycl::aspect::fp64)) {
134+
passed &= test<double, 16>(q);
135+
passed &= test<double, 32>(q);
136+
}
137+
130138
return passed ? 0 : 1;
131139
}

sycl/test-e2e/ESIMD/api/slm_gather_scatter_heavy.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,15 @@ int main() {
469469
passed &= test_vl1<half, 7>(q);
470470
passed &= test<half, 16, 2>(q);
471471
}
472+
if (dev.has(sycl::aspect::fp64)) {
473+
passed &= test<double, 8, 2>(q);
474+
passed &= test<double, 16, 5>(q);
475+
passed &= test<double, 32, 3>(q);
476+
}
477+
478+
passed &= test<int64_t, 8, 2>(q);
479+
passed &= test<int64_t, 16, 5>(q);
480+
passed &= test<int64_t, 32, 3>(q);
472481

473482
std::cout << (!passed ? "TEST FAILED\n" : "TEST Passed\n");
474483
return passed ? 0 : 1;

sycl/test-e2e/ESIMD/unified_memory_api/Inputs/gather.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,13 +509,13 @@ bool testSLM(queue Q, uint32_t MaskStride, PropertiesT) {
509509
uint32_t LocalElemOffset = LocalID * N;
510510

511511
// Allocate a bit more to safely initialize it with 8-element chunks.
512-
constexpr uint32_t SLMSize = (Threads * N + 8) * sizeof(T);
512+
constexpr uint32_t SLMSize = (Threads * N) * sizeof(T);
513513
slm_init<SLMSize>();
514514

515515
if (LocalID == 0) {
516-
for (int I = 0; I < Threads * N; I += 8) {
517-
simd<T, 8> InVec(In + GlobalElemOffset + I);
518-
simd<uint32_t, 8> offsets(I * sizeof(T), sizeof(T));
516+
for (int I = 0; I < Threads * N; I++) {
517+
simd<T, 1> InVec(In + GlobalElemOffset + I);
518+
simd<uint32_t, 1> offsets(I * sizeof(T), sizeof(T));
519519
slm_scatter<T>(offsets, InVec);
520520
}
521521
}

sycl/test-e2e/ESIMD/unified_memory_api/gather_acc.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ int main() {
3030
Passed &= testACC<uint32_t, TestFeatures>(Q);
3131
Passed &= testACC<float, TestFeatures>(Q);
3232
Passed &= testACC<ext::intel::experimental::esimd::tfloat32, TestFeatures>(Q);
33-
#ifdef __ESIMD_FORCE_STATELESS_MEM
3433
Passed &= testACC<int64_t, TestFeatures>(Q);
3534
if (Q.get_device().has(sycl::aspect::fp64))
3635
Passed &= testACC<double, TestFeatures>(Q);
37-
#endif // __ESIMD_FORCE_STATELESS_MEM
3836
std::cout << (Passed ? "Passed\n" : "FAILED\n");
3937
return Passed ? 0 : 1;
4038
}

sycl/test-e2e/ESIMD/unified_memory_api/gather_acc_dg2_pvc.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,9 @@ int main() {
3333
Passed &= testACC<uint32_t, TestFeatures>(Q);
3434
Passed &= testACC<float, TestFeatures>(Q);
3535
Passed &= testACC<ext::intel::experimental::esimd::tfloat32, TestFeatures>(Q);
36-
#ifdef __ESIMD_FORCE_STATELESS_MEM
3736
Passed &= testACC<int64_t, TestFeatures>(Q);
3837
if (Q.get_device().has(sycl::aspect::fp64))
3938
Passed &= testACC<double, TestFeatures>(Q);
40-
#endif // __ESIMD_FORCE_STATELESS_MEM
4139
std::cout << (Passed ? "Passed\n" : "FAILED\n");
4240
return Passed ? 0 : 1;
4341
}

sycl/test-e2e/ESIMD/unified_memory_api/slm_gather.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ int main() {
2929
Passed &= testSLM<uint32_t, TestFeatures>(Q);
3030
Passed &= testSLM<float, TestFeatures>(Q);
3131
Passed &= testSLM<ext::intel::experimental::esimd::tfloat32, TestFeatures>(Q);
32+
Passed &= testSLM<int64_t, TestFeatures>(Q);
33+
if (Q.get_device().has(sycl::aspect::fp64))
34+
Passed &= testSLM<double, TestFeatures>(Q);
3235
std::cout << (Passed ? "Passed\n" : "FAILED\n");
3336
return Passed ? 0 : 1;
3437
}

sycl/test-e2e/ESIMD/unified_memory_api/slm_gather_dg2_pvc.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ int main() {
3232
Passed &= testSLM<uint32_t, TestFeatures>(Q);
3333
Passed &= testSLM<float, TestFeatures>(Q);
3434
Passed &= testSLM<ext::intel::experimental::esimd::tfloat32, TestFeatures>(Q);
35+
Passed &= testSLM<int64_t, TestFeatures>(Q);
36+
if (Q.get_device().has(sycl::aspect::fp64))
37+
Passed &= testSLM<double, TestFeatures>(Q);
3538

3639
std::cout << (Passed ? "Passed\n" : "FAILED\n");
3740
return Passed ? 0 : 1;

0 commit comments

Comments
 (0)