最新帖子

页: [1] 2 3 ... 10
1
CUDA / Re: 不同CUDA 核函数之间的干扰问题
« 最后发表 作者 woaihb 九月 10, 2020, 10:51:06 am »
您好,
您可以稍微解释一下“初始化清0过程,这个是使用atomicAdd时候的一个常见要求”吗
我在进入kernel之前,通过cudaMemsetAsync(),将相关数组置零。

另:我在引入functionC()之前,使用atomicAdd()的这个kernel的计算时正常的,引入后functionA中atomicAdd的结果出现了负值(这是不符合逻辑的),所以我加入了一个if < 0的判断,用来debug;正如您建议的,直接使用atomicAdd的返回值进行判断,也是没有任何print信息,即没有负值。

另:在我提出问题的时间到现在,针对上述的问题,我偶然遇到了可以得到正常逻辑结果的方法:当我使用两块GPU计算时,functionC的运算结果是正确的,且没有影响到functionA的计算结果。(PS:上面讨论的所有情况都是基于4块GPU的问题)但是问题来了,完全相同的程序,使用4块GPU会出现上述问题,当只把程序中GPUNumber由4改成2后(确定其他参数全没有变)时,程序就运行正常了。
2
CUDA / Re: 在centos7下调用cudaGetDeviceCount 卡死问题
« 最后发表 作者 sisiy 九月 09, 2020, 01:17:00 pm »
获取cuda设备数量是基本操作(这个函数实际上就算你机器上没有显卡, 也能调用)

不清楚为何会卡死(我从来没见过有人在这个函数上卡死的)
3
CUDA / Re: pgi2020还会发布免费版本么?
« 最后发表 作者 sisiy 九月 09, 2020, 11:46:31 am »
建议在PGI官网论坛上问一下
4
CUDA / Re: 不同CUDA 核函数之间的干扰问题
« 最后发表 作者 屠戮人神 九月 09, 2020, 12:40:04 am »
问题:引入一个新的核函数后造成其他正常函数功能异常,且是连续多次运算中第一次运算正常,第二次运算结果开始异常(整个工程算一次运算,数据库增加一个条目算一次运算)

整个工程共有3个功能函数,三个核函数,对应关系分别如下
程序代码: [选择]
namespace spaceA
{
void functionA(const float* paraA);
void functionB(const float* paraB);
void functionC();

void functionA(const float* paraA, float* resultDataA)
{
    for(int i = 0; i < GPUNumber; i++)
    {
        cudaSetDevice(i);
        kernelA<<<Grid, Block, 0, stream[i]>>>(paraA, resultData);
    }
}

void functionB(const float* paraA)
{
    float* resultDataB;
    functionC(paraA, resultDataB);
    for(int i = 0; i < GPUNumber; i++)
    {
        cudaSetDevice(i);
        kernelB<<<Grid, Block, 0, stream[i]>>>(resultDataA, resultDataB);
    }
}

void functionC(const float* paraA, float* resultDataB)
{
    for(int i = 0; i < GPUNumber; i++)
    {
        cudaSetDevice(i);
        kernelC<<<Grid, Block, 0, stream[i]>>>(paraA, resultDataB);
    }
}   
} // namespace spaceA
/*
如上述所示:
原有工程为functionA and functionB, 工程程序运行正常;新开发functionC, functionC的计算结果用于functionB中,且functionC与functionA没有任何计算交集。
运算顺序为:functionA--> functionC-->functionB
(更改前的顺序为functionA--> functionB)
但是在测试加入functionC的程序时,发现如果单独执行一次运算,运算结果是正常的,但当继续执行第二次工程运算时,结果异常,经过对中间数据分析,发现数据异常的地方发生在functionA中,且在增加functionC时,并未对functionA进行任何的改动。
*/
程序代码: [选择]
static __global__ void kernelA(const float* paraA, float* resultDataA)
{
     int tid = blockDim.x * blockIdx.x + threadIdx.x;
      if (tid < threadNum)
      {
        for (int kk = 0; kk < Number; kk++)
        {
            int index = kk * binSum; // binSum是一常数,计算步骤省略了
            int currvoxelIndex = voxelIndex[index] + X; // X是一变量数值,计算步骤省略了

            if (currvoxelIndex < 0 || currvoxelIndex >= voxelNumber)
            {
                continue;
            }
            atomicAdd(&image[currvoxelIndex], mich * weight[index]);
            if(image[currvoxelIndex] < 0) //// mich and weight均为正数
            { //但是相乘的结果却出现负数
                printf("ERROR\n"); //但在这里打印结果,却没有出现负数
            } // 这样打印有问题吗
        }
      }
}

进一步阐述:

functionA的运算结果不应该有负值(kernelA中两个正数相乘不可能得出负值),加入functionC后,functionA的运算结果出现负值(如果将functionC注释掉,则没有负值),因此将functionA的所有中间数据打印,确定负值的具体位置,但是只有kernelA计算完成后将结果传回CPU后才出现负值,其他中间所有的数据,以及中间产生的数据都没有出现负值,在kernelA中的打印也没有出现负值。

你好,你的atomicAdd和普通load訪存讀取,并不能夠保持一致性。

atomicAdd(&image[currvoxelIndex], mich * weight[index]);
if(image[currvoxelIndex] < 0)   <----并不和上行atomicAdd保持一致性。

根據你的代碼,此處可能有2種含義:
(1)如果邏輯上,需要立刻判斷之前atomicAdd時候得到的值,直接使用atomicAdd()的返回值即可(注意返回的是沒有原子加法前的值,你可能需要手工模擬一下加法)。
(2)如果邏輯上,需要任意時刻得到image[currvoxelIndex]的值,請使用atomicAdd原子加上一個0值,來訪問當前值。

此外,如果你的這裏的if,只是爲了用來debug,即這行代碼本來就不存在,則:
我們沒有看到你的image[]中的元素得到任何初始化。雖然一定概率顯存中的值都是0,但也存在概率不是0. 任何代碼上的改動,分配時刻的變化,kernel調用的順序變化,均影響概率。

建議的解決方案:
請提供image[]的初始化清0過程,這個是使用atomicAdd時候的一個常見要求。

5
CUDA / Re: CUDA在图像细化处理
« 最后发表 作者 屠戮人神 九月 09, 2020, 12:23:47 am »
利用GPU做图像细化,效果和速度都可以,但是每次结果都有细微的差别
处理过程使用了共享内存,但是每次写内存都会同步线程,不知道问题出在哪里,每次结果不同是正常现象么

請你PO具體演算法,然後我們一起看下。光這樣說, 無法知道“結果不穩定”是否是正常的。有些演算法允許這樣,有得不允許,建議PO一下。
6
CUDA / CUDA在图像细化处理
« 最后发表 作者 Tsang 九月 07, 2020, 06:08:27 pm »
利用GPU做图像细化,效果和速度都可以,但是每次结果都有细微的差别
处理过程使用了共享内存,但是每次写内存都会同步线程,不知道问题出在哪里,每次结果不同是正常现象么
7
CUDA / Re: 给1000000个数,求第K大的数,这样的题目该怎么做啊
« 最后发表 作者 LibAndLab 九月 07, 2020, 08:31:18 am »
有人有思路吗
8
CUDA / 给1000000个数,求第K大的数,这样的题目该怎么做啊
« 最后发表 作者 LibAndLab 九月 03, 2020, 06:04:28 pm »
给1000000个数,求第K大的数,这样的题目该怎么做啊,我只知道求规约求最大值,求第K大的数该怎么做呢?不使用排序算法,直接求
9
CUDA / 不同CUDA 核函数之间的干扰问题
« 最后发表 作者 woaihb 九月 01, 2020, 10:59:44 am »
问题:引入一个新的核函数后造成其他正常函数功能异常,且是连续多次运算中第一次运算正常,第二次运算结果开始异常(整个工程算一次运算,数据库增加一个条目算一次运算)

整个工程共有3个功能函数,三个核函数,对应关系分别如下
程序代码: [选择]
namespace spaceA
{
void functionA(const float* paraA);
void functionB(const float* paraB);
void functionC();

void functionA(const float* paraA, float* resultDataA)
{
    for(int i = 0; i < GPUNumber; i++)
    {
        cudaSetDevice(i);
        kernelA<<<Grid, Block, 0, stream[i]>>>(paraA, resultData);
    }
}

void functionB(const float* paraA)
{
    float* resultDataB;
    functionC(paraA, resultDataB);
    for(int i = 0; i < GPUNumber; i++)
    {
        cudaSetDevice(i);
        kernelB<<<Grid, Block, 0, stream[i]>>>(resultDataA, resultDataB);
    }
}

void functionC(const float* paraA, float* resultDataB)
{
    for(int i = 0; i < GPUNumber; i++)
    {
        cudaSetDevice(i);
        kernelC<<<Grid, Block, 0, stream[i]>>>(paraA, resultDataB);
    }
}   
} // namespace spaceA
/*
如上述所示:
原有工程为functionA and functionB, 工程程序运行正常;新开发functionC, functionC的计算结果用于functionB中,且functionC与functionA没有任何计算交集。
运算顺序为:functionA--> functionC-->functionB
(更改前的顺序为functionA--> functionB)
但是在测试加入functionC的程序时,发现如果单独执行一次运算,运算结果是正常的,但当继续执行第二次工程运算时,结果异常,经过对中间数据分析,发现数据异常的地方发生在functionA中,且在增加functionC时,并未对functionA进行任何的改动。
*/
程序代码: [选择]
static __global__ void kernelA(const float* paraA, float* resultDataA)
{
     int tid = blockDim.x * blockIdx.x + threadIdx.x;
      if (tid < threadNum)
      {
        for (int kk = 0; kk < Number; kk++)
        {
            int index = kk * binSum; // binSum是一常数,计算步骤省略了
            int currvoxelIndex = voxelIndex[index] + X; // X是一变量数值,计算步骤省略了

            if (currvoxelIndex < 0 || currvoxelIndex >= voxelNumber)
            {
                continue;
            }
            atomicAdd(&image[currvoxelIndex], mich * weight[index]);
            if(image[currvoxelIndex] < 0) //// mich and weight均为正数
            { //但是相乘的结果却出现负数
                printf("ERROR\n"); //但在这里打印结果,却没有出现负数
            } // 这样打印有问题吗
        }
      }
}

进一步阐述:

functionA的运算结果不应该有负值(kernelA中两个正数相乘不可能得出负值),加入functionC后,functionA的运算结果出现负值(如果将functionC注释掉,则没有负值),因此将functionA的所有中间数据打印,确定负值的具体位置,但是只有kernelA计算完成后将结果传回CPU后才出现负值,其他中间所有的数据,以及中间产生的数据都没有出现负值,在kernelA中的打印也没有出现负值。
10
答复:升级一下你的 cmake.
 
cmake --version 看看版本是多少?估计是 3.10

 
如果低于 3.13 版本,对 cuda 10 以上会出问题

 
删掉现在的 cmake 版本

 
sudo apt autoremove cmake

 
sudo snap install cmake

 
然后检查 cmake 版本,应该会升级到 3.18

页: [1] 2 3 ... 10