0

I'm developing a program that use CUDA developing toolkit version 10.1 and I'm using visual studio 2012. I'm working on windows but I share code with a linux user. All the code works fine on the two cases, except for some line of code that works on linux but not on windows. So every time I have to change these lines. I would avoid to do this and by the fact that on linux the code compile well, I think there are some reasons why on windows doesn't compile, but these reasons must be for sure not about the code but about some visual studio setting or similar. Can you help me? In particular the line of codes are:

int n_devices = 0;
cudaGetDeviceCount(&n_devices);
cudaDeviceProp props[n_devices];

On the last line i have the error:

error: expression must have a constant value

I can fix this error defining const int n_devices = 1; and commenting the function cudaGetDeviceCount(&n_devices);. It works because I already know the right number of devices but for sure is less right solution than the previous one.

The other problem is that I have a utils.cuh file in which there are defined two const value

const float PI = 3.141592654f;
const float EPS = 1e-3f;

I invoke this two values in the utils.cu file and at compile time i have the error:

error: "PI" is undefined in device code

error: "EPS" is undefined in device code

I can fix this declaring these two variables in this way:

#define PI 3.141592654f
#define EPS 1e-3f

So even if I can fix all the two problems I really want to leave the code in the first configuration (since it works on linux). Could be a problem related to compiler version? I really don't know which could be the reason.

talonmies
  • 70,661
  • 34
  • 192
  • 269
  • 1
    The first issue is described [here](https://stackoverflow.com/questions/5246900/enabling-vlas-variable-length-arrays-in-ms-visual-c), it has nothing to do with CUDA. – Robert Crovella Jul 10 '19 at 14:30
  • 1
    The second issue is an enumerated limitation of CUDA when used with microsoft host compiler, see [here](https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#const-variables). – Robert Crovella Jul 10 '19 at 14:34
  • 1
    The first issue is that your program is not standard C++, it's g++-only. Try passing the `-pedantic` and `-ansi` options when compiling on Linux to help you find these issues earlier. – Ben Voigt Jul 10 '19 at 16:20

1 Answers1

3

You won't be able to fix either of these problems just by changing compiler versions or anything like that.

The first issue is described here and here, it has nothing to do with CUDA except insofar as CUDA is making use of the host compiler. The code you have shown makes use of a VLA (variable length array) which is part of the C99 standard but not part of any C++ standard. CUDA is primarily implemented based on C++, and makes use of the C++ host compiler to compile host code, which is what you have shown. On windows it is using the Microsoft compiler for that. So the Microsoft compiler is correct to disallow VLA, and there is no way to avoid this AFAIK. Your code works on linux, because on linux nvcc uses the g++ host compiler, and it allows (in a non-standard-compliant way) the use of a VLA in C++ host code.

I don't know of any method to address this that doesn't involve some change to your code, for cross-platform compatibility. But a small amount of (C or) C++ programming skill can provide a solution for you that should work either on linux or windows:

int n_devices = 0;
cudaGetDeviceCount(&n_devices);
cudaDeviceProp *props = new cudaDeviceProp[n_devices];

(if you wanted to use a C compliant method, you could use malloc in a similar fashion)

The second issue is a limitation of CUDA, it is documented here.

There is also no method to address this cross-platform that I know of that involves no changes to your code.

You already have identified one possible workaround that can work in a cross-platform way both on linux and windows:

#define PI 3.141592654f
#define EPS 1e-3f
Robert Crovella
  • 143,785
  • 11
  • 213
  • 257
  • Your link for the first issue is about compiling C programs (where VLAs are allowed) with the Microsoft compiler. This question is about a C++ program, where there simply is no such thing as a VLA. – Ben Voigt Jul 10 '19 at 16:21
  • @BenVoigt I don't disagree, but on linux, [at least with gnu](https://stackoverflow.com/questions/39334435/variable-length-array-vla-in-c-compilers), the g++ compiler seems to allow the use of VLA even in a C++ program. And this is I suspect in part where OP's question is originating, because they are witnessing a VLA working on Linux when compiled with `nvcc`, which uses g++ under the hood for host code compilation,which is what is in view here. I will edit my answer to make a reference to this, but I don't think an extended discussion in this answer will add any clarity. – Robert Crovella Jul 10 '19 at 16:25
  • Your new link is better, because it reflects that this is not supposed to work, vs the first link saying it's a missing feature. – Ben Voigt Jul 10 '19 at 16:28
  • edited my answer, feel free to edit it if you want to try to explain it better. – Robert Crovella Jul 10 '19 at 16:47