Skip to content

Commit e7fbf1a

Browse files
smaslov-intelagainull
authored andcommitted
Commit includes:
* New backend which implements interoperability for Level Zero. L0 interop handler getters and "make" functions for the following objects are implemented: platform, device, queue, program, accessor. * getNative() interoperability for the platform and program. Changes to ABI are non-breaking (new symbols are exported). Changed version of the sycl library accordingly. Author: Sergey V Maslov <[email protected]> Signed-off-by: Artur Gainullin <[email protected]>
1 parent 358ec04 commit e7fbf1a

File tree

20 files changed

+276
-25
lines changed

20 files changed

+276
-25
lines changed

sycl/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ option(SYCL_ENABLE_WERROR "Treat all warnings as errors in SYCL project" OFF)
99
option(SYCL_ADD_DEV_VERSION_POSTFIX "Adds -V postfix to version string" ON)
1010

1111
set(SYCL_MAJOR_VERSION 1)
12-
set(SYCL_MINOR_VERSION 0)
12+
set(SYCL_MINOR_VERSION 1)
1313
set(SYCL_PATCH_VERSION 0)
1414
set(SYCL_DEV_ABI_VERSION 1)
1515
if (SYCL_ADD_DEV_VERSION_POSTFIX)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//==------- Intel_level0.hpp - SYCL Level-Zero backend ---------------------==//
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+
#pragma once
10+
11+
//#include <ze_api.h> This should be included from user code
12+
#include <CL/sycl.hpp>
13+
14+
__SYCL_INLINE_NAMESPACE(cl) {
15+
namespace sycl {
16+
17+
template <> struct interop<backend::level0, platform> {
18+
using type = ze_driver_handle_t;
19+
};
20+
21+
template <> struct interop<backend::level0, device> {
22+
using type = ze_device_handle_t;
23+
};
24+
25+
template <> struct interop<backend::level0, queue> {
26+
using type = ze_command_queue_handle_t;
27+
};
28+
29+
template <> struct interop<backend::level0, program> {
30+
using type = ze_module_handle_t;
31+
};
32+
33+
template <typename DataT, int Dimensions, access::mode AccessMode>
34+
struct interop<backend::level0, accessor<DataT, Dimensions, AccessMode,
35+
access::target::global_buffer,
36+
access::placeholder::false_t>> {
37+
using type = char *;
38+
};
39+
40+
namespace level0 {
41+
42+
// Implementation of varios "make" functions resides in libsycl.so
43+
platform make_platform(pi_native_handle NativeHandle);
44+
device make_device(const platform &Platform, pi_native_handle NativeHandle);
45+
program make_program(const context &Context, pi_native_handle NativeHandle);
46+
queue make_queue(const context &Context, pi_native_handle InteropHandle);
47+
48+
// Construction of SYCL platform.
49+
template <typename T, typename std::enable_if<
50+
std::is_same<T, platform>::value>::type * = nullptr>
51+
T make(typename interop<backend::level0, T>::type Interop) {
52+
return make_platform(reinterpret_cast<pi_native_handle>(Interop));
53+
}
54+
55+
// Construction of SYCL device.
56+
template <typename T, typename std::enable_if<
57+
std::is_same<T, device>::value>::type * = nullptr>
58+
T make(const platform &Platform,
59+
typename interop<backend::level0, T>::type Interop) {
60+
return make_device(Platform, reinterpret_cast<pi_native_handle>(Interop));
61+
}
62+
63+
// Construction of SYCL program.
64+
template <typename T, typename std::enable_if<
65+
std::is_same<T, program>::value>::type * = nullptr>
66+
T make(const context &Context,
67+
typename interop<backend::level0, T>::type Interop) {
68+
return make_program(Context, reinterpret_cast<pi_native_handle>(Interop));
69+
}
70+
71+
// Construction of SYCL queue.
72+
template <typename T, typename std::enable_if<
73+
std::is_same<T, queue>::value>::type * = nullptr>
74+
T make(const context &Context,
75+
typename interop<backend::level0, T>::type Interop) {
76+
return make_queue(Context, reinterpret_cast<pi_native_handle>(Interop));
77+
}
78+
79+
} // namespace level0
80+
} // namespace sycl
81+
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/include/CL/sycl/detail/pi.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -850,9 +850,10 @@ piextDeviceGetNativeHandle(pi_device device, pi_native_handle *nativeHandle);
850850
/// NOTE: The created PI object takes ownership of the native handle.
851851
///
852852
/// \param nativeHandle is the native handle to create PI device from.
853+
/// \param platform is the platform of the device.
853854
/// \param device is the PI device created from the native handle.
854855
__SYCL_EXPORT pi_result piextDeviceCreateWithNativeHandle(
855-
pi_native_handle nativeHandle, pi_device *device);
856+
pi_native_handle nativeHandle, pi_platform platform, pi_device *device);
856857

857858
/// Selects the most appropriate device binary based on runtime information
858859
/// and the IR characteristics.
@@ -944,9 +945,10 @@ piextQueueGetNativeHandle(pi_queue queue, pi_native_handle *nativeHandle);
944945
/// NOTE: The created PI object takes ownership of the native handle.
945946
///
946947
/// \param nativeHandle is the native handle to create PI queue from.
948+
/// \param context is the PI context of the queue.
947949
/// \param queue is the PI queue created from the native handle.
948950
__SYCL_EXPORT pi_result piextQueueCreateWithNativeHandle(
949-
pi_native_handle nativeHandle, pi_queue *queue);
951+
pi_native_handle nativeHandle, pi_context context, pi_queue *queue);
950952

951953
//
952954
// Memory
@@ -1066,9 +1068,10 @@ piextProgramGetNativeHandle(pi_program program, pi_native_handle *nativeHandle);
10661068
/// NOTE: The created PI object takes ownership of the native handle.
10671069
///
10681070
/// \param nativeHandle is the native handle to create PI program from.
1071+
/// \param context is the PI context of the program.
10691072
/// \param program is the PI program created from the native handle.
10701073
__SYCL_EXPORT pi_result piextProgramCreateWithNativeHandle(
1071-
pi_native_handle nativeHandle, pi_program *program);
1074+
pi_native_handle nativeHandle, pi_context context, pi_program *program);
10721075

10731076
//
10741077
// Kernel

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,15 @@ template <class To, class From> inline To cast(From value) {
334334

335335
// These conversions should use PI interop API.
336336
template <> inline pi::PiProgram cast(cl_program) {
337-
RT::assertion(false, "pi::cast -> use piextProgramFromNative");
337+
RT::assertion(false, "pi::cast -> use piextCreateProgramWithNativeHandle");
338338
return {};
339339
}
340340

341341
template <> inline pi::PiDevice cast(cl_device_id) {
342-
RT::assertion(false, "pi::cast -> use piextDeviceFromNative");
342+
RT::assertion(false, "pi::cast -> use piextCreateDeviceWithNativeHandle");
343343
return {};
344344
}
345+
345346
} // namespace pi
346347
} // namespace detail
347348

sycl/include/CL/sycl/platform.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class __SYCL_EXPORT platform {
107107
/// \return a native handle, the type of which defined by the backend.
108108
template <backend BackendName>
109109
auto get_native() const -> typename interop<BackendName, platform>::type {
110-
return detail::pi::cast<typename interop<BackendName, platform>::type>(
110+
return reinterpret_cast<typename interop<BackendName, platform>::type>(
111111
getNative());
112112
}
113113

sycl/include/CL/sycl/program.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,17 @@ class __SYCL_EXPORT program {
322322
#endif // __SYCL_DEVICE_ONLY__
323323
}
324324

325+
/// Gets the native handle of the SYCL platform.
326+
///
327+
/// \return a native handle, the type of which defined by the backend.
328+
template <backend BackendName>
329+
auto get_native() const -> typename interop<BackendName, program>::type {
330+
return reinterpret_cast<typename interop<BackendName, program>::type>(
331+
getNative());
332+
}
333+
325334
private:
335+
pi_native_handle getNative() const;
326336
program(shared_ptr_class<detail::program_impl> impl);
327337

328338
/// Template-free version of get_kernel.

sycl/plugins/cuda/pi_cuda.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,10 +1308,12 @@ pi_result cuda_piextDeviceGetNativeHandle(pi_device device,
13081308
/// NOTE: The created PI object takes ownership of the native handle.
13091309
///
13101310
/// \param[in] nativeHandle The native handle to create PI device object from.
1311+
/// \param[in] platform is the PI platform of the device.
13111312
/// \param[out] device Set to the PI device object created from native handle.
13121313
///
13131314
/// \return TBD
13141315
pi_result cuda_piextDeviceCreateWithNativeHandle(pi_native_handle nativeHandle,
1316+
pi_platform platform,
13151317
pi_device *device) {
13161318
cl::sycl::detail::pi::die(
13171319
"Creation of PI device from native handle not implemented");
@@ -1845,10 +1847,12 @@ pi_result cuda_piextQueueGetNativeHandle(pi_queue queue,
18451847
/// NOTE: The created PI object takes ownership of the native handle.
18461848
///
18471849
/// \param[in] nativeHandle The native handle to create PI queue object from.
1850+
/// \param[in] context is the PI context of the queue.
18481851
/// \param[out] queue Set to the PI queue object created from native handle.
18491852
///
18501853
/// \return TBD
18511854
pi_result cuda_piextQueueCreateWithNativeHandle(pi_native_handle nativeHandle,
1855+
pi_context context,
18521856
pi_queue *queue) {
18531857
cl::sycl::detail::pi::die(
18541858
"Creation of PI queue from native handle not implemented");
@@ -2459,10 +2463,12 @@ pi_result cuda_piextProgramGetNativeHandle(pi_program program,
24592463
/// NOTE: The created PI object takes ownership of the native handle.
24602464
///
24612465
/// \param[in] nativeHandle The native handle to create PI program object from.
2466+
/// \param[in] context The PI context of the program.
24622467
/// \param[out] program Set to the PI program object created from native handle.
24632468
///
24642469
/// \return TBD
24652470
pi_result cuda_piextProgramCreateWithNativeHandle(pi_native_handle nativeHandle,
2471+
pi_context context,
24662472
pi_program *program) {
24672473
cl::sycl::detail::pi::die(
24682474
"Creation of PI program from native handle not implemented");

sycl/plugins/level_zero/pi_level0.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,10 +1181,16 @@ pi_result piextDeviceGetNativeHandle(pi_device Device,
11811181
}
11821182

11831183
pi_result piextDeviceCreateWithNativeHandle(pi_native_handle NativeHandle,
1184+
pi_platform Platform,
11841185
pi_device *Device) {
1186+
assert(NativeHandle);
1187+
assert(Device);
1188+
assert(Platform);
1189+
11851190
// Create PI device from the given L0 device handle.
1186-
die("piextDeviceCreateWithNativeHandle: not supported");
1187-
return PI_SUCCESS;
1191+
auto ZeDevice = pi_cast<ze_device_handle_t>(NativeHandle);
1192+
*Device = new _pi_device(ZeDevice, Platform);
1193+
return (*Device)->initialize();
11881194
}
11891195

11901196
pi_result piContextCreate(const pi_context_properties *Properties,
@@ -1367,15 +1373,27 @@ pi_result piQueueFinish(pi_queue Queue) {
13671373
return PI_SUCCESS;
13681374
}
13691375

1376+
13701377
pi_result piextQueueGetNativeHandle(pi_queue Queue,
13711378
pi_native_handle *NativeHandle) {
1372-
die("piextQueueGetNativeHandle: not supported");
1379+
assert(Queue);
1380+
assert(NativeHandle);
1381+
1382+
auto ZeQueue = pi_cast<ze_command_queue_handle_t*>(NativeHandle);
1383+
// Extract the L0 queue handle from the given PI queue
1384+
*ZeQueue = Queue->ZeCommandQueue;
13731385
return PI_SUCCESS;
13741386
}
13751387

13761388
pi_result piextQueueCreateWithNativeHandle(pi_native_handle NativeHandle,
1389+
pi_context Context,
13771390
pi_queue *Queue) {
1378-
die("piextQueueCreateWithNativeHandle: not supported");
1391+
assert(NativeHandle);
1392+
assert(Context);
1393+
assert(Queue);
1394+
1395+
auto ZeQueue = pi_cast<ze_command_queue_handle_t>(NativeHandle);
1396+
*Queue = new _pi_queue(ZeQueue, Context);
13791397
return PI_SUCCESS;
13801398
}
13811399

@@ -1869,13 +1887,28 @@ pi_result piProgramRelease(pi_program Program) {
18691887

18701888
pi_result piextProgramGetNativeHandle(pi_program Program,
18711889
pi_native_handle *NativeHandle) {
1872-
die("piextProgramGetNativeHandle: not supported");
1890+
assert(Program);
1891+
assert(NativeHandle);
1892+
1893+
auto ZeModule = pi_cast<ze_module_handle_t *>(NativeHandle);
1894+
// Extract the L0 module handle from the given PI program
1895+
*ZeModule = Program->ZeModule;
18731896
return PI_SUCCESS;
18741897
}
18751898

18761899
pi_result piextProgramCreateWithNativeHandle(pi_native_handle NativeHandle,
1900+
pi_context Context,
18771901
pi_program *Program) {
1878-
die("piextProgramCreateWithNativeHandle: not supported");
1902+
assert(NativeHandle);
1903+
assert(Context);
1904+
assert(Program);
1905+
1906+
auto ZeModule = pi_cast<ze_module_handle_t *>(NativeHandle);
1907+
assert(*ZeModule);
1908+
// Create PI program from the given L0 module handle
1909+
auto ZePIProgram = new _pi_program(*ZeModule, Context);
1910+
1911+
*Program = pi_cast<pi_program>(ZePIProgram);
18791912
return PI_SUCCESS;
18801913
}
18811914

sycl/plugins/opencl/pi_opencl.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ static pi_result USMSetIndirectAccess(pi_kernel kernel) {
160160

161161
extern "C" {
162162

163-
// Example of a PI interface that does not map exactly to an OpenCL one.
164163
pi_result piPlatformsGet(pi_uint32 num_entries, pi_platform *platforms,
165164
pi_uint32 *num_platforms) {
166165
cl_int result = clGetPlatformIDs(cast<cl_uint>(num_entries),
@@ -184,7 +183,6 @@ pi_result piextPlatformCreateWithNativeHandle(pi_native_handle nativeHandle,
184183
return PI_SUCCESS;
185184
}
186185

187-
// Example of a PI interface that does not map exactly to an OpenCL one.
188186
pi_result piDevicesGet(pi_platform platform, pi_device_type device_type,
189187
pi_uint32 num_entries, pi_device *devices,
190188
pi_uint32 *num_devices) {
@@ -274,7 +272,7 @@ pi_result piextDeviceSelectBinary(pi_device device, pi_device_binary *images,
274272
}
275273

276274
pi_result piextDeviceCreateWithNativeHandle(pi_native_handle nativeHandle,
277-
pi_device *piDevice) {
275+
pi_platform, pi_device *piDevice) {
278276
assert(piDevice != nullptr);
279277
*piDevice = reinterpret_cast<pi_device>(nativeHandle);
280278
return PI_SUCCESS;
@@ -321,7 +319,7 @@ pi_result piQueueCreate(pi_context context, pi_device device,
321319
}
322320

323321
pi_result piextQueueCreateWithNativeHandle(pi_native_handle nativeHandle,
324-
pi_queue *piQueue) {
322+
pi_context, pi_queue *piQueue) {
325323
assert(piQueue != nullptr);
326324
*piQueue = reinterpret_cast<pi_queue>(nativeHandle);
327325
return PI_SUCCESS;
@@ -406,6 +404,7 @@ pi_result piProgramCreate(pi_context context, const void *il, size_t length,
406404
}
407405

408406
pi_result piextProgramCreateWithNativeHandle(pi_native_handle nativeHandle,
407+
pi_context,
409408
pi_program *piProgram) {
410409
assert(piProgram != nullptr);
411410
*piProgram = reinterpret_cast<pi_program>(nativeHandle);

sycl/source/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ endfunction(add_sycl_rt_library)
9595
set(SYCL_SOURCES
9696
"${sycl_inc_dir}/CL/sycl.hpp"
9797
"backend/opencl.cpp"
98+
"backend/Intel_level0.cpp"
9899
"detail/accessor_impl.cpp"
99100
"detail/buffer_impl.cpp"
100101
"detail/builtins_common.cpp"

0 commit comments

Comments
 (0)