-2

I am working on CMake unit test cases that is using ctest.

I am having one question here.

Some part of my CMake is as below:

set(size_w   32  )
set(powerof2_w  5 )
foreach(size  ${size_w})
  foreach(pwr_of_2  ${powerof2_w})
    ...
    FUNCTION_EXE(${size} ${pwr_of_2})
  endforeach(pwr_of_2)
endforeach(size)

set(size_w   64  )
set(powerof2_w  6 )
foreach(size  ${size_w})
  foreach(pwr_of_2  ${powerof2_w})
    ...
    FUNCTION_EXE(${size} ${pwr_of_2})
  endforeach(pwr_of_2)
endforeach(size)

set(size_w   128  )
set(powerof2_w  7 )
foreach(size  ${size_w})
  foreach(pwr_of_2  ${powerof2_w})
    ...
    FUNCTION_EXE(${size} ${pwr_of_2})
  endforeach(pwr_of_2)
endforeach(size)

set(size_w   256  )
set(powerof2_w  8 )
foreach(size  ${size_w})
  foreach(pwr_of_2  ${powerof2_w})
    ...
    FUNCTION_EXE(${size} ${pwr_of_2})
  endforeach(pwr_of_2)
endforeach(size)

Expectation:

I want to reduce that one loop which is with powerof2_w parameter:

foreach(pwr_of_2  ${powerof2_w})

Is it possible to calculate the pwr_of_2 parameter from the size_w parameter inside the foreach(size ${size_w}) for-loop itself?

Note: Also, I want to combine all four of these for-loops into one for-loop using an array index.

Is this possible in CMake?

Kevin
  • 16,549
  • 8
  • 60
  • 74
jailaxmi k
  • 89
  • 3
  • 11
  • Can you please provide a more concrete example of the desired behavior? What is this *supposed* to do? Because the `size_w` and `powerof2_w` parameters are not *lists*, each loop will only have one iteration... – Kevin Feb 05 '20 at 14:42
  • Because of the limitation of sharing my data ,I would like to explain few things that the `size_w` is the width of my block . and in my code I am calculating the power_of_2 parameter.Its name different in my code.But I need to send that value from cmake only as I do not want to calculate that parameter in my source file . – jailaxmi k Feb 05 '20 at 14:47
  • Here `size_w` is changing from 32 ,64,128,256,512 ....so `powerof2_w` should be : 5,6,7,8,9 – jailaxmi k Feb 05 '20 at 14:49
  • @squareskittles,Is it possible to combine this (32 ,64,128,256,512) and (5,6,7,8,9 ) loop into one loop but with some condition check . – jailaxmi k Feb 05 '20 at 15:02
  • @squareskittles,but the pair (32 : 5 ) , (64:6) , (128:7) , (256:8) , (512:9) should go like this – jailaxmi k Feb 05 '20 at 15:05

1 Answers1

3

If I understand correctly, you are looking to calculate the exponential component for the powers of two for the given sizes:

32, 64, 128, 256, 512

These are powers of two with corresponding exponents of:

5, 6, 7, 8, 9

which we can calculate.

Unfortunately, CMake's math() function does not support exponential arithmetic. But luckily, powers of two are easy to manipulate using bit-shifting, which is supported in CMake. We can create a simple CMake function to calculate the (power of 2) exponents used to derive the sizes 32, 64, 128, etc.

function(calc_power_of_two_exponent num exponent)
    set(counter 0)
    # Shift until our number equals 1.
    while(num GREATER 1)
        # Right shift by 1
        math(EXPR num "${num} >> 1")
        # Count the number of times we shift.
        math(EXPR counter "${counter} + 1")
    endwhile()
    # Return the number of times shifted, which is the exponent.
    set(exponent ${counter} PARENT_SCOPE)
endfunction()

It looks like you want to iterate through these size and exponent values in pairs. We can set a list of sizes to iterate over, and calculate the corresponding exponent as we go.

set(sizes 32 64 128 256 512)

# Iterate through each size.
foreach(size ${sizes})
    # Call the function to calculate its base-2 power (or index).
    calc_power_of_two_exponent(${size} exponent)

    message(STATUS "${size} ${exponent}")
    FUNCTION_EXE(${size} ${exponent})
endforeach(size)

The status message can be used to confirm we pass the correct values to the FUNCTION_EXE function. This code prints:

32 5
64 6
128 7
256 8
512 9
Kevin
  • 16,549
  • 8
  • 60
  • 74