I am trying to access a global variable from inside the sycl kernel. A code that uses this pattern and its output is as follows.
#include<CL/sycl.hpp>
using namespace sycl;
int g_var = 22;
int * const g_ptr = &g_var;
int main() {
queue q{host_selector{}};
g_var = 27;
std::cout<<"global var changed : " <<g_var<<" "<<*g_ptr<<"\n";
q.submit( [=] (handler &h) {
stream os(1024, 128, h);
h.single_task([=] () {
os<<"global var : "<<*g_ptr<<"\n";
});
}).wait();
return 0;
}
Its output is as follows.
$$ dpcpp test.cpp; ./a.out
global var changed : 27 27
global var : 22
Even though g_var is changed to 27, it is printed with the initial value of 22 inside the kernel. Is this the intended behavior?
In general lambdas does not create a copy of global variables. Does dpc++ compiler create a copy of the global variable inside the device or does it propagate the constant value during compilation so as to not access the global memory at runtime?
SYCL divides execution and data through the "host" and "device." The data on the "host" lives on the CPU normally, and needs to be transferred to the "device" (GPU usuall) in order to be accessed for use in a SYCL kernel.
SYCL uses buffers and accessors, or "Unified Shared Memory" to transfer and provide access to data for the "device" side code (i.e. the code running on the GPU). So your pointer is never sent over to the device, and therefore never modified.
So instead of using
int * const g_ptr = &g_var;
you should use a buffer or USM. There are some lessons on these for buffers and USM in SYCL Academy.E.g. using buffers and accessors:
And using USM: