Skip to content

[SYCL] Host task accessor deduction guides #2055

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 3 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
105 changes: 85 additions & 20 deletions sycl/include/CL/sycl/accessor.hpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -944,9 +944,9 @@ class accessor :

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename TagT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>() &&
IsValidTag<TagT>() && IsPlaceH &&
(IsGlobalBuf || IsConstantBuf)>>
typename = detail::enable_if_t<
IsSameAsBuffer<T, Dims>() && IsValidTag<TagT>() && IsPlaceH &&
(IsGlobalBuf || IsConstantBuf || IsHostBuf)>>
accessor(buffer<T, Dims, AllocatorT> &BufferRef, TagT,
const property_list &PropertyList = {})
: accessor(BufferRef, PropertyList) {}
Expand Down Expand Up @@ -980,9 +980,9 @@ class accessor :

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename TagT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>() &&
IsValidTag<TagT>() && !IsPlaceH &&
(IsGlobalBuf || IsConstantBuf)>>
typename = detail::enable_if_t<
IsSameAsBuffer<T, Dims>() && IsValidTag<TagT>() && !IsPlaceH &&
(IsGlobalBuf || IsConstantBuf || IsHostBuf)>>
accessor(buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
TagT, const property_list &PropertyList = {})
: accessor(BufferRef, CommandGroupHandler, PropertyList) {}
Expand Down Expand Up @@ -1014,9 +1014,9 @@ class accessor :
#endif

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>() &&
(!IsPlaceH &&
(IsGlobalBuf || IsConstantBuf))>>
typename = detail::enable_if_t<
IsSameAsBuffer<T, Dims>() &&
(!IsPlaceH && (IsGlobalBuf || IsConstantBuf || IsHostBuf))>>
accessor(buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
range<Dimensions> AccessRange,
const property_list &PropertyList = {})
Expand All @@ -1027,9 +1027,9 @@ class accessor :

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename TagT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>() &&
IsValidTag<TagT>() && !IsPlaceH &&
(IsGlobalBuf || IsConstantBuf)>>
typename = detail::enable_if_t<
IsSameAsBuffer<T, Dims>() && IsValidTag<TagT>() && !IsPlaceH &&
(IsGlobalBuf || IsConstantBuf || IsHostBuf)>>
accessor(buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
range<Dimensions> AccessRange, TagT,
const property_list &PropertyList = {})
Expand Down Expand Up @@ -1078,9 +1078,9 @@ class accessor :
#endif

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>() &&
(!IsPlaceH &&
(IsGlobalBuf || IsConstantBuf))>>
typename = detail::enable_if_t<
IsSameAsBuffer<T, Dims>() &&
(!IsPlaceH && (IsGlobalBuf || IsConstantBuf || IsHostBuf))>>
accessor(buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
range<Dimensions> AccessRange, id<Dimensions> AccessOffset,
const property_list &PropertyList = {})
Expand All @@ -1105,9 +1105,9 @@ class accessor :

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename TagT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>() &&
IsValidTag<TagT>() && !IsPlaceH &&
(IsGlobalBuf || IsConstantBuf)>>
typename = detail::enable_if_t<
IsSameAsBuffer<T, Dims>() && IsValidTag<TagT>() && !IsPlaceH &&
(IsGlobalBuf || IsConstantBuf || IsHostBuf)>>
accessor(buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
range<Dimensions> AccessRange, id<Dimensions> AccessOffset, TagT,
const property_list &PropertyList = {})
Expand Down Expand Up @@ -1620,8 +1620,6 @@ class host_accessor
// buffer | handler | range | id | | property_list
// buffer | handler | range | id | mode_tag | property_list
// -------+---------+-------+----+----------+--------------
// host_accessor with handler argument will be added later
// to facilitate non-blocking accessor use case

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = typename detail::enable_if_t<
Expand All @@ -1644,6 +1642,24 @@ class host_accessor
mode_tag_t<AccessMode>, const property_list &PropertyList = {})
: host_accessor(BufferRef, PropertyList) {}

#endif

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>()>>
host_accessor(buffer<T, Dims, AllocatorT> &BufferRef,
handler &CommandGroupHandler,
const property_list &PropertyList = {})
: AccessorT(BufferRef, CommandGroupHandler, PropertyList) {}

#if __cplusplus > 201402L

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>()>>
host_accessor(buffer<DataT, Dimensions, AllocatorT> &BufferRef,
handler &CommandGroupHandler, mode_tag_t<AccessMode>,
const property_list &PropertyList = {})
: host_accessor(BufferRef, CommandGroupHandler, PropertyList) {}

#endif

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
Expand All @@ -1662,6 +1678,26 @@ class host_accessor
const property_list &PropertyList = {})
: host_accessor(BufferRef, AccessRange, {}, PropertyList) {}

#endif

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>()>>
host_accessor(buffer<DataT, Dimensions, AllocatorT> &BufferRef,
handler &CommandGroupHandler, range<Dimensions> AccessRange,
const property_list &PropertyList = {})
: AccessorT(BufferRef, CommandGroupHandler, AccessRange, {},
PropertyList) {}

#if __cplusplus > 201402L

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>()>>
host_accessor(buffer<DataT, Dimensions, AllocatorT> &BufferRef,
handler &CommandGroupHandler, range<Dimensions> AccessRange,
mode_tag_t<AccessMode>, const property_list &PropertyList = {})
: host_accessor(BufferRef, CommandGroupHandler, AccessRange, {},
PropertyList) {}

#endif

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
Expand All @@ -1680,6 +1716,28 @@ class host_accessor
mode_tag_t<AccessMode>, const property_list &PropertyList = {})
: host_accessor(BufferRef, AccessRange, AccessOffset, PropertyList) {}

#endif

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>()>>
host_accessor(buffer<DataT, Dimensions, AllocatorT> &BufferRef,
handler &CommandGroupHandler, range<Dimensions> AccessRange,
id<Dimensions> AccessOffset,
const property_list &PropertyList = {})
: AccessorT(BufferRef, CommandGroupHandler, AccessRange, AccessOffset,
PropertyList) {}

#if __cplusplus > 201402L

template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
typename = detail::enable_if_t<IsSameAsBuffer<T, Dims>()>>
host_accessor(buffer<DataT, Dimensions, AllocatorT> &BufferRef,
handler &CommandGroupHandler, range<Dimensions> AccessRange,
id<Dimensions> AccessOffset, mode_tag_t<AccessMode>,
const property_list &PropertyList = {})
: host_accessor(BufferRef, CommandGroupHandler, AccessRange, AccessOffset,
PropertyList) {}

#endif
};

Expand Down Expand Up @@ -1712,6 +1770,13 @@ host_accessor(buffer<DataT, Dimensions, AllocatorT>, Type1, Type2, Type3, Type4)
->host_accessor<DataT, Dimensions,
detail::deduceAccessMode<Type3, Type4>()>;

template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
typename Type2, typename Type3, typename Type4, typename Type5>
host_accessor(buffer<DataT, Dimensions, AllocatorT>, Type1, Type2, Type3, Type4,
Type5)
->host_accessor<DataT, Dimensions,
detail::deduceAccessMode<Type4, Type5>()>;

#endif

} // namespace sycl
Expand Down
5 changes: 5 additions & 0 deletions sycl/include/CL/sycl/buffer.hpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ class buffer {
return host_accessor{*this, args...};
}

template <typename... Ts>
auto get_host_access(handler &commandGroupHandler, Ts... args) {
return host_accessor{*this, commandGroupHandler, args...};
}

#endif

template <typename Destination = std::nullptr_t>
Expand Down
125 changes: 125 additions & 0 deletions sycl/test/basic_tests/accessor/Inputs/host_task_accessor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//==-------- host_task_accessor.cpp - SYCL accessor basic test -------------==//
//
// 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
//
//===----------------------------------------------------------------------===//
#include <CL/sycl.hpp>
#include <cassert>

int main() {
// Non-placeholder accessors.
{
int data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

sycl::buffer<int, 1> buf_data(data, sycl::range<1>(9),
{cl::sycl::property::buffer::use_host_ptr()});

sycl::queue Queue;

Queue.submit([&](sycl::handler &cgh) {

#if defined(accessor_new_api_test)
sycl::host_accessor acc_1(buf_data, cgh);
sycl::host_accessor acc_2(buf_data, cgh, sycl::range<1>(8));
sycl::host_accessor acc_3(buf_data, cgh, sycl::range<1>(8), sycl::id<1>(1));
sycl::host_accessor acc_4(buf_data, cgh, sycl::read_only);
sycl::host_accessor acc_5(buf_data, cgh, sycl::range<1>(8), sycl::read_only);
sycl::host_accessor acc_6(buf_data, cgh, sycl::range<1>(8), sycl::id<1>(1),
sycl::read_only);
sycl::host_accessor acc_7(buf_data, cgh, sycl::write_only);
sycl::host_accessor acc_8(buf_data, cgh, sycl::range<1>(8), sycl::write_only);
sycl::host_accessor acc_9(buf_data, cgh, sycl::range<1>(8), sycl::id<1>(1),
sycl::write_only);
#elif defined(buffer_new_api_test)
auto acc_1 = buf_data.get_host_access(cgh);
auto acc_2 = buf_data.get_host_access(cgh, sycl::range<1>(8));
auto acc_3 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::id<1>(1));
auto acc_4 = buf_data.get_host_access(cgh, sycl::read_only);
auto acc_5 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::read_only);
auto acc_6 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::id<1>(1),
sycl::read_only);
auto acc_7 = buf_data.get_host_access(cgh, sycl::write_only);
auto acc_8 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::write_only);
auto acc_9 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::id<1>(1),
sycl::write_only);
#endif

cgh.codeplay_host_task(
[=]() {
acc_7[6] = acc_1[0];
acc_8[7] = acc_2[1];
acc_9[7] = acc_3[1];
acc_1[0] = acc_4[3];
acc_2[1] = acc_5[4];
acc_3[1] = acc_6[4];
});
});
Queue.wait();

#if defined(accessor_new_api_test)
sycl::host_accessor host_acc(buf_data, sycl::read_only);
#elif defined(buffer_new_api_test)
auto host_acc = buf_data.get_host_access(sycl::read_only);
#endif
assert(host_acc[0] == 4 && host_acc[1] == 5 && host_acc[2] == 6);
assert(host_acc[3] == 4 && host_acc[4] == 5 && host_acc[5] == 6);
assert(host_acc[6] == 1 && host_acc[7] == 2 && host_acc[8] == 3);
}

// noinit accessors.
{
int data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

sycl::buffer<int, 1> buf_data(data, sycl::range<1>(9),
{cl::sycl::property::buffer::use_host_ptr()});

sycl::queue Queue;

Queue.submit([&](sycl::handler &cgh) {

#if defined(accessor_new_api_test)
sycl::host_accessor acc_1(buf_data, cgh, sycl::noinit);
sycl::host_accessor acc_2(buf_data, cgh, sycl::range<1>(8), sycl::noinit);
sycl::host_accessor acc_3(buf_data, cgh, sycl::range<1>(8), sycl::id<1>(1),
sycl::noinit);
sycl::host_accessor acc_7(buf_data, cgh, sycl::write_only, sycl::noinit);
sycl::host_accessor acc_8(buf_data, cgh, sycl::range<1>(8), sycl::write_only,
sycl::noinit);
sycl::host_accessor acc_9(buf_data, cgh, sycl::range<1>(8), sycl::id<1>(1),
sycl::write_only, sycl::noinit);
#elif defined(buffer_new_api_test)
auto acc_1 = buf_data.get_host_access(cgh, sycl::noinit);
auto acc_2 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::noinit);
auto acc_3 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::id<1>(1),
sycl::noinit);
auto acc_7 = buf_data.get_host_access(cgh, sycl::write_only, sycl::noinit);
auto acc_8 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::write_only,
sycl::noinit);
auto acc_9 = buf_data.get_host_access(cgh, sycl::range<1>(8), sycl::id<1>(1),
sycl::write_only, sycl::noinit);
#endif

cgh.codeplay_host_task(
[=]() {
acc_7[6] = acc_1[0];
acc_8[7] = acc_2[1];
acc_9[7] = acc_3[1];
acc_1[0] = 4;
acc_2[1] = 5;
acc_3[1] = 6;
});
});
Queue.wait();

#if defined(accessor_new_api_test)
sycl::host_accessor host_acc(buf_data, sycl::read_only);
#elif defined(buffer_new_api_test)
auto host_acc = buf_data.get_host_access(sycl::read_only);
#endif
assert(host_acc[0] == 4 && host_acc[1] == 5 && host_acc[2] == 6);
assert(host_acc[3] == 4 && host_acc[4] == 5 && host_acc[5] == 6);
assert(host_acc[6] == 1 && host_acc[7] == 2 && host_acc[8] == 3);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -Dbuffer_new_api_test -std=c++17 %S/Inputs/host_task_accessor.cpp -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %GPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -Daccessor_new_api_test -std=c++17 %S/Inputs/host_task_accessor.cpp -o %t.out
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %GPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out