diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3e0b14b744..adb8ba8350 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: - name: Configure run: | - cmake -B build -DBUILD_TESTING=ON -DENABLE_DEEPKS=ON -DENABLE_MLKEDF=ON -DENABLE_LIBXC=ON -DENABLE_LIBRI=ON -DENABLE_PAW=ON -DENABLE_GOOGLEBENCH=ON -DENABLE_RAPIDJSON=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=1 + cmake -B build -DBUILD_TESTING=ON -DENABLE_DEEPKS=ON -DENABLE_MLKEDF=ON -DENABLE_LIBXC=ON -DENABLE_LIBRI=ON -DENABLE_PAW=ON -DENABLE_GOOGLEBENCH=ON -DENABLE_RAPIDJSON=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DENABLE_FLOAT_FFTW=ON - uses: pre-commit/action@v3.0.1 with: diff --git a/source/module_basis/module_pw/CMakeLists.txt b/source/module_basis/module_pw/CMakeLists.txt index 549e41c93c..12a6b2183e 100644 --- a/source/module_basis/module_pw/CMakeLists.txt +++ b/source/module_basis/module_pw/CMakeLists.txt @@ -46,4 +46,8 @@ if(BUILD_TESTING) add_subdirectory(test_serial) add_subdirectory(kernels/test) endif() + add_subdirectory(module_fft/test) + if (ENABLE_FLOAT_FFTW) + add_subdirectory(module_fft/test_fftwf) + endif() endif() diff --git a/source/module_basis/module_pw/module_fft/fft_bundle.cpp b/source/module_basis/module_pw/module_fft/fft_bundle.cpp index c2718abf5d..f020596585 100644 --- a/source/module_basis/module_pw/module_fft/fft_bundle.cpp +++ b/source/module_basis/module_pw/module_fft/fft_bundle.cpp @@ -3,6 +3,7 @@ #include "module_base/module_device/device.h" #include "module_base/module_device/memory_op.h" +#include "module_base/tool_quit.h" #if defined(__CUDA) #include "fft_cuda.h" #endif @@ -10,11 +11,6 @@ #include "fft_rocm.h" #endif -template -std::unique_ptr make_unique(Args &&... args) -{ - return std::unique_ptr(new FFT_BASE(std::forward(args)...)); -} namespace ModulePW { FFT_Bundle::~FFT_Bundle() @@ -43,27 +39,48 @@ void FFT_Bundle::initfft(int nx_in, assert(this->device=="cpu" || this->device=="gpu"); assert(this->precision=="single" || this->precision=="double" || this->precision=="mixing"); - if (this->precision=="single") + float_flag = (this->precision=="single" || this->precision=="mixing")? true:false; + double_flag = true; + + if (this->device=="gpu") { - #if not defined (__ENABLE_FLOAT_FFTW) - if (this->device == "cpu"){ - float_define = false; - } - #endif - #if defined(__CUDA) || defined (__ROCM) - if (this->device == "gpu"){ - float_flag = float_define; - } + #if defined(__ROCM) + if (float_flag) + { + fft_float = make_unique>(); + fft_float->initfft(nx_in,ny_in,nz_in); + } + if (double_flag) + { + fft_double = make_unique>(); + fft_double->initfft(nx_in,ny_in,nz_in); + } + #elif defined(__CUDA) + if (float_flag) + { + fft_float = make_unique>(); + fft_float->initfft(nx_in,ny_in,nz_in); + } + if (double_flag) + { + fft_double = make_unique>(); + fft_double->initfft(nx_in,ny_in,nz_in); + } + #else + std::cout<<"wihout the CUDA OR DCU,but set the device as gpu, use cpu instead\n"; + this->device="cpu"; #endif - float_flag = float_define; - double_flag = true; - } - if (this->precision=="double") - { - double_flag = true; } + + #if not defined (__ENABLE_FLOAT_FFTW) + if (this->device == "cpu" && float_flag) + { + float_define = false; + ModuleBase::WARNING_QUIT("initfft", "please complie abacus with fftw3_FLOAT"); + } + #endif - if (device=="cpu") + if (this->device=="cpu") { fft_float = make_unique>(this->fft_mode); fft_double = make_unique>(this->fft_mode); @@ -94,21 +111,6 @@ void FFT_Bundle::initfft(int nx_in, xprime_in); } } - if (device=="gpu") - { - #if defined(__ROCM) - fft_float = make_unique>(); - fft_float->initfft(nx_in,ny_in,nz_in); - fft_double = make_unique>(); - fft_double->initfft(nx_in,ny_in,nz_in); - #elif defined(__CUDA) - fft_float = make_unique>(); - fft_float->initfft(nx_in,ny_in,nz_in); - fft_double = make_unique>(); - fft_double->initfft(nx_in,ny_in,nz_in); - #endif - } - } void FFT_Bundle::setupFFT() diff --git a/source/module_basis/module_pw/module_fft/fft_bundle.h b/source/module_basis/module_pw/module_fft/fft_bundle.h index 71ce5192f3..aabe1c2a85 100644 --- a/source/module_basis/module_pw/module_fft/fft_bundle.h +++ b/source/module_basis/module_pw/module_fft/fft_bundle.h @@ -6,6 +6,12 @@ #include "fft_cpu.h" namespace ModulePW { +template +std::unique_ptr make_unique(Args &&... args) +{ + return std::unique_ptr(new FFT_BASE(std::forward(args)...)); +} + class FFT_Bundle { public: diff --git a/source/module_basis/module_pw/module_fft/fft_cpu.cpp b/source/module_basis/module_pw/module_fft/fft_cpu.cpp index be920d4ae2..fb9c1b00ba 100644 --- a/source/module_basis/module_pw/module_fft/fft_cpu.cpp +++ b/source/module_basis/module_pw/module_fft/fft_cpu.cpp @@ -300,7 +300,7 @@ void FFT_CPU::setupFFT() template <> void FFT_CPU::clearfft(fftw_plan& plan) { - if (plan) + if (plan!=nullptr) { fftw_destroy_plan(plan); plan = nullptr; diff --git a/source/module_basis/module_pw/module_fft/fft_cpu.h b/source/module_basis/module_pw/module_fft/fft_cpu.h index c0fe9992eb..3bb2b5ab11 100644 --- a/source/module_basis/module_pw/module_fft/fft_cpu.h +++ b/source/module_basis/module_pw/module_fft/fft_cpu.h @@ -102,31 +102,31 @@ class FFT_CPU : public FFT_BASE void clearfft(fftw_plan& plan); void clearfft(fftwf_plan& plan); - fftw_plan planzfor = NULL; - fftw_plan planzbac = NULL; - fftw_plan planxfor1 = NULL; - fftw_plan planxbac1 = NULL; - fftw_plan planxfor2 = NULL; - fftw_plan planxbac2 = NULL; - fftw_plan planyfor = NULL; - fftw_plan planybac = NULL; - fftw_plan planxr2c = NULL; - fftw_plan planxc2r = NULL; - fftw_plan planyr2c = NULL; - fftw_plan planyc2r = NULL; - - fftwf_plan planfzfor = NULL; - fftwf_plan planfzbac = NULL; - fftwf_plan planfxfor1= NULL; - fftwf_plan planfxbac1= NULL; - fftwf_plan planfxfor2= NULL; - fftwf_plan planfxbac2= NULL; - fftwf_plan planfyfor = NULL; - fftwf_plan planfybac = NULL; - fftwf_plan planfxr2c = NULL; - fftwf_plan planfxc2r = NULL; - fftwf_plan planfyr2c = NULL; - fftwf_plan planfyc2r = NULL; + fftw_plan planzfor = nullptr; + fftw_plan planzbac = nullptr; + fftw_plan planxfor1 = nullptr; + fftw_plan planxbac1 = nullptr; + fftw_plan planxfor2 = nullptr; + fftw_plan planxbac2 = nullptr; + fftw_plan planyfor = nullptr; + fftw_plan planybac = nullptr; + fftw_plan planxr2c = nullptr; + fftw_plan planxc2r = nullptr; + fftw_plan planyr2c = nullptr; + fftw_plan planyc2r = nullptr; + + fftwf_plan planfzfor = nullptr; + fftwf_plan planfzbac = nullptr; + fftwf_plan planfxfor1= nullptr; + fftwf_plan planfxbac1= nullptr; + fftwf_plan planfxfor2= nullptr; + fftwf_plan planfxbac2= nullptr; + fftwf_plan planfyfor = nullptr; + fftwf_plan planfybac = nullptr; + fftwf_plan planfxr2c = nullptr; + fftwf_plan planfxc2r = nullptr; + fftwf_plan planfyr2c = nullptr; + fftwf_plan planfyc2r = nullptr; std::complex*c_auxg = nullptr; std::complex*c_auxr = nullptr; // fft space diff --git a/source/module_basis/module_pw/module_fft/fft_cpu_float.cpp b/source/module_basis/module_pw/module_fft/fft_cpu_float.cpp index b3e8d7d572..163350bd6f 100644 --- a/source/module_basis/module_pw/module_fft/fft_cpu_float.cpp +++ b/source/module_basis/module_pw/module_fft/fft_cpu_float.cpp @@ -269,7 +269,7 @@ void FFT_CPU::setupFFT() template <> void FFT_CPU::clearfft(fftwf_plan& plan) { - if (plan) + if (plan!=nullptr) { fftwf_destroy_plan(plan); plan = nullptr; diff --git a/source/module_basis/module_pw/module_fft/test/CMakeLists.txt b/source/module_basis/module_pw/module_fft/test/CMakeLists.txt new file mode 100644 index 0000000000..7cc726a886 --- /dev/null +++ b/source/module_basis/module_pw/module_fft/test/CMakeLists.txt @@ -0,0 +1,16 @@ +remove_definitions(-D__CUDA) +remove_definitions(-D__RCOM) + +AddTest( + TARGET fft_bundle_without_fftwf_test + LIBS parameter ${math_libs} base device FFTW3::FFTW3 + SOURCES fft_bundle_without_fftwf_test.cpp + ../fft_bundle.cpp ../fft_cpu.cpp +) + +AddTest( + TARGET fft_test_cpu + LIBS parameter ${math_libs} base device FFTW3::FFTW3 + SOURCES fft_test_cpu.cpp + ../fft_bundle.cpp ../fft_cpu.cpp +) \ No newline at end of file diff --git a/source/module_basis/module_pw/module_fft/test/fft_bundle_without_fftwf_test.cpp b/source/module_basis/module_pw/module_fft/test/fft_bundle_without_fftwf_test.cpp new file mode 100644 index 0000000000..7d64b52239 --- /dev/null +++ b/source/module_basis/module_pw/module_fft/test/fft_bundle_without_fftwf_test.cpp @@ -0,0 +1,64 @@ +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "malloc.h" +#include "fstream" +#define private public +#include "../fft_base.h" +#include "../fft_bundle.h" +#include "../fft_cpu.h" +#include "module_parameter/parameter.h" +#undef private +namespace ModulePW +{ +class FftBundleTest : public ::testing::Test +{ + protected: + FFT_Bundle fft_bundle; + std::string output; + void SetUp() override + { + } + void TearDown() override + { + } + }; + + TEST_F(FftBundleTest,setfft) + { + fft_bundle.setfft("cpu","single"); + EXPECT_EQ(fft_bundle.device,"cpu"); + EXPECT_EQ(fft_bundle.precision,"single"); + + fft_bundle.setfft("gpu","double"); + EXPECT_EQ(fft_bundle.device,"gpu"); + EXPECT_EQ(fft_bundle.precision,"double"); + } + + TEST_F(FftBundleTest,initfft) + { + fft_bundle.setfft("cpu","single"); + testing::internal::CaptureStdout(); + EXPECT_EXIT(fft_bundle.initfft(16,16,16,7,8,256,16,1,false,true), + ::testing::ExitedWithCode(1),""); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output,testing::HasSubstr("complie")); + + fft_bundle.setfft("cpu","double"); + fft_bundle.initfft(16,16,16,7,8,256,16,1,false,true); + EXPECT_EQ(fft_bundle.float_flag,false); + EXPECT_EQ(fft_bundle.double_flag,true); + + fft_bundle.setfft("gpu","double"); + fft_bundle.initfft(16,16,16,7,8,256,16,1,false,true); + EXPECT_EQ(fft_bundle.float_flag,false); + EXPECT_EQ(fft_bundle.double_flag,true); + + fft_bundle.setfft("gpu","single"); + testing::internal::CaptureStdout(); + EXPECT_EXIT(fft_bundle.initfft(16,16,16,7,8,256,16,1,false,true), + ::testing::ExitedWithCode(1),""); + output = testing::internal::GetCapturedStdout(); + EXPECT_THAT(output,testing::HasSubstr("complie")); + + } +} \ No newline at end of file diff --git a/source/module_basis/module_pw/module_fft/test/fft_test_cpu.cpp b/source/module_basis/module_pw/module_fft/test/fft_test_cpu.cpp new file mode 100644 index 0000000000..b98aa5c8cd --- /dev/null +++ b/source/module_basis/module_pw/module_fft/test/fft_test_cpu.cpp @@ -0,0 +1,130 @@ +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "malloc.h" +#include "fstream" +#define private public +#include "../fft_base.h" +#include "../fft_bundle.h" +#include "../fft_cpu.h" +#include "module_parameter/parameter.h" +#undef private +namespace ModulePW +{ + +class FftCpuTest : public ::testing::Test +{ +protected: + std::shared_ptr> fft_cpu_double; + std::shared_ptr> fft_cpu_float; + std::string output; + std::vector> input_double; + std::vector> input_float; + void SetUp() override + { + int value =0; + input_double.resize(4096); + std::generate(input_double.begin(),input_double.end(), + [&value]{return std::complex(value++,value);}); + fft_cpu_double = make_unique>(0); + fft_cpu_double->initfft(16,16,16,7,8,256,16,1,false,true); + fft_cpu_double->setupFFT(); + + } + void TearDown() override + { + fft_cpu_double->clear(); + } +}; + +TEST_F(FftCpuTest,initfft) +{ + + EXPECT_EQ(fft_cpu_double->fftnx,16); + EXPECT_EQ(fft_cpu_double->fftny,16); + EXPECT_EQ(fft_cpu_double->fftnxy,256); + EXPECT_EQ(fft_cpu_double->ns,256); + EXPECT_EQ(fft_cpu_double->lixy,7); + EXPECT_EQ(fft_cpu_double->rixy,8); + EXPECT_EQ(fft_cpu_double->nplane,16); + +} + +TEST_F(FftCpuTest,setupFFT) +{ + //cheak double cpu type + + EXPECT_EQ(sizeof(fft_cpu_double->z_auxg[0]),16); + EXPECT_EQ(sizeof(fft_cpu_double->d_rspace),8); + + FILE *file = fopen("plan_output.txt", "w"); + fflush(stdout); + stdout = file; + + fftw_print_plan(fft_cpu_double->planzbac); + fftw_print_plan(fft_cpu_double->planxbac1); + fclose(file); + stdout = fdopen(1, "w"); + + std::ifstream input_file("plan_output.txt"); + getline(input_file,output); + input_file.close(); + EXPECT_THAT(output,testing::HasSubstr("16")); + +} + +TEST_F(FftCpuTest,fftzforAndBac) +{ + fft_cpu_double->fftzfor(input_double.data(),input_double.data()); + fft_cpu_double->fftzbac(input_double.data(),input_double.data()); + + // the fftw need to normalization + for (int i=0;i<4096;i++) + { + EXPECT_EQ(input_double[i], + std::complex(fft_cpu_double->nplane*i,fft_cpu_double->nplane*i)); + } + +} + +TEST_F(FftCpuTest,fftxyforAndBac) +{ + fft_cpu_double->fftxyfor(input_double.data(),input_double.data()); + fft_cpu_double->fftxybac(input_double.data(),input_double.data()); + for (int i=0;i<2;i++) + { + EXPECT_EQ(input_double[i], + std::complex(fft_cpu_double->fftnxy*i,fft_cpu_double->fftnxy*i)); + } + +} + +TEST_F(FftCpuTest,clearfft) +{ + //test clean plan + EXPECT_NE(fft_cpu_double->planzbac,nullptr); + EXPECT_NE(fft_cpu_double->planzfor,nullptr); + EXPECT_NE(fft_cpu_double->planxfor1,nullptr); + EXPECT_NE(fft_cpu_double->planxbac1,nullptr); + EXPECT_NE(fft_cpu_double->planyfor,nullptr); + EXPECT_NE(fft_cpu_double->planybac,nullptr); + fft_cpu_double->cleanFFT(); + EXPECT_EQ(fft_cpu_double->planzbac,nullptr); + EXPECT_EQ(fft_cpu_double->planzfor,nullptr); + EXPECT_EQ(fft_cpu_double->planxfor1,nullptr); + EXPECT_EQ(fft_cpu_double->planxbac1,nullptr); + EXPECT_EQ(fft_cpu_double->planyfor,nullptr); + EXPECT_EQ(fft_cpu_double->planybac,nullptr); + +} + +TEST_F(FftCpuTest,clear) +{ + EXPECT_NE(fft_cpu_double->z_auxg,nullptr); + EXPECT_NE(fft_cpu_double->z_auxr,nullptr); + fft_cpu_double->clear(); + EXPECT_EQ(fft_cpu_double->z_auxg,nullptr); + EXPECT_EQ(fft_cpu_double->z_auxr,nullptr); + + +} +} \ No newline at end of file diff --git a/source/module_basis/module_pw/module_fft/test_fftwf/CMakeLists.txt b/source/module_basis/module_pw/module_fft/test_fftwf/CMakeLists.txt new file mode 100644 index 0000000000..af70ce4036 --- /dev/null +++ b/source/module_basis/module_pw/module_fft/test_fftwf/CMakeLists.txt @@ -0,0 +1,17 @@ +remove_definitions(-D__CUDA) +remove_definitions(-D__RCOM) + +add_compile_definitions(__ENABLE_FLOAT_FFTW) +find_package(FFTW3 REQUIRED) +AddTest( + TARGET fft_cpu_test + LIBS parameter ${math_libs} base device FFTW3::FFTW3 FFTW3::FFTW3_FLOAT + SOURCES fft_test_cpu.cpp + ../fft_bundle.cpp ../fft_cpu.cpp ../fft_cpu_float.cpp +) +AddTest( + TARGET fft_bundle_test + LIBS parameter ${math_libs} base device FFTW3::FFTW3 FFTW3::FFTW3_FLOAT + SOURCES fft_bundle_test.cpp + ../fft_bundle.cpp ../fft_cpu.cpp ../fft_cpu_float.cpp +) \ No newline at end of file diff --git a/source/module_basis/module_pw/module_fft/test_fftwf/fft_bundle_test.cpp b/source/module_basis/module_pw/module_fft/test_fftwf/fft_bundle_test.cpp new file mode 100644 index 0000000000..72f2107497 --- /dev/null +++ b/source/module_basis/module_pw/module_fft/test_fftwf/fft_bundle_test.cpp @@ -0,0 +1,60 @@ +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "malloc.h" +#include "fstream" +#define private public +#include "../fft_base.h" +#include "../fft_bundle.h" +#include "../fft_cpu.h" +#include "module_parameter/parameter.h" +#undef private +namespace ModulePW +{ +class FftBundleTest : public ::testing::Test +{ + protected: + FFT_Bundle fft_bundle; + std::string output; + void SetUp() override + { + } + void TearDown() override + { + } + }; + + TEST_F(FftBundleTest,setfft) + { + fft_bundle.setfft("cpu","single"); + EXPECT_EQ(fft_bundle.device,"cpu"); + EXPECT_EQ(fft_bundle.precision,"single"); + + fft_bundle.setfft("gpu","double"); + EXPECT_EQ(fft_bundle.device,"gpu"); + EXPECT_EQ(fft_bundle.precision,"double"); + } + + TEST_F(FftBundleTest,initfft) + { + fft_bundle.setfft("cpu","single"); + fft_bundle.initfft(16,16,16,7,8,256,16,1,false,true); + EXPECT_EQ(fft_bundle.float_flag,true); + EXPECT_EQ(fft_bundle.double_flag,true); + + fft_bundle.setfft("cpu","double"); + fft_bundle.initfft(16,16,16,7,8,256,16,1,false,true); + EXPECT_EQ(fft_bundle.float_flag,false); + EXPECT_EQ(fft_bundle.double_flag,true); + + fft_bundle.setfft("gpu","double"); + fft_bundle.initfft(16,16,16,7,8,256,16,1,false,true); + EXPECT_EQ(fft_bundle.float_flag,false); + EXPECT_EQ(fft_bundle.double_flag,true); + + fft_bundle.setfft("gpu","single"); + fft_bundle.initfft(16,16,16,7,8,256,16,1,false,true); + EXPECT_EQ(fft_bundle.float_flag,true); + EXPECT_EQ(fft_bundle.double_flag,true); + + } +} \ No newline at end of file diff --git a/source/module_basis/module_pw/module_fft/test_fftwf/fft_test_cpu.cpp b/source/module_basis/module_pw/module_fft/test_fftwf/fft_test_cpu.cpp new file mode 100644 index 0000000000..f06acdf524 --- /dev/null +++ b/source/module_basis/module_pw/module_fft/test_fftwf/fft_test_cpu.cpp @@ -0,0 +1,197 @@ +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "malloc.h" +#include "fstream" +#define private public +#include "../fft_base.h" +#include "../fft_bundle.h" +#include "../fft_cpu.h" +#include "module_parameter/parameter.h" +#undef private +namespace ModulePW +{ + +class FftCpuTest : public ::testing::Test +{ +protected: + std::shared_ptr> fft_cpu_double; + std::shared_ptr> fft_cpu_float; + std::string output; + std::vector> input_double; + std::vector> input_float; + void SetUp() override + { + int value =0; + input_double.resize(4096); + std::generate(input_double.begin(),input_double.end(), + [&value]{return std::complex(value++,value);}); + fft_cpu_double = make_unique>(0); + fft_cpu_double->initfft(16,16,16,7,8,256,16,1,false,true); + fft_cpu_double->setupFFT(); + + input_float.resize(4096); + value =0; + std::generate(input_float.begin(),input_float.end(), + [&value](){return std::complex(value++,value);}); + + fft_cpu_float = make_unique>(0); + fft_cpu_float->initfft(16,16,16,7,8,256,16,1,false,true); + fft_cpu_float->setupFFT(); + } + void TearDown() override + { + fft_cpu_double->clear(); + fft_cpu_float->clear(); + } +}; + +TEST_F(FftCpuTest,initfft) +{ + + EXPECT_EQ(fft_cpu_double->fftnx,16); + EXPECT_EQ(fft_cpu_double->fftny,16); + EXPECT_EQ(fft_cpu_double->fftnxy,256); + EXPECT_EQ(fft_cpu_double->ns,256); + EXPECT_EQ(fft_cpu_double->lixy,7); + EXPECT_EQ(fft_cpu_double->rixy,8); + EXPECT_EQ(fft_cpu_double->nplane,16); + + EXPECT_EQ(fft_cpu_float->fftnx,16); + EXPECT_EQ(fft_cpu_float->fftny,16); + EXPECT_EQ(fft_cpu_float->fftnxy,256); + EXPECT_EQ(fft_cpu_float->ns,256); + EXPECT_EQ(fft_cpu_float->lixy,7); + EXPECT_EQ(fft_cpu_float->rixy,8); + EXPECT_EQ(fft_cpu_float->nplane,16); +} + +TEST_F(FftCpuTest,setupFFT) +{ + //cheak double cpu type + + EXPECT_EQ(sizeof(fft_cpu_double->z_auxg[0]),16); + EXPECT_EQ(sizeof(fft_cpu_double->d_rspace),8); + + FILE *file = fopen("plan_output.txt", "w"); + fflush(stdout); + stdout = file; + + fftw_print_plan(fft_cpu_double->planzbac); + fftw_print_plan(fft_cpu_double->planxbac1); + fclose(file); + stdout = fdopen(1, "w"); + + std::ifstream input_file("plan_output.txt"); + getline(input_file,output); + input_file.close(); + EXPECT_THAT(output,testing::HasSubstr("16")); + + //check float cpu type + fft_cpu_float->setupFFT(); + EXPECT_EQ(sizeof(fft_cpu_float->c_auxg[0]),8); + EXPECT_EQ(sizeof(fft_cpu_double->s_rspace),8); + + file = fopen("planf_output.txt", "w"); + fflush(stdout); + stdout = file; + + fftwf_print_plan(fft_cpu_float->planfzbac); + fftwf_print_plan(fft_cpu_float->planfxbac1); + fclose(file); + stdout = fdopen(1, "w"); + + std::ifstream inputf_file("planf_output.txt"); + getline(inputf_file,output); + EXPECT_THAT(output,testing::HasSubstr("16")); +} + +TEST_F(FftCpuTest,fftzforAndBac) +{ + fft_cpu_double->fftzfor(input_double.data(),input_double.data()); + fft_cpu_double->fftzbac(input_double.data(),input_double.data()); + + // the fftw need to normalization + for (int i=0;i<4096;i++) + { + EXPECT_EQ(input_double[i], + std::complex(fft_cpu_double->nplane*i,fft_cpu_double->nplane*i)); + } + + fft_cpu_float->fftzfor(input_float.data(),input_float.data()); + fft_cpu_float->fftzbac(input_float.data(),input_float.data()); + + // the fftw need to normalization + for (int i=0;i<4096;i++) + { + EXPECT_EQ(input_float[i], + std::complex(fft_cpu_float->nplane*i,fft_cpu_float->nplane*i)); + } +} + +TEST_F(FftCpuTest,fftxyforAndBac) +{ + fft_cpu_double->fftxyfor(input_double.data(),input_double.data()); + fft_cpu_double->fftxybac(input_double.data(),input_double.data()); + for (int i=0;i<2;i++) + { + EXPECT_EQ(input_double[i], + std::complex(fft_cpu_double->fftnxy*i,fft_cpu_double->fftnxy*i)); + } + + fft_cpu_float->fftxyfor(input_float.data(),input_float.data()); + fft_cpu_float->fftxybac(input_float.data(),input_float.data()); + for (int i=0;i<2;i++) + { + EXPECT_EQ(input_float[i], + std::complex(fft_cpu_float->fftnxy*i,fft_cpu_float->fftnxy*i)); + } +} + +TEST_F(FftCpuTest,clearfft) +{ + //test clean plan + EXPECT_NE(fft_cpu_double->planzbac,nullptr); + EXPECT_NE(fft_cpu_double->planzfor,nullptr); + EXPECT_NE(fft_cpu_double->planxfor1,nullptr); + EXPECT_NE(fft_cpu_double->planxbac1,nullptr); + EXPECT_NE(fft_cpu_double->planyfor,nullptr); + EXPECT_NE(fft_cpu_double->planybac,nullptr); + fft_cpu_double->cleanFFT(); + EXPECT_EQ(fft_cpu_double->planzbac,nullptr); + EXPECT_EQ(fft_cpu_double->planzfor,nullptr); + EXPECT_EQ(fft_cpu_double->planxfor1,nullptr); + EXPECT_EQ(fft_cpu_double->planxbac1,nullptr); + EXPECT_EQ(fft_cpu_double->planyfor,nullptr); + EXPECT_EQ(fft_cpu_double->planybac,nullptr); + + EXPECT_NE(fft_cpu_float->planfzbac,nullptr); + EXPECT_NE(fft_cpu_float->planfzfor,nullptr); + EXPECT_NE(fft_cpu_float->planfxfor1,nullptr); + EXPECT_NE(fft_cpu_float->planfxbac1,nullptr); + EXPECT_NE(fft_cpu_float->planfyfor,nullptr); + EXPECT_NE(fft_cpu_float->planfybac,nullptr); + fft_cpu_float->cleanFFT(); + EXPECT_EQ(fft_cpu_float->planfzbac,nullptr); + EXPECT_EQ(fft_cpu_float->planfzfor,nullptr); + EXPECT_EQ(fft_cpu_float->planfxfor1,nullptr); + EXPECT_EQ(fft_cpu_float->planfxbac1,nullptr); + EXPECT_EQ(fft_cpu_float->planfyfor,nullptr); + EXPECT_EQ(fft_cpu_float->planfybac,nullptr); +} + +TEST_F(FftCpuTest,clear) +{ + EXPECT_NE(fft_cpu_double->z_auxg,nullptr); + EXPECT_NE(fft_cpu_double->z_auxr,nullptr); + fft_cpu_double->clear(); + EXPECT_EQ(fft_cpu_double->z_auxg,nullptr); + EXPECT_EQ(fft_cpu_double->z_auxr,nullptr); + + EXPECT_NE(fft_cpu_float->c_auxg,nullptr); + EXPECT_NE(fft_cpu_float->c_auxr,nullptr); + fft_cpu_float->clear(); + EXPECT_EQ(fft_cpu_float->c_auxg,nullptr); + EXPECT_EQ(fft_cpu_float->c_auxr,nullptr); + +} +} \ No newline at end of file