diff --git a/.gitignore b/.gitignore index 9648f7c..8c0e189 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.o *.swp *.so +*.so.* *.a *.dylib test/testcpp diff --git a/Makefile b/Makefile index 64d0a8e..dfebdce 100644 --- a/Makefile +++ b/Makefile @@ -1,58 +1,323 @@ -KFVER=131 +# +# Semantic versioning +# +# KFVER_MAJOR denotes the ABI version. +# +# - It must be bumped only if API public members are removed or +# changed in the incompatible +# +# KFVER_MINOR denotes the minor version within a compatible ABI. +# +# - It should be bumped if new API public members are added +# (but not removed!) so programs linked against the same library +# version continue operating properly +# +# KFVER_PATCH denotes bugfix count since the last minor update. +# +# - It should be bumped whenever a bug fix is pushed. +# -DATATYPE ?= float +export KFVER_MAJOR = 131 +export KFVER_MINOR = 1 +export KFVER_PATCH = 0 + +# +# Data type (float / int16_t / int32_t / simd) +# + +export KISSFFT_DATATYPE ?= float + +# +# Default options +# + +export KISSFFT_OPENMP ?= 0 +export KISSFFT_STATIC ?= 0 +export KISSFFT_TOOLS ?= 1 +export KISSFFT_USE_ALLOCA ?= 0 + +# +# Installation directories +# PREFIX ?= /usr/local -INCDIR ?= $(PREFIX)/include -LIBDIR ?= $(PREFIX)/lib +export ABS_PREFIX = $(abspath $(PREFIX)) + +BINDIR ?= $(ABS_PREFIX)/bin +export ABS_BINDIR = $(abspath $(BINDIR)) + +INCLUDEDIR ?= $(ABS_PREFIX)/include +export ABS_INCLUDEDIR = $(abspath $(INCLUDEDIR)) +export ABS_PKGINCLUDEDIR = $(ABS_INCLUDEDIR)/kissfft + +# +# Override LIBDIR with lib64 following CMake's +# GNUInstallDirs logic: +# + +CANDIDATE_LIBDIR_NAME = lib + +ifneq ($(MAKECMDGOALS),clean) + ifeq ($(shell uname -s),Linux) + _UNAME_ARCH = $(shell uname -i) + + ifeq (,$(_UNAME_ARCH)) + _UNAME_ARCH = $(shell uname -m) + + ifeq (,$(_UNAME_ARCH)) + $(warning WARNING: Can not detect system architecture!) + endif + endif + + ifeq ($(_UNAME_ARCH),x86_64) + CANDIDATE_LIBDIR_NAME = lib64 + endif + endif +endif + +CANDIDATE_LIBDIR = $(PREFIX)/$(CANDIDATE_LIBDIR_NAME) +LIBDIR ?= $(CANDIDATE_LIBDIR) + +export ABS_LIBDIR = $(abspath $(LIBDIR)) + +export INSTALL ?= install + +# +# Library name and version +# + +ifeq ($(KISSFFT_OPENMP), 1) + KISSFFTLIB_SHORTNAME = kissfft-$(KISSFFT_DATATYPE)-openmp + KISSFFT_PKGCONFIG = kissfft-$(KISSFFT_DATATYPE)-openmp.pc + KISSFFTLIB_FLAGS = -fopenmp + TYPEFLAGS = -fopenmp + PKGCONFIG_OPENMP = -fopenmp +else + KISSFFTLIB_SHORTNAME = kissfft-$(KISSFFT_DATATYPE) + KISSFFT_PKGCONFIG = kissfft-$(KISSFFT_DATATYPE).pc + TYPEFLAGS = + PKGCONFIG_OPENMP = +endif + +ifeq ($(KISSFFT_STATIC), 1) + KISSFFTLIB_NAME = lib$(KISSFFTLIB_SHORTNAME).a + KISSFFTLIB_FLAGS += -static +else ifeq ($(shell uname -s),Darwin) + KISSFFTLIB_NAME = lib$(KISSFFTLIB_SHORTNAME).dylib + KISSFFTLIB_FLAGS += -shared -Wl,-install_name,$(KISSFFTLIB_NAME) +else + KISSFFTLIB_SODEVELNAME = lib$(KISSFFTLIB_SHORTNAME).so + KISSFFTLIB_SONAME = $(KISSFFTLIB_SODEVELNAME).$(KFVER_MAJOR) + KISSFFTLIB_NAME = $(KISSFFTLIB_SONAME).$(KFVER_MINOR).$(KFVER_PATCH) + KISSFFTLIB_FLAGS += -shared -Wl,-soname,$(KISSFFTLIB_SONAME) +endif + +export KISSFFTLIB_SHORTNAME + +# +# Compile-time definitions by datatype +# +# +# Note: -DKISS_FFT_BUILD and -DKISS_FFT_SHARED control +# C symbol visibility. +# + +ifeq "$(KISSFFT_DATATYPE)" "int32_t" + TYPEFLAGS += -DFIXED_POINT=32 +else ifeq "$(KISSFFT_DATATYPE)" "int16_t" + TYPEFLAGS += -DFIXED_POINT=16 +else ifeq "$(KISSFFT_DATATYPE)" "simd" + TYPEFLAGS += -DUSE_SIMD=1 -msse +else ifeq "$(KISSFFT_DATATYPE)" "float" + TYPEFLAGS += -Dkiss_fft_scalar=$(KISSFFT_DATATYPE) +else ifeq "$(KISSFFT_DATATYPE)" "double" + TYPEFLAGS += -Dkiss_fft_scalar=$(KISSFFT_DATATYPE) +else + $(error ERROR: KISSFFT_DATATYPE must be one of: float double int16_t int32_t simd) +endif + +ifneq ($(KISSFFT_STATIC), 1) + TYPEFLAGS += -DKISS_FFT_SHARED +endif + +ifeq ($(KISSFFT_USE_ALLOCA), 1) + TYPEFLAGS += -DKISS_FFT_USE_ALLOCA=1 +endif + +# +# Compile-time definitions +# + +# +# Save pkgconfig variables before appending +# -DKISS_FFT_BUILD to TYPEFLAGS +# + +ifneq ($(shell uname -s),Darwin) + PKGCONFIG_KISSFFT_VERSION = $(KFVER_MAJOR).$(KFVER_MINOR).$(KFVER_PATCH) + PKGCONFIG_KISSFFT_OUTPUT_NAME = $(KISSFFTLIB_SHORTNAME) + PKGCONFIG_PKG_KISSFFT_DEFS = $(TYPEFLAGS) + PKGCONFIG_KISSFFT_PREFIX = $(ABS_PREFIX) + ifeq ($(ABS_INCLUDEDIR),$(ABS_PREFIX)/include) + PKGCONFIG_KISSFFT_INCLUDEDIR = $${prefix}/include + else + PKGCONFIG_KISSFFT_INCLUDEDIR = $(ABS_INCLUDEDIR) + + endif + ifeq ($(ABS_LIBDIR),$(ABS_PREFIX)/$(CANDIDATE_LIBDIR_NAME)) + PKGCONFIG_KISSFFT_LIBDIR = $${prefix}/$(CANDIDATE_LIBDIR_NAME) + else + PKGCONFIG_KISSFFT_LIBDIR = $(ABS_LIBDIR) + endif + PKGCONFIG_KISSFFT_PKGINCLUDEDIR = $${includedir}/kissfft +endif + +export TYPEFLAGS + +# Compile .c into .o +# + +# +# -DKISS_FFT_BUILD is used for library artifacts, so +# consumer executable in 'test' and 'tools' do _NOT_ +# need it. pkg-config output does not need it either. +# -INSTALL ?= install +%.c.o: %.c + $(CC) -Wall -fPIC \ + -o $@ \ + $(CFLAGS) $(TYPEFLAGS) -DKISS_FFT_BUILD \ + -c $< -ifeq ($(shell uname -s),Darwin) - SHARED_NAME := libkissfft.dylib - SHARED_FLAGS := -Wl,-install_name,$(SHARED_NAME) +# +# Target: "make all" +# + +all: kfc.c.o kiss_fft.c.o kiss_fftnd.c.o kiss_fftndr.c.o kiss_fftr.c.o +ifneq ($(KISSFFT_STATIC), 1) + $(CC) $(KISSFFTLIB_FLAGS) -o $(KISSFFTLIB_NAME) $^ + ifneq ($(shell uname -s),Darwin) + ln -sf $(KISSFFTLIB_NAME) $(KISSFFTLIB_SONAME) + ln -sf $(KISSFFTLIB_NAME) $(KISSFFTLIB_SODEVELNAME) + endif else - SHARED_NAME := libkissfft.so - SHARED_FLAGS := -Wl,-soname,$(SHARED_NAME) + $(AR) crus $(KISSFFTLIB_NAME) $^ +endif +ifneq ($(KISSFFT_TOOLS), 0) + make -C tools CFLAGADD="$(CFLAGADD)" all endif -all: - $(CC) -Wall -fPIC -c *.c -Dkiss_fft_scalar=$(DATATYPE) -o kiss_fft.o - $(AR) crus libkissfft.a kiss_fft.o - $(CC) -shared $(SHARED_FLAGS) -o $(SHARED_NAME) kiss_fft.o +# +# Target: "make install" +# install: all - $(INSTALL) -Dt $(INCDIR) -m 644 kiss_fft.h - $(INSTALL) -Dt $(LIBDIR) $(SHARED_NAME) + $(INSTALL) -Dt $(ABS_PKGINCLUDEDIR) -m 644 \ + kfc.h \ + kiss_fft.h \ + kissfft.hh \ + kissfft_i32.hh \ + kiss_fftnd.h \ + kiss_fftndr.h \ + kiss_fftr.h + $(INSTALL) -Dt $(ABS_LIBDIR) -m 644 $(KISSFFTLIB_NAME) +ifneq ($(KISSFFT_STATIC), 1) + ifneq ($(shell uname -s),Darwin) + cd $(LIBDIR) && \ + ln -sf $(KISSFFTLIB_NAME) $(KISSFFTLIB_SONAME) && \ + ln -sf $(KISSFFTLIB_NAME) $(KISSFFTLIB_SODEVELNAME) + endif +endif +ifneq ($(shell uname -s),Darwin) + mkdir "$(ABS_LIBDIR)/pkgconfig" + sed \ + -e 's+@PKGCONFIG_KISSFFT_VERSION@+$(PKGCONFIG_KISSFFT_VERSION)+' \ + -e 's+@KISSFFT_OUTPUT_NAME@+$(PKGCONFIG_KISSFFT_OUTPUT_NAME)+' \ + -e 's+@PKG_KISSFFT_DEFS@+$(PKGCONFIG_PKG_KISSFFT_DEFS)+' \ + -e 's+@PKG_OPENMP@+$(PKGCONFIG_OPENMP)+' \ + -e 's+@PKGCONFIG_KISSFFT_PREFIX@+$(PKGCONFIG_KISSFFT_PREFIX)+' \ + -e 's+@PKGCONFIG_KISSFFT_INCLUDEDIR@+$(PKGCONFIG_KISSFFT_INCLUDEDIR)+' \ + -e 's+@PKGCONFIG_KISSFFT_LIBDIR@+$(PKGCONFIG_KISSFFT_LIBDIR)+' \ + -e 's+@PKGCONFIG_KISSFFT_PKGINCLUDEDIR@+$(PKGCONFIG_KISSFFT_PKGINCLUDEDIR)+' \ + kissfft.pc.in 1>"$(ABS_LIBDIR)/pkgconfig/$(KISSFFT_PKGCONFIG)" +endif +ifneq ($(KISSFFT_TOOLS), 0) + make -C tools install +endif + +# +# Target: "make doc" +# doc: - @echo "Start by reading the README file. If you want to build and test lots of stuff, do a 'make testall'" - @echo "but be aware that 'make testall' has dependencies that the basic kissfft software does not." - @echo "It is generally unneeded to run these tests yourself, unless you plan on changing the inner workings" - @echo "of kissfft and would like to make use of its regression tests." + $(warning Start by reading the README file. If you want to build and test lots of stuff, do a 'make testall') + $(warning but be aware that 'make testall' has dependencies that the basic kissfft software does not.) + $(warning It is generally unneeded to run these tests yourself, unless you plan on changing the inner workings) + $(warning of kissfft and would like to make use of its regression tests.) + +# +# Target: "make testsingle" +# + +testsingle: + make clean + make all + make -C test CFLAGADD="$(CFLAGADD)" test testcpp + +# +# Target: "make testall" +# testall: - # The simd and int32_t types may or may not work on your machine - make -C test testcpp && test/testcpp - make -C test DATATYPE=simd CFLAGADD="$(CFLAGADD)" test - make -C test DATATYPE=int32_t CFLAGADD="$(CFLAGADD)" test - make -C test DATATYPE=int16_t CFLAGADD="$(CFLAGADD)" test - make -C test DATATYPE=float CFLAGADD="$(CFLAGADD)" test - make -C test DATATYPE=double CFLAGADD="$(CFLAGADD)" test - make -C test testsse - echo "all tests passed" + # Shared libraries + make KISSFFT_DATATYPE=double testsingle + make KISSFFT_DATATYPE=float testsingle + make KISSFFT_DATATYPE=int16_t testsingle + # The simd and int32_t types may or may not work on your machine + make KISSFFT_DATATYPE=int32_t testsingle + make KISSFFT_DATATYPE=simd testsingle + # Static libraries + make KISSFFT_DATATYPE=double KISSFFT_STATIC=1 testsingle + make KISSFFT_DATATYPE=float KISSFFT_STATIC=1 testsingle + make KISSFFT_DATATYPE=int16_t KISSFFT_STATIC=1 testsingle + # The simd and int32_t types may or may not work on your machine + make KISSFFT_DATATYPE=int32_t KISSFFT_STATIC=1 testsingle + make KISSFFT_DATATYPE=simd KISSFFT_STATIC=1 testsingle + # OpenMP libraries + make KISSFFT_DATATYPE=double KISSFFT_OPENMP=1 testsingle + make KISSFFT_DATATYPE=float KISSFFT_OPENMP=1 testsingle + make KISSFFT_DATATYPE=int16_t KISSFFT_OPENMP=1 testsingle + # The simd and int32_t types may or may not work on your machine + make KISSFFT_DATATYPE=int32_t KISSFFT_OPENMP=1 testsingle + make KISSFFT_DATATYPE=simd KISSFFT_OPENMP=1 testsingle + $(warning All tests passed!) + +# +# Target: "make tarball" +# tarball: clean git archive --prefix=kissfft/ -o kissfft$(KFVER).tar.gz v$(KFVER) git archive --prefix=kissfft/ -o kissfft$(KFVER).zip v$(KFVER) +# +# Target: "make clean" +# + clean: + rm -f *.o *.a *.so *.so.* cd test && make clean cd tools && make clean - rm -f kiss_fft*.tar.gz *~ *.pyc kiss_fft*.zip + rm -f kiss_fft*.tar.gz *~ *.pyc kiss_fft*.zip + +# +# Target: "make asm" +# asm: kiss_fft.s +# TODO: Sort out if we should add kfc / other C headers + kiss_fft.s: kiss_fft.c kiss_fft.h _kiss_fft_guts.h [ -e kiss_fft.s ] && mv kiss_fft.s kiss_fft.s~ || true $(CC) -S kiss_fft.c -O3 -mtune=native -ffast-math -fomit-frame-pointer -unroll-loops -dA -fverbose-asm diff --git a/tools/kfc.c b/kfc.c similarity index 100% rename from tools/kfc.c rename to kfc.c diff --git a/tools/kfc.h b/kfc.h similarity index 100% rename from tools/kfc.h rename to kfc.h diff --git a/tools/kiss_fftnd.c b/kiss_fftnd.c similarity index 100% rename from tools/kiss_fftnd.c rename to kiss_fftnd.c diff --git a/tools/kiss_fftnd.h b/kiss_fftnd.h similarity index 100% rename from tools/kiss_fftnd.h rename to kiss_fftnd.h diff --git a/tools/kiss_fftndr.c b/kiss_fftndr.c similarity index 100% rename from tools/kiss_fftndr.c rename to kiss_fftndr.c diff --git a/tools/kiss_fftndr.h b/kiss_fftndr.h similarity index 100% rename from tools/kiss_fftndr.h rename to kiss_fftndr.h diff --git a/tools/kiss_fftr.c b/kiss_fftr.c similarity index 100% rename from tools/kiss_fftr.c rename to kiss_fftr.c diff --git a/tools/kiss_fftr.h b/kiss_fftr.h similarity index 100% rename from tools/kiss_fftr.h rename to kiss_fftr.h diff --git a/kissfft.pc.in b/kissfft.pc.in index 0de9c3a..c8033f7 100644 --- a/kissfft.pc.in +++ b/kissfft.pc.in @@ -1,9 +1,10 @@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +prefix=@PKGCONFIG_KISSFFT_PREFIX@ +libdir=@PKGCONFIG_KISSFFT_LIBDIR@ +includedir=@PKGCONFIG_KISSFFT_INCLUDEDIR@ Name: kissfft Description: A Fast Fourier Transform (FFT) library that tries to Keep it Simple, Stupid -Version: @kissfft_VERSION@ +Version: @PKGCONFIG_KISSFFT_VERSION@ -Libs: -L${libdir} -l@KISSFFT_OUTPUT_NAME@ -Cflags: -I${includedir} @PKG_KISSFFT_DEFS@ \ No newline at end of file +Libs: @PKG_OPENMP@ -L${libdir} -l@KISSFFT_OUTPUT_NAME@ +Cflags: -I@PKGCONFIG_KISSFFT_PKGINCLUDEDIR@ @PKG_KISSFFT_DEFS@ diff --git a/test/Makefile b/test/Makefile index 5b1f219..9224c89 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,106 +1,188 @@ +# +# Warnings +# -WARNINGS=-W -Wall -Wstrict-prototypes -Wmissing-prototypes \ +WARNINGS = -W -Wall -Wstrict-prototypes -Wmissing-prototypes \ -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast \ -Wwrite-strings -CFLAGS=-O3 -I.. -I../tools $(WARNINGS) -CFLAGS+=-ffast-math -fomit-frame-pointer -#CFLAGS+=-funroll-loops -#CFLAGS+=-march=prescott -#CFLAGS+= -mtune=native +# +# Compile-time definitions +# + +CFLAGS = -O3 -I.. -I../tools $(WARNINGS) +CFLAGS += -ffast-math -fomit-frame-pointer +#CFLAGS += -funroll-loops +#CFLAGS += -march=prescott +#CFLAGS += -mtune=native # TIP: try adding -openmp or -fopenmp to enable OPENMP directives and use of multiple cores -#CFLAGS+=-fopenmp -CFLAGS+= $(CFLAGADD) +#CFLAGS += -fopenmp +CFLAGS += $(CFLAGADD) + +CXXFLAGS = -O3 -ffast-math -fomit-frame-pointer -I.. -W -Wall -march=native -mtune=native +# +# Count of FFT runs tested +# ifeq "$(NFFT)" "" - NFFT=1800 + NFFT = 1800 endif ifeq "$(NUMFFTS)" "" - NUMFFTS=10000 + NUMFFTS = 10000 endif -ifeq "$(DATATYPE)" "" - DATATYPE=float +# +# Test binary executable names +# + +SELFTESTSRC = twotonetest.c + +ifneq ($(KISSFFT_OPENMP),1) +BENCHKISS = bm-kiss-$(KISSFFT_DATATYPE) +BENCHFFTW = bm-fftw-$(KISSFFT_DATATYPE) +SELFTEST = st-$(KISSFFT_DATATYPE) +TESTREAL = tr-$(KISSFFT_DATATYPE) +TESTKFC = tkfc-$(KISSFFT_DATATYPE) +TESTFASTFILT = fastfilt-$(KISSFFT_DATATYPE) +TESTCPP = testcpp-$(KISSFFT_DATATYPE) +TESTSIMD = testsimd +else +BENCHKISS = bm-kiss-$(KISSFFT_DATATYPE)-openmp +BENCHFFTW = bm-fftw-$(KISSFFT_DATATYPE)-openmp +SELFTEST = st-$(KISSFFT_DATATYPE)-openmp +TESTREAL = tr-$(KISSFFT_DATATYPE)-openmp +TESTKFC = tkfc-$(KISSFFT_DATATYPE)-openmp +TESTFASTFILT = fastfilt-$(KISSFFT_DATATYPE)-openmp +TESTCPP = testcpp-$(KISSFFT_DATATYPE)-openmp +TESTSIMD = testsimd-openmp +CFLAGS += -fopenmp +CXXFLAGS += -fopenmp endif -BENCHKISS=bm_kiss_$(DATATYPE) -BENCHFFTW=bm_fftw_$(DATATYPE) -SELFTEST=st_$(DATATYPE) -TESTREAL=tr_$(DATATYPE) -TESTKFC=tkfc_$(DATATYPE) -FASTFILTREAL=ffr_$(DATATYPE) -SELFTESTSRC=twotonetest.c +ifeq "$(KISSFFT_DATATYPE)" "float" + # fftw needs to be built with --enable-float to build this lib + FFTWLIB = -lfftw3f +else + FFTWLIB = -lfftw3 +endif +FFTWLIBDIR ?= $(ABS_LIBDIR) +ABS_FFTWLIBDIR = $(abspath $(FFTWLIBDIR)) -TYPEFLAGS=-Dkiss_fft_scalar=$(DATATYPE) +# +# Check missing external libraries +# -ifeq "$(DATATYPE)" "int16_t" - TYPEFLAGS=-DFIXED_POINT=16 +ifneq ($(MAKECMDGOALS),clean) +LIBFFTW_MISSING = $(shell echo "int main(){return 0;}" > _test_library_dummy.c; \ + $(CC) -o _test_library_dummy _test_library_dummy.c $(FFTWLIB) -L$(ABS_FFTWLIBDIR); \ + echo $$?; \ + rm -f _test_library_dummy.c _test_library_dummy) endif -ifeq "$(DATATYPE)" "int32_t" - TYPEFLAGS=-DFIXED_POINT=32 +# +# Find Python interpreter +# + +ifneq ($(MAKECMDGOALS),clean) + PYTHON_INTERPRETER = $(shell python --version) + ifeq ($(PYTHON_INTERPRETER), ) + PYTHON_INTERPRETER = $(shell python2 --version) + ifeq ($(PYTHON_INTERPRETER), ) + PYTHON_INTERPRETER = $(shell python3 --version) + ifeq ($(PYTHON_INTERPRETER), ) + $(error ERROR: Can not find Python interpreter!) + else + PYTHON_INTERPRETER = "python3" + endif + else + PYTHON_INTERPRETER = "python2" + endif + else + PYTHON_INTERPRETER = "python" + endif endif -ifeq "$(DATATYPE)" "simd" - TYPEFLAGS=-DUSE_SIMD=1 -msse -endif +# +# Target: "make all" +# +all: $(BENCHKISS) $(SELFTEST) $(BENCHFFTW) $(TESTREAL) $(TESTKFC) $(TESTFASTFILT) -ifeq "$(DATATYPE)" "float" - # fftw needs to be built with --enable-float to build this lib - FFTWLIB=-lfftw3f -else - FFTWLIB=-lfftw3 -endif +# +# Individual test make rules +# -FFTWLIBDIR=-L/usr/local/lib/ +$(SELFTEST): $(SELFTESTSRC) + $(CC) -o $@ $(CFLAGS) $(TYPEFLAGS) $< -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -SRCFILES=../kiss_fft.c ../tools/kiss_fftnd.c ../tools/kiss_fftr.c pstats.c ../tools/kfc.c ../tools/kiss_fftndr.c +$(TESTKFC): ../kfc.c + $(CC) -o $@ $(CFLAGS) -DKFC_TEST $(TYPEFLAGS) $^ -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -all: tools $(BENCHKISS) $(SELFTEST) $(BENCHFFTW) $(TESTREAL) $(TESTKFC) +$(TESTREAL): test_real.c + $(CC) -o $@ $(CFLAGS) $(TYPEFLAGS) $< -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -tools: - cd ../tools && make all +$(BENCHKISS): benchkiss.c pstats.c + $(CC) -o $@ $(CFLAGS) $(TYPEFLAGS) $^ -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -test_simd: test_simd.c $(SRCFILES) - $(CC) -o $@ -g $(CFLAGS) -DUSE_SIMD=1 -msse $+ -lm +$(TESTFASTFILT): ../tools/fftutil.c + $(CC) -o $@ $(CFLAGS) -DKFC_TEST $(TYPEFLAGS) $^ -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -testsse: test_simd - ./test_simd +$(BENCHFFTW): benchfftw.c pstats.c + $(warning ======attempting to build FFTW benchmark) +ifeq ($(LIBFFTW_MISSING), 0) + $(CC) -o $@ $(CFLAGS) -DDATATYPE$(KISSFFT_DATATYPE) $^ $(FFTWLIB) -L$(ABS_FFTWLIBDIR) -L.. -l$(KISSFFTLIB_SHORTNAME) -lm +else + $(warning WARNING: No FFTW development files found! FFTW not available for comparison!0 +endif + +# +# Test SSE +# + +$(TESTSIMD): test_simd.c +ifeq "$(KISSFFT_DATATYPE)" "simd" + $(CC) -o $@ -g $(CFLAGS) -DUSE_SIMD=1 -msse $< -L.. -l$(KISSFFTLIB_SHORTNAME) -lm +else + $(error ERROR: This test makes sense only with KISSFFT_DATATYPE=simd) +endif -$(SELFTEST): $(SELFTESTSRC) $(SRCFILES) - $(CC) -o $@ $(CFLAGS) $(TYPEFLAGS) $+ -lm +testsse: $(TESTSIMD) + LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):.." ./$(TESTSIMD) -$(TESTKFC): $(SRCFILES) - $(CC) -o $@ $(CFLAGS) -DKFC_TEST $(TYPEFLAGS) $+ -lm - -$(TESTREAL): test_real.c $(SRCFILES) - $(CC) -o $@ $(CFLAGS) $(TYPEFLAGS) $+ -lm +# +# Test C++ +# -$(BENCHKISS): benchkiss.c $(SRCFILES) - $(CC) -o $@ $(CFLAGS) $(TYPEFLAGS) $+ -lm +$(TESTCPP): testcpp.cc ../kissfft.hh + $(CXX) -o $@ $(CXXFLAGS) testcpp.cc -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -$(BENCHFFTW): benchfftw.c pstats.c - @echo "======attempting to build FFTW benchmark" - @$(CC) -o $@ $(CFLAGS) -DDATATYPE$(DATATYPE) $+ $(FFTWLIB) $(FFTWLIBDIR) -lm || echo "FFTW not available for comparison" +testcpp: $(TESTCPP) + LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):.." ./$(TESTCPP) + +# +# Target: "make test" +# test: all - @./$(TESTKFC) - @echo "======1d & 2-d complex fft self test (type= $(DATATYPE) )" - @./$(SELFTEST) - @echo "======real FFT (type= $(DATATYPE) )" - @./$(TESTREAL) - @echo "======timing test (type=$(DATATYPE))" - @./$(BENCHKISS) -x $(NUMFFTS) -n $(NFFT) - @[ -x ./$(BENCHFFTW) ] && ./$(BENCHFFTW) -x $(NUMFFTS) -n $(NFFT) ||true - @echo "======higher dimensions type=$(DATATYPE))" - @./testkiss.py - -CXXFLAGS=-O3 -ffast-math -fomit-frame-pointer -I.. -I../tools -W -Wall -march=native -mtune=native -testcpp: testcpp.cc ../kissfft.hh - $(CXX) -o $@ $(CXXFLAGS) testcpp.cc -lm +ifeq "$(KISSFFT_DATATYPE)" "simd" + make testsse +endif + @LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):.." ./$(TESTKFC) + $(warning ======1d & 2-d complex fft self test (type= $(KISSFFT_DATATYPE) )) + @LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):.." ./$(SELFTEST) + $(warning ======real FFT (type= $(KISSFFT_DATATYPE) )) + @LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):.." ./$(TESTREAL) + $(warning ======timing test (type=$(KISSFFT_DATATYPE))) + @LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):.." ./$(BENCHKISS) -x $(NUMFFTS) -n $(NFFT) + @[ -x ./$(BENCHFFTW) ] && LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):.." ./$(BENCHFFTW) -x $(NUMFFTS) -n $(NFFT) || true + $(warning ======higher dimensions (type=$(KISSFFT_DATATYPE))) + @LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):.." $(PYTHON_INTERPRETER) ./testkiss.py + +# +# Target: "make clean" +# clean: - rm -f *~ bm_* st_* tr_* kf_* tkfc_* ff_* ffr_* *.pyc *.pyo *.dat testcpp + rm -f *~ bm-* st-* tr-* kf-* tkfc-* ff-* fastfilt-* *.pyc *.pyo *.dat testcpp-* testsimd testsimd-* _test_library_dummy _test_library_dummy.c diff --git a/tools/Makefile b/tools/Makefile index f490533..fae8735 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,62 +1,101 @@ -WARNINGS=-W -Wall -Wstrict-prototypes -Wmissing-prototypes \ +# +# Warnings +# + +WARNINGS = -W -Wall -Wstrict-prototypes -Wmissing-prototypes \ -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast \ -Wwrite-strings -ifeq "$(DATATYPE)" "" - DATATYPE=float -endif +# +# Compile-time definitions +# -ifeq "$(DATATYPE)" "int32_t" - TYPEFLAGS=-DFIXED_POINT=32 -endif +CFLAGS = -Wall -O3 $(WARNINGS) +#CFLAGS = -Wall -O3 -pedantic -march=pentiumpro -ffast-math -fomit-frame-pointer $(WARNINGS) +# If the above flags do not work, try the following +# tip: try -openmp or -fopenmp to use multiple cores -ifeq "$(DATATYPE)" "int16_t" - TYPEFLAGS=-DFIXED_POINT=16 -endif +CFLAGS += $(CFLAGADD) -ifeq "$(DATATYPE)" "simd" - TYPEFLAGS=-DUSE_SIMD=1 -msse +# +# Check missing external libraries +# + +ifneq ($(MAKECMDGOALS),clean) +LIBPNG_MISSING = $(shell echo "int main(){return 0;}" > _test_library_dummy.c; \ + $(CC) -o _test_library_dummy _test_library_dummy.c -lpng; \ + echo $$?; \ + rm -f _test_library_dummy.c _test_library_dummy) endif -ifeq "$(TYPEFLAGS)" "" - TYPEFLAGS=-Dkiss_fft_scalar=$(DATATYPE) +# +# Tool names +# + +ifneq ($(KISSFFT_OPENMP),1) +FFTUTIL = fft-$(KISSFFT_DATATYPE) +FASTFILT = fastconv-$(KISSFFT_DATATYPE) +FASTFILTREAL = fastconvr-$(KISSFFT_DATATYPE) +PSDPNG = psdpng-$(KISSFFT_DATATYPE) +DUMPHDR = dumphdr-$(KISSFFT_DATATYPE) +else +FFTUTIL = fft-$(KISSFFT_DATATYPE)-openmp +FASTFILT = fastconv-$(KISSFFT_DATATYPE)-openmp +FASTFILTREAL = fastconvr-$(KISSFFT_DATATYPE)-openmp +PSDPNG = psdpng-$(KISSFFT_DATATYPE)-openmp +DUMPHDR = dumphdr-$(KISSFFT_DATATYPE)-openmp endif -ifneq ("$(KISS_FFT_USE_ALLOCA)","") - CFLAGS+= -DKISS_FFT_USE_ALLOCA=1 -endif -CFLAGS+= $(CFLAGADD) +# +# Target: "make all" +# +all: $(FFTUTIL) $(FASTFILT) $(FASTFILTREAL) $(PSDPNG) +# $(DUMPHDR) -FFTUTIL=fft_$(DATATYPE) -FASTFILT=fastconv_$(DATATYPE) -FASTFILTREAL=fastconvr_$(DATATYPE) -PSDPNG=psdpng_$(DATATYPE) -DUMPHDR=dumphdr_$(DATATYPE) +# +# Individual tool make rules +# -all: $(FFTUTIL) $(FASTFILT) $(FASTFILTREAL) -# $(PSDPNG) -# $(DUMPHDR) +$(FASTFILTREAL): kiss_fastfir.c + $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) -DREAL_FASTFIR $< -DFAST_FILT_UTIL -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -#CFLAGS=-Wall -O3 -pedantic -march=pentiumpro -ffast-math -fomit-frame-pointer $(WARNINGS) -# If the above flags do not work, try the following -CFLAGS=-Wall -O3 $(WARNINGS) -# tip: try -openmp or -fopenmp to use multiple cores +$(FASTFILT): kiss_fastfir.c + $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) $< -DFAST_FILT_UTIL -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -$(FASTFILTREAL): ../kiss_fft.c kiss_fastfir.c kiss_fftr.c - $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) -DREAL_FASTFIR $+ -DFAST_FILT_UTIL -lm +$(FFTUTIL): fftutil.c + $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) $< -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -$(FASTFILT): ../kiss_fft.c kiss_fastfir.c - $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) $+ -DFAST_FILT_UTIL -lm +$(PSDPNG): psdpng.c +ifeq "$(KISSFFT_DATATYPE)" "simd" + $(warning WARNING: psdpng can not utilize SIMD!) +else ifeq ($(LIBPNG_MISSING), 0) + $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) $< -L.. -l$(KISSFFTLIB_SHORTNAME) -lpng -lm +else + $(error ERROR: no libpng development files found!) +endif -$(FFTUTIL): ../kiss_fft.c fftutil.c kiss_fftnd.c kiss_fftr.c kiss_fftndr.c - $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) $+ -lm +$(DUMPHDR): dumphdr.c + $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) $< -L.. -l$(KISSFFTLIB_SHORTNAME) -lm -$(PSDPNG): ../kiss_fft.c psdpng.c kiss_fftr.c - $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) $+ -lpng -lm +# +# Target: "make install" +# + +install: all + $(INSTALL) -Dt $(ABS_BINDIR) -m 755 \ + $(FFTUTIL) \ + $(FASTFILT) \ + $(FASTFILTREAL) + +ifneq "$(KISSFFT_DATATYPE)" "simd" + $(INSTALL) -Dt $(ABS_BINDIR) -m 755 \ + $(PSDPNG) +endif -$(DUMPHDR): ../kiss_fft.c dumphdr.c - $(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) $+ -lm +# +# Target: "make clean" +# clean: - rm -f *~ fft fft_* fastconv fastconv_* fastconvr fastconvr_* psdpng psdpng_* + rm -f *~ fft fft-* fastconv fastconv-* fastconvr fastconvr-* psdpng psdpng-* _test_library_dummy _test_library_dummy.c