nvcc坚称thrust::complex既没有real() 也没有imag()

后端开发 2026-07-11
#include <stdio.h>
#include <thrust/complex.h>
#include <thrust/device_vector.h>
// #include <thrust/host_vector.h>

int main(int argc, char *argv[]) {

  thrust::device_vector<thrust::complex<float>> data(1);
  // thrust::host_vector<thrust::complex<float>> data(1);
  data[0] =
      thrust::complex<float>(static_cast<float>(1.0), static_cast<float>(2.0));
  data[0] *= static_cast<float>(5.0);

  printf("data[0] = %f %fi\n", data[0].real(), data[0].imag());
}

当我尝试用nvcc编译上述代码时,它说:

test.cu(14): error: class "thrust::THRUST_300104_SM_750_NS::device_reference<thrust::THRUST_300104_SM_750_NS::complex<float>>" has no member "real"
    printf("data[0] = %f %fi\n", data[0].real(), data[0].imag());
                                         ^

test.cu(14): error: class "thrust::THRUST_300104_SM_750_NS::device_reference<thrust::THRUST_300104_SM_750_NS::complex<float>>" has no member "imag"
    printf("data[0] = %f %fi\n", data[0].real(), data[0].imag());
                                                         ^

如果我把上面的 "device_vector" 行注释掉,并把下面等价的 "host_vector" 行取消注释,nvcc就能毫无问题地编译。这是怎么回事?

我正在使用CUDA工具包13.1.115。WSL,Ubuntu 24.04。

解决方案

device_vector 在GPU上分配内存。你不能直接访问GPU内存中的对象。

因此 [index] 仅提供一个类型为 device_reference 的代理对象。请注意其文档中的以下段落。

某些在普通对象上可以执行的操作,由于C++语言的要求,无法通过它们对应的 device_reference 对象实现。例如,因为成员访问运算符不能被重载,引用对象的成员变量和成员函数不能通过其 device_reference 直接访问。

相反,你必须使用基本的赋值运算,在主机类型之间进行转换。

using cf = thrust::complex<float>;
using device_ref_cf = thrust::device_reference<cf>;
thrust::device_vector<cf> data(1);
device_ref_cf reference = data[0];
cf value = reference; // or directly value = data[0]. Copies to host
printf("data[0] = %f %fi\n", value.real(), value.imag());
value = cf(1.0f, 2.0f);
value *= 5.0f;
reference = value; // or directly data[0] = value. copy to device

请注意,将单个值来回拷贝到GPU的开销非常大。最好先用所有数据初始化一个主机向量,然后一次性进行大批量拷贝。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章