I am writing a C program where I operate nested for
loops, one within another, as follows:
for(i[0] = 0; i[0] < n[0]; i[0]++)
for(i[1] = 0; i[1] < n[1]; i[1]++)
for(i[2] = 0; i[2] < n[2]; i[2]++)
{
do_lot_of_work(i, n, 3);
}
As you can see, the above code has three nested for
loops. In my program, it accounts for 3 dimensions. However, I want to make my program expandable, which can account of any number of dimensions, on the fly, as the user wishes; i.e. for 4 dimensions, I wish to have four nested for
loops, and do the work as do_lot_of_work(i,n,4)
. Similarly, for any number of dimensions.
My question is: how to make the aforementioned nesting of for
loops expandable?
Please note that, in order to achieve the goal, I am willing to sacrifice the inner for
loops, but wish to keep the first for
loop, in order to make my program parallel with OpenMP.
When the nesting level is not known at compile time, use recursion to achieve the same effect:
void do_work(int i[], int n[], int pos, int size) {
if (pos == size) {
// All i-s are set - we are ready to roll
do_lot_of_work(i, n, size);
} else {
for (i[pos] = 0 ; i[pos] < n[pos] ; i[pos]++) {
do_work(i, n, pos+1, size);
}
}
}
Use a recursive function.
void tons_of_work( int i[], int n[], int dims ) {
loop_level( 0, i, n, dims );
}
void loop_level( int level, int i[], int n[], int dims ) {
if ( level == dims ) {
do_lot_of_work( i, n, dims );
} else {
int * ilevel = & i[ level ];
for ( *ilevel = 0; *ilevel != n[ level ]; ++ *ilevel ) {
loop_level( level + 1, i, n, dims );
}
}
}
loop_level
calls itself to produce nested loops, until the innermost loop level is reached. Then it starts to do "real" work instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With