From 48b841284a5bea488ba24c349b1f1a607dffd073 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 1 Aug 2024 16:12:57 -0700 Subject: [PATCH 01/11] doc(example/real): fix comment, better prog name --- example/real-transform.f90 | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 example/real-transform.f90 diff --git a/example/real-transform.f90 b/example/real-transform.f90 new file mode 100644 index 0000000..845f3c0 --- /dev/null +++ b/example/real-transform.f90 @@ -0,0 +1,51 @@ +program round_trip_transform_of_real_function + !! This program invokes fftpack's rrft function to compute the forward transform of a real function + !! and constructs the resulting complex Fourier coefficients by (re)organizing and normalizing the + !! rfft result according to array element layout described at [1]. The program also demonstrates + !! the inverse transform of the normalized rrft result to recover the original function. + !! + !! [1] https://docs.scipy.org/doc/scipy/reference/generated/scipy.fftpack.rfft.html#scipy.fftpack.rfft + use fftpack, only: rfft, irfft + implicit none + integer j, k + integer, parameter :: N = 8 + double precision, parameter :: two_pi = 2.D0*acos(-1.D0), tolerance = 1.0D-06, f_avg = 3.D0, zero=0.D0 + double precision, parameter :: x(0:N-1) = [(two_pi*dble(j)/dble(N), j=0,N-1)] + double precision, parameter :: f(0:N-1) = f_avg + cos(x) + !! sample f(x) = 3 + cos(x) uniformly on [0,2*pi) + !! = 3 + (exp(i*x) - exp(-i*x))/2 + !! which yields the Fourier coefficients + !! { 3, k = 0 + !! f_hat = { 1/2, k = 1 + !! { 0, otherwise + double precision, dimension(0:N-1) :: f_round_trip, rfft_f + integer, parameter :: rk = kind(two_pi) + complex(rk) f_hat(0:N/2) + character(len=*), parameter :: real_format = "(a,*(g10.4,:,1x))" !! space-separated values + character(len=*), parameter :: complex_format= "(a,*('(',g10.4,',',g10.4,')',:,1x)))" !! space-separated complex values + + call assert(mod(N,2)==0, "the algorithm below requires even N") + + rfft_f(:) = rfft(f)/dble(N) + f_hat(:) = [ & + cmplx(rfft_f(0),zero), & + [( cmplx(rfft_f(k),rfft_f(k+1)), k=lbound(rfft_f,1)+1,ubound(rfft_f,1)-1,2)], & + cmplx(zero,rfft_f(N-1)) & + ] + f_round_trip(:) = irfft(rfft_f) + + print real_format, "f = ", f + print complex_format, "f_hat = ", f_hat + print real_format, "f_round_trip = ",f_round_trip + + call assert(all(abs(f_round_trip - f) < tolerance), "inverse of forward FFT must yield the original function") + +contains + + pure subroutine assert(assertion, description) + logical, intent(in) :: assertion + character(len=*), intent(in) :: description + if (.not. assertion) error stop description + end subroutine + +end program From 24f6a67473c37abf3d6fa5109d3346a335086ac9 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 1 Aug 2024 16:14:15 -0700 Subject: [PATCH 02/11] feat(example): add complex-transform.f90 --- example/complex-transform.f90 | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 example/complex-transform.f90 diff --git a/example/complex-transform.f90 b/example/complex-transform.f90 new file mode 100644 index 0000000..182ea2b --- /dev/null +++ b/example/complex-transform.f90 @@ -0,0 +1,46 @@ +program round_trip_transform_of_complex_function + !! This program invokes fftpack's fft function to compute the forward transform of a complex function + !! and the inverse transform of the result. An assertion verifies the expected result of the forward + !! transform according to the element layout described at [1]. A second assertion checks that the + !! inverse transform recovers the original function. + !! + !! [1] https://docs.scipy.org/doc/scipy/reference/generated/scipy.fftpack.fft.html#scipy.fftpack.fft + use fftpack, only: fft, ifft + implicit none + integer j, k + integer, parameter :: N = 8 + double precision, parameter :: two_pi = 2.D0*acos(-1.D0), tolerance = 1.0D-06, f_avg = 3.D0, zero=0.D0 + double precision, parameter :: x(0:N-1) = [(two_pi*dble(j)/dble(N), j=0,N-1)] + integer, parameter :: rk = kind(two_pi) + complex(rk), parameter :: f(0:N-1) = f_avg + cos(x) + !! sample f(x) = 3 + cos(x) uniformly on [0,2*pi) + !! = 3 + (exp(i*x) - exp(-i*x))/2 + !! which yields the Fourier coefficients + !! { 3, k = 0 + !! f_hat = { 1/2, k = 1 + !! { 1/2, k = -1 + !! { 0, otherwise + complex(rk), dimension(0:N-1) :: f_round_trip, fft_f + character(len=*), parameter :: real_format = "(a,*(g10.4,:,1x))" !! space-separated values + character(len=*), parameter :: complex_format= "(a,*('(',g10.4,',',g10.4,')',:,1x)))" !! space-separated complex values + + call assert(mod(N,2)==0, "the algorithm below requires even N") + + fft_f(:) = fft(f)/dble(N) + f_round_trip(:) = ifft(fft_f) + + print complex_format, "f = ", f + print complex_format, "fft_f = ", fft_f + print complex_format, "f_round_trip = ",f_round_trip + + !call assert(all(abs(f_round_trip - f) < tolerance), "inverse of forward FFT must yield the original function") + +contains + + pure subroutine assert(assertion, description) + logical, intent(in) :: assertion + character(len=*), intent(in) :: description + if (.not. assertion) error stop description + end subroutine + +end program From 1b93a0d16e2373a8b1fffcf65e6860c3e6c48772 Mon Sep 17 00:00:00 2001 From: ZUO Zhihua Date: Fri, 2 Aug 2024 21:56:17 +0800 Subject: [PATCH 03/11] remove duplicate example_real_transform --- example/real-forward-transform.f90 | 51 ------------------------------ 1 file changed, 51 deletions(-) delete mode 100644 example/real-forward-transform.f90 diff --git a/example/real-forward-transform.f90 b/example/real-forward-transform.f90 deleted file mode 100644 index 8e0d902..0000000 --- a/example/real-forward-transform.f90 +++ /dev/null @@ -1,51 +0,0 @@ -program forward_transform_of_real_function - !! This program invokes fftpack's rrft function to compute the forward transform of a real function - !! and constructs the resulting complex Fourier coefficients by (re)organizing and normalizing the - !! rfft result according to array element layout described at [1]. The program also demonstrates - !! the inverse transform of the raw rrft result to recover the original function. - !! - !! [1] https://docs.scipy.org/doc/scipy/reference/generated/scipy.fftpack.rfft.html#scipy.fftpack.rfft - use fftpack, only: rfft, irfft - implicit none - integer j, k - integer, parameter :: N = 8 - double precision, parameter :: two_pi = 2.D0*acos(-1.D0), tolerance = 1.0D-06, f_avg = 3.D0, zero=0.D0 - double precision, parameter :: x(0:N-1) = [(two_pi*dble(j)/dble(N), j=0,N-1)] - double precision, parameter :: f(0:N-1) = f_avg + cos(x) - !! sample f(x) = 3 + cos(x) uniformly on [0,2*pi) - !! = 3 + (exp(i*x) - exp(-i*x))/2 - !! which yields the Fourier coefficients - !! { 3, k = 0 - !! f_hat = { 1/2, k = 1 - !! { 0, otherwise - double precision, dimension(0:N-1) :: f_round_trip, rfft_f - integer, parameter :: rk = kind(two_pi) - complex(rk) f_hat(0:N/2) - character(len=*), parameter :: real_format = "(a,*(g10.4,:,1x))" !! space-separated values - character(len=*), parameter :: complex_format= "(a,*('(',g10.4,',',g10.4,')',:,1x)))" !! space-separated complex values - - call assert(mod(N,2)==0, "the algorithm below requires even N") - - rfft_f(:) = rfft(f)/dble(N) - f_hat(:) = [ & - cmplx(rfft_f(0),zero), & - [( cmplx(rfft_f(k),rfft_f(k+1)), k=lbound(rfft_f,1)+1,ubound(rfft_f,1)-1,2)], & - cmplx(zero,rfft_f(N-1)) & - ] - f_round_trip(:) = irfft(rfft_f) - - print real_format, "f = ", f - print complex_format, "f_hat = ", f_hat - print real_format, "f_round_trip = ",f_round_trip - - call assert(all(abs(f_round_trip - f) < tolerance), "inverse of forward FFT must yield the original function") - -contains - - pure subroutine assert(assertion, description) - logical, intent(in) :: assertion - character(len=*), intent(in) :: description - if (.not. assertion) error stop description - end subroutine - -end program From a59773fa489f8fd4df168abf97bcfe1cf315b4f7 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 8 Aug 2024 11:57:15 -0700 Subject: [PATCH 04/11] chore(example): match file/program names --- example/{complex-transform.f90 => complex_transforms.f90} | 2 +- example/{real-transform.f90 => real_transforms.f90} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename example/{complex-transform.f90 => complex_transforms.f90} (97%) rename example/{real-transform.f90 => real_transforms.f90} (97%) diff --git a/example/complex-transform.f90 b/example/complex_transforms.f90 similarity index 97% rename from example/complex-transform.f90 rename to example/complex_transforms.f90 index 182ea2b..f1ff0f5 100644 --- a/example/complex-transform.f90 +++ b/example/complex_transforms.f90 @@ -1,4 +1,4 @@ -program round_trip_transform_of_complex_function +program complex_transforms !! This program invokes fftpack's fft function to compute the forward transform of a complex function !! and the inverse transform of the result. An assertion verifies the expected result of the forward !! transform according to the element layout described at [1]. A second assertion checks that the diff --git a/example/real-transform.f90 b/example/real_transforms.f90 similarity index 97% rename from example/real-transform.f90 rename to example/real_transforms.f90 index 845f3c0..c250b31 100644 --- a/example/real-transform.f90 +++ b/example/real_transforms.f90 @@ -1,4 +1,4 @@ -program round_trip_transform_of_real_function +program real_transforms !! This program invokes fftpack's rrft function to compute the forward transform of a real function !! and constructs the resulting complex Fourier coefficients by (re)organizing and normalizing the !! rfft result according to array element layout described at [1]. The program also demonstrates From e15ca399485a1b688e31457e9a1d22b59a7c82b0 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 8 Aug 2024 11:58:03 -0700 Subject: [PATCH 05/11] build(cmake): add progs in example/CMakeLists.txt --- example/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 2ada3bd..ddd4b43 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -9,3 +9,9 @@ target_link_libraries(bench3 fftpack) add_executable(rfft_example) target_link_libraries(rfft_example fftpack) + +add_executable(complex_transforms) +target_link_libraries(complex_transforms fftpack) + +add_executable(real_transforms) +target_link_libraries(real_transforms fftpack) From 82c0cd31885c1b4d20590b486c8f3ff18cdb2010 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 8 Aug 2024 12:52:51 -0700 Subject: [PATCH 06/11] chore(CI): update CI to use {macos,gcc}-latest --- .github/workflows/cmake.yml | 2 +- .github/workflows/fpm.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 12f654b..616a3cd 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -17,7 +17,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest] toolchain: - - {compiler: gcc, version: 11} + - {compiler: gcc, version: 14} - {compiler: intel-classic, version: '2021.9'} include: - os: ubuntu-latest diff --git a/.github/workflows/fpm.yml b/.github/workflows/fpm.yml index 55c4f84..6414adb 100644 --- a/.github/workflows/fpm.yml +++ b/.github/workflows/fpm.yml @@ -8,13 +8,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-11] - gcc_v: [10] # Version of GFortran we want to use. + os: [ubuntu-latest, macos-latest] + gcc_v: [14] # Version of GFortran we want to use. include: - os: ubuntu-latest os-arch: linux-x86_64 - - os: macos-11 + - os: macos-latest os-arch: macos-x86_64 env: From 94b924522ac42310d3bde81beaf103b739039b4a Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 8 Aug 2024 13:41:25 -0700 Subject: [PATCH 07/11] Revert "chore(CI): update CI to use {macos,gcc}-latest" This reverts commit 82c0cd31885c1b4d20590b486c8f3ff18cdb2010. --- .github/workflows/cmake.yml | 2 +- .github/workflows/fpm.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 616a3cd..12f654b 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -17,7 +17,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest] toolchain: - - {compiler: gcc, version: 14} + - {compiler: gcc, version: 11} - {compiler: intel-classic, version: '2021.9'} include: - os: ubuntu-latest diff --git a/.github/workflows/fpm.yml b/.github/workflows/fpm.yml index 6414adb..55c4f84 100644 --- a/.github/workflows/fpm.yml +++ b/.github/workflows/fpm.yml @@ -8,13 +8,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] - gcc_v: [14] # Version of GFortran we want to use. + os: [ubuntu-latest, macos-11] + gcc_v: [10] # Version of GFortran we want to use. include: - os: ubuntu-latest os-arch: linux-x86_64 - - os: macos-latest + - os: macos-11 os-arch: macos-x86_64 env: From 1b74847c21412967b025992ed1cca6793c8893ec Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 8 Aug 2024 21:04:47 -0700 Subject: [PATCH 08/11] build(CI): switch to macos-latest but keep GCC 10 --- .github/workflows/fpm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fpm.yml b/.github/workflows/fpm.yml index 55c4f84..6cddc44 100644 --- a/.github/workflows/fpm.yml +++ b/.github/workflows/fpm.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-11] + os: [ubuntu-latest, macos-latest] gcc_v: [10] # Version of GFortran we want to use. include: - os: ubuntu-latest From 07798940d3731b1aac918541c6aa17b6b845f259 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 8 Aug 2024 21:06:01 -0700 Subject: [PATCH 09/11] build(CI): update GCC from 10 to 11 --- .github/workflows/fpm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fpm.yml b/.github/workflows/fpm.yml index 6cddc44..b6e37f3 100644 --- a/.github/workflows/fpm.yml +++ b/.github/workflows/fpm.yml @@ -9,7 +9,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - gcc_v: [10] # Version of GFortran we want to use. + gcc_v: [11] # Version of GFortran we want to use. include: - os: ubuntu-latest os-arch: linux-x86_64 From 2cb89358efb07df0e084862abec3405a2ef899d9 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Thu, 8 Aug 2024 21:07:58 -0700 Subject: [PATCH 10/11] build(CI): update GCC from 11 to 12 --- .github/workflows/fpm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fpm.yml b/.github/workflows/fpm.yml index b6e37f3..bd41cec 100644 --- a/.github/workflows/fpm.yml +++ b/.github/workflows/fpm.yml @@ -9,7 +9,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - gcc_v: [11] # Version of GFortran we want to use. + gcc_v: [12] # Version of GFortran we want to use. include: - os: ubuntu-latest os-arch: linux-x86_64 From d646b905ce02ffd630955da96939efde09e77257 Mon Sep 17 00:00:00 2001 From: ZUO Zhihua Date: Sat, 10 Aug 2024 03:38:08 +0800 Subject: [PATCH 11/11] update gcc and fpm version for macos --- .github/workflows/fpm.yml | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/.github/workflows/fpm.yml b/.github/workflows/fpm.yml index bd41cec..42730f1 100644 --- a/.github/workflows/fpm.yml +++ b/.github/workflows/fpm.yml @@ -8,13 +8,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] - gcc_v: [12] # Version of GFortran we want to use. + os: [ubuntu-latest, macos-12] + gcc_v: [11] # Version of GFortran we want to use. include: - os: ubuntu-latest os-arch: linux-x86_64 - - os: macos-11 + - os: macos-12 os-arch: macos-x86_64 env: @@ -25,24 +25,35 @@ jobs: - name: Checkout code uses: actions/checkout@v1 - - name: Install GFortran macOS - if: contains(matrix.os, 'macos') - run: | - ln -s /usr/local/bin/gfortran-${GCC_V} /usr/local/bin/gfortran - which gfortran-${GCC_V} - which gfortran - - name: Install GFortran Linux if: contains(matrix.os, 'ubuntu') run: | sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_V} 100 \ --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} \ --slave /usr/bin/gcov gcov /usr/bin/gcov-${GCC_V} - + + # Backport gfortran shared libraries to version 9 folder. This is necessary because the macOS release of fpm + # 0.10.0 used for bootstrapping has these paths hardcoded in the executable. + # See https://github.com/fortran-lang/fpm/pull/1061 + - name: MacOS patch libgfortran + if: contains(matrix.os, 'macos') + run: | + ln -s /usr/local/bin/gfortran-${GCC_V} /usr/local/bin/gfortran + which gfortran-${GCC_V} + which gfortran + mkdir /usr/local/opt/gcc@10 + mkdir /usr/local/opt/gcc@10/lib + mkdir /usr/local/opt/gcc@10/lib/gcc + mkdir /usr/local/opt/gcc@10/lib/gcc/10 + mkdir /usr/local/lib/gcc/10 + ln -fs /usr/local/opt/gcc@${GCC_V}/lib/gcc/${GCC_V}/libquadmath.0.dylib /usr/local/opt/gcc@10/lib/gcc/10/libquadmath.0.dylib + ln -fs /usr/local/opt/gcc@${GCC_V}/lib/gcc/${GCC_V}/libgfortran.5.dylib /usr/local/opt/gcc@10/lib/gcc/10/libgfortran.5.dylib + ln -fs /usr/local/lib/gcc/${GCC_V}/libgcc_s.1.dylib /usr/local/lib/gcc/10/libgcc_s.1.dylib + - name: Install fpm - uses: fortran-lang/setup-fpm@v3 + uses: fortran-lang/setup-fpm@v5 with: - fpm-version: 'v0.8.2' + fpm-version: 'v0.9.0' - name: Build fftpack run: |