2

I am trying to tell my compiler to unroll a loop for me using #pragma unroll. However, the number of iterations is determined by a compile-time variable, so the loop needs to be unrolled that many times. Like this:

#define ITEMS 4

#pragma unroll (ITEMS + 1)
for (unsigned int ii = 0; ii <= ITEMS; ++ii) 
    /* do something */;

The compiler doesn't like this, though, as it gives me the following warning: warning: extra characters in the unroll pragma (expected a single positive integer), ignoring pragma for this loop. I understand what this means, of course: it wants a single integer rather than an expression. Is there a way to do this, though, without changing the unroll parameter every time I change ITEMS?

The compiler I am using is CUDA's NVCC compiler.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
Yellow
  • 3,955
  • 6
  • 45
  • 74
  • Would it work with `#define ITEMS 5` and `#pragma unroll ITEMS`, then `for(..., ii < ITEMS; ...)`? – Daniel Fischer Jun 04 '13 at 11:06
  • Yes, that would work, except for the fact that `ITEMS` is used in many more places throughout my code, and it would be odd to define it as one too many. What I also tried is `#define ITEMS_PLUS_ONE (ITEMS + 1)` but this gives the same 'extra characters' warning. – Yellow Jun 04 '13 at 11:12
  • `#define ITEMS_PLUS_ONE 5` and `#define ITEMS (ITEMS_PLUS_ONE - 1)`? (If it works, an ugly workaround is better than nothing.) – Daniel Fischer Jun 04 '13 at 11:14
  • Haha, that's a funny one. Yes that would work indeed and would be a not-so-elegant-yet-efficient work-around. :-) I'll work with that for now. But I guess I am looking for a more general answer, if there is another trick to get the compiler to read expression in this pragma. – Yellow Jun 04 '13 at 11:18
  • 1
    Yes, a nicer solution would sure be nice. But I have no good idea how to make the preprocessor compute `ITEMS + 1` so that the pragma gets the single integer it wants, so ugly workaround is the best I can offer. – Daniel Fischer Jun 04 '13 at 11:22

1 Answers1

2

You could do it the other way around:

Note: Just noticed Daniel Fischer's comment, which suggests exactly the same, before me.

#define ITEMS_PLUS_ONE 5
#define ITEMS (ITEMS_PLUS_ONE - 1)

The issue is that the preprocessor doesn't do math. It only does copy&paste.
When you write #define ITEMS_PLUS_ONE (ITEMS + 1), unroll is replaced with (4 + 1), not with 5.
Once this reaches the compiler, it doesn't matter. Even without optimization, the calculation is done during compilation, and (4 + 1) is exactly the same as 5.
But in your compiler, #pragma unroll is processed before compilation, and wants the simple number.

ugoren
  • 16,023
  • 3
  • 35
  • 65
  • That makes sense, thanks. So in other words: there is no way to do this in a not-work-around way, since the preprocessor cannot do math, right? – Yellow Jun 04 '13 at 14:24
  • 1
    @Jelle, right. Some compilers accept `#pragma unroll` with an expression, your compiler doesn't. Since it doesn't, you're stuck - the preprocessor surely can't do math. – ugoren Jun 04 '13 at 18:42