The AI Engine architecture uses stream data extensively for DMA-based I/O, for communicating between two AI Engines, and for communicating between the AI Engine and the programmable logic (PL). This raises the potential for a resource deadlock when the data flow graph has reconvergent data paths. If the pipeline depth of one path is longer than the other, the producer kernel can stall and might not be able to push data into the shorter path because of back pressure. At the same time, the consumer kernel is waiting to receive data on the longer path due to the lack of data. If the order of data production and consumption between two data paths is different, a deadlock can happen even between two kernels that are directly connected with two data paths. The following figure illustrates the paths.
If the producer kernel is trying to push data on stream
S1 and runs into back pressure while the consumer kernel is still trying to read data
from stream S2, a deadlock occurs. A general way to fix this situation is to create more
buffering in the paths that have back pressure in the source code by using a fifo_depth
constraint on a connection.
p = kernel::create(producer);
c = kernel::create(consumer);
connect s1(p.out[0], c.in[0]);
connect s2(p.out[1], c.in[1]);
fifo_depth(s1) = 20;
fifo_depth(s2) = 10;
fifo_depth()
constraint is only valid on stream and buffer
type kernel connections. It is not available on cascade stream type connections, because
there is a two deep 512-bit wide FIFO on both the input and output cascade streams that
allows storing up to four values between AI Engines.