Skip to content

Commit 0fdae34

Browse files
[SYCL] Implement PI cast for vectors and fix OpenCL specializations (#6278)
This commit makes two changes related to pi::cast: Implements pi::cast between vectors by applying pi::cast to the individual elements of the input vector, storing the casted values in a new vector. Moves the OpenCL specializations into the backend traits file for OpenCL. Additionally, PI_OPENCL_AVAILABLE is removed as it was only defined in the pi_opencl subproject whereas pi::cast, including the moved specializations, are used by the SYCL interop headers. Signed-off-by: Larsen, Steffen <[email protected]>
1 parent c7e5711 commit 0fdae34

File tree

5 files changed

+84
-36
lines changed

5 files changed

+84
-36
lines changed

sycl/include/CL/sycl/detail/backend_traits_opencl.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <CL/sycl/context.hpp>
2020
#include <CL/sycl/detail/backend_traits.hpp>
2121
#include <CL/sycl/detail/defines.hpp>
22+
#include <CL/sycl/detail/pi.hpp>
2223
#include <CL/sycl/device.hpp>
2324
#include <CL/sycl/event.hpp>
2425
#include <CL/sycl/kernel_bundle.hpp>
@@ -188,6 +189,26 @@ template <> struct InteropFeatureSupportMap<backend::opencl> {
188189
static constexpr bool MakeKernel = true;
189190
static constexpr bool MakeKernelBundle = true;
190191
};
192+
193+
namespace pi {
194+
// Cast for std::vector<cl_event>, according to the spec, make_event
195+
// should create one(?) event from a vector of cl_event
196+
template <class To> inline To cast(std::vector<cl_event> value) {
197+
RT::assertion(value.size() == 1,
198+
"Temporary workaround requires that the "
199+
"size of the input vector for make_event be equal to one.");
200+
return cast<To>(value[0]);
201+
}
202+
203+
// These conversions should use PI interop API.
204+
template <>
205+
inline PiProgram
206+
cast(cl_program) = delete; // Use piextCreateProgramWithNativeHandle
207+
208+
template <>
209+
inline PiDevice
210+
cast(cl_device_id) = delete; // Use piextCreateDeviceWithNativeHandle
211+
} // namespace pi
191212
} // namespace detail
192213
} // namespace sycl
193214
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/include/CL/sycl/detail/pi.hpp

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313

1414
#pragma once
1515

16-
#ifdef PI_OPENCL_AVAILABLE
17-
#include <CL/sycl/detail/cl.h>
18-
#endif // PI_OPENCL_AVAILABLE
1916
#include <CL/sycl/backend_types.hpp>
2017
#include <CL/sycl/detail/export.hpp>
2118
#include <CL/sycl/detail/os_util.hpp>
@@ -423,39 +420,21 @@ template <class To, class From> inline To cast(From value) {
423420
return (To)(value);
424421
}
425422

426-
template <class To, class From> inline To cast(std::vector<From> value) {
427-
// Silence the unused parameter warning.
428-
(void)value;
429-
RT::assertion(false,
430-
"Compatibility specialization, not expected to be used. "
431-
"The only allowed cast using a vector of From values is "
432-
"implemented in the OpenCL backend (see cl_event case).");
433-
return {};
423+
// Helper traits for identifying std::vector with arbitrary element type.
424+
template <typename T> struct IsStdVector : std::false_type {};
425+
template <typename T> struct IsStdVector<std::vector<T>> : std::true_type {};
426+
427+
// Overload for vectors that applies the cast to all elements. This
428+
// creates a new vector.
429+
template <class To, class FromE> To cast(std::vector<FromE> Values) {
430+
static_assert(IsStdVector<To>::value, "Return type must be a vector.");
431+
To ResultVec;
432+
ResultVec.reserve(Values.size());
433+
for (FromE &Val : Values)
434+
ResultVec.push_back(cast<typename To::value_type>(Val));
435+
return ResultVec;
434436
}
435437

436-
#ifdef PI_OPENCL_AVAILABLE
437-
438-
// Cast for std::vector<cl_event>, according to the spec, make_event
439-
// should create one(?) event from a vector of cl_event
440-
template <class To> inline To cast(std::vector<cl_event> value) {
441-
RT::assertion(value.size() == 1,
442-
"Temporary workaround requires that the "
443-
"size of the input vector for make_event be equal to one.");
444-
return (To)(value[0]);
445-
}
446-
447-
// These conversions should use PI interop API.
448-
template <> inline pi::PiProgram cast(cl_program) {
449-
RT::assertion(false, "pi::cast -> use piextCreateProgramWithNativeHandle");
450-
return {};
451-
}
452-
453-
template <> inline pi::PiDevice cast(cl_device_id) {
454-
RT::assertion(false, "pi::cast -> use piextCreateDeviceWithNativeHandle");
455-
return {};
456-
}
457-
#endif // PI_OPENCL_AVAILABLE
458-
459438
} // namespace pi
460439
} // namespace detail
461440

sycl/plugins/opencl/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,3 @@ add_sycl_plugin(opencl
1919
)
2020

2121
set_target_properties(pi_opencl PROPERTIES LINKER_LANGUAGE CXX)
22-
23-
target_compile_definitions(pi_opencl PRIVATE PI_OPENCL_AVAILABLE)

sycl/unittests/pi/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ add_sycl_unittest(PiTests OBJECT
44
EnqueueMemTest.cpp
55
PiMock.cpp
66
PlatformTest.cpp
7+
PiUtility.cpp
78
pi_arguments_handler.cpp
89
piInteropRetain.cpp
910
)

sycl/unittests/pi/PiUtility.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//==--------------------- PiUtility.cpp -- check for internal PI utilities -==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <CL/opencl.h>
10+
#include <CL/sycl.hpp>
11+
#include <CL/sycl/backend/opencl.hpp>
12+
13+
#include <gtest/gtest.h>
14+
15+
namespace {
16+
using namespace cl::sycl;
17+
18+
TEST(PiUtilityTest, CheckPiCastScalar) {
19+
std::int32_t I = 42;
20+
std::int64_t L = 1234;
21+
float F = 31.2f;
22+
double D = 4321.1234;
23+
float ItoF = detail::pi::cast<float>(I);
24+
double LtoD = detail::pi::cast<double>(L);
25+
std::int32_t FtoI = detail::pi::cast<std::int32_t>(F);
26+
std::int32_t DtoL = detail::pi::cast<std::int64_t>(D);
27+
EXPECT_EQ((std::int32_t)F, FtoI);
28+
EXPECT_EQ((float)I, ItoF);
29+
EXPECT_EQ((std::int64_t)D, DtoL);
30+
EXPECT_EQ((double)L, LtoD);
31+
}
32+
33+
TEST(PiUtilityTest, CheckPiCastVector) {
34+
std::vector<std::int32_t> IVec{6, 1, 5, 2, 3, 4};
35+
std::vector<float> IVecToFVec = detail::pi::cast<std::vector<float>>(IVec);
36+
ASSERT_EQ(IVecToFVec.size(), IVec.size());
37+
for (size_t I = 0; I < IVecToFVec.size(); ++I)
38+
EXPECT_EQ(IVecToFVec[I], (float)IVec[I]);
39+
}
40+
41+
TEST(PiUtilityTest, CheckPiCastOCLEventVector) {
42+
// Current special case for vectors of OpenCL vectors. This may change in the
43+
// future.
44+
std::vector<cl_event> EVec{(cl_event)0};
45+
pi_native_handle ENativeHandle = detail::pi::cast<pi_native_handle>(EVec);
46+
EXPECT_EQ(ENativeHandle, (pi_native_handle)EVec[0]);
47+
}
48+
49+
} // namespace

0 commit comments

Comments
 (0)