Forum Discussion
How does AOC compiler map fixed point MAC operations to DSP ip blocks?
- 7 years ago
With 16.1.2, whether DTYPE is short or int, as long as partial_sum is int, I get 1024 DSPs for j=512.
Based on what you are saying, it seems the OpenCL compiler (v17+) does not correctly instantiate the IPs and infers 32-bit MULs instead of 16-bit ones (while the estimation in the report is based on 16-bit MULs), and for j > 759, since it thinks DSPs are fully utilized, it instantiates the logic-based IP instead of the DSP-based one . For cases where j <= 759, it seems the mapper is smart enough to pack the operations properly and reduce DSP usage, but for j > 759, since the compiler has instantiated logic-based IP, the mapper does not convert the logic-based IP to DSP-based and you get high logic usage but low DSP utilization.
I tested all the way to v18.1. With DTYPE=short and partial_sum defined as int, the DSP usage gets capped at 379 (379.5 actually!!!) for j > 759 and the rest of the operations are mapped to logic. However, with both defined as short, 17.0+ seems to correctly map two MULs per DSP but DSP usage gets capped at 50% this time. It seems there is still some code somewhere in the compiler (probably the linker) that has not been updated correctly with the new way DSP mapping happens, and is still using the old codes (pre-17.0) of two DSPs per MUL for DTYPE=short and partial_sum=int, and one DSP per MUL for DTYPE=short and partial_sum=short.
It is certainly possible to use all the DSPs on Arria 10 with 16-bit arithmetic. For example, you can look at the paper from Altera which claims to do so in OpenCL and another one which does so using an HDL library wrapped in OpenCL (both linked in the other thread). The behavior you are observing here seems to be a bug in the OpenCL compiler.
You have mentioned that the compiler doesn't take DTYPE decalaration into account because partial_sum is int. When I change DTYPE to int and try j = 128 the resource estimation as follows :
+--------------------------------------------------------------------+
; Estimated Resource Usage Summary ;
+----------------------------------------+---------------------------+
; Resource + Usage ;
+----------------------------------------+---------------------------+
; Logic utilization ; 24% ;
; ALUTs ; 13% ;
; Dedicated logic registers ; 12% ;
; Memory blocks ; 21% ;
; DSP blocks ; 17% ;
+----------------------------------------+---------------------------;
DSP blocks : 256 as two DSP blocks required for performing 32 x 32 multplication.
when i change DTYPE to short with j = 128 the resource estimation is as follows:
+--------------------------------------------------------------------+
; Estimated Resource Usage Summary ;
+----------------------------------------+---------------------------+
; Resource + Usage ;
+----------------------------------------+---------------------------+
; Logic utilization ; 20% ;
; ALUTs ; 10% ;
; Dedicated logic registers ; 10% ;
; Memory blocks ; 15% ;
; DSP blocks ; 4% ;
+----------------------------------------+---------------------------;
DSP blocks = 64 as one dsp block performs two 16x16 multiplication with one addition. I think changing DTYPE does make difference in the number of DSP usage from the above results.
In j = 512, after the complete compilation process, top.fit.summary shows the DSP usage as 256 blocks and not 1024 using aoc v 17.1. This is exactly what we expected as each dsp block is capable of performing two 18 x 18 multiplication accumulating 32 bit result (In our case partial_sum). This is demonstrated in section 3.1.2 in the following document.
(https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_nfp_dsp.pdf). Do you think the compiler also uses the same mode for mapping the DSP blocks?
But this doesn't happen in the case j > 759. Somehow compiler gets confused and maps the multiplications to logic after using 379.5 DSPs (1518 /4). I tried checking after complete compilation (j = 768). First the aoc compiler increases the logic utilization. Thus, synthesis step takes lot of time (In my case 1 day). The top.fit.place.rpt also shows the same number of DSP blocks. I feel the throughput would also decrease as extra multiplication are performed on logic.
I tried using arbitrary precision integer extension and tried changing pratial_sum to int27_t. I dont think aoc allows me to change kernel declarations with arbitrary precision data types. No Luck again :(
AOC compiler performs well with mapping floating point multiplications. But did you come across programs which were able to use more than 50% DSP blocks with 8 bit or 16 bit fixed point multiplications on Arria 10 or any other FPGA device?