Device Code Modification
This topic describes some techniques you should consider when converting your OpenCL device code to SYCL*.
Channels/Pipes
You can use OpenCL channels and their SYCL equivalent pipes to send data from one kernel to another in a FIFO manner without going through device memory. This topic describes how to transform OpenCL channels into SYCL pipes.
In OpenCL, channels are an Intel® extension and you declare them as file scope variables using the syntax provided in the table below. This makes the channel unique within a given OpenCL kernel program and allows the compiler to make static connectivity. In SYCL, pipes use the C++ type system to guarantee static connectivity. Therefore, as you can see in the SYCL code below, my_pipe is a C++ type rather than a file scope variable as in OpenCL.
The first template argument of a pipe declaration can be of any type, but it is typically a user-defined C++ class or struct. The class or struct must be forward declared and need not be defined. This naming method is like the kernel naming method described in the Basic Device Code Modification section. The second template argument is the data type that the pipe contains. The third (optional) argument is the minimum number of elements that the pipe must store. The default value of 0 allows the compiler to choose a depth.
The following table summarizes the declaration and usage of OpenCL channels and SYCL pipes:
OpenCL | SYCL |
---|---|
|
|
// blocking write_channel_intel(my_pipe, write_data); // non-blocking bool success_code = write_channel_nb_intel(my_pipe, write_data); |
|
|
|
In your OpenCL design, you may have used an array of channels. In SYCL, this is replaced with C++ meta-programming. To convert an array of channels in OpenCL to SYCL, refer to the pipe_array SYCL FPGA tutorial on GitHub.
I/O Pipes
I/O pipes are a special type of FIFO used to interface with input or output features of an FPGA board. These features may include network cards, PCIe busses, cameras, or other processing devices or protocols. Assume that the board_spec.xml file in your BSP has the following section describing the interface to a UDP offload engine that is implemented inside the BSP:
<channels> <interface name="udp_0" port="udp0_out" type="streamsource" width="256" chan_id="io_pipe_in"/> <interface name="udp_0" port="udp0_in" type="streamsink" width="256" chan_id="io_pipe_out"/> </channels>
Then, the following table shows how you would construct the I/O pipe in both OpenCL and SYCL:
OpenCL | SYCL |
---|---|
|
|
In OpenCL, the io attribute on the pipe must match the chan_id in the board_spec.xml file. In SYCL, the static id member of the pipe type identifier is used as an index to get the child interface of the channel's node in the board_spec.xml file. The methods for reading and writing to the I/O pipe are the same as those discussed in the Channels/Pipes section.