使用 uint2 和 CUDA 的问题

Issue working with uint2 and CUDA

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

这是代码片段:

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

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

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

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

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

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

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

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

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