UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer andrea_2202
Observer
4,297 Views
Registered: ‎05-29-2017

SDSOC pragma HLS array partitioning error

Jump to solution

Hi everyone,

I'm tring to apply the array partitioning pragma using SDSOC but i receive an error.

My code is this:

 

void spmv(DTYPE matrix_val[NNZ], DTYPE vector[V_SIZE])

#pragma HLS ARRAY_PARTITION variable = matrix_val     cyclic      factor=E
#pragma HLS ARRAY_PARTITION variable = vector         cyclic      factor=E

 

Unfortunatly despite HLS complete correctly the syntesis, SDSOC build stop because this error:

 

            [SDSoC ERROR 0-0] The argument 'matrix_val' of the Vivado HLS function 'spmv' has been partitioned with an #pragma HLS or directive, which is disallowed.  Within a hardware function you must copy arguments into local variables that can then be partitioned for parallel access.

 

Why SDSoc is not able to apply the ARRAY_PARTITION pragma to a parameter of a function?

Why this problem there isn't in HLS?
       

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
Observer wsun
Observer
6,538 Views
Registered: ‎05-26-2016

Re: SDSOC pragma HLS array partitioning error

Jump to solution

If your memory is too big to fit on the FPGA, array partitioning won't help you. You can use the zero_copy pragma. Notice you will lose performance that way. But you can buffer up some memory on the FPGA and partition the buffer to make up some performance.

 

 

View solution in original post

0 Kudos
10 Replies
Observer wsun
Observer
4,082 Views
Registered: ‎05-26-2016

Re: SDSOC pragma HLS array partitioning error

Jump to solution

Because you are partitioning the array on the HW/SW interface. 

 

You can create a array inside the HW function and partition that array. Copy from the interface array to the internal array. Check out the samples/mmult_pipelined in your installation area for an example.

0 Kudos
Observer andrea_2202
Observer
4,073 Views
Registered: ‎05-29-2017

Re: SDSOC pragma HLS array partitioning error

Jump to solution

Hi @wsun,

thanks for your answer.

Unfortunatly, I can't.

The array that i'm trying to partitioning is too large and could not be copy into the FPGA.

Have you any suggestion on how can I fix it?

0 Kudos
Observer wsun
Observer
6,539 Views
Registered: ‎05-26-2016

Re: SDSOC pragma HLS array partitioning error

Jump to solution

If your memory is too big to fit on the FPGA, array partitioning won't help you. You can use the zero_copy pragma. Notice you will lose performance that way. But you can buffer up some memory on the FPGA and partition the buffer to make up some performance.

 

 

View solution in original post

0 Kudos
Observer andrea_2202
Observer
3,901 Views
Registered: ‎05-29-2017

Re: SDSOC pragma HLS array partitioning error

Jump to solution

The solution that I've found is to manually split the array into different arrays on ARM side.

I just build the same infrastructure that is generated by HLS but directly on sdsoc.

obviously it is less manageable because if I change the vector partition factor I have to manually add more vectors to the head of my function, but it works!

 

Thanks for the help!

0 Kudos
Visitor ljlukis
Visitor
3,551 Views
Registered: ‎10-30-2017

Re: SDSOC pragma HLS array partitioning error

Jump to solution

I have this same problem - which from what I see in this thread has not in fact been solved - somebody just found a work around. The function I am trying to implement in h/w:

 

 

void function(
 float cos_vals[48][100],
 float sin_vals[48][100],
 float pwr_vals[121][100])
{
 #pragma HLS array_partition variable=cos_vals block factor=12 dim=2
 for (int istep = 0; istep < NUM_RANGE_STEPS; istep++)
 {
  for (int beam_index = 0; beam_index < NUM_BEAMS; beam_index++)
  {
   float sb = 0, cb = 0;
   for (int ich = 0; ich < SIM_NUM_CHANNELS; ich++)
   {
    const float cos_beta = 0.1f;
    const float sin_beta = 0.2f;
    const float c = cos_vals[ich][istep];
    const float s = sin_vals[ich][istep];
    sb += s*cos_beta + c*sin_beta;
    cb += c*cos_beta - s*sin_beta;
   }
   float pwr = sb*sb + cb*cb;
   pwr_vals[beam_index][istep] = pwr;
  }
 }
}

The error, which I am getting with clean sdsoc build with Estimate Performace checked. Same as originally reported:

ERROR: [HLS2XD 83-102] The argument 'cos_vals' of the Vivado HLS function 'fpga_beamformer' has been partitioned with an #pragma HLS or directive, which is disallowed.  Within a hardware function you must copy arguments into local variables that can then be partitioned for parallel access. 

 

Somebody suggested maybe the arrays are too big. I calculate about 38kBytes for the cos_vals and sin_vals arrays plus around 48kBytes for the pwr_vals array which should fine for the XC7Z020 part on my ZC702 eval board.

 

In the "SDSoC Environment Optimization Guide" it has an example of function arguments with the same #pragma, which the error message says is not allowed. Also it says "The ARRAY_PARTITION directive might not be used on arrays which are internal to the function and not function arguments." Which seem to be the opposite of what the error message says you must do.

 

I'm new with all of this, but surely this seems not right.

 

0 Kudos
Explorer
Explorer
3,544 Views
Registered: ‎09-19-2017

Re: SDSOC pragma HLS array partitioning error

Jump to solution

Hi,

 

You have a different problem than this thread (which has an accepted solution). SDSoC doesn't support partitioning arrays on the interface of a function. When you do partition an array argument to a function, HLS splits the array into multiple separate interfaces on the generated IP (rather than one, that gets generated without the partitioning pragma). SDSoC doesn't currently support having multiple memory interfaces on the IP for the same argument of the function. 

 

If you want to partition the array, you'll have to copy the data from the unpartitioned argument, into a local variable completely inside your function. The matrix multiplication example template application for zc702 (or zcu102 or other platforms) has an example of this. 

 

Please start a new thread if you have any more problems since this thread already has an accepted solution.


Sam

0 Kudos
Visitor ljlukis
Visitor
3,540 Views
Registered: ‎10-30-2017

Re: SDSOC pragma HLS array partitioning error

Jump to solution
Hmmm. Thanks. Doesn't the SDSoC Environment Optimization Guide (UG1235 v2017.2) p45 show and say exactly the opposite?
0 Kudos
Explorer
Explorer
3,533 Views
Registered: ‎09-19-2017

Re: SDSOC pragma HLS array partitioning error

Jump to solution
You are exactly right. That guide is wrong. But still, don't put partition pragmas on function arguments ;-D

Sam
0 Kudos
Observer andrea_2202
Observer
3,509 Views
Registered: ‎05-29-2017

Re: SDSOC pragma HLS array partitioning error

Jump to solution

Hi @skalicky and @ljlukis,

the solution provided by @skalicky:

"If you want to partition the array, you'll have to copy the data from the unpartitioned argument, into a local variable completely inside your function"

 

unfortunatly is not always feasible. It depends on the amount of data you need to store while running the function.

Consider that a possible alternative solution(for example in my application it was not possible to save all the data internally) is to split the input array into multiple array in the same way done by HLS using pragma.

Using a CPU function you can preprocessing your stream and generate a multiple streams of vectors using a N plitting factor.

 

For example I moved from this implementation:

void fpgaFastMult(
        bool toBeUpdatedBuffer[MAXBUFFERSIZE/ E],
        DTYPE newValue[MAXBUFFERSIZE/ E],
        DTYPE rowVal[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE colVal[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE constantTermBuffer[MAXBUFFERSIZE/ E]
        ){

 

to this one with E=4

 

void fpgaFastMult(
        bool toBeUpdatedBuffer_1[MAXBUFFERSIZE/ E],
        bool toBeUpdatedBuffer_2[MAXBUFFERSIZE/ E],
        bool toBeUpdatedBuffer_3[MAXBUFFERSIZE/ E],
        bool toBeUpdatedBuffer_4[MAXBUFFERSIZE/ E],
        DTYPE newValue_1[MAXBUFFERSIZE/ E],
        DTYPE newValue_2[MAXBUFFERSIZE/ E],
        DTYPE newValue_3[MAXBUFFERSIZE/ E],
        DTYPE newValue_4[MAXBUFFERSIZE/ E],
        DTYPE rowVal_1[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE rowVal_2[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE rowVal_3[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE rowVal_4[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE colVal_1[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE colVal_2[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE colVal_3[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE colVal_4[MAXBUFFERSIZE * MAXROWBUFFER / E],
        DTYPE constantTermBuffer_1[MAXBUFFERSIZE/ E],
        DTYPE constantTermBuffer_2[MAXBUFFERSIZE/ E],
        DTYPE constantTermBuffer_3[MAXBUFFERSIZE/ E],
        DTYPE constantTermBuffer_4[MAXBUFFERSIZE/ E]
        ){

 

With this reorganization of the input array you are able to unroll and pipeline the loop with a factor of 4 in the same way that HLS pragma array partition cyclic factor=4 and get a II=1

 

Hope it can help.

 

Andrea

0 Kudos
Contributor
Contributor
255 Views
Registered: ‎07-25-2016

Re: SDSOC pragma HLS array partitioning error

Jump to solution

Hi,
Any update on this issue? I'm still facing a similar error in SDSoC 2018.3. I've created a new thread here: https://forums.xilinx.com/t5/SDSoC-Environment-and-reVISION/SDSoC-with-multidimensional-array-arguments/m-p/1027054/highlight/false

But it really seems that multiple ports are not yet supported in SDSoC.

BR,

Stefano

0 Kudos