Skip to content

Commit ee6e9e8

Browse files
[SYCL][ESIMD][EMU] ESIMD_CPU Kernel launch and Emulated Intrinsics
* This PR is for enabling kernel launching for ESIMD_CPU * Also contains emulated intrinsics for memory operations * esimd_cpu backend is loaded in SYCL runtime * Base PR : intel#4011
1 parent 9778952 commit ee6e9e8

File tree

14 files changed

+904
-96
lines changed

14 files changed

+904
-96
lines changed

sycl/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,15 @@ if(SYCL_BUILD_PI_ROCM)
285285
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libspirv-builtins pi_rocm)
286286
endif()
287287

288+
if (SYCL_BUILD_PI_ESIMD_CPU)
289+
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libcmrt-headers)
290+
if (MSVC)
291+
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libcmrt-libs libcmrt-dlls)
292+
else()
293+
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libcmrt-sos)
294+
endif()
295+
endif()
296+
288297
# Use it as fake dependency in order to force another command(s) to execute.
289298
add_custom_command(OUTPUT __force_it
290299
COMMAND "${CMAKE_COMMAND}" -E echo

sycl/include/CL/sycl/accessor.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,11 @@ class image_accessor
671671
AccessorBaseHost::getPtr() /*Ptr to Image*/);
672672
#endif
673673
}
674+
675+
#ifndef __SYCL_DEVICE_ONLY__
676+
public:
677+
void *get_pointer() const { return detail::AccessorBaseHost::getPtr(); }
678+
#endif // __SYCL_DEVICE_ONLY__
674679
};
675680

676681
template <typename DataT, int Dimensions, access::mode AccessMode,

sycl/include/CL/sycl/detail/cg_types.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,9 @@ class HostTask {
243243
template <class KernelType, class KernelArgType, int Dims, typename KernelName>
244244
class HostKernel : public HostKernelBase {
245245
using IDBuilder = sycl::detail::Builder;
246-
KernelType MKernel;
247246

248247
public:
248+
KernelType MKernel;
249249
HostKernel(KernelType Kernel) : MKernel(Kernel) {}
250250
void call(const NDRDescT &NDRDesc, HostProfilingInfo *HPI) override {
251251
// adjust ND range for serial host:

sycl/include/CL/sycl/handler.hpp

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,98 @@ class __SYCL_EXPORT handler {
514514
return {z, y, x};
515515
}
516516

517+
/* The kernel passed to StoreLambda can take an id, an item or an nd_item as
518+
* its argument. Since esimd plugin directly invokes the kernel (doesn’t use
519+
* piKernelSetArg), the kernel argument type must be known to the plugin.
520+
* However, passing kernel argument type to the plugin requires changing ABI
521+
* in HostKernel class. To overcome this problem, helpers below wrap the
522+
* “original” kernel with a functor that always takes an nd_item as argument.
523+
* A functor is used instead of a lambda because extractArgsAndReqsFromLambda
524+
* needs access to the “original” kernel and keeps references to its internal
525+
* data, i.e. the kernel passed as argument cannot be local in scope. The
526+
* functor itself is again encapsulated in a std::function since functor’s
527+
* type is unknown to the plugin.
528+
*/
529+
530+
template <class KernelType, class NormalizedKernelType, int Dims>
531+
KernelType *ResetHostKernelHelper(const KernelType &KernelFunc) {
532+
NormalizedKernelType NormalizedKernel(KernelFunc);
533+
auto NormalizedKernelFunc =
534+
std::function<void(const sycl::nd_item<Dims> &)>(NormalizedKernel);
535+
auto HostKernelPtr =
536+
new detail::HostKernel<decltype(NormalizedKernelFunc),
537+
sycl::nd_item<Dims>, Dims, KernelType>(
538+
NormalizedKernelFunc);
539+
MHostKernel.reset(HostKernelPtr);
540+
return &HostKernelPtr->MKernel.template target<NormalizedKernelType>()
541+
->MKernelFunc;
542+
}
543+
544+
template <class KernelType, typename ArgT, int Dims>
545+
typename std::enable_if<std::is_same<ArgT, sycl::id<Dims>>::value,
546+
KernelType *>::type
547+
ResetHostKernel(const KernelType &KernelFunc) {
548+
struct NormalizedKernelType {
549+
KernelType MKernelFunc;
550+
NormalizedKernelType(const KernelType &KernelFunc)
551+
: MKernelFunc(KernelFunc) {}
552+
void operator()(const nd_item<Dims> &Arg) {
553+
MKernelFunc(Arg.get_global_id());
554+
}
555+
};
556+
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims>(
557+
KernelFunc);
558+
}
559+
template <class KernelType, typename ArgT, int Dims>
560+
typename std::enable_if<std::is_same<ArgT, sycl::nd_item<Dims>>::value,
561+
KernelType *>::type
562+
ResetHostKernel(const KernelType &KernelFunc) {
563+
struct NormalizedKernelType {
564+
KernelType MKernelFunc;
565+
NormalizedKernelType(const KernelType &KernelFunc)
566+
: MKernelFunc(KernelFunc) {}
567+
void operator()(const nd_item<Dims> &Arg) { MKernelFunc(Arg); }
568+
};
569+
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims>(
570+
KernelFunc);
571+
}
572+
573+
template <class KernelType, typename ArgT, int Dims>
574+
typename std::enable_if<std::is_same<ArgT, sycl::item<Dims, false>>::value,
575+
KernelType *>::type
576+
ResetHostKernel(const KernelType &KernelFunc) {
577+
struct NormalizedKernelType {
578+
KernelType MKernelFunc;
579+
NormalizedKernelType(const KernelType &KernelFunc)
580+
: MKernelFunc(KernelFunc) {}
581+
void operator()(const nd_item<Dims> &Arg) {
582+
sycl::item<Dims, false> Item = detail::Builder::createItem<Dims, false>(
583+
Arg.get_global_range(), Arg.get_global_id());
584+
MKernelFunc(Item);
585+
}
586+
};
587+
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims>(
588+
KernelFunc);
589+
}
590+
591+
template <class KernelType, typename ArgT, int Dims>
592+
typename std::enable_if<std::is_same<ArgT, sycl::item<Dims, true>>::value,
593+
KernelType *>::type
594+
ResetHostKernel(const KernelType &KernelFunc) {
595+
struct NormalizedKernelType {
596+
KernelType MKernelFunc;
597+
NormalizedKernelType(const KernelType &KernelFunc)
598+
: MKernelFunc(KernelFunc) {}
599+
void operator()(const nd_item<Dims> &Arg) {
600+
sycl::item<Dims, true> Item = detail::Builder::createItem<Dims, true>(
601+
Arg.get_global_range(), Arg.get_global_id(), Arg.get_offset());
602+
MKernelFunc(Item);
603+
}
604+
};
605+
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims>(
606+
KernelFunc);
607+
}
608+
517609
/// Stores lambda to the template-free object
518610
///
519611
/// Also initializes kernel name, list of arguments and requirements using
@@ -530,18 +622,17 @@ class __SYCL_EXPORT handler {
530622
"kernel_handler is not yet supported by host device.",
531623
PI_INVALID_OPERATION);
532624
}
533-
MHostKernel.reset(
534-
new detail::HostKernel<KernelType, LambdaArgType, Dims, KernelName>(
535-
KernelFunc));
625+
KernelType *KernelPtr =
626+
ResetHostKernel<KernelType, LambdaArgType, Dims>(KernelFunc);
536627

537628
using KI = sycl::detail::KernelInfo<KernelName>;
538629
// Empty name indicates that the compilation happens without integration
539630
// header, so don't perform things that require it.
540631
if (KI::getName() != nullptr && KI::getName()[0] != '\0') {
541632
// TODO support ESIMD in no-integration-header case too.
542633
MArgs.clear();
543-
extractArgsAndReqsFromLambda(MHostKernel->getPtr(), KI::getNumParams(),
544-
&KI::getParamDesc(0), KI::isESIMD());
634+
extractArgsAndReqsFromLambda(reinterpret_cast<char *>(KernelPtr),
635+
KI::getNumParams(), &KI::getParamDesc(0));
545636
MKernelName = KI::getName();
546637
MOSModuleHandle = detail::OSUtil::getOSModuleHandle(KI::getName());
547638
} else {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//==-------- atomic_intrin.hpp - Atomic intrinsic definition file ----------==//
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+
#pragma once
9+
10+
#include <CL/sycl/exception.hpp>
11+
12+
template <typename Ty> Ty atomic_add_fetch(Ty *ptr, Ty val) {
13+
#ifdef _WIN32
14+
// TODO: Windows will be supported soon
15+
throw cl::sycl::feature_not_supported();
16+
#else
17+
return __atomic_add_fetch(ptr, val, __ATOMIC_RELAXED);
18+
#endif
19+
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)