cuda-memcheck无法检测R包中的内存泄漏

lan*_*dau 0 valgrind memory-leaks cuda r

我正在构建CUDA加速的R包,我想调试cuda-memcheck.所以在这个最小的例子中(在deliberate_memory_leakGitHub分支中),我someCUDAcode.c通过注释掉必要的调用来创建内存泄漏cudaFree.然后,我看是否cuda-memcheck可以找到泄漏.

$ cuda-memcheck --leak-check full  Rscript -e 'library(rcppcuda); hello()'
========= CUDA-MEMCHECK
An object of class "MyClass"
Slot "x":
 [1]  1  2  3  4  5  6  7  8  9 10

Slot "y":
 [1]  1  2  3  4  5  6  7  8  9 10

[1] "Object changed."
An object of class "MyClass"
Slot "x":
 [1] 500   2   3   4   5   6   7   8   9  10

Slot "y":
 [1]    1 1000    3    4    5    6    7    8    9   10

========= LEAK SUMMARY: 0 bytes leaked in 0 allocations
========= ERROR SUMMARY: 0 errors
$
Run Code Online (Sandbox Code Playgroud)

没运气.然后我在R扩展手册中看到R -d "valgrind --tool=memcheck --leak-check=full" --vanilla < mypkg-Ex.R了正确的使用方法valgrind.所以我创建了一个test.R文件library(rcppcuda); hello()并尝试了这个.

R -d "cuda-memcheck --leak-check full" --vanilla < test.R
*** Further command line arguments ('--vanilla ') disregarded
*** (maybe use 'run --vanilla ' from *inside* cuda-memcheck --leak-check full)

========= CUDA-MEMCHECK
Fatal error: you must specify '--save', '--no-save' or '--vanilla'
========= LEAK SUMMARY: 0 bytes leaked in 0 allocations
========= ERROR SUMMARY: 0 errors
Run Code Online (Sandbox Code Playgroud)

最后,

$ cuda-memcheck --leak-check full R --vanilla < test.R
========= CUDA-MEMCHECK

R version 3.2.0 (2015-04-16) -- "Full of Ingredients"
Copyright (C) 2015 The R Foundation for Statistical Computing
Platform: x86_64-unknown-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> library(rcppcuda); hello()
An object of class "MyClass"
Slot "x":
 [1]  1  2  3  4  5  6  7  8  9 10

Slot "y":
 [1]  1  2  3  4  5  6  7  8  9 10

[1] "Object changed."
An object of class "MyClass"
Slot "x":
 [1] 500   2   3   4   5   6   7   8   9  10

Slot "y":
 [1]    1 1000    3    4    5    6    7    8    9   10

> 
========= LEAK SUMMARY: 0 bytes leaked in 0 allocations
========= ERROR SUMMARY: 0 errors
$
Run Code Online (Sandbox Code Playgroud)

是否可以cuda-memcheck为R包工作?我知道我以为我已经把它弄清楚,但那时候,我实际上并没有验证cuda-memcheck给我的答案.

Rob*_*lla 6

这不是有效的CUDA代码:

extern "C" void someCUDAcode() {
  int a;
  CUDA_CALL(cudaMalloc((void**) &a, sizeof(int)));
  mykernel<<<1, 1>>>(1);
//  CUDA_CALL(cudaFree(&a));
}
Run Code Online (Sandbox Code Playgroud)
  1. 当我们想要做一个cudaMalloc操作时,我们在C中使用指针,而不是普通的变量,如下所示:

      int *a;
      CUDA_CALL(cudaMalloc((void**) &a, sizeof(int)));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 当我们想要释放先前分配的指针时,我们只传递指针,而不是它的地址:

    CUDA_CALL(cudaFree(a));
    
    Run Code Online (Sandbox Code Playgroud)
  3. 最后,cuda-memcheck(cuda-memcheck --help)的命令行帮助指示:

    --leak-check <full|no>[默认:否]

    打印CUDA分配的泄漏信息.

    注意:程序必须以cudaDeviceReset()结束才能使用.

(类似的说明也在文档中.)

我认为第3项是代码中缺少的关键因素.对您的代码进行以下修改会为我生成适当的报告:

$ cat t786.cu
#include <stdio.h>

#define CUDA_CALL(x) {if((x) != cudaSuccess){ \
  printf("CUDA error at %s:%d\n",__FILE__,__LINE__); \
  printf("  %s\n", cudaGetErrorString(cudaGetLastError()));}}

__global__ void mykernel(int a){
  int id = threadIdx.x;
  int b = a;
  b++;
  id++;
}

int main() {
  int *a;
  CUDA_CALL(cudaMalloc((void**) &a, sizeof(int)));
  mykernel<<<1, 1>>>(1);
//  CUDA_CALL(cudaFree(a));
  cudaDeviceReset();
}
$ nvcc -o t786 t786.cu
$ cuda-memcheck --leak-check full ./t786
========= CUDA-MEMCHECK
========= Leaked 4 bytes at 0x402500000
=========     Saved host backtrace up to driver entry point at cudaMalloc time
=========     Host Frame:/lib64/libcuda.so.1 (cuMemAlloc_v2 + 0x17f) [0x13629f]
=========     Host Frame:./t786 [0x2dbb3]
=========     Host Frame:./t786 [0x610b]
=========     Host Frame:./t786 [0x3deaf]
=========     Host Frame:./t786 [0x2646]
=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf5) [0x21d65]
=========     Host Frame:./t786 [0x2539]
=========
========= LEAK SUMMARY: 4 bytes leaked in 1 allocations
========= ERROR SUMMARY: 0 errors
$
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`cudaDeviceReset()`消除了cuda上下文,这意味着设备的所有代码和数据都被无效,并且所有(设备)分配都被破坏.因此,您需要注意将它放在R项目中的确切位置.如果您的项目在退出时会调用例程,那么可能就是放置它的地方. (2认同)