【问题标题】:"-Nan" value for the total sum of array elements with GPU code带有 GPU 代码的数组元素总和的“-Nan”值
【发布时间】:2016-02-21 18:44:30
【问题描述】:

我正在编写一个计算数组元素总和的 OpenCL 代码。对于 1D 输入数组,每一个都可以正常工作,最大为 1.024 * 1e+8,但对于 1.024 * 1e+9,最终值为“-Nan”。

这是this link上的代码源

内核代码在this link

还有this link上的Makefile

这是最后一个有效的数组大小的结果(最后一个有效的大小值是 1.024 * 1e+8):

$ ./sumReductionGPU 102400000 

Max WorkGroup size = 4100
Number of WorkGroups = 800000

  Problem size = 102400000

  Final Sum Sequential = 5.2428800512000000000e+15

  Final Sum GPU = 5.2428800512000000000e+15

  Initializing Arrays : Wall Clock = 0 second 673785 micro

  Preparing GPU/OpenCL : Wall Clock = 1 second 925451 micro

  Time for one NDRangeKernel call and WorkGroups final Sum  : Wall Clock = 0 second 30511 micro

  Time for Sequential Sum computing  : Wall Clock = 0 second 398485 micro

我有local_item_size = 128,所以如上所示,我有800000 Work-GroupsNWorkItems = 1.024 * 1e+8

现在,如果我取 1.024 * 10^9,则不再计算部分总和,我得到数组元素总和的“-nan”值。

$ ./sumReductionGPU 1024000000

Max WorkGroup size = 4100
Number of WorkGroups = 8000000

  Problem size = 1024000000

  Final Sum Sequential = 5.2428800006710899200e+17

  Final Sum GPU =                 -nan

  Initializing Arrays : Wall Clock = 24 second 360088 micro

  Preparing GPU/OpenCL : Wall Clock = 19 second 494640 micro

  Time for one NDRangeKernel call and WorkGroups final Sum  : Wall Clock = 0 second 481910 micro

  Time for Sequential Sum computing  : Wall Clock = 166 second 214384 micro

也许我已经达到了 GPU 单元可以计算的极限。但我想征求您的意见以确认这一点。

如果 double8 bytes,则输入数组需要 1.024 * 1e9 * 8 ~ 8 GB:是不是太多了?我只有 8 GB 的 RAM。

根据您的经验,这个问题可能来自哪里?

谢谢

【问题讨论】:

  • 请检查mallocclCreateBuffer 调用之一是否由于内存不足而失败。还要检查 size_t 在您的平台上是 32 位还是 64 位整数。
  • 谢谢,问题来自 clCreateBuffer,它对 1.024*1e9 工作项失败

标签: arrays sum opencl


【解决方案1】:

您已经发现,您的一维输入数组需要大量内存。因此,mallocclCreateBuffer 的内存分配容易失败。

对于malloc,我建议使用辅助函数checked_malloc,它会检测到内存分配失败,打印出一条消息并退出程序。

#include <stdlib.h>
#include <stdio.h>

void * checked_malloc(size_t size, const char purpose[]) {
  void *result = malloc(size);
  if(result == NULL) {
    fprintf(stderr, "ERROR: malloc failed for %s\n", purpose);
    exit(1);
  }
  return result;
}

int main()
{
  double *p1 = checked_malloc(1e8 * sizeof *p1, "array1");
  double *p2 = checked_malloc(64 * 1e9 * sizeof *p2, "array2");
  return 0;
}

在我只有 48 GB 虚拟内存的电脑上,第二次分配失败,程序打印:

ERROR: malloc failed for array2

您也可以将此方案应用于clCreateBuffer。但是,无论如何,您必须检查每个 OpenCL 调用的结果。因此,我建议为此使用宏:

#define CHECK_CL_ERROR(result) if(result != CL_SUCCESS) { \
    fprintf(stderr, "OpenCL call failed at: %s:%d with code %d\n", __FILE__, __LINE__, result); }

一个示例用法是:

cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY,
    nWorkItems * sizeof(double), NULL, &ret);
CHECK_CL_ERROR(ret);

【讨论】:

  • 感谢您的建议
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 2013-05-28
  • 2015-09-20
相关资源
最近更新 更多