Intel® oneAPI DPC++/C++ Compiler
Talk to fellow users of Intel® oneAPI DPC++/C++ Compiler and companion tools like Intel® oneAPI DPC++ Library, Intel® DPC++ Compatibility Tool, and Intel® Distribution for GDB*

Buffer accessor iteration for initialization.

nnain1
Novo colaborador I
3.225 Visualizações

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 Solução
AbhishekD_Intel
Moderador
3.225 Visualizações

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

Ver solução na publicação original

5 Respostas
AbhishekD_Intel
Moderador
3.226 Visualizações

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

nnain1
Novo colaborador I
3.225 Visualizações

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

Your code is also convenient.

AbhishekD_Intel
Moderador
3.225 Visualizações

Hi,

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

Thank you

-Abhishek

nnain1
Novo colaborador I
3.225 Visualizações

Yes thank you.

AbhishekD_Intel
Moderador
3.225 Visualizações

Thank you,

We are closing this thread.

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

Stay Healthy Stay Safe!

-Abhishek

Responder