【问题标题】:Issue working with uint2 and CUDA使用 uint2 和 CUDA 时出现问题
【发布时间】:2015-05-18 22:22:45
【问题描述】:

最近我开始使用 CUDA 和 Ethereum,我在一个函数上发现了一些代码片段,当我尝试移植到 cuda 文件时,我得到了一些错误。

这里是sn-p的代码:

void keccak_f1600_round(uint2* a, uint r, uint out_size)
{

#if !__ENDIAN_LITTLE__
    for (uint i = 0; i != 25; ++i)
        a[i] = make_uint2(a[i].y, a[i].x);
#endif

uint2 b[25];
uint2 t;

// Theta
b[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20];

#if !__ENDIAN_LITTLE__
    for (uint i = 0; i != 25; ++i)
        a[i] = make_uint2(a[i].y, a[i].x);
#endif

}

我正在关注b[0] 行的错误是:

error: no operator "^=" matches these operands operand types are: uint2 ^= uint2

说实话,我对 uint2 和 cuda 没有太多经验,这就是为什么我要问我应该如何解决这个问题。

【问题讨论】:

  • 显然uint2 不是数字类型;我认为这是一个结构。我对 CUDA 不熟悉,所以我没有更多的细节。
  • 你希望这个操作员做什么?按位异或?你需要自己实现它。
  • @m.s.按位异或,通过自己实现,您应该添加两个参数(a[0].x + a[0].y)而不是a[0]

标签: c cuda bit-manipulation uint


【解决方案1】:

异或运算符适用于 unsigned long long,但不适用于 uint2(对于 CUDA,它是一个包含两个无符号整数的内置结构)。

要使代码正常工作,有多种选择。我想到的一些:

  • 您可以在执行异或的行中的每个 uint2 之前使用 reinterpret-cast(请参阅How to use reinterpret_cast in C++?

  • 您现在可以在任何使用 uint2 的地方重写代码以使用 unsigned long long 类型。这可能会产生最易于维护的代码。

  • 您可以将 uint2 类型中的异或行重写为使用 uint2 的 .x 和 .y 成员的一对异或行,因为每个都是无符号的 int 类型。

  • 您可以定义联合类型以允许访问当前类型为 uint2 的数据,可以是 uint2 或 unsigned long long。

  • 您可以重载 ^ 异或运算符以使用 uint2 类型。

  • 您可以用 asm 语句替换产生错误的行,以生成 PTX 代码来为您执行异或。见http://docs.nvidia.com/cuda/inline-ptx-assembly/index.html#using-inline-ptx-assembly-in-cuda

【讨论】:

  • 对于第三个项目符号,你的意思是我应该记住 .x 中所有组件的 xfull xor (a[0] ....) .x 和 y 相同吗?
  • 您当前拥有的位置:b[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]; 相反,您将拥有:b[0].x = a[0].x ^ a[5].x ^ a[10].x ^ a[15].x ^ a[20].x; b[0].y = a[0].y ^ a[5].y ^ a[10].y ^ a[15].y ^ a[20].y;
【解决方案2】:

uint2 只是一个结构,您需要使用a[].xa[].y 来实现^。我找不到内置声明的位置,但 Are there advantages to using the CUDA vector types? 对它们的使用有很好的描述。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 2021-10-08
    • 2020-06-14
    • 2011-08-19
    • 1970-01-01
    • 2021-03-13
    • 2011-06-14
    相关资源
    最近更新 更多