diff --git a/math/sfft/Makefile b/math/sfft/Makefile index 2a1f158197f6..18373880bb4c 100644 --- a/math/sfft/Makefile +++ b/math/sfft/Makefile @@ -1,115 +1,102 @@ PORTNAME= sfft -PORTVERSION= 0.1.0 -PORTREVISION= 12 +DISTVERSION= 0.1.0 +PORTREVISION= 13 CATEGORIES= math MASTER_SITES= http://spiral.net/software/sfft/ LOCAL/bf DISTFILES= ${DISTNAME}${EXTRACT_SUFX} EXTRACT_ONLY= ${DISTNAME}${EXTRACT_SUFX} MAINTAINER= ports@FreeBSD.org COMMENT= Optimized Sparse Fast Fourier Transform WWW= https://spiral.net/software/sfft.html LICENSE= GPLv2 -ONLY_FOR_ARCHS= amd64 i386 +ONLY_FOR_ARCHS= aarch64 amd64 armv7 i386 ONLY_FOR_ARCHS_REASON= requires SSE instructions, which are x86-specific +BROKEN_armv7= /usr/local/bin/ld: error: unsupported option: -z relro + +BUILD_DEPENDS_aarch64= ${LOCALBASE}/include/sse2neon.h:devel/sse2neon +BUILD_DEPENDS_armv7= ${BUILD_DEPENDS_aarch64} +BUILD_DEPENDS+= ${BUILD_DEPENDS_${ARCH}} + LIB_DEPENDS= libfftw3.so:math/fftw3 -USES= uidfix zip +USES= localbase:ldflags uidfix zip USE_GCC= yes USE_LDCONFIG= yes OPTIONS_DEFINE= OPTIMIZED_CFLAGS PROFILE DOCS OPTIONS_DEFAULT= OPTIMIZED_CFLAGS BUILD_WRKSRC= ${WRKSRC}/src INSTALL_WRKSRC= ${BUILD_WRKSRC} -CFLAGS+= -fopenmp -msse2 -Iflopcount -I${LOCALBASE}/include -LDFLAGS+= -L${LOCALBASE}/lib +CFLAGS_armv7= -mfpu=neon +CFLAGS_i386= -msse2 +CFLAGS+= -fopenmp -Iflopcount +CXXFLAGS+= ${CFLAGS_${ARCH}} -fopenmp -Iflopcount HEADERS= sfft.h HDIR= include/sfft MAKE_ENV= LDADD="-lfftw3 ${LIBM}" LIB=sfft SHLIB_MAJOR="${SHLIB_MAJOR}" \ SRCCONF=/dev/null SRCS="${SRCS}" PLIST_FILES= ${HEADERS:S|^|${HDIR}/|} lib/libsfft.a lib/libsfft.so \ lib/libsfft.so.${SHLIB_MAJOR} SHLIB_MAJOR= 1 SRCS= common.cc computefourier-1.0-2.0.cc \ computefourier-3.0.cc fftw.cc filters.cc parameters.cc \ sfft.cc simulation.cc timer.cc utils.cc .include -.if !${ARCH:Mamd64} && !${MACHINE_CPU:Msse2} -IGNORE= this port requires SSE2, and benefits from SSE3 -- set CPUTYPE\ -appropriately -.endif - LIBM= -lm .if ${PORT_OPTIONS:MDOCS} || make(makesum) DISTFILES+= sfft-doc.pdf PORTDOCS= sfft-doc.pdf .endif .if ${PORT_OPTIONS:MOPTIMIZED_CFLAGS} CFLAGS+= -O3 -ffast-math .endif .if ${PORT_OPTIONS:MPROFILE} .if defined(NOPROFILE) || defined(NO_PROFILE) || defined(WITHOUT_PROFILE) IGNORE= you have defined WITH_PROFILE, but have also defined\ WITHOUT_PROFILE, NOPROFILE, or NO_PROFILE .elif !exists(/usr/lib/libc_p.a) IGNORE= you have chosen WITH_PROFILE, but have not installed the\ base system profiling libraries .endif PLIST_FILES+= lib/libsfft_p.a .else MAKE_ENV+= WITHOUT_PROFILE=yes .endif post-extract: - @${CP} /usr/include/complex.h ${BUILD_WRKSRC}/sfftcomplex.h @${PRINTF} "LIBDIR=\t${PREFIX}/lib\n.include \n" > \ ${BUILD_WRKSRC}/Makefile -post-patch: - @${REINPLACE_CMD} -e 's/string\.h/cstring/' \ - ${WRKSRC}/src/utils.cc - @${REINPLACE_CMD} -E -e '// \ - {s// "sfftcomplex.h"/; x ; \ - s|^.*$$|#endif|; G; x; \ - s|^.*$$|extern "C" {|; G; x; \ - s|^.*$$|#ifdef __cplusplus|; G; x; \ - s|^.*$$|#ifdef __cplusplus|; H; \ - s|^.*$$|}|; H; \ - s|^.*$$|#endif|; H; x;}' \ - ${WRKSRC}/src/computefourier-1.0-2.0.h \ - ${WRKSRC}/src/computefourier-3.0.h \ - ${WRKSRC}/src/fft.h - CORELIMIT?= /usr/bin/limits -Sc 0 do-test: - @cd ${BUILD_WRKSRC}; \ - ${CXX} ${CXXFLAGS} -o sfft-verification verification.cc \ - ${LDFLAGS} libsfft.a -lfftw3 ${LIBM} ; \ - for _v in 1 2 3 ; do \ - for _k in 5 10 50; do \ - echo "Checking sfft version $${_v} with $${_k} frequency components:"; \ - ${CORELIMIT} ./sfft-verification -k $${_k} -r 3 -v $${_v} || ${TRUE} ; \ - done ; done + cd ${BUILD_WRKSRC} && ${CXX} ${CXXFLAGS} -o sfft-verification verification.cc \ + ${LDFLAGS} libsfft.a -lfftw3 ${LIBM} +.for v in 1 2 3 +. for k in 5 10 50 + @${ECHO_CMD} "Checking sfft version $v with $k frequency components:" + cd ${BUILD_WRKSRC} && ${CORELIMIT} ./sfft-verification -k $k -r 3 -v $v || ${TRUE} +. endfor +.endfor post-install: @${MKDIR} ${STAGEDIR}${PREFIX}/${HDIR} @cd ${BUILD_WRKSRC}; ${INSTALL_DATA} ${HEADERS} ${STAGEDIR}${PREFIX}/${HDIR} post-install-DOCS-on: @${MKDIR} ${STAGEDIR}${DOCSDIR} ${INSTALL_DATA} ${_DISTDIR}/${PORTDOCS} ${STAGEDIR}${DOCSDIR} .include diff --git a/math/sfft/files/patch-src__computefourier-1.0-2.0.cc b/math/sfft/files/patch-src__computefourier-1.0-2.0.cc index 09b1e51d5b29..d7a691a639bb 100644 --- a/math/sfft/files/patch-src__computefourier-1.0-2.0.cc +++ b/math/sfft/files/patch-src__computefourier-1.0-2.0.cc @@ -1,55 +1,55 @@ ---- src/computefourier-1.0-2.0.cc.orig 2013-06-13 08:12:25.000000000 -0400 -+++ src/computefourier-1.0-2.0.cc 2013-08-09 00:26:54.000000000 -0400 -@@ -248,8 +248,13 @@ +--- src/computefourier-1.0-2.0.cc.orig 2013-06-13 12:12:25 UTC ++++ src/computefourier-1.0-2.0.cc +@@ -248,8 +248,13 @@ inner_loop_locate(sfft_v1v2_data * data, complex_t * o __m128d ad_bc = _mm_mul_pd(ab, dc); __m128d ac_mbd = _mm_mul_pd(ac_bd, signs); +#ifdef __SSE3__ __m128d ab_times_cd = _mm_hadd_pd(ac_mbd, ad_bc); - +#else + __m128d ab_times_cd_lo = _mm_shuffle_pd(ac_mbd, ad_bc, 0); + __m128d ab_times_cd_hi = _mm_shuffle_pd(ac_mbd, ad_bc, 3); + __m128d ab_times_cd = _mm_add_pd(ab_times_cd_lo, ab_times_cd_hi); +#endif unsigned int i_mod_B_p_offset = (i & B2_m_1) + offset; __m128d xy = _mm_load_pd(d_x_sampt + i_mod_B_p_offset); __m128d st = _mm_add_pd(xy, ab_times_cd); -@@ -283,7 +288,13 @@ +@@ -283,7 +288,13 @@ inner_loop_locate(sfft_v1v2_data * data, complex_t * o __m128d ab_square = _mm_mul_pd(ab, ab); __m128d cd_square = _mm_mul_pd(cd, cd); +#ifdef __SSE3__ __m128d r = _mm_hadd_pd(ab_square, cd_square); +#else + __m128d r_lo = _mm_shuffle_pd(ab_square, cd_square, 0); + __m128d r_hi = _mm_shuffle_pd(ab_square, cd_square, 3); + __m128d r = _mm_add_pd(r_lo, r_hi); +#endif _mm_store_pd(samples + j, r); } -@@ -390,11 +401,23 @@ +@@ -390,11 +401,23 @@ estimate_values(sfft_v1v2_data * data, const int *hits __m128d ad_bc = _mm_mul_pd(ab, dc); __m128d mad_bc = _mm_mul_pd(ad_bc, signs); +#ifdef __SSE3__ __m128d acpbd_bcmad = _mm_hadd_pd(ac_bd, mad_bc); +#else + __m128d acpbd_bcmad_lo = _mm_shuffle_pd(ac_bd, mad_bc, 0); + __m128d acpbd_bcmad_hi = _mm_shuffle_pd(ac_bd, mad_bc, 3); + __m128d acpbd_bcmad = _mm_add_pd(acpbd_bcmad_lo, acpbd_bcmad_hi); +#endif __m128d cd_squares = _mm_mul_pd(cd, cd); + +#ifdef __SSE3__ __m128d cd_squares_sum = _mm_hadd_pd(cd_squares, cd_squares); +#else + __m128d cd_squares_flip = _mm_shuffle_pd(cd_squares, cd_squares, 1); + __m128d cd_squares_sum = _mm_add_pd(cd_squares, cd_squares_flip); +#endif __m128d r = _mm_div_pd(acpbd_bcmad, cd_squares_sum); diff --git a/math/sfft/files/patch-src__computefourier-3.0.cc b/math/sfft/files/patch-src__computefourier-3.0.cc index aba106fdd70a..e1653f6f1de0 100644 --- a/math/sfft/files/patch-src__computefourier-3.0.cc +++ b/math/sfft/files/patch-src__computefourier-3.0.cc @@ -1,132 +1,132 @@ ---- src/computefourier-3.0.cc.orig 2013-06-13 08:12:26.000000000 -0400 -+++ src/computefourier-3.0.cc 2013-08-10 17:02:52.000000000 -0400 -@@ -416,27 +416,64 @@ +--- src/computefourier-3.0.cc.orig 2013-06-13 12:12:26 UTC ++++ src/computefourier-3.0.cc +@@ -416,27 +416,64 @@ update_gaussian_loops2(int key, complex_t value, compl __m128d t1r = _mm_mul_pd(v1r, ab31); __m128d t1i = _mm_mul_pd(v1i, ba31); + +#ifdef __SSE3__ __m128d remove1 = _mm_addsub_pd(t1r, t1i); +#else +__m128i mask_fliplo = _mm_set_epi32(0, 0, 0x80000000, 0); +__m128d t1i_fliplo = _mm_xor_pd(t1i, _mm_castsi128_pd(mask_fliplo)); +__m128d remove1 = _mm_add_pd(t1r, t1i_fliplo); +#endif __m128d t2r = _mm_mul_pd(v1r, ab32); __m128d t2i = _mm_mul_pd(v1i, ba32); + +#ifdef __SSE3__ __m128d remove2 = _mm_addsub_pd(t2r, t2i); +#else +__m128d t2i_fliplo = _mm_xor_pd(t2i, _mm_castsi128_pd(mask_fliplo)); +__m128d remove2 = _mm_add_pd(t2r, t2i_fliplo); +#endif __m128d t3r = _mm_mul_pd(v1r, ab33); __m128d t3i = _mm_mul_pd(v1i, ba33); + +#ifdef __SSE3__ __m128d remove3 = _mm_addsub_pd(t3r, t3i); +#else +__m128d t3i_fliplo = _mm_xor_pd(t3i, _mm_castsi128_pd(mask_fliplo)); +__m128d remove3 = _mm_add_pd(t3r, t3i_fliplo); +#endif __m128d t4r = _mm_mul_pd(v2r, ab31); __m128d t4i = _mm_mul_pd(v2i, ba31); + +#ifdef __SSE3__ __m128d remove4 = _mm_addsub_pd(t4r, t4i); +#else +__m128d t4i_fliplo = _mm_xor_pd(t4i, _mm_castsi128_pd(mask_fliplo)); +__m128d remove4 = _mm_add_pd(t4r, t4i_fliplo); +#endif __m128d t5r = _mm_mul_pd(v2r, ab32); __m128d t5i = _mm_mul_pd(v2i, ba32); + +#ifdef __SSE3__ __m128d remove5 = _mm_addsub_pd(t5r, t5i); +#else +__m128d t5i_fliplo = _mm_xor_pd(t5i, _mm_castsi128_pd(mask_fliplo)); +__m128d remove5 = _mm_add_pd(t5r, t5i_fliplo); +#endif __m128d t6r = _mm_mul_pd(v2r, ab33); __m128d t6i = _mm_mul_pd(v2i, ba33); + +#ifdef __SSE3__ __m128d remove6 = _mm_addsub_pd(t6r, t6i); +#else +__m128d t6i_fliplo = _mm_xor_pd(t6i, _mm_castsi128_pd(mask_fliplo)); +__m128d remove6 = _mm_add_pd(t6r, t6i_fliplo); +#endif FLOPCOUNT_INCREMENT(6 * (4 + 2)); -@@ -524,11 +561,28 @@ +@@ -524,11 +561,28 @@ estimate_freq_gauss_loops2(sfft_v3_data * data, int WH __m128d a3b3_sq = _mm_mul_pd(a3b3, a3b3); FLOPCOUNT_INCREMENT(8); +#ifdef __SSE3__ __m128d c0c1 = _mm_hadd_pd(a0b0_sq, a1b1_sq); __m128d c2c3 = _mm_hadd_pd(a2b2_sq, a3b3_sq); +#else + __m128d c0c1_lo = _mm_shuffle_pd(a0b0_sq, a1b1_sq, 0); + __m128d c0c1_hi = _mm_shuffle_pd(a0b0_sq, a1b1_sq, 3); + __m128d c0c1 = _mm_add_pd(c0c1_lo, c0c1_hi); + __m128d c2c3_lo = _mm_shuffle_pd(a2b2_sq, a3b3_sq, 0); + __m128d c2c3_hi = _mm_shuffle_pd(a2b2_sq, a3b3_sq, 3); + __m128d c2c3 = _mm_add_pd(c2c3_lo, c2c3_hi); +#endif + FLOPCOUNT_INCREMENT(4); +#ifdef __SSE3__ __m128d zbc = _mm_hadd_pd(c0c1, c2c3); +#else + __m128d zbc_lo = _mm_shuffle_pd(c0c1, c2c3, 0); + __m128d zbc_hi = _mm_shuffle_pd(c0c1, c2c3, 3); + __m128d zbc = _mm_add_pd(zbc_lo, zbc_hi); +#endif + FLOPCOUNT_INCREMENT(1); _mm_store_pd(zero_buck_check, zbc); -@@ -681,13 +735,35 @@ +@@ -681,13 +735,35 @@ estimate_freq_mansour_loops2(sfft_v3_data * data, int __m128d a3b3_sq = _mm_mul_pd(a3b3, a3b3); FLOPCOUNT_INCREMENT(8); +#ifdef __SSE3__ __m128d c0c1 = _mm_hadd_pd(a0b0_sq, a1b1_sq); +#else + __m128d c0c1_lo = _mm_shuffle_pd(a0b0_sq, a1b1_sq, 0); + __m128d c0c1_hi = _mm_shuffle_pd(a0b0_sq, a1b1_sq, 3); + __m128d c0c1 = _mm_add_pd(c0c1_lo, c0c1_hi); +#endif + __m128d c0c1_normed = _mm_mul_pd(c0c1, norm2vec); + +#ifdef __SSE3__ __m128d c2c3 = _mm_hadd_pd(a2b2_sq, a3b3_sq); +#else + __m128d c2c3_lo = _mm_shuffle_pd(a2b2_sq, a3b3_sq, 0); + __m128d c2c3_hi = _mm_shuffle_pd(a2b2_sq, a3b3_sq, 3); + __m128d c2c3 = _mm_add_pd(c2c3_lo, c2c3_hi); +#endif + __m128d c2c3_normed = _mm_mul_pd(c2c3, norm2vec); FLOPCOUNT_INCREMENT(8); +#ifdef __SSE3__ __m128d zbc = _mm_hadd_pd(c0c1_normed, c2c3_normed); +#else + __m128d zbc_lo = _mm_shuffle_pd(c0c1_normed, c2c3_normed, 0); + __m128d zbc_hi = _mm_shuffle_pd(c0c1_normed, c2c3_normed, 3); + __m128d zbc = _mm_add_pd(zbc_lo, zbc_hi); +#endif + FLOPCOUNT_INCREMENT(1); _mm_store_pd(zero_buck_check, zbc); diff --git a/math/sfft/files/patch-src_fft.h b/math/sfft/files/patch-src_fft.h new file mode 100644 index 000000000000..0c3f9d3483a9 --- /dev/null +++ b/math/sfft/files/patch-src_fft.h @@ -0,0 +1,15 @@ +--- src/fft.h.orig 2024-10-15 16:15:00 UTC ++++ src/fft.h +@@ -32,6 +32,12 @@ + //#define USE_FLOAT + #define USE_DOUBLE + ++#ifdef __cplusplus ++#define complex __complex__ ++#undef I ++#define I ((float __complex__)1.0j) ++#endif ++ + #ifdef USE_FLOAT + typedef float complex complex_t; + typedef float real_t; diff --git a/math/sfft/files/patch-src_intrinsics.h b/math/sfft/files/patch-src_intrinsics.h new file mode 100644 index 000000000000..e721bb6706aa --- /dev/null +++ b/math/sfft/files/patch-src_intrinsics.h @@ -0,0 +1,13 @@ +--- src/intrinsics.h.orig 2024-10-15 15:55:56 UTC ++++ src/intrinsics.h +@@ -20,7 +20,9 @@ + */ + + +-#if defined(__ICC) ++#if defined(__arm__) || defined(__aarch64__) ++#include ++#elif defined(__ICC) + #include + #elif defined(__GNUC__) + #include diff --git a/math/sfft/files/patch-src_simulation.cc b/math/sfft/files/patch-src_simulation.cc new file mode 100644 index 000000000000..c97106ae1a38 --- /dev/null +++ b/math/sfft/files/patch-src_simulation.cc @@ -0,0 +1,11 @@ +--- src/simulation.cc.orig 2024-10-15 16:05:30 UTC ++++ src/simulation.cc +@@ -50,7 +50,7 @@ void simulation::setup(int argc, char **argv) + int version = 1; + int fftw_opt = FFTW_ESTIMATE; + +- char ch; ++ int ch; + while ((ch = getopt(argc, argv, "hton:k:r:v:")) != EOF) + { + switch (ch) diff --git a/math/sfft/files/patch-src_timing__many.cc b/math/sfft/files/patch-src_timing__many.cc new file mode 100644 index 000000000000..15b475a5eab6 --- /dev/null +++ b/math/sfft/files/patch-src_timing__many.cc @@ -0,0 +1,11 @@ +--- src/timing_many.cc.orig 2024-10-15 16:05:53 UTC ++++ src/timing_many.cc +@@ -51,7 +51,7 @@ parse_arguments(int argc, char **argv, int *n, int *k, + parse_arguments(int argc, char **argv, int *n, int *k, int *num_inputs, + int *version, int *fftw_opt, bool * simple_parallelism) + { +- char ch; ++ int ch; + while ((ch = getopt(argc, argv, "htosi:n:k:v:")) != EOF) + { + switch (ch)