The AI Engine architecture uses stream data extensively for the following purposes:
- DMA-based I/O
- Communicating between two AI Engines
- Communicating between the AI Engine and the programmable logic (PL)
This raises the potential for a resource deadlock if 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.
If a stall occurs, the kernel might be unable 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 occur. This can even happen between two kernels that are directly connected with two data paths. The following figure shows the paths.
If the producer kernel is trying to push data on stream S1
and encounters back pressure while the consumer kernel is still trying to read data from
stream S2, a deadlock occurs. You can fix this by creating more buffering in the paths
that have back pressure in the source code. Do this 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 unavailable on cascade stream type connections due to two
deep 512-bit wide FIFOs on both input and output cascade streams. This allows storing up
to four values between AI Engines.