Pass Data to Algorithms
Contents
Pass Data to Algorithms¶
You can use one of the following ways to pass data to an algorithm executed with a device policy:
oneapi:dpl::begin
andoneapi::dpl::end
functionsUnified shared memory (USM) pointers and
std::vector
with USM allocatorsIterators of host-side
std::vector
Use oneapi::dpl::begin and oneapi::dpl::end Functions¶
oneapi::dpl::begin
and oneapi::dpl::end
are special helper functions that
allow you to pass SYCL buffers to parallel algorithms. These functions accept
a SYCL buffer and return an object of an unspecified type that provides the following API:
It satisfies
CopyConstructible
andCopyAssignable
C++ named requirements and comparable withoperator==
andoperator!=
.It gives the following valid expressions:
a + n
,a - n
, anda - b
, wherea
andb
are objects of the type, andn
is an integer value. The effect of those operations is the same as for the type that satisfies theLegacyRandomAccessIterator
, a C++ named requirement.It provides the
get_buffer
method, which returns the buffer passed to thebegin
andend
functions.
The begin
and end
functions can take SYCL 2020 deduction tags and sycl::no_init
as arguments
to explicitly mention which access mode should be applied to the buffer accessor when submitting a
SYCL kernel to a device. For example:
auto first1 = begin(buf, sycl::read_only);
auto first2 = begin(buf, sycl::write_only, sycl::no_init);
auto first3 = begin(buf, sycl::no_init);
The example above allows you to control the access mode for the particular buffer passing to a parallel algorithm.
To use the functions, add #include <oneapi/dpl/iterator>
to your code. For example:
#include <oneapi/dpl/execution>
#include <oneapi/dpl/algorithm>
#include <oneapi/dpl/iterator>
#include <sycl/sycl.hpp>
int main(){
sycl::buffer<int> buf { 1000 };
auto buf_begin = oneapi::dpl::begin(buf);
auto buf_end = oneapi::dpl::end(buf);
std::fill(oneapi::dpl::execution::dpcpp_default, buf_begin, buf_end, 42);
return 0;
}
Use Host-Side std::vector¶
oneAPI DPC++ Library parallel algorithms can be called with ordinary (host-side) iterators, as seen in the example below. In this case, a temporary SYCL buffer is created, and the data is copied to this buffer. After processing on a device is complete, the modified data is copied from the temporary buffer back to the host container. For example:
#include <oneapi/dpl/execution>
#include <oneapi/dpl/algorithm>
#include <vector>
int main(){
std::vector<int> vec( 1000 );
std::fill(oneapi::dpl::execution::dpcpp_default, vec.begin(), vec.end(), 42);
// each element of vec equals to 42
return 0;
}
Working with SYCL buffers is recommended to reduce data copying between the host and device.