Buffer Wrappers#
// Defined in <oneapi/dpl/iterator>
namespace oneapi {
namespace dpl {
template < typename T, typename AllocatorT, typename TagT >
/*unspecified*/ begin( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
TagT tag = sycl::read_write );
template < typename T, typename AllocatorT, typename TagT >
/*unspecified*/ begin( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
TagT tag, sycl::property::no_init );
template < typename T, typename AllocatorT >
/*unspecified*/ begin( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
sycl::property::no_init );
template < typename T, typename AllocatorT, typename TagT >
/*unspecified*/ end( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
TagT tag = sycl::read_write );
template < typename T, typename AllocatorT, typename TagT >
/*unspecified*/ end( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
TagT tag, sycl::property::no_init );
template < typename T, typename AllocatorT >
/*unspecified*/ end( sycl::buffer<T, /*dim=*/1, AllocatorT> buf,
sycl::property::no_init );
}
}
oneapi::dpl::begin
and oneapi::dpl::end
are helper functions
for passing SYCL buffers to oneDPL algorithms.
These functions accept a SYCL buffer and return a buffer position object,
which type satisfies the following requirements but is otherwise unspecified:
It is copy-constructible and copy-assignable.
It is comparable with
operator==
andoperator!=
.It provides the
get_buffer()
method that for a buffer position object returns the SYCL buffer, which the object was built over.The expressions
a + n
anda - n
, wherea
is a buffer position object andn
is an integer value, are valid and evaluate to a buffer position object such that the corresponding position in the buffer follows (precedes) that ofa
byn
. If this new position is out of the buffer bounds, the behavior is undefined.The expression
a - b
, wherea
andb
are buffer position objects, is valid and evaluates to an integer valuen
such thata == b + n
.
If these operators and expressions are applied to buffer position objects that are not built over the same SYCL buffer, the behavior is undefined.
When invoking an algorithm, the buffer passed to begin
should be the same
as the buffer passed to end
. Otherwise, the behavior is undefined.
An algorithm may return a buffer position object, which can then be compared and used in expressions with other objects built over the same buffer.
namespace dpl = oneapi::dpl; // see "Namespaces"
sycl::buffer buf {/*...*/};
auto pos = dpl::find(dpl::execution::dpcpp_default, dpl::begin(buf), dpl::end(buf), value);
int value_index = (pos == dpl::end(buf)) ? -1 : (pos - dpl::begin(buf));
Note
Though buffer position objects substitute for iterators as arguments and return values of oneDPL algorithms, they cannot be used as iterators in other contexts, including dereference, as their type does not satisfy the C++ standard requirements for an iterator.
SYCL deduction tags (the TagT
parameters) and sycl::property::no_init
allow to specify an access mode to be used by algorithms for accessing a SYCL buffer.
The mode serves as a hint, and can be overridden depending on semantics of the algorithm.
When invoking an algorithm, the same access mode arguments should be used
for begin
and end
. Otherwise, the behavior is undefined.
namespace dpl = oneapi::dpl;
sycl::buffer buf {/*...*/};
auto policy = dpl::execution::dpcpp_default;
auto buf_begin = dpl::begin(buf, sycl::write_only);
auto buf_end_1 = dpl::end(buf, sycl::write_only); // arguments match begin()
dpl::fill(policy, buf_begin, buf_end_1, 42); // OK
auto buf_end_2 = dpl::end(buf, sycl::write_only, sycl::no_init); // arguments do not match
dpl::fill(policy, buf_begin, buf_end_2, 42); // undefined behavior