【问题标题】:Can I use a dynamic array as C++ template typename?我可以使用动态数组作为 C++ 模板类型名吗?
【发布时间】:2015-05-29 06:30:33
【问题描述】:

如下代码:

template<typename PatternType>
cl_int enqueueFillBuffer(
    const Buffer& buffer,
    PatternType pattern,
    ::size_t offset,
    ::size_t size,
    const VECTOR_CLASS<Event>* events = NULL,
    Event* event = NULL) const
{
    cl_event tmp;
    cl_int err = detail::errHandler(
        ::clEnqueueFillBuffer(
            object_, 
            buffer(),
            static_cast<void*>(&pattern),
            sizeof(PatternType), 
            offset, 
            size,
            (events != NULL) ? (cl_uint) events->size() : 0,
            (events != NULL && events->size() > 0) ? (cl_event*) &events->front() : NULL,
            (event != NULL) ? &tmp : NULL),
            __ENQUEUE_FILL_BUFFER_ERR);

    if (event != NULL && err == CL_SUCCESS)
        *event = tmp;

    return err;
}

如果数组长度6是静态指定的,则可以编译代码。

queue.enqueueFillBuffer<float[6]>(buffer, nodes, 2345, 123456);

我的问题是如何使长度 6 成为变量并通过编译?由于 C99 支持动态数组,因此 sizeof(float[n]) 可以正确获取大小(对于代码 sizeof(PatternType))。但是我无法使下面的代码通过编译:

int n = 6;
queue.enqueueFillBuffer<float[n]>(buffer, nodes, 2345, 123456);

【问题讨论】:

  • n 不是编译时常量,因此编译器无法在编译时推导出静态数组类型。
  • 最好将您的代码 sn-p 减少到理解您的问题所需的最低限度。对于您的示例,您可以提供一个空函数。真的够了!
  • 是的,编译器不能推导出静态数组,为什么不能通过动态数组的方式处理它。
  • 我保留整个代码sn-p,因为它是第三方库头文件,我认为是设计缺陷。
  • AFAIK,C++ 中没有动态数组之类的东西(一些编译器将其作为扩展提供)。

标签: c++ arrays templates dynamic-arrays


【解决方案1】:

考虑使用std::array。更一般地,假设一个类似 STL 的容器将被传递给您的方法。例如,

std::array<float, 6> nodes;
nodes[0] = ...

std::vector<float> nodes;
nodes.resize(6);
nodes[0] = ...

然后是行

static_cast<void*>(&pattern),
sizeof(PatternType),

可以替换为

static_cast<void*>(pattern.data()),
sizeof(typename PatternType::value_type) * pattern.size(), 

然后编译器可以推断出类型,所以调用方法就变成了

queue.enqueueFillBuffer(buffer, nodes, 2345, 123456);

不需要显式的模板参数。

【讨论】:

  • 哦,不。无法修改代码“static_cast(&pattern), sizeof(PatternType)”。它来自 OpenCL 1.2 C++ Wrapper 头文件。这只是问题的关键。我认为这是一个设计缺陷。不知道Khronos Group的成员能不能看到。
  • 啊,我明白了。我假设you're using this header file。可以fork修改一下,不然看不到解决办法。
  • Mike,这种情况下的动态数组肯定是无效的,因为编译器无法推断出模板参数的大小。我看到了您向 Khronos 提交的错误,但如果您仔细阅读 OpenCL 规范,您会注意到模式类型应该是内置类型之一:“数据模式必须是标量或向量整数或浮点数据OpenCL 支持的类型,如 6.1.1 和 6.1.2 节所述。”。虽然结果应该是一样的,但是像你试图做的那样传入一个数组确实是无效的。
  • @Lee 是对的,请参阅page 85 of this PDF。简而言之,它说您显然 必须 使用 cl_* 类型。但另一方面,这些类型只是通常的floatdouble 等的类型定义,所以理论上你应该能够使用std::vector&lt;cl_float4&gt;std::vector&lt;cl_float4&gt;
  • 规范中说“pattern_size 的最大值是 OpenCL 设备支持的最大整数或浮点向量数据类型的大小”。这意味着模式大小是ulong16,最多128字节。不能使用 std::vector。
【解决方案2】:

答案是没有办法完成它。 关于enqueueFillBuffer的实现,请参考:https://www.khronos.org/bugzilla/show_bug.cgi?id=1347 支持的最大模式大小为 ulong16,128 字节。

【讨论】:

    猜你喜欢
    • 2023-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    相关资源
    最近更新 更多