KhronosGroup/SYCL-Docs

Question about buffers of the form `buffer<const T>`

Closed this issue · 2 comments

My question basically is if this should compile in SYCL2020:

std::vector<int> data(100);
const int* hostData = data.data();

sycl::buffer<const int> buf(hostData, sycl::range<1>(100));

Generally, I don't see why it shouldn't but in Table 39 of the spec in the description of the constructor buffer(const T* hostData, const range<Dimensions>& bufferRange, const property_list& propList = {}) the spec states

The host address is const T, so the host accesses can be read-only. However, the typename T is not const so the device accesses can be both read and write accesses.

I'm a bit confused about the typename T is not const part: does that mean that buffers of the form buffer<const T> are in general not allowed in SYCL2020? Or is this specific constructor only allowed if T is not const?

Yes, I think that should compile, and it does on DPC++. Note, however, that this code uses this constructor:

buffer(T* hostData, const range<Dimensions>& bufferRange, const property_list& propList = {});

Note that it's the constructor that takes T *, not const T *. In this case, the template parameter T is const int.

It's possible to write either of the two lines below, which end up calling different constructors:

sycl::buffer<const int> buf(hostData, sycl::range<1>(100));  // Constructor taking "T *"
sycl::buffer<int> buf(hostData, sycl::range<1>(100));        // Constructor taking "const T *"

You can also rely on CTAD to deduce T:

sycl::buffer buf(hostData, sycl::range<1>(100));  // "T" deduced as "int".  Constructor taking "const T *"

This is because of the deduction guide:

template <class T, int Dimensions>
buffer(const T*, const range<Dimensions>&, const property_list& = {})
     -> buffer<T, Dimensions>;

Oh I see now. Thanks for clarifying.