Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ Master (working towards v2.5.0), 10/24/25
* cmake: cache query and result for supported compiler flags to speed up
configuration (Stanimirov #725).
* move include/common to include/finufft_common (Stanimirov #734)
* Fixed symbol visibility issues so shared libraries export the Fortran wrapper
entry points and test helpers consistently on Windows and macOS. This
included tightening default visibility in the makefile, introducing
`FINUFFT_EXPORT_TEST` for test-only APIs, and ensuring FFT backends are linked
through a dedicated `finufft_fftlibs` interface target. (Barbone, Reinecke #737)

V 2.4.1 7/8/25

Expand Down
4 changes: 4 additions & 0 deletions cmake/setupDUCC.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ if(ducc0_ADDED)
target_link_libraries(ducc0 PRIVATE Threads::Threads)
endif()
enable_asan(ducc0)
set_target_properties(ducc0 PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN YES)

add_library(finufft_fftlibs INTERFACE)
target_link_libraries(finufft_fftlibs INTERFACE ducc0)
endif()
3 changes: 3 additions & 0 deletions cmake/setupFFTW.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,6 @@ if(FINUFFT_FFTW_LIBRARIES STREQUAL DEFAULT OR FINUFFT_FFTW_LIBRARIES STREQUAL DO
endif()
endif()
endif()

add_library(finufft_fftlibs INTERFACE)
target_link_libraries(finufft_fftlibs INTERFACE ${FINUFFT_FFTW_LIBRARIES})
1 change: 1 addition & 0 deletions cmake/toolchain.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ set(FINUFFT_CXX_FLAGS_RELEASE
-ftree-vectorize
-fimplicit-constexpr
-fcx-limited-range
-fno-semantic-interposition
-O3
/Ox
/fp:contract
Expand Down
3 changes: 2 additions & 1 deletion cmake/utils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ include(CheckCXXCompilerFlag)
function(filter_supported_compiler_flags input_flags_var output_flags_var)
string(MD5 input_hash "${${input_flags_var}}")
if(DEFINED SUPPORTED_FLAGS_${input_hash})
message(STATUS "Using cached flags for ${input_flags_var}: ${SUPPORTED_FLAGS_${input_hash}}")
message(STATUS "Using cached flags for ${input_flags_var}: ${SUPPORTED_FLAGS_${input_hash}}")
set(${output_flags_var} ${SUPPORTED_FLAGS_${input_hash}} PARENT_SCOPE)
return()
endif()
Expand Down Expand Up @@ -113,4 +113,5 @@ function(finufft_link_test target)
if(FINUFFT_HAS_NO_DEPRECATED_DECLARATIONS)
target_compile_options(${target} PRIVATE -Wno-deprecated-declarations)
endif()
target_link_libraries(${target} PRIVATE finufft_fftlibs)
endfunction()
48 changes: 48 additions & 0 deletions fortran/finufftfort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extern "C" {
#endif

// --------------------- guru interface from fortran ------------------------
FINUFFT_EXPORT
void finufft_makeplan_(int *type, int *n_dims, i64 *n_modes, int *iflag, int *n_transf,
f64 *tol, finufft_plan *plan, finufft_opts *o, int *ier) {
if (!plan)
Expand All @@ -45,6 +46,7 @@ void finufft_makeplan_(int *type, int *n_dims, i64 *n_modes, int *iflag, int *n_
}
}

FINUFFT_EXPORT
void finufft_setpts_(finufft_plan *plan, i64 *M, f64 *xj, f64 *yj, f64 *zj, i64 *nk,
f64 *s, f64 *t, f64 *u, int *ier) {
if (!*plan) {
Expand All @@ -56,20 +58,23 @@ void finufft_setpts_(finufft_plan *plan, i64 *M, f64 *xj, f64 *yj, f64 *zj, i64
*ier = finufft_setpts(*plan, *M, xj, yj, zj, nk_safe, s, t, u);
}

FINUFFT_EXPORT
void finufft_execute_(finufft_plan *plan, c128 *weights, c128 *result, int *ier) {
if (!plan)
fprintf(stderr, "%s fortran: finufft_plan unallocated!", __func__);
else
*ier = finufft_execute(*plan, weights, result);
}

FINUFFT_EXPORT
void finufft_execute_adjoint_(finufft_plan *plan, c128 *weights, c128 *result, int *ier) {
if (!plan)
fprintf(stderr, "%s fortran: finufft_plan unallocated!", __func__);
else
*ier = finufft_execute_adjoint(*plan, weights, result);
}

FINUFFT_EXPORT
void finufft_destroy_(finufft_plan *plan, int *ier) {
if (!plan)
fprintf(stderr, "%s fortran: finufft_plan unallocated!", __func__);
Expand All @@ -79,6 +84,7 @@ void finufft_destroy_(finufft_plan *plan, int *ier) {

// ------------ use FINUFFT to set the default options ---------------------
// (Note the finufft_opts is created in f90-style derived types, not here)
FINUFFT_EXPORT
void finufft_default_opts_(finufft_opts *o) {
if (!o)
fprintf(stderr, "%s fortran: opts must be allocated!\n", __func__);
Expand All @@ -89,102 +95,121 @@ void finufft_default_opts_(finufft_opts *o) {

// -------------- simple and many-vector interfaces --------------------
// --- 1D ---
FINUFFT_EXPORT
void finufft1d1_(i64 *nj, f64 *xj, c128 *cj, int *iflag, f64 *eps, i64 *ms, c128 *fk,
finufft_opts *o, int *ier) {
*ier = finufft1d1(*nj, xj, cj, *iflag, *eps, *ms, fk, o);
}

FINUFFT_EXPORT
void finufft1d1many_(int *ntransf, i64 *nj, f64 *xj, c128 *cj, int *iflag, f64 *eps,
i64 *ms, c128 *fk, finufft_opts *o, int *ier) {
*ier = finufft1d1many(*ntransf, *nj, xj, cj, *iflag, *eps, *ms, fk, o);
}

FINUFFT_EXPORT
void finufft1d2_(i64 *nj, f64 *xj, c128 *cj, int *iflag, f64 *eps, i64 *ms, c128 *fk,
finufft_opts *o, int *ier) {
*ier = finufft1d2(*nj, xj, cj, *iflag, *eps, *ms, fk, o);
}

FINUFFT_EXPORT
void finufft1d2many_(int *ntransf, i64 *nj, f64 *xj, c128 *cj, int *iflag, f64 *eps,
i64 *ms, c128 *fk, finufft_opts *o, int *ier) {
*ier = finufft1d2many(*ntransf, *nj, xj, cj, *iflag, *eps, *ms, fk, o);
}

FINUFFT_EXPORT
void finufft1d3_(i64 *nj, f64 *x, c128 *c, int *iflag, f64 *eps, i64 *nk, f64 *s, c128 *f,
finufft_opts *o, int *ier) {
*ier = finufft1d3(*nj, x, c, *iflag, *eps, *nk, s, f, o);
}

FINUFFT_EXPORT
void finufft1d3many_(int *ntransf, i64 *nj, f64 *x, c128 *c, int *iflag, f64 *eps,
i64 *nk, f64 *s, c128 *f, finufft_opts *o, int *ier) {
*ier = finufft1d3many(*ntransf, *nj, x, c, *iflag, *eps, *nk, s, f, o);
}

// --- 2D ---
FINUFFT_EXPORT
void finufft2d1_(i64 *nj, f64 *xj, f64 *yj, c128 *cj, int *iflag, f64 *eps, i64 *ms,
i64 *mt, c128 *fk, finufft_opts *o, int *ier) {
*ier = finufft2d1(*nj, xj, yj, cj, *iflag, *eps, *ms, *mt, fk, o);
}
FINUFFT_EXPORT
void finufft2d1many_(int *ntransf, i64 *nj, f64 *xj, f64 *yj, c128 *cj, int *iflag,
f64 *eps, i64 *ms, i64 *mt, c128 *fk, finufft_opts *o, int *ier) {
*ier = finufft2d1many(*ntransf, *nj, xj, yj, cj, *iflag, *eps, *ms, *mt, fk, o);
}

FINUFFT_EXPORT
void finufft2d2_(i64 *nj, f64 *xj, f64 *yj, c128 *cj, int *iflag, f64 *eps, i64 *ms,
i64 *mt, c128 *fk, finufft_opts *o, int *ier) {
*ier = finufft2d2(*nj, xj, yj, cj, *iflag, *eps, *ms, *mt, fk, o);
}
FINUFFT_EXPORT
void finufft2d2many_(int *ntransf, i64 *nj, f64 *xj, f64 *yj, c128 *cj, int *iflag,
f64 *eps, i64 *ms, i64 *mt, c128 *fk, finufft_opts *o, int *ier) {
*ier = finufft2d2many(*ntransf, *nj, xj, yj, cj, *iflag, *eps, *ms, *mt, fk, o);
}

FINUFFT_EXPORT
void finufft2d3_(i64 *nj, f64 *x, f64 *y, c128 *c, int *iflag, f64 *eps, i64 *nk, f64 *s,
f64 *t, c128 *f, finufft_opts *o, int *ier) {
*ier = finufft2d3(*nj, x, y, c, *iflag, *eps, *nk, s, t, f, o);
}

FINUFFT_EXPORT
void finufft2d3many_(int *ntransf, i64 *nj, f64 *x, f64 *y, c128 *c, int *iflag, f64 *eps,
i64 *nk, f64 *s, f64 *t, c128 *f, finufft_opts *o, int *ier) {
*ier = finufft2d3many(*ntransf, *nj, x, y, c, *iflag, *eps, *nk, s, t, f, o);
}

// --- 3D ---
FINUFFT_EXPORT
void finufft3d1_(i64 *nj, f64 *xj, f64 *yj, f64 *zj, c128 *cj, int *iflag, f64 *eps,
i64 *ms, i64 *mt, i64 *mu, c128 *fk, finufft_opts *o, int *ier) {
*ier = finufft3d1(*nj, xj, yj, zj, cj, *iflag, *eps, *ms, *mt, *mu, fk, o);
}

FINUFFT_EXPORT
void finufft3d1many_(int *ntransf, i64 *nj, f64 *xj, f64 *yj, f64 *zj, c128 *cj,
int *iflag, f64 *eps, i64 *ms, i64 *mt, i64 *mu, c128 *fk,
finufft_opts *o, int *ier) {
*ier =
finufft3d1many(*ntransf, *nj, xj, yj, zj, cj, *iflag, *eps, *ms, *mt, *mu, fk, o);
}

FINUFFT_EXPORT
void finufft3d2_(i64 *nj, f64 *xj, f64 *yj, f64 *zj, c128 *cj, int *iflag, f64 *eps,
i64 *ms, i64 *mt, i64 *mu, c128 *fk, finufft_opts *o, int *ier) {
*ier = finufft3d2(*nj, xj, yj, zj, cj, *iflag, *eps, *ms, *mt, *mu, fk, o);
}

FINUFFT_EXPORT
void finufft3d2many_(int *ntransf, i64 *nj, f64 *xj, f64 *yj, f64 *zj, c128 *cj,
int *iflag, f64 *eps, i64 *ms, i64 *mt, i64 *mu, c128 *fk,
finufft_opts *o, int *ier) {
*ier =
finufft3d2many(*ntransf, *nj, xj, yj, zj, cj, *iflag, *eps, *ms, *mt, *mu, fk, o);
}

FINUFFT_EXPORT
void finufft3d3_(i64 *nj, f64 *x, f64 *y, f64 *z, c128 *c, int *iflag, f64 *eps, i64 *nk,
f64 *s, f64 *t, f64 *u, c128 *f, finufft_opts *o, int *ier) {
*ier = finufft3d3(*nj, x, y, z, c, *iflag, *eps, *nk, s, t, u, f, o);
}

FINUFFT_EXPORT
void finufft3d3many_(int *ntransf, i64 *nj, f64 *x, f64 *y, f64 *z, c128 *c, int *iflag,
f64 *eps, i64 *nk, f64 *s, f64 *t, f64 *u, c128 *f, finufft_opts *o,
int *ier) {
*ier = finufft3d3many(*ntransf, *nj, x, y, z, c, *iflag, *eps, *nk, s, t, u, f, o);
}

// --------------------- guru interface from fortran ------------------------
FINUFFT_EXPORT
void finufftf_makeplan_(int *type, int *n_dims, i64 *n_modes, int *iflag, int *n_transf,
f32 *tol, finufftf_plan *plan, finufft_opts *o, int *ier) {
if (!plan)
Expand All @@ -198,6 +223,7 @@ void finufftf_makeplan_(int *type, int *n_dims, i64 *n_modes, int *iflag, int *n
}
}

FINUFFT_EXPORT
void finufftf_setpts_(finufftf_plan *plan, i64 *M, f32 *xj, f32 *yj, f32 *zj, i64 *nk,
f32 *s, f32 *t, f32 *u, int *ier) {
if (!*plan) {
Expand All @@ -209,20 +235,23 @@ void finufftf_setpts_(finufftf_plan *plan, i64 *M, f32 *xj, f32 *yj, f32 *zj, i6
*ier = finufftf_setpts(*plan, *M, xj, yj, zj, nk_safe, s, t, u);
}

FINUFFT_EXPORT
void finufftf_execute_(finufftf_plan *plan, c64 *weights, c64 *result, int *ier) {
if (!plan)
fprintf(stderr, "%s fortran: finufft_plan unallocated!", __func__);
else
*ier = finufftf_execute(*plan, weights, result);
}

FINUFFT_EXPORT
void finufftf_execute_adjoint_(finufftf_plan *plan, c64 *weights, c64 *result, int *ier) {
if (!plan)
fprintf(stderr, "%s fortran: finufft_plan unallocated!", __func__);
else
*ier = finufftf_execute_adjoint(*plan, weights, result);
}

FINUFFT_EXPORT
void finufftf_destroy_(finufftf_plan *plan, int *ier) {
if (!plan)
fprintf(stderr, "%s fortran: finufft_plan unallocated!", __func__);
Expand All @@ -232,6 +261,7 @@ void finufftf_destroy_(finufftf_plan *plan, int *ier) {

// ------------ use FINUFFT to set the default options ---------------------
// (Note the finufft_opts is created in f90-style derived types, not here)
FINUFFT_EXPORT
void finufftf_default_opts_(finufft_opts *o) {
if (!o)
fprintf(stderr, "%s fortran: opts must be allocated!\n", __func__);
Expand All @@ -242,95 +272,113 @@ void finufftf_default_opts_(finufft_opts *o) {

// -------------- simple and many-vector interfaces --------------------
// --- 1D ---
FINUFFT_EXPORT
void finufftf1d1_(i64 *nj, f32 *xj, c64 *cj, int *iflag, f32 *eps, i64 *ms, c64 *fk,
finufft_opts *o, int *ier) {
*ier = finufftf1d1(*nj, xj, cj, *iflag, *eps, *ms, fk, o);
}

FINUFFT_EXPORT
void finufftf1d1many_(int *ntransf, i64 *nj, f32 *xj, c64 *cj, int *iflag, f32 *eps,
i64 *ms, c64 *fk, finufft_opts *o, int *ier) {
*ier = finufftf1d1many(*ntransf, *nj, xj, cj, *iflag, *eps, *ms, fk, o);
}

FINUFFT_EXPORT
void finufftf1d2_(i64 *nj, f32 *xj, c64 *cj, int *iflag, f32 *eps, i64 *ms, c64 *fk,
finufft_opts *o, int *ier) {
*ier = finufftf1d2(*nj, xj, cj, *iflag, *eps, *ms, fk, o);
}

FINUFFT_EXPORT
void finufftf1d2many_(int *ntransf, i64 *nj, f32 *xj, c64 *cj, int *iflag, f32 *eps,
i64 *ms, c64 *fk, finufft_opts *o, int *ier) {
*ier = finufftf1d2many(*ntransf, *nj, xj, cj, *iflag, *eps, *ms, fk, o);
}

FINUFFT_EXPORT
void finufftf1d3_(i64 *nj, f32 *x, c64 *c, int *iflag, f32 *eps, i64 *nk, f32 *s, c64 *f,
finufft_opts *o, int *ier) {
*ier = finufftf1d3(*nj, x, c, *iflag, *eps, *nk, s, f, o);
}

FINUFFT_EXPORT
void finufftf1d3many_(int *ntransf, i64 *nj, f32 *x, c64 *c, int *iflag, f32 *eps,
i64 *nk, f32 *s, c64 *f, finufft_opts *o, int *ier) {
*ier = finufftf1d3many(*ntransf, *nj, x, c, *iflag, *eps, *nk, s, f, o);
}

// --- 2D ---
FINUFFT_EXPORT
void finufftf2d1_(i64 *nj, f32 *xj, f32 *yj, c64 *cj, int *iflag, f32 *eps, i64 *ms,
i64 *mt, c64 *fk, finufft_opts *o, int *ier) {
*ier = finufftf2d1(*nj, xj, yj, cj, *iflag, *eps, *ms, *mt, fk, o);
}
FINUFFT_EXPORT
void finufftf2d1many_(int *ntransf, i64 *nj, f32 *xj, f32 *yj, c64 *cj, int *iflag,
f32 *eps, i64 *ms, i64 *mt, c64 *fk, finufft_opts *o, int *ier) {
*ier = finufftf2d1many(*ntransf, *nj, xj, yj, cj, *iflag, *eps, *ms, *mt, fk, o);
}

FINUFFT_EXPORT
void finufftf2d2_(i64 *nj, f32 *xj, f32 *yj, c64 *cj, int *iflag, f32 *eps, i64 *ms,
i64 *mt, c64 *fk, finufft_opts *o, int *ier) {
*ier = finufftf2d2(*nj, xj, yj, cj, *iflag, *eps, *ms, *mt, fk, o);
}
FINUFFT_EXPORT
void finufftf2d2many_(int *ntransf, i64 *nj, f32 *xj, f32 *yj, c64 *cj, int *iflag,
f32 *eps, i64 *ms, i64 *mt, c64 *fk, finufft_opts *o, int *ier) {
*ier = finufftf2d2many(*ntransf, *nj, xj, yj, cj, *iflag, *eps, *ms, *mt, fk, o);
}

FINUFFT_EXPORT
void finufftf2d3_(i64 *nj, f32 *x, f32 *y, c64 *c, int *iflag, f32 *eps, i64 *nk, f32 *s,
f32 *t, c64 *f, finufft_opts *o, int *ier) {
*ier = finufftf2d3(*nj, x, y, c, *iflag, *eps, *nk, s, t, f, o);
}

FINUFFT_EXPORT
void finufftf2d3many_(int *ntransf, i64 *nj, f32 *x, f32 *y, c64 *c, int *iflag, f32 *eps,
i64 *nk, f32 *s, f32 *t, c64 *f, finufft_opts *o, int *ier) {
*ier = finufftf2d3many(*ntransf, *nj, x, y, c, *iflag, *eps, *nk, s, t, f, o);
}

// --- 3D ---
FINUFFT_EXPORT
void finufftf3d1_(i64 *nj, f32 *xj, f32 *yj, f32 *zj, c64 *cj, int *iflag, f32 *eps,
i64 *ms, i64 *mt, i64 *mu, c64 *fk, finufft_opts *o, int *ier) {
*ier = finufftf3d1(*nj, xj, yj, zj, cj, *iflag, *eps, *ms, *mt, *mu, fk, o);
}

FINUFFT_EXPORT
void finufftf3d1many_(int *ntransf, i64 *nj, f32 *xj, f32 *yj, f32 *zj, c64 *cj,
int *iflag, f32 *eps, i64 *ms, i64 *mt, i64 *mu, c64 *fk,
finufft_opts *o, int *ier) {
*ier =
finufftf3d1many(*ntransf, *nj, xj, yj, zj, cj, *iflag, *eps, *ms, *mt, *mu, fk, o);
}

FINUFFT_EXPORT
void finufftf3d2_(i64 *nj, f32 *xj, f32 *yj, f32 *zj, c64 *cj, int *iflag, f32 *eps,
i64 *ms, i64 *mt, i64 *mu, c64 *fk, finufft_opts *o, int *ier) {
*ier = finufftf3d2(*nj, xj, yj, zj, cj, *iflag, *eps, *ms, *mt, *mu, fk, o);
}

FINUFFT_EXPORT
void finufftf3d2many_(int *ntransf, i64 *nj, f32 *xj, f32 *yj, f32 *zj, c64 *cj,
int *iflag, f32 *eps, i64 *ms, i64 *mt, i64 *mu, c64 *fk,
finufft_opts *o, int *ier) {
*ier =
finufftf3d2many(*ntransf, *nj, xj, yj, zj, cj, *iflag, *eps, *ms, *mt, *mu, fk, o);
}

FINUFFT_EXPORT
void finufftf3d3_(i64 *nj, f32 *x, f32 *y, f32 *z, c64 *c, int *iflag, f32 *eps, i64 *nk,
f32 *s, f32 *t, f32 *u, c64 *f, finufft_opts *o, int *ier) {
*ier = finufftf3d3(*nj, x, y, z, c, *iflag, *eps, *nk, s, t, u, f, o);
}

FINUFFT_EXPORT
void finufftf3d3many_(int *ntransf, i64 *nj, f32 *x, f32 *y, f32 *z, c64 *c, int *iflag,
f32 *eps, i64 *nk, f32 *s, f32 *t, f32 *u, c64 *f, finufft_opts *o,
int *ier) {
Expand Down
Loading
Loading