Debug a SYCL* Application on a CPU
Use the simple SYCL application named Array Transform to perform basic debugging operations, such as break, run, print, continue, info, and next. The application being debugged is limited to running on multiple CPU threads by setting the ONEAPI_DEVICE_SELECTOR=*:cpu environment variable.
The debug array transform application used in this example can be found in the Intel oneAPI sample repo or by way of the oneapi-cli sample browser tool. After you have installed and initialized the Intel oneAPI Base Toolkit (sourced setvars.sh), run oneapi-cli --help in your terminal command line. The sample includes a build script to create an application that can be debugged and run on either a CPU or a GPU (the compiler debug flags are set during the build).
Before you proceed, make sure you have completed all the necessary setup steps and successfully completed the debug session in the Get Started Guide.
Basic Debugging
If you have not already done so, start the debugger:
Make sure that the kernel is offloaded to the correct device:
Example output:
Consider the Array Transform sample, which contains a simple kernel function that can be offloaded to different devices:
The code processes elements of the input array depending on whether they are even or odd, and produces an output array.
Define a breakpoint at line 54:
Expected output:
Run the program:
When the thread hits the breakpoint, you should see the following output:
Now you can issue the usual Intel Distribution for GDB commands to inspect the local variables, print a stack trace, and get information on threads. For your convenience, common Intel Distribution for GDB commands are provided in the Cheat Sheet.
Keep debugging and display the value of the index variable:
Expected output:
Continue program execution:
You should see the next breakpoint hit event, which comes from another thread.
If you print the value of the index variable now:
The output differs from the previous one:
To print data elements, use the bracket operator of the accessor:
Expected output:
You can also print the accessor contents:
Expected output:
Note, that the output is pretty-printed, as the compiler provides a pretty-printer for the sycl::accessor class. You can also print the accessor without pretty-printers using the following command:
Expected output:
To examine the data managed by the accessor in yourself, use
where the x command examines the memory contents at the given address and /4dw specifies that the examination output must contain four items in decimal format, word-length each.
Expected output:
Single stepping
A common debugging activity is single-stepping in the source. The step and next commands allow you to step through source lines, stepping into or over function calls.
To check the current thread data, run the following command:
You should get the following output:
To check the data of a particular thread, run:
Example output:
To make Thread 3 move forward by one source line, run:
You should see the following output:
Stepping has not occurred. Instead, a breakpoint event from Thread 5 is received and the debugger switched the context to that thread. This happens because you are debugging a multi-threaded program and multiple events may be received from different threads. This is the default behavior, but you can configure it for more efficient debugging. To ensure that the current thread executes a single line without interference, configure the scheduler-locking setting. By default scheduler-locking is “off” for continue/step commands, which means that all threads are resumed when executing one of those commands. For more information refer to documention in the Intel® Distribution for GDB* User Manual (PDF).
Now configure set scheduler-locking step on to keep the other threads stopped while the current thread is stepping:
Continue executing the next command:
You should see the following output:
Continue executing the next command:
You should see the following output:
To see the value of index variable, run:
You should see the following output:
Run:
The expected output is shown below:
Finally, run:
You should see the following output: