简体   繁体   中英

CUDA code compile on Linux but not in Windows ( Visual Studio 2012)

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM