0

I have a working code (not shown) that performs a series of complex->complex fast fourier transforms using the cufft library. I have been attempting to simplify this code by using the thrust library and its thrust::complex type. In order to keep the program code similar to the underlying mathematics, I define host_vectors of iterators (pointers), p1 and p2, which point to different locations in the device_vector, pr. I attempt to cast to cufftDoubleComplex type in _V1 and _V2 for use in the cufft call. However, it is _V1 that is giving me an issue in: cufftExecZ2Z(qr_to_qk, _V1, _V2, cuFFTFORWARD), since _V1 doesn't have the .data() member. The code (cut-down version) is as follows:

#include <stdlib.h>
#include <cuda.h>
#include <cufft.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/complex.h>
#define cuFFTFORWARD -1
#define cuFFTINVERSE 1

using namespace std;

int main ()
{
  int m[3], M, r, n;
  cufftHandle pr_to_pk;

  n = 90;
  m[0] = 16;
  m[1] = m[0];
  m[2] = m[0];

  M = m[0]*m[1]*m[2];
  
  // allocate memory for the propagators
  thrust::device_vector<thrust::complex<double>> pr(2*(n+1)*M);

  // fill pr with a number sequence (dummy data)
  thrust::sequence(pr.begin(), pr.end());

  // allocate memory to store iterators pointing to device vector elements
  thrust::host_vector<thrust::device_vector<thrust::complex<double>>::iterator> p1(n+1);
  thrust::host_vector<thrust::device_vector<thrust::complex<double>>::iterator> p2(n+1);

  // save interators pointing to start of memory for p1 and p2
  for (r=0; r<=n; r++) {
      p1[r] = pr.begin()+2*r*M;
      p2[(n+1-r)%(n+1)] = pr.begin()+(2*r+1)*M;
  }

  // set up the cufft plan
  cufftPlanMany(&pr_to_pk,3,m,NULL,1,0,NULL,1,0, CUFFT_Z2Z,2);
  
  // allocate memory for q(k)
  thrust::device_vector<thrust::complex<double>> pk(2*M);

  // attempt to cast to cufftDoubleComplex
  cufftDoubleComplex* _V1 = (cufftDoubleComplex*)thrust::raw_pointer_cast(p1[1]);
  cufftDoubleComplex* _V2 = (cufftDoubleComplex*)thrust::raw_pointer_cast(pk.data());

  // attempt the first cufft 
  cufftExecZ2Z(pr_to_pk, _V1, _V2, cuFFTFORWARD);

  cout << "complete" << endl;
}

Upon compilation, I get the following:

error: class "thrust::detail::pointer_raw_pointerthrust::detail::normal_iterator<thrust::device_ptr<thrust::complex<double>>>" has no member "type" detected during instantiation of class "thrust::detail::pointer_traits [with Ptr=thrust::detail::normal_iteratorthrust::device_ptr<thrust::complex<double>>]"

Unfortunately, in spite of many different attempts of casting for _V1, I have been unable to get the code to successfully compile and run. If anyone can help shed some light on how to get the call to cufftExecZ2Z(pr_to_pk, _V1, _V2, cuFFTFORWARD); working, it would be greatly appreciated. I'm trying to avoid creating n number of p1 and p2 vectors, which I think would solve the problem but get very messy.

codephys
  • 1
  • 1
  • 1
    a thrust device iterator cannot be directly cast to an ordinary address/pointer. You must first dereference the iterator to get an item, then take the address of that item and cast. See [here](https://stackoverflow.com/questions/45350747/converting-thrust-device-iterators-to-raw-pointers) (which I arrived at via a google search of "thrust iterator raw_pointer_cast"). Try this: `cufftDoubleComplex* _V1 = (cufftDoubleComplex*)thrust::raw_pointer_cast(&((p1[1])[0]));` (which compiles cleanly for me) – Robert Crovella Feb 16 '23 at 17:56
  • Thank you, Robert, for providing an explanation in addition to code that works. I understand that I was incorrectly interpreting the iterator. Much appreciated. – codephys Feb 16 '23 at 19:54

0 Answers0