【发布时间】:2015-08-20 15:03:52
【问题描述】:
下面的程序对执行一些推力操作的“测试”函数进行了 3 次连续调用。这 3 个调用中的每一个都为问题提供了不同的大小:
- 第一次通话3,000;
- 第二次调用300,000,000;
- 第三次呼叫又是 3,000。
第二次调用预计会失败,但如果我正确清理了 GPU 的状态,第三次调用应该会成功(与第一次一样)。不幸的是,它也失败了。此外,连续调用也会导致失败,直到我退出进程并重新开始。
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <cuda.h>
#include <thrust/system_error.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <thrust/execution_policy.h>
#define CUDA_CALL(x)do { if((x) != cudaSuccess) { return -11;}} while(0)
typedef typename thrust::device_vector<size_t> tDevVecInt;
typedef typename thrust::device_vector<float> tDevVecFlt;
struct modSim : public thrust::unary_function<int, int>
{
int szMat;
int p;
modSim(int in1, int in2)
{
this->p = in1;
this->szMat = in2;
}
__host__ __device__ int operator()(const int &x)
{
return (x/szMat)*p+(x%p);
}
};
int test(size_t szData)
{
modSim moduloCol(3, 33);
CUDA_CALL(cudaSetDevice(0));
try
{
tDevVecFlt devRand(szData);
tDevVecInt devIndices(szData);
tDevVecFlt devData(szData);
thrust::sequence(devRand.begin(), devRand.end());
thrust::tabulate(devIndices.begin(), devIndices.end(), moduloCol);
thrust::sort_by_key(devIndices.begin(), devIndices.end(), devRand.begin());
}
catch(std::bad_alloc &e)
{
std::cout << e.what() << std::endl;
CUDA_CALL(cudaDeviceReset());
CUDA_CALL(cudaSetDevice(0));
return -3;
}
catch(thrust::system_error &e)
{
std::cout << e.what() << std::endl;
CUDA_CALL(cudaDeviceReset());
CUDA_CALL(cudaSetDevice(0));
return -2;
}
CUDA_CALL(cudaDeviceReset());
return 0;
}
int main(void)
{
size_t n;
int retVal;
n = 3000;
retVal = test(n);
std::cout << retVal << std::endl;
n = 300000000;
retVal = test(n);
std::cout << retVal << std::endl;
n = 3000;
retVal = test(n);
std::cout << retVal << std::endl;
return(0);
}
在我的设置中(Windows 8、NVIDIA GeForce 820m 和 2GB 专用 VRAM、使用 nvcc 编译的 CUDA 7.0,命令行是 "$nvcc -arch=compute_20 test.cu -run"),我得到这个:
- 第一次调用 N = 3,000 成功;
- 第二次调用 N = 300,000,000 失败,但
bad allocation: out of memory除外; - 第三次调用 N = 3,000 失败并返回
thrust::system error : after cub_::DeviceRadixSort::SortPairs(1): out of memory。
所以输出看起来像这样:
0
bad allocation: out of memory
-3
after cub_::DeviceRadixSort::SortPairs(1): out of memory
-2
如上所述,第三次调用不应失败,因为它与成功的第一次调用相同。
此失败似乎是上一次调用(发出bad alloc)的结果,但我在bad alloc 之后用cudaDeviceReset() 和cudaSetDevice() 清理了所有内容。
尽管有清洁说明,但设备并没有恢复到功能状态,我不明白为什么。
如果我做错了什么,在第一次失败后不结束我的进程的情况下,将 GPU 恢复到功能状态的正确方法是什么?
有人复制这个吗?
【问题讨论】:
-
我不明白你为什么要在你的内部使用指向此类向量的指针
testfunctions。尝试使用直接实例而不是带有实例的指针的代码。当您删除指向它们的指针时,可能没有调用向量析构函数 -
感谢您的评论。是的,这是以前测试的残余,我在您的 cmets 之后编辑了我的帖子,不幸的是,行为保持不变。