Intel® oneAPI Data Parallel C++
Support for Intel® oneAPI DPC++ Compiler, Intel® oneAPI DPC++ Library, Intel ICX Compiler , Intel® DPC++ Compatibility Tool, and GDB*

Buffer accessor iteration for initialization.

nnain1
New Contributor I
1,665 Views

Sycl compiler provides the begin() and end() iterator for itration to buffer as

auto a_a = a.get_access<access::mode::read_write>();
// Initialize buffer a with increasing integer starting at 0
std::iota(a_a.begin(), a_a.end(), 0);

But in dpc++ compiler gives error for begin() and end().

The following way of buffer initialization is quite convenient in Sycl.

buffer<Type> a{ N };
{        
        auto a_a = a.get_access<access::mode::read_write>();
        // Initialize buffer a with increasing integer starting at 0
        std::iota(a_a.begin(), a_a.end(), 0);
}

How can I have similar approach in DPC++?

What I have seen so far in DPC++ is

std::array<int, N> data_b;
for (int i = 0; i < N; ++i) {
        data_b = 0;

Then assign to buffer.

0 Kudos
1 Solution
AbhishekD_Intel
Moderator
1,665 Views

Hi Naing,

Thanks for your finding, but before explaining your issue I want to explain you that Buffers are a data abstraction that represents one or more objects of a given C++ type. Buffers represent data objects rather than specific memory addresses, so they cannot be directly accessed like regular C++ arrays. Indeed, a buffer object might map to multiple different memory locations on several different devices, or even on the same device for performance reasons. Instead, we use accessor objects to read and write buffers. The accessor communicates the data type, the size, the target, and the access mode.

So, Accessors will not have an Iterator function like begin() or end() directly associated with it.

So acc.begin() and acc.end() will give error while compiling it with DPC++ as well as SYCL. Still, we tried using the above code snippets you provided and it's not working over SYCL and DPC++. 

If those mentioned code snippets worked with SYCL for you, please enlightened us with more information regarding your environment.

There is a way around to follow the same approach you want to try, the below code snippet will help:

        std::vector<int> v(nElems);
        std::iota(std::begin(v), std::end(v), 0);

        // Create a buffer with no associated user storage
        sycl::buffer<int, 1> b{ nElems };

        // Create a queue
        sycl::queue myQueue;
        myQueue.submit([&](sycl::handler &cgh) {
                    
                        sycl::accessor<int, 1, sycl::access::mode::write, sycl::access::target::global_buffer>acc(b, cgh);
                        // Copy the elements of the vector into the buffer associated with the accessor
                        cgh.copy(v.data(), acc);
         
                        });

 

Let us know if it gets resolved for you.

-Abhishek

View solution in original post

0 Kudos
5 Replies
AbhishekD_Intel
Moderator
1,666 Views

Hi Naing,

Thanks for your finding, but before explaining your issue I want to explain you that Buffers are a data abstraction that represents one or more objects of a given C++ type. Buffers represent data objects rather than specific memory addresses, so they cannot be directly accessed like regular C++ arrays. Indeed, a buffer object might map to multiple different memory locations on several different devices, or even on the same device for performance reasons. Instead, we use accessor objects to read and write buffers. The accessor communicates the data type, the size, the target, and the access mode.

So, Accessors will not have an Iterator function like begin() or end() directly associated with it.

So acc.begin() and acc.end() will give error while compiling it with DPC++ as well as SYCL. Still, we tried using the above code snippets you provided and it's not working over SYCL and DPC++. 

If those mentioned code snippets worked with SYCL for you, please enlightened us with more information regarding your environment.

There is a way around to follow the same approach you want to try, the below code snippet will help:

        std::vector<int> v(nElems);
        std::iota(std::begin(v), std::end(v), 0);

        // Create a buffer with no associated user storage
        sycl::buffer<int, 1> b{ nElems };

        // Create a queue
        sycl::queue myQueue;
        myQueue.submit([&](sycl::handler &cgh) {
                    
                        sycl::accessor<int, 1, sycl::access::mode::write, sycl::access::target::global_buffer>acc(b, cgh);
                        // Copy the elements of the vector into the buffer associated with the accessor
                        cgh.copy(v.data(), acc);
         
                        });

 

Let us know if it gets resolved for you.

-Abhishek

0 Kudos
nnain1
New Contributor I
1,665 Views

Thank you. The code sample is from trisycl test code.

Your code is also convenient.

0 Kudos
AbhishekD_Intel
Moderator
1,665 Views

Hi,

Thanks for the information, let us know if the given solution worked for you?

Thank you

-Abhishek

0 Kudos
nnain1
New Contributor I
1,665 Views

Yes thank you.

0 Kudos
AbhishekD_Intel
Moderator
1,665 Views

Thank you,

We are closing this thread.

You can always post a new thread is you faced any problem.

Stay Healthy Stay Safe!

-Abhishek

0 Kudos
Reply