我正在构建CUDA加速的R包,我想用cuda-memcheck
进行调试。因此,在this minimal example(在deliberate_memory_leak
GitHub分支中),我通过注释掉对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
$
没有运气。然后我在R extensions manual中看到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
最后,
$ 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
$
是否可以让cuda-memcheck
适用于R套餐?我知道我以为我已经弄明白了here,但那时候,我并没有真正验证cuda-memcheck
给我的答案。
答案 0 :(得分:6)
这不是有效的CUDA代码:
extern "C" void someCUDAcode() {
int a;
CUDA_CALL(cudaMalloc((void**) &a, sizeof(int)));
mykernel<<<1, 1>>>(1);
// CUDA_CALL(cudaFree(&a));
}
当我们想要进行cudaMalloc
操作时,我们在C中使用指针,而不是普通变量,如下所示:
int *a;
CUDA_CALL(cudaMalloc((void**) &a, sizeof(int)));
当我们想要释放先前分配的指针时,我们只传递指针,而不是它的地址:
CUDA_CALL(cudaFree(a));
最后,cuda-memcheck(cuda-memcheck --help
)的命令行帮助表明:
- 泄密检查
<full|no>
[默认:否]打印CUDA分配的泄漏信息。
注意:程序必须以cudaDeviceReset()结束才能生效。
(类似的说明也在documentation中。)
我认为第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
$