cuComplex.h和exp()

时间:2012-03-25 14:00:02

标签: c cuda

Q0:

cuComplex.h是否支持exp()?

Q1:

如何写A = B * exp(i * C),其中A,B,C是相同大小的实数数组?这是对的吗?

主:

cuComplex A;
float B;
cuComplex c;

内核:

c[idx] = ( 0, C[idx] );

A[idx] = B[idx] * exp( c[idx] ); 

Q2:

cuComplex包含2个浮点数,这意味着我必须为原始矩阵分配2倍的内存。有没有办法创造纯虚数?

2 个答案:

答案 0 :(得分:7)

cuComplex.h仅提供cuComplex的一些基本操作(主要是在CUBLAS和CUFFT库中使用的那些),不支持指数函数。

您可以使用分量算术自己实现指数。 cuComplex将复数的实部存储在x分量中,将虚部存储在y分量中。给定复数z = x + i * y,指数可以计算为:

exp(z)= exp(x)*(cos(y)+ i * sin(y))

这导致以下CUDA代码(未经测试):

cuComplex my_complex_exp (cuComplex arg)
{
   cuComplex res;
   float s, c;
   float e = expf(arg.x);
   sincosf(arg.y, &s, &c);
   res.x = c * e;
   res.y = s * e;
   return res;
}

答案 1 :(得分:1)

Thrust现在也支持complex exponentials

为此功能不必使用推力。您可以包括推力复合头文件,并在普通的CUDA代码中使用这些构造。

$ cat t1793.cu
#include <cuComplex.h>
#include <thrust/complex.h>
#include <stdio.h>

__host__ __device__
cuFloatComplex my_complex_exp (cuFloatComplex arg)
{
   cuFloatComplex res;
   float s, c;
   float e = expf(arg.x);
   sincosf(arg.y, &s, &c);
   res.x = c * e;
   res.y = s * e;
   return res;
}

__global__ void demo(){

  cuFloatComplex a = make_cuFloatComplex(1.0f, 1.0f);
  thrust::complex<float> b(1.0f, 1.0f);
  printf("thrust: %f,%f, cuComplex: %f,%f\n", exp(b).real(), exp(b).imag(), cuCrealf( my_complex_exp(a)), cuCimagf(my_complex_exp(a)));
}

int main(){

  demo<<<1,1>>>();
  cudaDeviceSynchronize();
}
$ nvcc -o t1793 t1793.cu
$ cuda-memcheck ./t1793
========= CUDA-MEMCHECK
thrust: 1.468694,2.287355, cuComplex: 1.468694,2.287355
========= ERROR SUMMARY: 0 errors
$