Skip to content

Commit dbca829

Browse files
committed
Adding options to switch kernel at runtime
1 parent b4b8a10 commit dbca829

File tree

20 files changed

+556
-164
lines changed

20 files changed

+556
-164
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ if(FINUFFT_USE_CPU)
8383
add_subdirectory(src)
8484
endif()
8585

86+
add_subdirectory(src/common)
87+
8688
if(FINUFFT_USE_CUDA)
8789
include(cuda_setup)
8890
add_subdirectory(src/cuda)

cmake/utils.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function(enable_asan target)
103103
endfunction()
104104

105105
function(finufft_link_test target)
106-
target_link_libraries(${target} PRIVATE finufft::finufft)
106+
target_link_libraries(${target} PRIVATE finufft::finufft finufft::common)
107107
if(FINUFFT_USE_DUCC0)
108108
target_compile_definitions(${target} PRIVATE FINUFFT_USE_DUCC0)
109109
endif()

include/finufft.fh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ c DEPRECATED: spread_kerpad kept for ABI compatibility, ignored by library
2020
real*8 upsampfac
2121
integer spread_thread, maxbatchsize, spread_nthr_atomic
2222
integer spread_max_sp_size
23+
integer spread_kernel
2324
integer fftw_lock_fun, fftw_unlock_fun, fftw_lock_data
2425

2526
end type

include/finufft/spreadinterp.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ namespace finufft {
2121
namespace spreadinterp {
2222

2323
template<typename T>
24-
FINUFFT_EXPORT_TEST int setup_spreader(finufft_spread_opts &opts, T eps, double upsampfac,
25-
int kerevalmeth, int debug, int showwarn,
26-
int spreadinterponly, int dim);
24+
FINUFFT_EXPORT_TEST int setup_spreader(
25+
finufft_spread_opts &opts, T eps, double upsampfac, int kerevalmeth, int debug,
26+
int showwarn, int spreadinterponly, int dim, int kernel_type = 0);
2727

2828
int spreadcheck(UBIGINT N1, UBIGINT N2, UBIGINT N3, const finufft_spread_opts &opts);
2929
template<typename T>

include/finufft_common/kernel.h

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <vector>
77

88
#include <finufft_common/constants.h>
9+
#include <finufft_common/utils.h>
10+
#include <finufft_spread_opts.h>
911

1012
namespace finufft::kernel {
1113

@@ -56,15 +58,34 @@ template<class T, class F> std::vector<T> fit_monomials(F &&f, int n, T a, T b)
5658
return c;
5759
}
5860

59-
template<typename T> T evaluate_kernel(T x, T beta, T c) {
60-
/* ES ("exp sqrt") kernel evaluation at single real argument:
61-
phi(x) = exp(beta.(sqrt(1 - (2x/n_s)^2) - 1)), for |x| < nspread/2
62-
related to an asymptotic approximation to the Kaiser--Bessel, itself an
63-
approximation to prolate spheroidal wavefunction (PSWF) of order 0.
64-
This is the "reference implementation", used by eg finufft/onedim_* 2/17/17.
65-
Rescaled so max is 1, Barnett 7/21/24
61+
template<typename T> T evaluate_kernel(T x, T beta, T c, int kernel_type = 0) {
62+
/* Kernel evaluation at single real argument.
63+
kernel_type == 0 : ES ("exp sqrt") kernel (default)
64+
phi_ES(x) = exp(beta*(sqrt(1 - c*x^2) - 1))
65+
kernel_type == 1 : Kaiser--Bessel (KB) kernel
66+
phi_KB(x) = I_0(beta*sqrt(1 - c*x^2)) / I_0(beta)
67+
Note: `std::cyl_bessel_i` from <cmath> is used for I_0.
68+
Rescaled so max is 1.
6669
*/
70+
if (kernel_type == 1) {
71+
// Kaiser--Bessel (normalized by I0(beta)). Use std::cyl_bessel_i from <cmath>.
72+
const T inner = std::sqrt(T(1) - c * x * x);
73+
const T arg = beta * inner;
74+
const double i0_arg = ::finufft::common::cyl_bessel_i(0, static_cast<double>(arg));
75+
const double i0_beta = ::finufft::common::cyl_bessel_i(0, static_cast<double>(beta));
76+
return static_cast<T>(i0_arg / i0_beta);
77+
}
78+
79+
// default to ES
6780
return std::exp(beta * (std::sqrt(T(1) - c * x * x) - T(1)));
6881
}
6982

83+
FINUFFT_EXPORT int compute_kernel_ns(double upsampfac, double tol, int kernel_type,
84+
const finufft_spread_opts &opts);
85+
86+
FINUFFT_EXPORT void initialize_kernel_params(finufft_spread_opts &opts, double upsampfac,
87+
double tol, int kernel_type);
88+
89+
FINUFFT_EXPORT double sigma_max_tol(double upsampfac, int kernel_type, int max_ns);
90+
7091
} // namespace finufft::kernel

include/finufft_common/utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ namespace common {
1313
FINUFFT_EXPORT_TEST void gaussquad(int n, double *xgl, double *wgl);
1414
std::tuple<double, double> leg_eval(int n, double x);
1515

16+
// Series implementation of the modified Bessel function of the first kind I_nu(x)
17+
double cyl_bessel_i(double nu, double x) noexcept;
18+
1619
// helper to generate the integer sequence in range [Start, End]
1720
template<int Offset, typename Seq> struct offset_seq;
1821

include/finufft_mod.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module finufft_mod
2121
real(kind=C_DOUBLE) :: upsampfac
2222
integer(kind=C_INT) :: spread_thread, maxbatchsize
2323
integer(kind=C_INT) :: spread_nthr_atomic, spread_max_sp_size
24+
integer(kind=C_INT) :: spread_kernel
2425
integer(kind=C_SIZE_T) :: fftw_lock_fun, fftw_unlock_fun, fftw_lock_data
2526
! really, last should be type(C_PTR) :: etc, but fails to print nicely
2627

include/finufft_opts.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ typedef struct finufft_opts { // defaults see finufft_core.cpp:finufft_default_o
3232
int spread_nthr_atomic; // if >=0, threads above which spreader OMP critical goes
3333
// atomic
3434
int spread_max_sp_size; // if >0, overrides spreader (dir=1) max subproblem size
35+
int spread_function; // (dev only) 0:DEFAULT, (do not change), there is no guarantee
36+
// what non-zero values do and behaviour can change anytime
3537
// sphinx tag (don't remove): @opts_end
3638

3739
// User can provide their own FFTW planner lock functions for thread safety

include/finufft_spread_opts.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ typedef struct finufft_spread_opts {
2626
double ES_beta;
2727
double ES_halfwidth;
2828
double ES_c;
29+
// Kernel selector: 0 = ES (default), 1 = Kaiser--Bessel (KB)
30+
int kernel_type; // default 0
2931
} finufft_spread_opts;
3032

3133
#endif // FINUFFT_SPREAD_OPTS_H

matlab/finufft.mw

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ $ }
103103
$ else if (strcmp(fname[ifield],"spread_max_sp_size") == 0) {
104104
$ oc->spread_max_sp_size = (int)round(*mxGetPr(mxGetFieldByNumber(om,idx,ifield)));
105105
$ }
106+
$ else if (strcmp(fname[ifield],"spread_kernel") == 0) {
107+
$ oc->spread_kernel = (int)round(*mxGetPr(mxGetFieldByNumber(om,idx,ifield)));
108+
$ }
106109
$ else if (strcmp(fname[ifield],"spreadinterponly") == 0) {
107110
$ oc->spreadinterponly = (int)round(*mxGetPr(mxGetFieldByNumber(om,idx,ifield)));
108111
$ }

0 commit comments

Comments
 (0)