首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在库达图中使用__constant__?

如何在库达图中使用__constant__?
EN

Stack Overflow用户
提问于 2022-11-08 20:00:06
回答 1查看 31关注 0票数 0

我正在尝试使用一个库达图来加入一堆内核,这些内核使用__constant__参数来设置不会改变的值。一个小的测试用例:

代码语言:javascript
运行
复制
#include <iostream>
#include <vector>

template<typename T>
__constant__ T scalar[1];

__constant__ size_t size_a[1];

template<typename T>
__global__ void set_buffer(T *buffer) {
    const size_t index = blockIdx.x*blockDim.x + threadIdx.x;
    buffer[min(index, size_a[0])] = scalar<T>[0];
}

int main(int argc, const char * argv[]) {
    cudaGraph_t graph;
    cudaGraphCreate(&graph, 0);

    cudaStream_t stream;
    cudaStreamCreate(&stream);

    const double src = 10.0;

    cudaGraphNode_t node_a;
    cudaGraphAddMemcpyNodeToSymbol(&node_a, graph, NULL, 0,
                                   scalar<double>, &src, sizeof(double),
                                   0, cudaMemcpyHostToDevice);

    const size_t length = 100; 

    cudaGraphNode_t node_b;
    cudaGraphAddMemcpyNodeToSymbol(&node_b, graph, NULL, 0,
                                   size_a, &length, sizeof(size_t),
                                   0, cudaMemcpyHostToDevice);

    double *result;
    cudaMalloc(&result, length*sizeof(double));

    cudaKernelNodeParams params;
    params.func = (void *) set_buffer<double>;
    params.gridDim = dim3(1, 1, 1);
    params.blockDim = dim3(512, 1, 1);
    params.sharedMemBytes = 0;
    params.kernelParams = {reinterpret_cast<void **> (&result)};
    params.extra = NULL;

    cudaGraphNode_t node_c;
    std::vector<cudaGraphNode_t> deps = {node_a, node_b};
    cudaGraphAddKernelNode(&node_c, graph, deps.data(), deps.size(),
                           &params);

    cudaGraphExec_t exec;
    cudaGraphInstantiate(&exec, graph, NULL, NULL, 0);

    cudaGraphLaunch(exec, stream);
    cudaStreamSynchronize(stream);

    std::vector<double> host_result(length);
    cudaMemcpy(host_result.data(),
               result, length*sizeof(double),
               cudaMemcpyDeviceToHost);

    for (size_t i = 0; i < length; i++) {
        std::cout << i << " " << host_result[i] << std::endl;
    }    
}

当我运行它时,它看起来不像是cudaGraphAddMemcpyNodeToSymbol正在做什么。因为当我运行它时,它会打印出来。

代码语言:javascript
运行
复制
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
...
90 0
91 0
92 0
93 0
94 0
95 0
96 0
97 0
98 0
99 0

为什么内核不改变缓冲区中的值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-08 22:58:32

当我运行您的代码时,会出现一个seg错误。你是否出了故障并不是真正的问题。

问题在于:

代码语言:javascript
运行
复制
params.kernelParams = {reinterpret_cast<void **> (&result)};

那是不对的。正确的方法如下:

代码语言:javascript
运行
复制
void *kernelargs[1] = {(void *)&result};
params.kernelParams = kernelargs;

你也有一个错误:

代码语言:javascript
运行
复制
buffer[min(index, size_a[0])] = scalar<T>[0];
       ^^^^^^^^^^^^^^^^^^^^^

您要放入size_a[0]的值为100,因此任何index为100或更高的线程都将尝试在索引为100的元素处索引到buffer中,这超出了分配的范围。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74366485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档