【问题标题】:Passing variables from parent kernel to child kernel in dynamic parallelism in cuda在cuda中以动态并行方式将变量从父内核传递到子内核
【发布时间】:2014-09-05 22:07:56
【问题描述】:

我正在尝试在 cuda 中使用动态并行。我处于这样一种情况,即父内核有一个需要传递给子内核以进行进一步计算的变量。我已经浏览了网络中的资源 here

它提到局部变量不能传递给子内核,并提到了传递变量的方法,我试图将变量传递为

#include <stdio.h>
#include <cuda.h>


__global__ void square(float *a, int N)
{
  int idx = blockIdx.x * blockDim.x + threadIdx.x;

  if(N==10)
  {
  a[idx] = a[idx] * a[idx];
  }
}
// Kernel that executes on the CUDA device
__global__ void first(float *arr, int N)
{
  int idx = blockIdx.x * blockDim.x + threadIdx.x;
  int n=N; // this value of n can be changed locally and need to be passed
  printf("%d\n",n);
  cudaMalloc((void **) &n, sizeof(int));

  square <<< 1, N >>> (arr, n);

}

// main routine that executes on the host
int main(void)
{
  float *a_h, *a_d;  // Pointer to host & device arrays
  const int N = 10;  // Number of elements in arrays
  size_t size = N * sizeof(float);
  a_h = (float *)malloc(size);        // Allocate array on host
  cudaMalloc((void **) &a_d, size);   // Allocate array on device
  // Initialize host array and copy it to CUDA device
  for (int i=0; i<N; i++) a_h[i] = (float)i;
  cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);
  // Do calculation on device:

  first <<< 1, 1 >>> (a_d, N);
  //cudaThreadSynchronize();
  // Retrieve result from device and store it in host array
  cudaMemcpy(a_h, a_d, sizeof(float)*N, cudaMemcpyDeviceToHost);
  // Print results
  for (int i=0; i<N; i++) printf("%d %f\n", i, a_h[i]);
  // Cleanup
  free(a_h); cudaFree(a_d);
}

并且父子内核的值没有被传递。如何传递局部变量的值。有什么办法吗?

【问题讨论】:

    标签: cuda dynamic-programming


    【解决方案1】:

    这个操作不合适:

    int n=N; // this value of n can be changed locally and need to be passed
    
    cudaMalloc((void **) &n, sizeof(int)); // illegal
    

    它不适用于主机代码,也不适用于设备代码。 n 是一个 int 变量。您不应该为其分配指针。当您尝试在 64 位环境中执行此操作时,您是在尝试在 32 位 int 数量之上写入一个 64 位指针。它不会起作用。

    尚不清楚为什么您仍然需要它。 n 是一个整数参数,大概指定了 arr 数组 float 的大小。你不需要在它上面分配任何东西。

    如果您使用cuda-memcheck 运行此代码,您很容易发现该错误。您也可以在设备代码中执行proper cuda error checking,其方式与在主机代码中执行的方式完全相同。

    当我在first 内核中注释掉cudaMalloc 行时,您的代码对我来说运行正确。

    【讨论】:

    • 是的,它在没有 cudaMalloc 的情况下工作。然而,在文档中提到局部变量不能传递给子内核,但在上面的例子中传递局部变量 io 工作得很好。这怎么可能??
    • 局部变量可以通过按值作为内核参数传递给子内核。该文档指出不应传递指向局部变量的指针。您编写的代码按first 中的值传递n
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 2016-04-14
    • 2015-11-28
    • 2017-01-28
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    相关资源
    最近更新 更多