Community
cancel
Showing results for 
Search instead for 
Did you mean: 
nnain1
New Contributor I
155 Views

Buffer accessor iteration for initialization.

Jump to solution

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.

Tags (1)
0 Kudos
1 Solution
AbhishekD_Intel
Moderator
155 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

5 Replies
AbhishekD_Intel
Moderator
156 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

nnain1
New Contributor I
155 Views

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

Your code is also convenient.

AbhishekD_Intel
Moderator
155 Views

Hi,

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

Thank you

-Abhishek

nnain1
New Contributor I
155 Views

Yes thank you.

AbhishekD_Intel
Moderator
155 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

Reply