Skip to content

[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

Merged
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
ee6e9e8
[SYCL][ESIMD][EMU] ESIMD_CPU Kernel launch and Emulated Intrinsics
dongkyunahn-intel Jun 28, 2021
6b15320
Atomic fix
dongkyunahn-intel Jun 29, 2021
3249056
Removing dependency on _pi_image/buffer in kernel compilation
dongkyunahn-intel Jul 8, 2021
7b163d6
Revert changes in ESIMD_CPU device interface
dongkyunahn-intel Jul 9, 2021
0151dc7
Revert file relocation for future merging
dongkyunahn-intel Jul 9, 2021
7533a83
Changes in ESIMD_CPU device interface definition
dongkyunahn-intel Jul 9, 2021
c96efe1
Removing interleaved '__SYCL_DEVICE_ONLY__' in memory_intrin.hpp
dongkyunahn-intel Jul 15, 2021
1266ceb
Removing 'get_pointer()' and changing space for 'raw_send'
dongkyunahn-intel Jul 20, 2021
986a4f8
Merge branch 'sycl' into esimdcpu_kernel_launch_memory_intrinsic
dongkyunahn-intel Jul 26, 2021
c14a755
Build failure fix after merging sycl branch
dongkyunahn-intel Jul 26, 2021
33c3645
Merge branch 'sycl' into esimdcpu_kernel_launch_memory_intrinsic
dongkyunahn-intel Aug 26, 2021
2a9e789
Reverting a change already applied in PR#4011
dongkyunahn-intel Aug 26, 2021
49bc656
Rebase fix / File path order fix
dongkyunahn-intel Aug 26, 2021
1fd05a9
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Aug 27, 2021
69d1cfb
Handling 'void' kernel argument type
dongkyunahn-intel Aug 30, 2021
94cb161
Clang-format error fix
dongkyunahn-intel Aug 30, 2021
0b87d06
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Sep 3, 2021
80d4c5e
'Group' argument fix
dongkyunahn-intel Sep 7, 2021
b9f9663
Empty header file generation for toolchain building w/o CM
dongkyunahn-intel Sep 7, 2021
686a2eb
Enabling kernel execution with kernel_handler argument
dongkyunahn-intel Sep 8, 2021
7d1e481
Adding 'esimd_cpu' in ParseAllowList unit-test
dongkyunahn-intel Sep 9, 2021
8044e82
Merge branch 'sycl' into esimdcpu_kernel_launch_memory_intrinsic
dongkyunahn-intel Sep 10, 2021
a586d1e
Update sycl/include/sycl/ext/intel/experimental/esimd/detail/atomic_i…
dongkyunahn-intel Sep 13, 2021
3671aad
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Sep 13, 2021
1afc4dc
clang-format fix
dongkyunahn-intel Sep 13, 2021
37a0e78
Recovering isESIMD() argument
dongkyunahn-intel Sep 16, 2021
3710d07
__esimd_raw_send* are removed
dongkyunahn-intel Sep 17, 2021
6a41df5
Typo fix - recovering a line removed by mistake
dongkyunahn-intel Sep 17, 2021
bb6c3a0
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Sep 21, 2021
b698f1e
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Sep 22, 2021
f183ec2
New cpp file to contain getESIMDDeviceInterface
dongkyunahn-intel Sep 22, 2021
4543b8f
Reordering backend initializations
dongkyunahn-intel Sep 22, 2021
21f11fe
Failure fixes
dongkyunahn-intel Sep 22, 2021
30d738f
Windows ABI test failure fix
dongkyunahn-intel Sep 24, 2021
76771f4
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Sep 24, 2021
c042ae7
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Sep 29, 2021
ceb309d
single_task debugging
dongkyunahn-intel Sep 29, 2021
b073a4e
Fixing void(void) type kernel failure
dongkyunahn-intel Oct 1, 2021
be26fc0
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Oct 1, 2021
d4846bf
Merging fixes
dongkyunahn-intel Oct 1, 2021
7e65a1b
clang-format fix / void(sycl::group<Dims>) type fix for host device
dongkyunahn-intel Oct 1, 2021
2ef648b
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Oct 5, 2021
41490ea
clang-format error fix
dongkyunahn-intel Oct 5, 2021
9b57175
Reverting changes in memory intrinsic implementations
dongkyunahn-intel Oct 11, 2021
c7fad03
Missing revert from previous reverting
dongkyunahn-intel Oct 11, 2021
71b7a8f
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Oct 15, 2021
06f132c
Build error fix from esimd_cpu/emulator renaming
dongkyunahn-intel Oct 15, 2021
4d96d4b
Missing changes for esimd_cpu/emulator renaming
dongkyunahn-intel Oct 18, 2021
e45087b
Another renaming change
dongkyunahn-intel Oct 18, 2021
c1e6f9c
clang-format fix
dongkyunahn-intel Oct 18, 2021
6985a64
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Oct 28, 2021
8ee0bd8
Re-privatizing 'MKernel' for backward compatibility
dongkyunahn-intel Nov 16, 2021
2bf84de
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Nov 18, 2021
b85ba9f
ParseAllowList failure fix
dongkyunahn-intel Nov 18, 2021
7a3e968
clang-format fix
dongkyunahn-intel Nov 18, 2021
270763f
Merge branch 'sycl' of https://github.com/intel/llvm into esimdcpu_ke…
dongkyunahn-intel Nov 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions sycl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -291,17 +291,17 @@ if(SYCL_BUILD_PI_HIP)
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libspirv-builtins pi_hip)
endif()

# TODO : Remove 'if (NOT MSVC)' when CM_EMU supports Windows
# environment
if (NOT MSVC)
if (SYCL_BUILD_PI_ESIMD_CPU)
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS pi_esimd_cpu libcmrt-headers)
if (MSVC)
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libcmrt-libs libcmrt-dlls)
else()
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libcmrt-sos)
endif()
if (SYCL_BUILD_PI_ESIMD_CPU)
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS pi_esimd_cpu libcmrt-headers)
if (MSVC)
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libcmrt-libs libcmrt-dlls)
else()
list(APPEND SYCL_TOOLCHAIN_DEPLOY_COMPONENTS libcmrt-sos)
endif()
else()
# TODO/FIXME : Removing empty header file (cm_rt.h) generation when
# the ESIMD_CPU support is enabled by default
file (TOUCH ${SYCL_INCLUDE_BUILD_DIR}/sycl/CL/cm_rt.h)
endif()

# Use it as fake dependency in order to force another command(s) to execute.
Expand Down
2 changes: 1 addition & 1 deletion sycl/include/CL/sycl/detail/cg_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,9 @@ class HostTask {
template <class KernelType, class KernelArgType, int Dims, typename KernelName>
class HostKernel : public HostKernelBase {
using IDBuilder = sycl::detail::Builder;
KernelType MKernel;

public:
KernelType MKernel;
HostKernel(KernelType Kernel) : MKernel(Kernel) {}
void call(const NDRDescT &NDRDesc, HostProfilingInfo *HPI) override {
// adjust ND range for serial host:
Expand Down
157 changes: 152 additions & 5 deletions sycl/include/CL/sycl/handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This version is supposed to be used with parallel_for_workgroup, which is not supported for ESIMD. So I'd make operator() just throw, and comment out detail::runKernelWithArg(MKernelFunc, Arg.get_group());

Copy link
Contributor Author

@dongkyunahn-intel dongkyunahn-intel Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests containing parallel_for_work_group should not be run with ESIMD, as they will fail. You may exclude those tests for ESIMD_CPU_EMU. @vladimirlaz, can we create a lit feature for ESIMD CPU EMU plugin similar to opencl and level zero?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert changes related to this 'group' argument support after a lit feature for ESIMD CPU Emulation plug-in is created.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert changes related to this 'group' argument support after a lit feature for ESIMD CPU Emulation plug-in is created.

Am I right here? Should ResetHostKernel also have to cover sycl::group<> argument type because MHostKernel.reset() from left side is changed with call to ResetHostKernel?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vladimirlaz / @kbobrovs , are we going to create a lit feature for ESIMD_CPU emulation for this type of exclusion?

And, how did tests with parallel_for_work_groups pass for ESIMD so far?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to highlight that on-device tests (the tests which actually executed on target BE) have been removed from the intel/llvm repo to intel/llvm-test-suite (see #4393).
So, these test should be migrated to intel/llvm-test-suite. Correspondign feature can be added the (see HIP BE as an example).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vladimirlaz, the tests I mentioned above are already in intel/llvm-test-suite. You can see in their URLs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dongkyunahn-intel you can create LIT feature esimd_cpu and use it for the tests (like @kbobrovs suggested).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vladimirlaz , what file should I update for creating a LIT feature?

}
};
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
Expand All @@ -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),
KI::getNumParams(), &KI::getParamDesc(0),
KI::isESIMD());
MKernelName = KI::getName();
MOSModuleHandle = detail::OSUtil::getOSModuleHandle(KI::getName());
} else {
Expand Down
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) {
#ifdef _WIN32
// TODO: Windows will be supported soon
throw cl::sycl::feature_not_supported();
#else
return __atomic_add_fetch(ptr, val, __ATOMIC_RELAXED);
#endif
}
Loading