-
Notifications
You must be signed in to change notification settings - Fork 808
[SYCL][ESIMD][EMU] ESIMD_CPU Kernel launch and ESIMD_EMU backend loading #4020
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 33 commits
ee6e9e8
6b15320
3249056
7b163d6
0151dc7
7533a83
c96efe1
1266ceb
986a4f8
c14a755
33c3645
2a9e789
49bc656
1fd05a9
69d1cfb
94cb161
0b87d06
80d4c5e
b9f9663
686a2eb
7d1e481
8044e82
a586d1e
3671aad
1afc4dc
37a0e78
3710d07
6a41df5
bb6c3a0
b698f1e
f183ec2
4543b8f
21f11fe
30d738f
76771f4
c042ae7
ceb309d
b073a4e
be26fc0
d4846bf
7e65a1b
2ef648b
41490ea
9b57175
c7fad03
71b7a8f
06f132c
4d96d4b
e45087b
c1e6f9c
6985a64
8ee0bd8
2bf84de
b85ba9f
7a3e968
270763f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -551,6 +551,152 @@ class __SYCL_EXPORT handler { | |
} | ||
} | ||
|
||
/* The kernel passed to StoreLambda can take an id, an item or an nd_item as | ||
* its argument. Since esimd plugin directly invokes the kernel (doesn’t use | ||
* piKernelSetArg), the kernel argument type must be known to the plugin. | ||
* However, passing kernel argument type to the plugin requires changing ABI | ||
* in HostKernel class. To overcome this problem, helpers below wrap the | ||
* “original” kernel with a functor that always takes an nd_item as argument. | ||
* A functor is used instead of a lambda because extractArgsAndReqsFromLambda | ||
* needs access to the “original” kernel and keeps references to its internal | ||
* data, i.e. the kernel passed as argument cannot be local in scope. The | ||
* functor itself is again encapsulated in a std::function since functor’s | ||
* type is unknown to the plugin. | ||
*/ | ||
|
||
// For 'void' kernel argument | ||
template <class KernelType, class NormalizedKernelType, typename KernelName> | ||
KernelType *ResetHostKernelHelper(const KernelType &KernelFunc) { | ||
NormalizedKernelType NormalizedKernel(KernelFunc); | ||
auto NormalizedKernelFunc = std::function<void(void)>(NormalizedKernel); | ||
auto HostKernelPtr = | ||
new detail::HostKernel<decltype(NormalizedKernelFunc), void, 0, | ||
KernelName>(NormalizedKernelFunc); | ||
MHostKernel.reset(HostKernelPtr); | ||
return &HostKernelPtr->MKernel.template target<NormalizedKernelType>() | ||
->MKernelFunc; | ||
} | ||
|
||
// For non-'void' kernel argument - id, item w/wo offset, nd_item | ||
template <class KernelType, class NormalizedKernelType, int Dims, | ||
typename KernelName> | ||
KernelType *ResetHostKernelHelper(const KernelType &KernelFunc) { | ||
NormalizedKernelType NormalizedKernel(KernelFunc); | ||
auto NormalizedKernelFunc = | ||
std::function<void(const sycl::nd_item<Dims> &)>(NormalizedKernel); | ||
auto HostKernelPtr = | ||
new detail::HostKernel<decltype(NormalizedKernelFunc), | ||
sycl::nd_item<Dims>, Dims, KernelName>( | ||
NormalizedKernelFunc); | ||
MHostKernel.reset(HostKernelPtr); | ||
return &HostKernelPtr->MKernel.template target<NormalizedKernelType>() | ||
->MKernelFunc; | ||
} | ||
|
||
// For 'void' kernel argument | ||
template <class KernelType, typename ArgT, int Dims, typename KernelName> | ||
typename std::enable_if<std::is_same<ArgT, void>::value, KernelType *>::type | ||
ResetHostKernel(const KernelType &KernelFunc) { | ||
static_assert(Dims == 0, "Dimension of 'void' argument must be zero"); | ||
struct NormalizedKernelType { | ||
KernelType MKernelFunc; | ||
NormalizedKernelType(const KernelType &KernelFunc) | ||
: MKernelFunc(KernelFunc) {} | ||
void operator()(void) { detail::runKernelWithoutArg(MKernelFunc); } | ||
}; | ||
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, | ||
KernelName>(KernelFunc); | ||
} | ||
|
||
// For 'sycl::id<Dims>' kernel argument | ||
template <class KernelType, typename ArgT, int Dims, typename KernelName> | ||
typename std::enable_if<std::is_same<ArgT, sycl::id<Dims>>::value, | ||
KernelType *>::type | ||
ResetHostKernel(const KernelType &KernelFunc) { | ||
struct NormalizedKernelType { | ||
KernelType MKernelFunc; | ||
NormalizedKernelType(const KernelType &KernelFunc) | ||
: MKernelFunc(KernelFunc) {} | ||
void operator()(const nd_item<Dims> &Arg) { | ||
detail::runKernelWithArg(MKernelFunc, Arg.get_global_id()); | ||
} | ||
}; | ||
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims, | ||
KernelName>(KernelFunc); | ||
} | ||
|
||
// For 'sycl::nd_item<Dims>' kernel argument | ||
template <class KernelType, typename ArgT, int Dims, typename KernelName> | ||
typename std::enable_if<std::is_same<ArgT, sycl::nd_item<Dims>>::value, | ||
KernelType *>::type | ||
ResetHostKernel(const KernelType &KernelFunc) { | ||
struct NormalizedKernelType { | ||
KernelType MKernelFunc; | ||
NormalizedKernelType(const KernelType &KernelFunc) | ||
: MKernelFunc(KernelFunc) {} | ||
void operator()(const nd_item<Dims> &Arg) { | ||
detail::runKernelWithArg(MKernelFunc, Arg); | ||
} | ||
}; | ||
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims, | ||
KernelName>(KernelFunc); | ||
} | ||
|
||
// For 'sycl::item<Dims, without_offset>' kernel argument | ||
template <class KernelType, typename ArgT, int Dims, typename KernelName> | ||
typename std::enable_if<std::is_same<ArgT, sycl::item<Dims, false>>::value, | ||
KernelType *>::type | ||
ResetHostKernel(const KernelType &KernelFunc) { | ||
struct NormalizedKernelType { | ||
KernelType MKernelFunc; | ||
NormalizedKernelType(const KernelType &KernelFunc) | ||
: MKernelFunc(KernelFunc) {} | ||
void operator()(const nd_item<Dims> &Arg) { | ||
sycl::item<Dims, false> Item = detail::Builder::createItem<Dims, false>( | ||
Arg.get_global_range(), Arg.get_global_id()); | ||
detail::runKernelWithArg(MKernelFunc, Item); | ||
} | ||
}; | ||
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims, | ||
KernelName>(KernelFunc); | ||
} | ||
|
||
// For 'sycl::item<Dims, with_offset>' kernel argument | ||
template <class KernelType, typename ArgT, int Dims, typename KernelName> | ||
typename std::enable_if<std::is_same<ArgT, sycl::item<Dims, true>>::value, | ||
KernelType *>::type | ||
ResetHostKernel(const KernelType &KernelFunc) { | ||
struct NormalizedKernelType { | ||
KernelType MKernelFunc; | ||
NormalizedKernelType(const KernelType &KernelFunc) | ||
: MKernelFunc(KernelFunc) {} | ||
void operator()(const nd_item<Dims> &Arg) { | ||
sycl::item<Dims, true> Item = detail::Builder::createItem<Dims, true>( | ||
Arg.get_global_range(), Arg.get_global_id(), Arg.get_offset()); | ||
detail::runKernelWithArg(MKernelFunc, Item); | ||
} | ||
}; | ||
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims, | ||
KernelName>(KernelFunc); | ||
} | ||
|
||
// For 'sycl::group<Dims>' kernel argument | ||
template <class KernelType, typename ArgT, int Dims, typename KernelName> | ||
typename std::enable_if<std::is_same<ArgT, sycl::group<Dims>>::value, | ||
KernelType *>::type | ||
ResetHostKernel(const KernelType &KernelFunc) { | ||
struct NormalizedKernelType { | ||
KernelType MKernelFunc; | ||
NormalizedKernelType(const KernelType &KernelFunc) | ||
: MKernelFunc(KernelFunc) {} | ||
void operator()(const nd_item<Dims> &Arg) { | ||
detail::runKernelWithArg(MKernelFunc, Arg.get_group()); | ||
|
||
} | ||
}; | ||
return ResetHostKernelHelper<KernelType, struct NormalizedKernelType, Dims, | ||
KernelName>(KernelFunc); | ||
} | ||
|
||
/// Stores lambda to the template-free object | ||
/// | ||
/// Also initializes kernel name, list of arguments and requirements using | ||
|
@@ -568,18 +714,19 @@ class __SYCL_EXPORT handler { | |
"kernel_handler is not yet supported by host device.", | ||
PI_INVALID_OPERATION); | ||
} | ||
MHostKernel.reset( | ||
new detail::HostKernel<KernelType, LambdaArgType, Dims, KernelName>( | ||
KernelFunc)); | ||
KernelType *KernelPtr = | ||
ResetHostKernel<KernelType, LambdaArgType, Dims, KernelName>( | ||
KernelFunc); | ||
|
||
using KI = sycl::detail::KernelInfo<KernelName>; | ||
// Empty name indicates that the compilation happens without integration | ||
// header, so don't perform things that require it. | ||
if (KI::getName() != nullptr && KI::getName()[0] != '\0') { | ||
// TODO support ESIMD in no-integration-header case too. | ||
MArgs.clear(); | ||
extractArgsAndReqsFromLambda(MHostKernel->getPtr(), KI::getNumParams(), | ||
&KI::getParamDesc(0), KI::isESIMD()); | ||
extractArgsAndReqsFromLambda(reinterpret_cast<char *>(KernelPtr), | ||
dongkyunahn-intel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
KI::getNumParams(), &KI::getParamDesc(0), | ||
KI::isESIMD()); | ||
MKernelName = KI::getName(); | ||
MOSModuleHandle = detail::OSUtil::getOSModuleHandle(KI::getName()); | ||
} else { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//==-------- atomic_intrin.hpp - Atomic intrinsic definition file ----------==// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
#pragma once | ||
|
||
#include <CL/sycl/exception.hpp> | ||
|
||
// This function implements atomic update of pre-existing variable in the | ||
// absense of C++ 20's atomic_ref. | ||
template <typename Ty> Ty atomic_add_fetch(Ty *ptr, Ty val) { | ||
dongkyunahn-intel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#ifdef _WIN32 | ||
// TODO: Windows will be supported soon | ||
throw cl::sycl::feature_not_supported(); | ||
#else | ||
return __atomic_add_fetch(ptr, val, __ATOMIC_RELAXED); | ||
#endif | ||
} |
Uh oh!
There was an error while loading. Please reload this page.