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: 
Highlighted
Contributor
Contributor
341 Views
Registered: ‎07-25-2016

SDSoC with multidimensional array arguments

Hi everyone,

I'm not sure whether this is the right section of the forum since it's a problem more related to SDSoC. Anyway, I'm trying to design a component with multiple FIFO interfaces that can be read in parallel. The hardware function looks something like this:

// Copy Pragma, i.e. use DMAs
#pragma SDS data copy (x_port[0:NUM_INPUTS * INPUT_SIZE])
#pragma SDS data copy (w_port[0:NUM_W * W_SIZE])
#pragma SDS data copy (y_port[0:NUM_INPUTS * OUTPUT_SIZE])
// Memory attribute
#pragma SDS data mem_attribute (x_port:PHYSICAL_CONTIGUOUS)
#pragma SDS data mem_attribute (w_port:PHYSICAL_CONTIGUOUS)
#pragma SDS data mem_attribute (y_port:PHYSICAL_CONTIGUOUS)
// Specify DMAs type
#pragma SDS data data_mover (x_port:AXIDMA_SIMPLE)
#pragma SDS data data_mover (w_port:AXIDMA_SIMPLE)
#pragma SDS data data_mover (y_port:AXIDMA_SIMPLE)
void foo(const data_t x_port[NUM_INPUTS][INPUT_SIZE], const data_t w_port[NUM_W][W_SIZE], data_t y_port[NUM_INPUTS][OUTPUT_SIZE]) { #pragma HLS DATAFLOW #pragma HLS ARRAY_PARTITION variable=x_port complete dim=1 #pragma HLS ARRAY_PARTITION variable=w_port complete dim=1 #pragma HLS ARRAY_PARTITION variable=y_port complete dim=1 #pragma HLS INTERFACE ap_ctrl_chain port=return #pragma HLS INTERFACE ap_fifo port=x_port #pragma HLS INTERFACE ap_fifo port=w_port #pragma HLS INTERFACE ap_fifo port=y_port // ...

The HLS part runs flawlessly: the generated hardware component looks exactly how I wanted it to be.

Then in the caller function I do something like this (which might actually be a bad idea, I'm not super expert of C++):

// Overloading of new (and delete, not showed) operator:
void* operator new(size_t size) {
    void* p = sds_alloc(size);
    return p;
}

int main(int argc, char const *argv[]) {
  // ...

  auto x = new data_t[NUM_TESTS][NUM_INPUTS][INPUT_SIZE];
  auto w = new data_t[NUM_W][W_SIZE];
  auto y = new data_t[NUM_TESTS][NUM_INPUTS][OUTPUT_SIZE];

  for (int i = 0; i < NUM_TESTS; ++i) {
    foo(x[i], w, y[i]);
  }

  // ...

After the HLS synthesis, SDSoC "goes crazy" in the data motion network generation. In particular, throwing errors on not being able to find the ports for the SDSoC pragmas. The log shows indeed the function arguments of foo, listing however w_port0[32], w_port1[32]... notice the appended '0' and '1' in the name, coming from the partitioning in HLS, I assume. I also noticed that the name and the size of the ports is mismatching (notice the x_port listed twice first with [2][1024], correct, and then [14][2048], wrong: picking up the w_port values instead). Something similar to this:

WARNING: [DMAnalysis 83-4484] Cannot find argument w_port in accelerator function foo(const data_t x_port0[2][1024], const data_t x_port1[14][2048], const data_t w_port0[32][384], const data_t w_port1[2][32], const ap_uint<16> w_port2[32], const ap_uint<16> w_port3[32], data_t w_port4[2][512], , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ), please check SDS pragmas for foo
WARNING: [DMAnalysis 83-4484] Cannot find argument x_port in accelerator function foo(const data_t x_port0[2][1024], const data_t x_port1[14][2048], const data_t w_port0[32][384], const data_t w_port1[2][32], const ap_uint<16> w_port2[32], const ap_uint<16> w_port3[32], data_t w_port4[2][512], , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ), please check SDS pragmas for foo
WARNING: [DMAnalysis 83-4484] Cannot find argument y_port in accelerator function foo(const data_t x_port0[2][1024], const data_t x_port1[14][2048], const data_t w_port0[32][384], const data_t w_port1[2][32], const ap_uint<16> w_port2[32], const ap_uint<16> w_port3[32], data_t w_port4[2][512], , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ), please check SDS pragmas for foo
INFO: [DMAnalysis 83-4497] Analyzing callers to hardware accelerators...
opt: /scratch/builds/2018.3/continuous/2018_12_06_2405991/build/swig/products/sdx/soc/ext/llvm_clang/v3.9/llvm/lnx64/llvm/include/llvm/IR/CallSite.h:159: ValTy* llvm::CallSiteBase<FunTy, BBTy, ValTy, UserTy, UseTy, InstrTy, CallTy, InvokeTy, IterTy>::getArgument(unsigned int) const [with FunTy = llvm::Function; BBTy = llvm::BasicBlock; ValTy = llvm::Value; UserTy = llvm::User; UseTy = llvm::Use; InstrTy = llvm::Instruction; CallTy = llvm::CallInst; InvokeTy = llvm::InvokeInst; IterTy = llvm::Use*]: Assertion `arg_begin() + ArgNo < arg_end() && "Argument # out of range!"' failed.
#0 0x000000000129cef5 llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../llvm-clang/lnx64/llvm/bin/opt+0x129cef5)
#1 0x000000000129af1e llvm::sys::RunSignalHandlers() (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../llvm-clang/lnx64/llvm/bin/opt+0x129af1e)
#2 0x000000000129b042 SignalHandler(int) (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../llvm-clang/lnx64/llvm/bin/opt+0x129b042)
#3 0x00007f9bba32c890 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12890)
#4 0x00007f9bb8de0e97 gsignal /build/glibc-OTsEL5/glibc-2.27/signal/../sysdeps/unix/sysv/linux/raise.c:51:0
#5 0x00007f9bb8de2801 abort /build/glibc-OTsEL5/glibc-2.27/stdlib/abort.c:81:0
#6 0x00007f9bb8dd239a __assert_fail_base /build/glibc-OTsEL5/glibc-2.27/assert/assert.c:89:0
#7 0x00007f9bb8dd2412 (/lib/x86_64-linux-gnu/libc.so.6+0x30412)
#8 0x00007f9bb8a90cb4 (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../lib/lnx64.o/XidanePass.so+0x6acb4)
#9 0x00007f9bb8a71710 _init (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../lib/lnx64.o/XidanePass.so+0x4b710)
#10 0x00007f9bb8a88874 (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../lib/lnx64.o/XidanePass.so+0x62874)
#11 0x0000000000e86094 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../llvm-clang/lnx64/llvm/bin/opt+0xe86094)
#12 0x00000000005ff0a3 main (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../llvm-clang/lnx64/llvm/bin/opt+0x5ff0a3)
#13 0x00007f9bb8dc3b97 __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:344:0
#14 0x0000000000642e99 _start (/opt/Xilinx/SDSoC/SDx/2018.3/bin/../llvm-clang/lnx64/llvm/bin/opt+0x642e99)
Stack dump:
0.	Program arguments: /opt/Xilinx/SDSoC/SDx/2018.3/bin/../llvm-clang/lnx64/llvm/bin/opt -load /opt/Xilinx/SDSoC/SDx/2018.3/bin/../lib/lnx64.o/XidanePass.so -disable-output -mem2reg -basicaa -XidanePass --dmclkid 3 --repo /home/ste/phd/svd/hls/_sds/.cdb/xd_ip_db.xml --dmdb /opt/Xilinx/SDSoC/SDx/2018.3/data/DM.db -os linux -processor cortex-a53 -partition 0 
1.	Running pass 'Data motion analysis and network generation' on module '<stdin>'.
/opt/Xilinx/SDSoC/SDx/2018.3/bin/XidanePass: line 9:  3997 Aborted                 (core dumped) ${BIN_DIR}/../llvm-clang/lnx64/llvm/bin/opt -load ${BIN_DIR}/../lib/lnx64.o/XidanePass.so -disable-output -mem2reg -basicaa -XidanePass ${ARGS} < sds_all.o
XidanePass exited with return code -2
- exited unexpectedly
sds++ log file saved as /home/ste/phd/svd/hls/_sds/reports/sds.log
ERROR: [SdsCompiler 83-5004] Build failed
sds++ completed at Wed Oct 02 18:54:25 CEST 2019

If I remove the SDSoC pragmas, then similar errors show up at the same point (data motion generation), claiming that the mem_attribute for ports (with appended number) must be specified.

Any idea/workaround for this? Is it possible at all or shall I just wait for the next versions (I'm using SDSoC 2018.3)? It's gonna be kinda tiresome to manually specify all arguments separately, e.g. x0 x1 x2 w0 w1 and so on, and not really a portable solution for other design points.

Thank you for your time, BR,

Stefano

0 Kudos
7 Replies
334 Views
Registered: ‎07-23-2019

Re: SDSoC with multidimensional array arguments

No...

The new operator (even your overloaded one) takes the size (a number), you are providing an array. I would go mad as well, it could be generating a 3-D array of array spaces...

Do something like this, and forget about overloading, please, unless you create a truly new functionality

size_t matrix_size_bytes = sizeof(int) *NUM_TESTS * NUM_INPUTS * INPUT_SIZE; 
//Allocate memory:
int *in1 = (int *) sds_alloc(matrix_size_bytes);

 

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

Re: SDSoC with multidimensional array arguments

I know about it I and I truly believe it's the proper way of doing that. Overloading it's indeed a work around for calling that particular hardware function, which I need having multiple ports.

Maybe I'm unaware of other ways of modeling that hardware specification I need. 

Stefano 

0 Kudos
315 Views
Registered: ‎07-23-2019

Re: SDSoC with multidimensional array arguments

But your 'new' new operator is not taking a size_t argument to pass it to sds_alloc!

0 Kudos
307 Views
Registered: ‎07-23-2019

Re: SDSoC with multidimensional array arguments

Try at least:

auto x = new sizeof(data_t)*(NUM_TESTS * NUM_INPUTS * INPUT_SIZE);
0 Kudos
Contributor
Contributor
274 Views
Registered: ‎07-25-2016

Re: SDSoC with multidimensional array arguments

Hi again,

From some quick tests, it seems that the global new operator 'automatically calls' the sizeof operator, so having:

auto x_new = new data_t[M][N][K];
data_t* x_sds = (data_t*)sds_alloc(sizeof(data_t) * M * N * K);
// Both x_new and x_sds allocate the same amount.
// But I cannot pass x_sds to foo(), the compiler is obviously complaining.

allocates the proper amount of bytes in both cases. So I'm not sure whether this overloading is actually the root problem. Another thing I can try is to turn data_t into a class and overload its specific new operator (instead of having a global overloading).

 

Again, my main end goal is to have a way of using multiple ports in my hardware function, eventually modeling them through multidimensional arrays. And I highlight again that the problem arises at the data motion generation, in the logs, after this message shows up:

INFO: [DMAnalysis 83-4497] Analyzing callers to hardware accelerators...

Stefano

0 Kudos
237 Views
Registered: ‎07-23-2019

Re: SDSoC with multidimensional array arguments

oh man.... data_t is a type, right? shouldn't you use the actual variable (array) name instead?

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

Re: SDSoC with multidimensional array arguments

@archangel-lightworks  I don't understand your reply and we're going off topic.

I found I similar thread here: https://forums.xilinx.com/t5/SDSoC-Environment-and-reVISION/SDSOC-pragma-HLS-array-partitioning-error/td-p/781205 , where they report:

SDSoC doesn't currently support having multiple memory interfaces on the IP for the same argument of the function. 


Appartenly it might still be a feature not yet supported by SDSoC version 2018.3.

Stefano

0 Kudos