Advertisement
Guest User

clfft time_freq_distribution

a guest
Nov 26th, 2014
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.05 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <chrono>
  4. #include <algorithm>
  5. #include <complex>
  6. #include <vector>
  7. #include <clFFT.h>
  8. #include <algorithm>
  9. #include <fstream>
  10. #include <memory>
  11.  
  12. float toAmpl(std::complex<float> val)
  13. {
  14.     return sqrt(val.real()*val.real()+val.imag()*val.imag());
  15. }
  16.  
  17. const size_t WINDOW_SIZE = 256;
  18. const size_t MAX_ARRAY_LENGTH = 8192;
  19. const size_t FFTS_COUNT = MAX_ARRAY_LENGTH-WINDOW_SIZE;
  20.  
  21. /* OpenCL variables */
  22. cl_int err;
  23. cl_platform_id platform = 0;
  24. cl_device_id device = 0;
  25. cl_context_properties props[3] = {CL_CONTEXT_PLATFORM, 0, 0};
  26. cl_context ctx = 0;
  27. cl_command_queue queue = 0;
  28. cl_mem data_buffer = 0;
  29. cl_mem out_buffer = 0;
  30. cl_mem temp_buffer = 0;
  31. cl_mem inplace_buffers[FFTS_COUNT];
  32. cl_mem out_buffers[FFTS_COUNT];
  33. cl_mem temp_buffers[FFTS_COUNT];
  34. _cl_buffer_region inplace_regions[FFTS_COUNT];
  35. _cl_buffer_region out_regions[FFTS_COUNT];
  36. _cl_buffer_region temp_regions[FFTS_COUNT];
  37.  
  38. /* clFFT variables */
  39. int status = 0;
  40. int ret = 0;
  41.  
  42. size_t tmpBufferSize;
  43. size_t N;
  44. clfftPlanHandle planHandle;
  45. clfftDim dim = CLFFT_1D;
  46. size_t clLengths[1];
  47.  
  48.  
  49. std::vector<std::complex<float>> generate(size_t size)
  50. {
  51.     std::vector<std::complex<float>> buffer;
  52.     buffer.reserve(size);
  53.     for(size_t i = 0; i<size; i++)
  54.     {
  55.         double x = 2*M_PI*0.125*i;
  56.         buffer.push_back(std::complex<float>(0.5*cos(x), 0.5*sin(x)));
  57.     }
  58.     return buffer;
  59. }
  60.  
  61. void OCLFFTInit()
  62. {
  63.     srand(time(0));
  64.     /* OpenCL init */
  65.     err = clGetPlatformIDs(1, &platform, NULL);
  66.     err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
  67.  
  68.     cl_ulong res;
  69.     clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &res, NULL);
  70.  
  71.     props[1] = (cl_context_properties) platform;
  72.     ctx = clCreateContext(props, 1, &device, NULL, NULL, &err);    
  73.     queue = clCreateCommandQueue(ctx, device, 0, &err);    
  74.  
  75.     /* clFFT init */
  76.     clfftSetupData fftSetup;
  77.     err = clfftInitSetupData(&fftSetup);
  78.     err = clfftSetup(&fftSetup);    
  79.  
  80.     /* Plan init */
  81.     clLengths[0] = WINDOW_SIZE;
  82.     err = clfftCreateDefaultPlan(&planHandle, ctx, dim, clLengths);
  83.     err = clfftSetPlanPrecision(planHandle, CLFFT_SINGLE);    
  84.     err = clfftSetLayout(planHandle, CLFFT_COMPLEX_INTERLEAVED, CLFFT_COMPLEX_INTERLEAVED);
  85.     err = clfftSetPlanBatchSize(planHandle, 1000);
  86.     err = clfftSetResultLocation(planHandle, CLFFT_OUTOFPLACE);    
  87.     err = clfftBakePlan(planHandle, 1, &queue, NULL, NULL);    
  88.  
  89.     /* Buffers initialization */
  90.  
  91.     clfftGetTmpBufSize(planHandle, &tmpBufferSize);
  92.  
  93.     temp_buffer = tmpBufferSize != 0 ? clCreateBuffer(ctx, CL_MEM_READ_WRITE, sizeof(std::complex<float>)*FFTS_COUNT*tmpBufferSize, 0, &err) : 0;        
  94.     data_buffer = clCreateBuffer(ctx, CL_MEM_READ_WRITE, sizeof(std::complex<float>)*MAX_ARRAY_LENGTH, 0, &err);    
  95.     out_buffer = clCreateBuffer(ctx, CL_MEM_READ_WRITE, sizeof(std::complex<float>)*FFTS_COUNT*WINDOW_SIZE, 0, &err);
  96.  
  97.  
  98.     /* Subbuffers initialization */
  99.     for(size_t i=0; i<FFTS_COUNT; i++)
  100.     {
  101.         inplace_regions[i].origin = i*sizeof(std::complex<float>);
  102.         inplace_regions[i].size = WINDOW_SIZE*sizeof(std::complex<float>);
  103.         inplace_buffers[i] = clCreateSubBuffer(data_buffer, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, &inplace_regions[i], &err);
  104.         out_regions[i].origin = i*WINDOW_SIZE*sizeof(std::complex<float>);
  105.         out_regions[i].size = WINDOW_SIZE*sizeof(std::complex<float>);
  106.         out_buffers[i] = clCreateSubBuffer(out_buffer, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, &out_regions[i], &err);
  107.         if(tmpBufferSize != 0)
  108.         {
  109.             temp_regions[i].origin = tmpBufferSize*i;
  110.             temp_regions[i].size = tmpBufferSize;
  111.             temp_buffers[i] = clCreateSubBuffer(temp_buffer, CL_MEM_READ_WRITE, CL_BUFFER_CREATE_TYPE_REGION, &temp_regions[i], &err);
  112.         }
  113.     }
  114.  
  115. }
  116.  
  117.  
  118. std::vector<std::complex<float>> time_freq_distribution(std::vector<std::complex<float>> time_domain)
  119. {        
  120.     err = clEnqueueWriteBuffer(queue, data_buffer, CL_TRUE, 0, time_domain.size()*sizeof(std::complex<float>), time_domain.data(), 0, 0, 0);    
  121.     for(size_t i=0; i<time_domain.size()-WINDOW_SIZE; i++)
  122.     {
  123.         clfftEnqueueTransform (planHandle, CLFFT_FORWARD, 1, &queue, 0, NULL, NULL, &inplace_buffers[i], &out_buffers[i], tmpBufferSize != 0 ? temp_buffers[i] : 0);
  124.     }
  125.     clFinish(queue);
  126.     std::vector<std::complex<float>> out;
  127.     out.resize(time_domain.size()*WINDOW_SIZE);
  128.     err = clEnqueueReadBuffer(queue, out_buffer, CL_TRUE, 0, time_domain.size()*WINDOW_SIZE*sizeof(std::complex<float>), out.data(), 0, 0, 0);
  129.     switch (err)
  130.     {
  131.     case CL_INVALID_COMMAND_QUEUE: std::cout << "queue" << std::endl; break;
  132.     case CL_INVALID_CONTEXT: std::cout << "context" << std::endl; break;
  133.     case CL_INVALID_MEM_OBJECT: std::cout << "mem object" << std::endl; break;
  134.     case CL_INVALID_VALUE: std::cout << "value" << std::endl; break;
  135.     case CL_INVALID_EVENT_WAIT_LIST: std::cout << "event wait list" << std::endl; break;
  136.     case CL_MEM_OBJECT_ALLOCATION_FAILURE: std::cout << "object allocation failure" << std::endl; break;
  137.     case CL_OUT_OF_HOST_MEMORY: std::cout << "OOM" << std::endl; break;
  138.     case CL_SUCCESS: std::cout << "success" << std::endl; break;
  139.     default: std::cout << "undefined" << err << std::endl; break;
  140.     }
  141.  
  142.     return out;
  143. }
  144.  
  145. int main (void)
  146. {
  147.  
  148.     OCLFFTInit();    
  149.  
  150.     std::cout << "clFFT has been initialized." << std::endl;    
  151.  
  152.     std::vector<std::complex<float>> freq_time_domain;        
  153.  
  154.  
  155.     for(int i=0; i<10; i++)
  156.     {        
  157.         auto time_domain = generate(4096);
  158.  
  159.         auto start = std::chrono::high_resolution_clock::now();
  160.         freq_time_domain = time_freq_distribution(time_domain);
  161.         auto end = std::chrono::high_resolution_clock::now();
  162.         std::cout << "Test(cl): "<< i << ". Time elapsed: " << std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count() << *freq_time_domain.end() << std::endl;
  163.     }
  164.  
  165.  
  166.     clfftTeardown();
  167.     return 0;
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement