I have this function "cost_compare" that I would like to offload on FPGA for some experimental purposes. This function, how it is called and its arguments are as follows.
The synthesis tool doesn't accept double pointers as arguments for HW functions (in fact it is very picky about using pointers especially to data structures).
How do I get rid of the pointers in the function argument list? In other words, how do I convert pointers in this example to values? How does this possible solution affect the call by reference performed by spec_qsort?
Thanks in advance Hooman
typedef struct arc *arc_p;
typedef LONG cost_t;
typedef struct basket
{
arc_t *a;
cost_t cost;
cost_t abs_cost;
LONG number;
} BASKET;
/* ... */
typedef struct arc
{
int id;
cost_t cost;
node_p tail, head;
short ident;
arc_p nextout, nextin;
flow_t flow;
cost_t org_cost;
} arc;
/* ... */
extern int cost_compare( BASKET **b1, BASKET **b2 );
/* ... */
int cost_compare( BASKET **b1, BASKET **b2 )
{
if( (*b1)->abs_cost < (*b2)->abs_cost )
return 1;
if( (*b1)->abs_cost > (*b2)->abs_cost )
return -1;
if( (*b1)->a->id > (*b2)->a->id )
return 1;
else
return -1;
}
/* ... */
spec_qsort(perm + 1, basket_sizes[thread], sizeof(BASKET*),
(int (*)(const void *, const void *))cost_compare);
/* ... */
BASKET* max, *act;
for (j = 1; j < num_threads; j++) {
act = *perm_p[j];
if (act->number >= 0) {
if (!max || cost_compare(&act, &max) < 0) {
max = act;
max_pos = j;
}
}
/* ... */
BASKET* max_basket;
static BASKET **opt_basket;
for (i = 0; i< num_threads; i++) {
if ((!max_basket && opt_basket[i]) || (opt_basket[i] &&
cost_compare(&opt_basket[i], &max_basket) < 0)) {
max_basket = opt_basket[i];
}
}
/* ... */
=========================================
Thanks @Gerardo Zinno. When I run in SW, your approach (in the last paragraph) works fine. However, when I synthesis 'cost_compare' on FPGA using Xilinx SDSoC, it only works for
if(b1->abs_cost < b2->abs_cost)
but not for
if( b1->a->id > b2->a->id )
and the tools gives me this error:
ERROR: [SYNCHK 200-61] /home/a1083898/Xilinx_examples/original_routeplanning/src/pbeampp.c:85: unsupported memory access on variable 'x' which is (or contains) an array with unknown size at compile time.
ERROR: [SYNCHK 200-41] /home/a1083898/Xilinx_examples/original_routeplanning/src/pbeampp.c:89: unsupported pointer reinterpretation from type 'i8*' to type '%struct.arc.1.4.6 = type { i32, i64, %struct.node.0.3.5*, %s...' on variable 'x'.
ERROR: [SYNCHK 200-11] /home/a1083898/Xilinx_examples/original_routeplanning/src/pbeampp.c:89: Argument 'x' has an unsynthesizable type 'i8*' (possible cause(s): pointer to pointer or global pointer).
ERROR: [SYNCHK 200-11] /home/a1083898/Xilinx_examples/original_routeplanning/src/pbeampp.c:89: Argument 'x' has an unsynthesizable type 'i8*' (possible cause(s): structure variable cannot be decomposed due to (1) unsupported type conversion; (2) memory copy operation; (3) function pointer used in struct; (4) unsupported pointer comparison).'
Also when called by 'qsort' as
qsort(perm + 1, basket_sizes[thread], sizeof(BASKET*), cost_compare);
I receive this warning:
warning: incompatible pointer types passing 'int (void *, void *)' to parameter of type '__compar_fn_t' (aka 'int (*)(const void *, const void *)') [-Wincompatible-pointer-types]
I know this error has nothing to do with C programming but if there is any way to get rid of 'b1->a->id' and 'b2->a->id', I believe the problem could be solved with the HW synthesis tool.
Kind regards Hooman