currently I am trying to implement GRAMPC on an FPGA for the Crazyflie (Quadrotor), by using High-Level Synthesis.
I have already read the other posts on embedded implementations (using CFLAG -DFIXEDSIZE etc.).
However I am receiving an linker error:
Error in llvm-link
while executing
"source C:/Users/usr/AppData/Roaming/Xilinx/Vitis/test090903/solution1/csynth.tcl"
invoked from within
"hls::main C:/Users/usr/AppData/Roaming/Xilinx/Vitis/test090903/solution1/csynth.tcl"
("uplevel" body line 1)
invoked from within
"uplevel 1 hls::main {*}$newargs"
(procedure "hls_proc" line 16)
invoked from within
"hls_proc [info nameofexecutable] $argv"
I am aware of the fact that the authors are not experts in the field of HLS however maybe you still have thoughts on the issue.
Best regards
Haig Conti Georges Sajelian
Technical University of Darmstadt
Self-Organizing Systems Lab
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think that you have not posted the complete error message of the linker. A linker error typically includes something like "undefined reference to function ..." or "multiple definition of ...", where the name of the function is an important hint on how to fix the error. A common reason for such linker errors is that not all relevant source or library files are included in the linking process.
Best regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sadly (unless I am missing some hidden errors), this should be the whole error message that is produced (see attachments).
In addition the Console is issuing a lot of warnings about unused parameters in the problem_description.hpp, probfct_QUADROTOR.c. and some other files. Maybe the problem lies there?
Another thing that might be an issue is the usage of any kind of print function or data read/write. I have undefined PRINTRES in the main and tried to comment out all the print related functions, however maybe I am missing some spots. Is there a "bare bone" GRAMPC version with no error prints etc. ?
I have read a paper about the implementation of GRAMPC via HLS and they talk about a wrapper that they used to make the GRAMPC C code work in HLS. The relevant paragraphs are these two:
"The available code can be compiled for microcontrollers with minor changes. However, for FPGA, standard C functions are not directly synthesizable. In this work, we developed C wrapper to transform the original GRAMPC C code to the synthesizable HLS code for the
Xilinx FPGA board."
"The developed wrapper statically defines the initialization parameters to avoid dynamic memory allocation. Library functions of C are replaced with inline functions while making necessary changes in some of the other functions. The wrapper eliminates all generalized functions by transforming the code into problem specific version, e.g., having a choice of integrator at run time does not work with FPGA the way it works with microcontrollers. Thus the code executes with pre-defined options."
I concluded that with the 2.2 update (introducing static memory usage) this wrapper was not needed anymore, but maybe this is still the case. Sadly, their wrapper is nowhere to be found on the internet. However I am still hoping that I am doing a "dumb" mistake...
Thank you for committing your time to my issue.
Best regards
Haig Conti Georges Sajelian
Technical University of Darmstadt
Self-Organizing Systems Lab
Sadly (unless I am missing some hidden errors), this should be the whole error message that is produced (see attachments).
Maybe there is some option (like --verbose) that can be activated to get more detailed error messages?
In addition the Console is issuing a lot of warnings about unused parameters in the problem_description.hpp, probfct_QUADROTOR.c. and some other files. Maybe the problem lies there?
Unused parameters do not lead to linker errors, so this should not be the problem.
Another thing that might be an issue is the usage of any kind of print function or data read/write. I have undefined PRINTRES in the main and tried to comment out all the print related functions, however maybe I am missing some spots. Is there a "bare bone" GRAMPC version with no error prints etc. ?
This could be the issue. The print-related functions are located in grampc_mess.h where you could modify lines 99-102 and redefine the macros appropriately.
However, for FPGA, standard C functions are not directly synthesizable
While not many, there are some spots where standard C functions are used. In grampc_macro.h you can find macros for sqrt(...) and pow(...) which you would need to redefine. A quick way would be to remove all includes of C standard headers (stdlib.h, stdio.h, math.h, string.h) and then work through the compiler errors. In most cases, you should be able to simply remove/comment the respective lines, since the core algorithm in grampc_run.c does not require them.
I concluded that with the 2.2 update (introducing static memory usage) this wrapper was not needed anymore, but maybe this is still the case.
The fixedsize-option that was in introduced in 2.2 addresses only the problem of missing dynamic memory allocation, but does not remove the dependencies on some standard C functions. But this could be a nice addition for version 2.3.
Best regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have run some tests in a seperate test-case and concluded that the usage of "math.h"-Macros in the grampc_macro.h should not be a problem as they seem to be supported natively.
Functions such as "printf()" shouldn't cause any problems as well. They will just be ignored by the synthesis.
I have found no option to increase the information on errors, only one to decrease it.
I still think GRAMPC is the right fit for our study case, however, my time available for this project is beginning to run out but maybe my successor will find the solution to the problem.
Best regards
Haig Conti Georges Sajelian
Technical University of Darmstadt
Self-Organizing Systems Lab
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
if I understand you correctly, using functions from stdlib.h, stdio.h, math.h and string.h is not a problem, because the HLS generates appropriate code, right?
I have seen in your list of warnings that you have included the file problem_description.hpp from GRAMPC's C++ interface. This could be the reason for the linker error if you compile the C++ interface together with the probfct_QUADROTOR.c since then you have two implementations of the probfct interface (one in probfct_QUADROTOR.c and one in problem_description.cpp). If you use a standard C example, you should not include cpp/grampc.hpp, cpp/problem_description.hpp as well as compile&link cpp/grampc.cpp and cpp/problem_description.cpp.
Best regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
if "indirect function calls" also includes the usage of function pointers, then there are some spots in GRAMPC that need to be modified:
- function evaluate_sys in grampc_run.c (line 595) to directly call the integrator
- function evaluate_adjsys in grampc_run.c (line 625) to directly call the integrator
- function evaluate_cost in grampc_run.c (line 1262) to directly call the integrator
None of these is difficult to change, since the usage of function pointers is not strictly needed here.
Best regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Greetings all,
currently I am trying to implement GRAMPC on an FPGA for the Crazyflie (Quadrotor), by using High-Level Synthesis.
I have already read the other posts on embedded implementations (using CFLAG -DFIXEDSIZE etc.).
However I am receiving an linker error:
Error in llvm-link
while executing
"source C:/Users/usr/AppData/Roaming/Xilinx/Vitis/test090903/solution1/csynth.tcl"
invoked from within
"hls::main C:/Users/usr/AppData/Roaming/Xilinx/Vitis/test090903/solution1/csynth.tcl"
("uplevel" body line 1)
invoked from within
"uplevel 1 hls::main {*}$newargs"
(procedure "hls_proc" line 16)
invoked from within
"hls_proc [info nameofexecutable] $argv"
I am aware of the fact that the authors are not experts in the field of HLS however maybe you still have thoughts on the issue.
Best regards
Haig Conti Georges Sajelian
Technical University of Darmstadt
Self-Organizing Systems Lab
Dear Haig,
I think that you have not posted the complete error message of the linker. A linker error typically includes something like "undefined reference to function ..." or "multiple definition of ...", where the name of the function is an important hint on how to fix the error. A common reason for such linker errors is that not all relevant source or library files are included in the linking process.
Best regards,
Andreas Völz
Dear Andreas Völz,
thank you for replying so fast.
Sadly (unless I am missing some hidden errors), this should be the whole error message that is produced (see attachments).
In addition the Console is issuing a lot of warnings about unused parameters in the problem_description.hpp, probfct_QUADROTOR.c. and some other files. Maybe the problem lies there?
Another thing that might be an issue is the usage of any kind of print function or data read/write. I have undefined PRINTRES in the main and tried to comment out all the print related functions, however maybe I am missing some spots. Is there a "bare bone" GRAMPC version with no error prints etc. ?
I have read a paper about the implementation of GRAMPC via HLS and they talk about a wrapper that they used to make the GRAMPC C code work in HLS. The relevant paragraphs are these two:
"The available code can be compiled for microcontrollers with minor changes. However, for FPGA, standard C functions are not directly synthesizable. In this work, we developed C wrapper to transform the original GRAMPC C code to the synthesizable HLS code for the
Xilinx FPGA board."
"The developed wrapper statically defines the initialization parameters to avoid dynamic memory allocation. Library functions of C are replaced with inline functions while making necessary changes in some of the other functions. The wrapper eliminates all generalized functions by transforming the code into problem specific version, e.g., having a choice of integrator at run time does not work with FPGA the way it works with microcontrollers. Thus the code executes with pre-defined options."
I concluded that with the 2.2 update (introducing static memory usage) this wrapper was not needed anymore, but maybe this is still the case. Sadly, their wrapper is nowhere to be found on the internet. However I am still hoping that I am doing a "dumb" mistake...
Thank you for committing your time to my issue.
Best regards
Haig Conti Georges Sajelian
Technical University of Darmstadt
Self-Organizing Systems Lab
Dear Haig,
Maybe there is some option (like --verbose) that can be activated to get more detailed error messages?
Unused parameters do not lead to linker errors, so this should not be the problem.
This could be the issue. The print-related functions are located in grampc_mess.h where you could modify lines 99-102 and redefine the macros appropriately.
While not many, there are some spots where standard C functions are used. In grampc_macro.h you can find macros for sqrt(...) and pow(...) which you would need to redefine. A quick way would be to remove all includes of C standard headers (stdlib.h, stdio.h, math.h, string.h) and then work through the compiler errors. In most cases, you should be able to simply remove/comment the respective lines, since the core algorithm in grampc_run.c does not require them.
The fixedsize-option that was in introduced in 2.2 addresses only the problem of missing dynamic memory allocation, but does not remove the dependencies on some standard C functions. But this could be a nice addition for version 2.3.
Best regards,
Andreas Völz
Dear Andreas Völz,
I have run some tests in a seperate test-case and concluded that the usage of "math.h"-Macros in the grampc_macro.h should not be a problem as they seem to be supported natively.
Functions such as "printf()" shouldn't cause any problems as well. They will just be ignored by the synthesis.
I have found no option to increase the information on errors, only one to decrease it.
I still think GRAMPC is the right fit for our study case, however, my time available for this project is beginning to run out but maybe my successor will find the solution to the problem.
Best regards
Haig Conti Georges Sajelian
Technical University of Darmstadt
Self-Organizing Systems Lab
Dear Haig,
if I understand you correctly, using functions from stdlib.h, stdio.h, math.h and string.h is not a problem, because the HLS generates appropriate code, right?
I have seen in your list of warnings that you have included the file problem_description.hpp from GRAMPC's C++ interface. This could be the reason for the linker error if you compile the C++ interface together with the probfct_QUADROTOR.c since then you have two implementations of the probfct interface (one in probfct_QUADROTOR.c and one in problem_description.cpp). If you use a standard C example, you should not include cpp/grampc.hpp, cpp/problem_description.hpp as well as compile&link cpp/grampc.cpp and cpp/problem_description.cpp.
Best regards,
Andreas Völz
Dear Andreas Völz,
Excluding all cpp/hpp-files removed the linker error and the synthesis started. Thank you for noticing that mistake!
Now the "fun" begins: all indirect/virtual function calls are not supported by the synthesis...
These problems are however out of the GRAMPC scope as they are only synthesis related.
I thank you for all the help!
Best regards
Haig Conti Georges Sajelian
Technical University of Darmstadt
Self-Organizing Systems Lab
Dear Haig,
if "indirect function calls" also includes the usage of function pointers, then there are some spots in GRAMPC that need to be modified:
- function evaluate_sys in grampc_run.c (line 595) to directly call the integrator
- function evaluate_adjsys in grampc_run.c (line 625) to directly call the integrator
- function evaluate_cost in grampc_run.c (line 1262) to directly call the integrator
None of these is difficult to change, since the usage of function pointers is not strictly needed here.
Best regards,
Andreas Völz