经过一段长时间的手动调整和半自动调试后,我终于找到了内核崩溃的原因。是不是你不能在内核中制作一个for循环太长时间? 这是最小完整和可验证的代码: 错误是:未指定的启动失败
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
#include <stdio.h>
using namespace std;
typedef unsigned char uchar;
struct NodePointer {
int id;
uchar dist;
int idintree;
NodePointer() :id(0), dist(0), idintree(-1){}
};
struct TreeNode {
NodePointer father;
NodePointer children[4];
int id;
int childrenNum;
int idintree;
TreeNode() :id(0), childrenNum(0), idintree(-1){}
};
__global__ void
kernel4(int NumTN, TreeNode* tempthistree, int size)
{
int index = blockIdx.x*blockDim.x + threadIdx.x;
if (index < NumTN)
{
for (int i = 0; i < size; i++)
{
TreeNode node1 = tempthistree[i];
printf(" node %d in tree %d, its id in tree is %d, its child num is %d\n", i, index, node1.idintree, node1.childrenNum);
}
}
}
int main()
{
int n1 = 33417;
TreeNode * testtree;
cudaMallocManaged(&testtree, n1*sizeof(TreeNode));
for (int i = 0; i < n1; i++)
{
TreeNode c;
c.idintree = i;
c.id = i;
c.father.id = i - 1;
c.father.dist = 1;
c.childrenNum = i % 4;
int aaa = i % 4;
for (int j = 0; j < 4; j++)
{
c.children[j].dist = j;
c.children[j].id = 1;
c.children[j].idintree = 10;
}
testtree[i] = c;
}
kernel4 << <1, 1 >> >(4000, testtree, n1);
cudaDeviceSynchronize();
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess)
{
printf("Kernel3 error :%s\n", cudaGetErrorString(err));
system("pause");
}
}
答案 0 :(得分:0)
假设您使用的是Windows,可能会遇到超时检测和恢复问题,这意味着您的内核执行时间过长。
看到这个答案: C++: Simple CUDA volume reconstruction code crashing
答案 1 :(得分:0)
首先,内核调用:kernel4 << <1, 1 >> >(4000, testtree, n1)
您正在使用1个块,只有1个线程。所以你的索引只在这里变为0。您正在为此线程提供以下任务:CPU,请执行for循环。所以那里没有并行性。
你可以在内核中使用for循环,但我建议你把它放在外面。至少在这里有可能:
__global__ void
kernel4(int NumTN, TreeNode* tempthistree, int size)
{
int index = blockIdx.x*blockDim.x + threadIdx.x;
for (int i=0;i<NumTN;i++)
{
if (index < size)
{
TreeNode node1 = tempthistree[index];
printf("node %d in tree %d, its id in tree is %d, its child num is %d\n", index, i, node1.idintree, node1.childrenNum);
}
}
}
现在你需要更多的线程,n1最小。在一个块中有1024个线程(现在)的限制,因此您需要更多的块才能达到n1。例如ceil(n1 / 1024)块。
另外,我在C中不确定,但在结构中使用数组时要小心。尝试使用内存传输的简短示例,看看你是否得到了正确的答案(我在使用fortran时遇到了一些问题)。
PS:还要检查你的计算能力:printf仅适用于计算能力> = 2.0的GPU。