You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CUDA动态并行中如何让父核等待子核完成后再执行后续代码?

问题

在CUDA动态并行场景下,需要子核runParatron完全执行完毕后,父核runMLP才进入for循环的下一次迭代。但当前输出显示子核的打印语句晚于父核的“[”打印,说明未实现等待。尝试调用cudaDeviceSynchronize函数时编译报错,提示该主机代码无法在设备代码中执行且未定义,求正确的同步方法。

相关代码:

__global__ void runMLP(double* x, double* outputs, double* weights, activation_function* A_Fs, int*     CIL, int layers, int bias, int* WLO, int* OLO) {

    if (CIL[0] > 511) {
        copyElements <<<CIL[0] / 32, 32>>> (outputs, x, CIL[0]);
        //I WOULD ALSO LIKE TO WAIT HERE
    }
    else
        for (int i = 0;i < CIL[0];i++) {
            outputs[i] = x[i];
        }

    for (int i = 1;i < layers;i++) {
        printf("----------------------Layer %d :: InputSize %d :: Layer weight offset %d ::     Layer output offset %d----------------------\n", i, CIL[i-1], WLO[i-1], OLO[i]);
        runParatron <<< (CIL[i] / 32) + 1, 32>>> (outputs + OLO[i - 1], outputs +     OLO[i], weights + WLO[i - 1], A_Fs[i], CIL[i - 1], CIL[i], bias);
        //cudaDeviceSynchronize(); //THIS IS WHERE I NEED TO WAIT UNTIL NEXT ITERATION
    }
    if (A_Fs[layers - 1] == SOFTMAX) {
        double* temp = outputs + OLO[layers - 1];
        printf("[");
        for (int i = 0;i < CIL[layers-1];i++) {
            printf("% d, ", temp[i]);
        }
        printf("]\n");
        double denom = 0;
        for (int i = 0;i < CIL[layers - 1];i++) {
            denom += temp[i];
        }
        if (denom < DBL_MIN)
            denom = DBL_MIN;
        for (int i = 0;i < CIL[layers - 1];i++) {
            temp[i] /= denom;
        }
    }
}

异常输出示例:

//All Cell: starting lines are produced from child kernel
[Cell: 0 :: weightOffset 0 :: AF 2 //As you can see, there is the "[" here when it should be
Cell: 1 :: weightOffset 6 :: AF 2
Cell: 2 :: weightOffset 12 :: AF 2
Cell: 3 :: weightOffset 18 :: AF 2
-502657059,  2118981138,  1645236453, ] //Down here!
解决方法
  • 正确启用cudaDeviceSynchronize():设备端调用该函数需要两个前提:编译时添加-rdc=true选项启用动态并行,并链接CUDA runtime库;GPU计算能力需达到3.5及以上(支持动态并行)。之前编译报错大概率是未开启动态并行编译选项。
  • 流同步替代方案:可以在父核内创建CUDA流,将子核任务提交到该流后,调用cudaStreamSynchronize等待任务完成。示例代码如下:
    for (int i = 1;i < layers;i++) {
        printf("----------------------Layer %d :: InputSize %d :: Layer weight offset %d ::     Layer output offset %d----------------------\n", i, CIL[i-1], WLO[i-1], OLO[i]);
        cudaStream_t stream;
        cudaStreamCreate(&stream);
        runParatron <<< (CIL[i] / 32) + 1, 32, 0, stream>>> (outputs + OLO[i - 1], outputs + OLO[i], weights + WLO[i - 1], A_Fs[i], CIL[i - 1], CIL[i], bias);
        cudaStreamSynchronize(stream);
        cudaStreamDestroy(stream);
    }
    
  • 性能与兼容性注意:动态并行同步会带来一定延迟,需评估对整体性能的影响;同时要确认运行代码的GPU支持动态并行(计算能力3.5+)。

内容的提问来源于stack exchange,提问作者yugi957

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 04:40:55