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
새로운 기여자 I
3,235 조회수

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 포인트
1 솔루션
AbhishekD_Intel
중재자
3,235 조회수

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 포인트
5 응답
AbhishekD_Intel
중재자
3,236 조회수

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 포인트
nnain1
새로운 기여자 I
3,235 조회수

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

Your code is also convenient.

0 포인트
AbhishekD_Intel
중재자
3,235 조회수

Hi,

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

Thank you

-Abhishek

0 포인트
nnain1
새로운 기여자 I
3,235 조회수

Yes thank you.

0 포인트
AbhishekD_Intel
중재자
3,235 조회수

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 포인트
응답