yum-mirror/VkFFT
git clone https://git.yummers.dev/yum-mirror/VkFFT
9a96811
develop
1//general parts 2#include <stdio.h> 3#include <vector> 4#include <memory> 5#include <string.h> 6#include <chrono> 7#include <thread> 8#include <iostream> 9#ifndef __STDC_FORMAT_MACROS 10#define __STDC_FORMAT_MACROS 11#endif 12#include <inttypes.h> 13 14//ROCM parts 15#include "hip/hip_runtime.h" 16#include <hipfft/hipfft.h> 17 18#include "user_benchmark_rocFFT.h" 19 20void user_benchmark_rocFFT (bool file_output ,FILE * output ,rocFFTUserSystemParameters * userParams ,int device_id ) 21{ 22hipSetDevice (device_id ); 23const int num_runs = 7 ; 24double benchmark_result [2 ]= {0 ,0 };//averaged result = sum(system_size/iteration_time)/num_benchmark_samples 25uint64_t storageComplexSize = 8 ; 26switch (userParams -> P ) { 27case 0 : 28storageComplexSize = (2 * sizeof (float )); 29break ; 30case 1 : 31storageComplexSize = (2 * sizeof (double )); 32break ; 33case 2 : 34storageComplexSize = (2 * 2 ); 35break ; 36default : 37storageComplexSize = (2 * sizeof (float )); 38break ; 39 } 40uint64_t bufferSize = 0 ; 41if (userParams -> R2C ) { 42bufferSize = (uint64_t )(storageComplexSize /2 )* (userParams -> X + 2 )* userParams -> Y * userParams -> Z * userParams -> B ; 43 } 44else { 45bufferSize = (uint64_t )storageComplexSize * userParams -> X * userParams -> Y * userParams -> Z * userParams -> B ; 46 } 47 48float * buffer_input = (float * )malloc (bufferSize ); 49for (uint64_t i = 0 ;i < bufferSize /sizeof (float );i ++ ) { 50buffer_input [i ]= (float )(2 * ((float )rand ()) /RAND_MAX - 1.0 ); 51 } 52for (int n = 0 ;n < 2 ;n ++ ) { 53double run_time [num_runs ][2 ]; 54for (int r = 0 ;r < num_runs ;r ++ ) { 55hipfftHandle plan ; 56hipfftHandle plan2 ; 57void * dataC ; 58 59int dims [3 ]; 60int FFTdim = 1 ; 61if (userParams -> Y > 1 )FFTdim ++ ; 62if (userParams -> Z > 1 )FFTdim ++ ; 63switch (FFTdim ) { 64case 1 : 65dims [0 ]= userParams -> X ; 66dims [1 ]= 1 ; 67dims [2 ]= 1 ; 68break ; 69case 2 : 70dims [0 ]= userParams -> Y ; 71dims [1 ]= userParams -> X ; 72dims [2 ]= 1 ; 73break ; 74case 3 : 75dims [0 ]= userParams -> Z ; 76dims [1 ]= userParams -> Y ; 77dims [2 ]= userParams -> X ; 78break ; 79 } 80 81hipMalloc ((void ** )& dataC ,bufferSize ); 82 83if (hipGetLastError ()!= hipSuccess ) { 84fprintf (stderr ,"ROCM error: Failed to allocate\n" ); 85return ; 86 } 87hipMemcpy (dataC ,buffer_input ,bufferSize ,hipMemcpyHostToDevice ); 88 89//forward + inverse 90int iembed [2 ][3 ]; 91int istride [2 ]= {1 ,1 }; 92int idist [2 ]= {bufferSize /userParams -> B /storageComplexSize ,bufferSize /userParams -> B /storageComplexSize }; 93if (userParams -> R2C )idist [0 ] *=2 ; 94int oembed [2 ][3 ]; 95int ostride [2 ]= {1 ,1 }; 96int odist [2 ]= {bufferSize /userParams -> B /storageComplexSize ,bufferSize /userParams -> B /storageComplexSize }; 97if (userParams -> R2C )odist [1 ] *=2 ; 98switch (FFTdim ) { 99case 1 : 100iembed [0 ][0 ]= (userParams -> R2C ) ?dims [0 ]+ 2 :dims [0 ]; 101oembed [0 ][0 ]= (userParams -> R2C ) ? (dims [0 ]+ 2 ) /2 :dims [0 ]; 102 103iembed [1 ][0 ]= (userParams -> R2C ) ? (dims [0 ]+ 2 ) /2 :dims [0 ]; 104oembed [1 ][0 ]= (userParams -> R2C ) ?dims [0 ]+ 2 :dims [0 ]; 105break ; 106case 2 : 107iembed [0 ][0 ]= dims [0 ]; 108iembed [0 ][1 ]= (userParams -> R2C ) ?dims [1 ]+ 2 :dims [1 ]; 109oembed [0 ][0 ]= dims [0 ]; 110oembed [0 ][1 ]= (userParams -> R2C ) ? (dims [1 ]+ 2 ) /2 :dims [1 ]; 111 112iembed [1 ][0 ]= dims [0 ]; 113iembed [1 ][1 ]= (userParams -> R2C ) ? (dims [1 ]+ 2 ) /2 :dims [1 ]; 114oembed [1 ][0 ]= dims [0 ]; 115oembed [1 ][1 ]= (userParams -> R2C ) ?dims [1 ]+ 2 :dims [1 ]; 116break ; 117case 3 : 118iembed [0 ][0 ]= idist [0 ]; 119iembed [0 ][1 ]= dims [1 ]; 120iembed [0 ][2 ]= (userParams -> R2C ) ?dims [2 ]+ 2 :dims [2 ]; 121oembed [0 ][0 ]= odist [0 ]; 122oembed [0 ][1 ]= dims [1 ]; 123oembed [0 ][2 ]= (userParams -> R2C ) ? (dims [2 ]+ 2 )/2 :dims [2 ]; 124 125iembed [1 ][0 ]= idist [0 ]; 126iembed [1 ][1 ]= dims [1 ]; 127iembed [1 ][2 ]= (userParams -> R2C ) ? (dims [2 ]+ 2 )/2 :dims [2 ]; 128oembed [1 ][0 ]= odist [0 ]; 129oembed [1 ][1 ]= dims [1 ]; 130oembed [1 ][2 ]= (userParams -> R2C ) ?dims [2 ]+ 2 :dims [2 ]; 131break ; 132 } 133switch (userParams -> P ) { 134case 0 : 135if (userParams -> R2C ){ 136hipfftPlanMany (& plan ,FFTdim ,dims ,iembed [0 ],istride [0 ],idist [0 ],oembed [0 ],ostride [0 ],odist [0 ],HIPFFT_R2C ,userParams -> B ); 137hipfftPlanMany (& plan2 ,FFTdim ,dims ,iembed [1 ],istride [1 ],idist [1 ],oembed [1 ],ostride [1 ],odist [1 ],HIPFFT_C2R ,userParams -> B ); 138 }else { 139hipfftPlanMany (& plan ,FFTdim ,dims ,iembed [0 ],istride [0 ],idist [0 ],oembed [0 ],ostride [0 ],odist [0 ],HIPFFT_C2C ,userParams -> B ); 140 } 141break ; 142case 1 : 143if (userParams -> R2C ){ 144hipfftPlanMany (& plan ,FFTdim ,dims ,iembed [0 ],istride [0 ],idist [0 ],oembed [0 ],ostride [0 ],odist [0 ],HIPFFT_D2Z ,userParams -> B ); 145hipfftPlanMany (& plan2 ,FFTdim ,dims ,iembed [1 ],istride [1 ],idist [1 ],oembed [1 ],ostride [1 ],odist [1 ],HIPFFT_Z2D ,userParams -> B ); 146 }else 147hipfftPlanMany (& plan ,FFTdim ,dims ,iembed [0 ],istride [0 ],idist [0 ],oembed [0 ],ostride [0 ],odist [0 ],HIPFFT_Z2Z ,userParams -> B ); 148break ; 149 } 150 151float totTime = 0 ; 152 std::chrono::steady_clock::time_point timeSubmit = std::chrono::steady_clock::now (); 153for (int i = 0 ;i < userParams -> N ;i ++ ) { 154switch (userParams -> P ) { 155case 0 : 156if (userParams -> R2C ){ 157hipfftExecR2C (plan , (hipfftReal * )dataC , (hipfftComplex * )dataC ); 158hipfftExecC2R (plan2 , (hipfftComplex * )dataC , (hipfftReal * )dataC ); 159 }else { 160hipfftExecC2C (plan , (hipfftComplex * )dataC , (hipfftComplex * )dataC ,-1 ); 161hipfftExecC2C (plan , (hipfftComplex * )dataC , (hipfftComplex * )dataC ,1 ); 162 } 163break ; 164case 1 : 165if (userParams -> R2C ){ 166hipfftExecD2Z (plan , (hipfftDoubleReal * )dataC , (hipfftDoubleComplex * )dataC ); 167hipfftExecZ2D (plan2 , (hipfftDoubleComplex * )dataC , (hipfftDoubleReal * )dataC ); 168 }else { 169hipfftExecZ2Z (plan , (hipfftDoubleComplex * )dataC , (hipfftDoubleComplex * )dataC ,-1 ); 170hipfftExecZ2Z (plan , (hipfftDoubleComplex * )dataC , (hipfftDoubleComplex * )dataC ,1 ); 171 } 172break ; 173 } 174 } 175hipDeviceSynchronize (); 176 std::chrono::steady_clock::time_point timeEnd = std::chrono::steady_clock::now (); 177totTime = (std::chrono::duration_cast < std::chrono::microseconds > (timeEnd - timeSubmit ).count ()* 0.001 ) /userParams -> N ; 178 179run_time [r ][0 ]= totTime ; 180if (n > 0 ) { 181if (r == num_runs - 1 ) { 182double std_error = 0 ; 183double avg_time = 0 ; 184for (uint64_t t = 2 ;t < num_runs ;t ++ ) { 185avg_time += run_time [t ][0 ]; 186 } 187avg_time /= (num_runs - 2 ); 188for (uint64_t t = 2 ;t < num_runs ;t ++ ) { 189std_error += (run_time [t ][0 ]- avg_time )* (run_time [t ][0 ]- avg_time ); 190 } 191std_error = sqrt (std_error / (num_runs - 2 )); 192if (file_output ) 193fprintf (output ,"rocFFT System: %" PRIu64 "x%" PRIu64 "x%" PRIu64 " Batch: %" PRIu64 " Buffer: %" PRIu64 " MB avg_time_per_step: %0.3f ms std_error: %0.3f num_iter: %" PRIu64 " benchmark: %" PRIu64 " scaled bandwidth: %0.1f\n" ,userParams -> X ,userParams -> Y ,userParams -> Z ,userParams -> B ,bufferSize /1024 /1024 ,avg_time ,std_error ,userParams -> N , (uint64_t )(((double )bufferSize /1024 ) /avg_time ), ((double )bufferSize /1024.0 /1024.0 /1.024 * 4 * FFTdim /avg_time )); 194 195printf ("rocFFT System: %" PRIu64 "x%" PRIu64 "x%" PRIu64 " Batch: %" PRIu64 " Buffer: %" PRIu64 " MB avg_time_per_step: %0.3f ms std_error: %0.3f num_iter: %" PRIu64 " benchmark: %" PRIu64 " scaled bandwidth: %0.1f\n" ,userParams -> X ,userParams -> Y ,userParams -> Z ,userParams -> B ,bufferSize /1024 /1024 ,avg_time ,std_error ,userParams -> N , (uint64_t )(((double )bufferSize /1024 ) /avg_time ), ((double )bufferSize /1024.0 /1024.0 /1.024 * 4 * FFTdim /avg_time )); 196benchmark_result [0 ]+= ((double )bufferSize /1024 ) /avg_time ; 197 } 198 199 } 200hipfftDestroy (plan ); 201if (userParams -> R2C ) 202hipfftDestroy (plan2 ); 203hipFree (dataC ); 204hipDeviceSynchronize (); 205//hipfftComplex* output_rocFFT = (hipfftComplex*)(malloc(sizeof(hipfftComplex) * dims[0] * dims[1] * dims[2])); 206//hipMemcpy(output_rocFFT, dataC, sizeof(hipfftComplex) * dims[0] * dims[1] * dims[2], hipMemcpyDeviceToHost); 207//hipDeviceSynchronize(); 208 } 209 } 210free (buffer_input ); 211}