cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
y.lee0320
Participant
Participant
815 Views
Registered: ‎01-02-2019

Can we apply more than one array partitioning mechanisms to an array in HLS?

Jump to solution

Hi,

I am designing an image process core on Vivado HLS. There is an array which several functions use it for different purpose. To fulfill the pipeline of the functions and loops, I need to apply several array partitioning mechanisms.

For example, for the first function below, I need to apply

"#pragma HLS ARRAY_PARTITION variable=Mean_Buf_ITP block factor=8 dim=1". 

For the 2nd function, I probably need to apply 

#pragma HLS ARRAY_PARTITION variable=Mean_Buf_ITP cyclic factor=8 dim=2

#pragma HLS ARRAY_PARTITION variable=Mean_Buf_ITP cyclic factor=8 dim=1

Any good idea or advices for partitioning ?  Thanks in advance.

 

/* function #1 */

void Mean_Buf_ITP_Shift_Up(unsigned int Mean_Buf_ITP[ GS_Filter_Size + 1 ][ DRAM_W ]) {
for( int Row = 0; Row < GS_Filter_Size; Row++ ){
   for( int Col = 0; Col < DRAM_W; Col++ ){
#pragma HLS PIPELINE
       Mean_Buf_ITP[ Row ][ Col ] = Mean_Buf_ITP[ Row + 1 ][ Col ];
   }
}

 

/* function #2 */

void Mean_ITP( unsigned short Row, unsigned short Col, unsigned int Mean_Buf_ITP[ GS_Filter_Size + 1 ][ DRAM_W ] , unsigned short ITP_Window[ GS_Filter_Size ][GS_Filter_Size ]){
#pragma HLS INLINE off
//#pragma HLS INLINE
// static char GS_Y_START, GS_Y_END, GS_X_START, GS_X_END;
char y, x;
unsigned char MN_Row_Mid, MN_Col_Mid, up, down, left, right;
unsigned char GS_Row, GS_Col;
short MN_Row, MN_Col;
unsigned short ITP_1, ITP_2, ITP_3;

//GS_Y_START = -( GS_Filter_Size >> 1 );
//GS_Y_END = GS_Filter_Size >> 1;
//GS_X_START = GS_Y_START;
//GS_X_END = GS_Y_END;

MN_Row_Mid = (unsigned char)( Row >> MN_Block_Shift );
MN_Col_Mid = (unsigned char)( Col >> MN_Block_Shift );

up = (unsigned char)( Row - (unsigned int)( MN_Row_Mid ) * (unsigned int)( MN_Block_Size ) );
down = MN_Block_Size - up;
left = (unsigned char)( Col - (unsigned int)( MN_Col_Mid ) * (unsigned int)( MN_Block_Size ) );
right = MN_Block_Size - left;

for( y = GS_Y_START; y <= GS_Y_END; y++ ){
  for( x = GS_X_START; x <= GS_X_END; x++ ){

#pragma HLS PIPELINE
     GS_Row = (unsigned char)( (char)( GS_Filter_Size >> 1 ) + y );
     GS_Col = (unsigned char)( (char)( GS_Filter_Size >> 1 ) + x );

     MN_Row = (short)( MN_Row_Mid ) + (short)( y );
     MN_Col = (short)( MN_Col_Mid ) + (short)( x );

     if( MN_Row >= 0 && MN_Row < DRAM_H - 1 && MN_Col >= 0 && MN_Col < DRAM_W - 1 ){

         // Interpolation Above Part
         ITP_1 = ( Mean_Buf_ITP[ GS_Row ][ MN_Col ] * right + Mean_Buf_ITP[ GS_Row ][ MN_Col + 1 ] * left ) >> MN_Block_Shift;
         // Interpolation Below Part
         ITP_2 = ( Mean_Buf_ITP[ GS_Row + 1 ][ MN_Col ] * right + Mean_Buf_ITP[ GS_Row + 1 ][ MN_Col + 1 ] * left ) >> MN_Block_Shift;
         // Interpolation
         ITP_3 = ( ITP_1 * down + ITP_2 * up ) >> MN_Block_Shift;

         // Output: ITP_Window[][]
         ITP_Window[ GS_Row ][ GS_Col ] = ITP_3;

       }
    }
  }

}

0 Kudos
1 Solution

Accepted Solutions
u4223374
Advisor
Advisor
802 Views
Registered: ‎04-26-2015

Yes, you can definitely do that. As long as each partition directive applies to a different dimension you can have several applying to a single array.

View solution in original post

0 Kudos
3 Replies
u4223374
Advisor
Advisor
803 Views
Registered: ‎04-26-2015

Yes, you can definitely do that. As long as each partition directive applies to a different dimension you can have several applying to a single array.

View solution in original post

0 Kudos
y.lee0320
Participant
Participant
797 Views
Registered: ‎01-02-2019

Thank you for your prompt answer.

The partition did consume lots of resource, Furthermore. even I have applied three mechanism, I still cannot fulfill all. I got WARNING message as follows. Any suggestion?  I don't want to do array 0 complete, cannot afford it !@@

===============================================================================

INFO: [SCHED 204-61] Pipelining function 'Mean_Buf_ITP_Shift_U'.
WARNING: [SCHED 204-68] Unable to enforce a carried dependence constraint (II = 1, distance = 1, offset = 1)
between 'store' operation (ExtraProc.cpp:924) of variable 'Mean_Buf_ITP_load_1_s', ExtraProc.cpp:924 on array 'Mean_Buf_ITP_1_0' and 'load' operation ('Mean_Buf_ITP_1_0_l', ExtraProc.cpp:924) on array 'Mean_Buf_ITP_1_0'.
INFO: [SCHED 204-61] Pipelining result : Target II = 1, Final II = 2, Depth = 9.

....

INFO: [SCHED 204-61] Pipelining function 'Mean_ITP'.
WARNING: [SCHED 204-69] Unable to schedule 'load' operation ('Mean_Buf_ITP_1_0_loa_5', ExtraProc.cpp:977) on array 'Mean_Buf_ITP_1_0' due to limited memory ports. Please consider using a memory core with more ports or partitioning the array 'Mean_Buf_ITP_1_0'.
WARNING: [SCHED 204-69] Unable to schedule 'load' operation ('Mean_Buf_ITP_1_7_loa', ExtraProc.cpp:977) on array 'Mean_Buf_ITP_1_7' due to limited memory ports. Please consider using a memory core with more ports or partitioning the array 'Mean_Buf_ITP_1_7'.
WARNING: [SCHED 204-69] Unable to schedule 'store' operation (ExtraProc.cpp:982) of variable 'ITP_3_4_4', ExtraProc.cpp:979 on array 'ITP_Window' due to limited memory ports. Please consider using a memory core with more ports or partitioning the array 'ITP_Window'.
INFO: [SCHED 204-61] Pipelining result : Target II = 1, Final II = 25, Depth = 46.

==========================================================================================

0 Kudos
u4223374
Advisor
Advisor
759 Views
Registered: ‎04-26-2015

The first one is a dependence limitation - HLS can't be sure that you're not going to read from one location on the cycle after you wrote to that location. Because BRAM takes an extra cycle to actually do the write, if this occurs then the read will get "old" data from the BRAM.You can tell HLS to assume that it's not going to happen (with the DEPENDENCE pragma) but only if you're sure that it really won't happen.

 

The complaints about limited memory ports suggest that you've got a pragma trying to pipeline the whole Mean_ITW function. Have a look for that - if you're calling Mean_ITW in a loop then the pragma is probably in that loop too.

0 Kudos