cudaSetDevice

What’s the problem of cudaSetDevice with freopen? The following code snippet does not work, the cudaMallocHost call fails with “all CUDA-capable devices are busy or unavailable”. If I change the freopen to fopen, or set the device after closing the file, everything goes smooth.

Do I miss something or is this a bug?

int main(int argc,char *argv[])

{

  cudaError_t err;

  int *h_data,*g_data;

  FILE *fp;

cudaSetDevice(3);

  fp=freopen("test.txt","w",stdin);

  fprintf(fp,"Hello you!\n");

  fclose(fp);

err=cudaMallocHost((void **) &h_data, 1024*sizeof(int));

  printf("cudaMallocHost: %s\n",cudaGetErrorString(err));

  err=cudaMalloc((void **) &g_data, 1024*sizeof(int));

  printf("cudaMalloc:     %s\n",cudaGetErrorString(err));

memset(h_data,0,1024*sizeof(int));

  err=cudaMemcpy(g_data,h_data,1024*sizeof(int),cudaMemcpyHostToDevice);

  printf("cudaMemcpy:     %s\n",cudaGetErrorString(err));

err=cudaThreadExit();

  printf("cudaThreadExit: %s\n",cudaGetErrorString(err));

  exit(0);

}

Dunno if it is related or not, but are you sure opening stdin with a write mode is a wise idea?

Yeah, that’s a typo. Happens also with freopen(“test.dat”,“r”,stdin) and freopen(“test.dat”,“w”,stdout).

Doing fclose() on stdout doesn’t make any more sense if there is I/O afterwards which will try to write to it. You should never try closing or opening stdout, stdin or stderr in user code. That is likely to cause underlying libc problems which can lead to anything.

This works flawlessly (64 bit CUDA 3.2, Ubuntu 10.04 LTS):

avidday@cuda:~$ nvcc -Xptxas="-v" -Xcompiler="-Wall" -o bwalk bwalk.cu 

ptxas info    : Compiling entry function '__cuda_dummy_entry__' for 'sm_10'

ptxas info    : Used 0 registers

avidday@cuda:~$ ./bwalk 

avidday@cuda:~$ cat test.txt 

Hello you!

cudaMallocHost: no error

cudaMalloc:     no error

cudaMemcpy:     no error

cudaThreadExit: no error

avidday@cuda:~$ cat bwalk.cu 

#include <stdio.h>

int main(int argc,char *argv[])

{

  cudaError_t err;

  int *h_data,*g_data;

  FILE *fp;

cudaSetDevice(0);

  fp=freopen("test.txt","w+",stdout);

  fprintf(fp,"Hello you!\n");

  // fclose(fp);

err=cudaMallocHost((void **) &h_data, 1024*sizeof(int));

  printf("cudaMallocHost: %s\n",cudaGetErrorString(err));

  err=cudaMalloc((void **) &g_data, 1024*sizeof(int));

  printf("cudaMalloc:     %s\n",cudaGetErrorString(err));

memset(h_data,0,1024*sizeof(int));

  err=cudaMemcpy(g_data,h_data,1024*sizeof(int),cudaMemcpyHostToDevice);

printf("cudaMemcpy:     %s\n",cudaGetErrorString(err));

err=cudaThreadExit();

  printf("cudaThreadExit: %s\n",cudaGetErrorString(err));

  exit(0);

}

so all I can conclude is that you are doing something unreasonable to stdout or stdin in your code.