kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit 76d194f7d276cfa8ed3d4756ae144806c5d61bfb
parent 37503a1dd5db8f45df55599ea1de5927a821fbb9
Author: bmanga <[email protected]>
Date:   Wed, 21 Aug 2019 14:35:26 +0100

Merge branch 'dev' into dft-gcc
Diffstat:
MCMakeLists.txt | 15+++++++++++++--
Acmake/cmake_uninstall.cmake.in | 21+++++++++++++++++++++
Mcmake/target_set_arch.cmake | 57++++++++++++++++++++++++++++++---------------------------
Minclude/kfr/base/univector.hpp | 2++
Minclude/kfr/cometa.hpp | 7-------
Minclude/kfr/dsp/units.hpp | 10++++++++--
Minclude/kfr/io/tostring.hpp | 2--
Minclude/kfr/math/impl/select.hpp | 5+++++
8 files changed, 79 insertions(+), 40 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -186,10 +186,21 @@ add_library(kfr_io ${KFR_IO_SRC}) target_link_libraries(kfr_io kfr) target_compile_definitions(kfr_io PUBLIC KFR_ENABLE_FLAC=1) -install(TARGETS kfr kfr_io ARCHIVE DESTINATION lib) +install(TARGETS kfr kfr_io ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) if (ENABLE_DFT) - install(TARGETS kfr_dft ARCHIVE DESTINATION lib) + install(TARGETS kfr_dft ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) endif () install(DIRECTORY include/kfr DESTINATION include) + +# uninstall target +if(NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake) +endif() diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) diff --git a/cmake/target_set_arch.cmake b/cmake/target_set_arch.cmake @@ -1,34 +1,35 @@ if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)") - set(ARCH_FLAGS_GNU_generic -DCMT_FORCE_GENERIC_CPU) - set(ARCH_FLAGS_GNU_sse2 -msse2) - set(ARCH_FLAGS_GNU_sse3 -msse3) - set(ARCH_FLAGS_GNU_ssse3 -mssse3) - set(ARCH_FLAGS_GNU_sse41 -msse4.1) - set(ARCH_FLAGS_GNU_sse42 -msse4.2) - set(ARCH_FLAGS_GNU_avx -msse4.2 -mavx) - set(ARCH_FLAGS_GNU_avx2 -msse4.2 -mavx2 -mfma) - set(ARCH_FLAGS_GNU_avx512 -msse4.2 -mavx2 -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl) - - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - # SSE2 is part of x86_64 - set(ARCH_FLAG_MS_SSE2) - else() - set(ARCH_FLAG_MS_SSE2 -arch:SSE2) - endif() - - set(ARCH_FLAGS_MS_generic ${ARCH_FLAG_MS_SSE2} -DCMT_FORCE_GENERIC_CPU) - set(ARCH_FLAGS_MS_sse2 ${ARCH_FLAG_MS_SSE2}) - set(ARCH_FLAGS_MS_sse3 ${ARCH_FLAG_MS_SSE2} -D__SSE3__) - set(ARCH_FLAGS_MS_ssse3 ${ARCH_FLAG_MS_SSE2} -D__SSSE3__) - set(ARCH_FLAGS_MS_sse41 ${ARCH_FLAG_MS_SSE2} -D__SSE3__ -D__SSSE3__ -D__SSE4_1__) - set(ARCH_FLAGS_MS_sse42 ${ARCH_FLAG_MS_SSE2} -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__) - set(ARCH_FLAGS_MS_avx -arch:AVX) - set(ARCH_FLAGS_MS_avx2 -arch:AVX2) - set(ARCH_FLAGS_MS_avx512 -arch:AVX512) + function(target_set_arch TARGET MODE ARCH) + + set(ARCH_FLAGS_GNU_generic -DCMT_FORCE_GENERIC_CPU) + set(ARCH_FLAGS_GNU_sse2 -msse2) + set(ARCH_FLAGS_GNU_sse3 -msse3) + set(ARCH_FLAGS_GNU_ssse3 -mssse3) + set(ARCH_FLAGS_GNU_sse41 -msse4.1) + set(ARCH_FLAGS_GNU_sse42 -msse4.2) + set(ARCH_FLAGS_GNU_avx -msse4.2 -mavx) + set(ARCH_FLAGS_GNU_avx2 -msse4.2 -mavx2 -mfma) + set(ARCH_FLAGS_GNU_avx512 -msse4.2 -mavx2 -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl) + + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + # SSE2 is part of x86_64 + set(ARCH_FLAG_MS_SSE2) + else() + set(ARCH_FLAG_MS_SSE2 -arch:SSE2) + endif() + + set(ARCH_FLAGS_MS_generic ${ARCH_FLAG_MS_SSE2} -DCMT_FORCE_GENERIC_CPU) + set(ARCH_FLAGS_MS_sse2 ${ARCH_FLAG_MS_SSE2}) + set(ARCH_FLAGS_MS_sse3 ${ARCH_FLAG_MS_SSE2} -D__SSE3__) + set(ARCH_FLAGS_MS_ssse3 ${ARCH_FLAG_MS_SSE2} -D__SSSE3__) + set(ARCH_FLAGS_MS_sse41 ${ARCH_FLAG_MS_SSE2} -D__SSE3__ -D__SSSE3__ -D__SSE4_1__) + set(ARCH_FLAGS_MS_sse42 ${ARCH_FLAG_MS_SSE2} -D__SSE3__ -D__SSSE3__ -D__SSE4_1__ -D__SSE4_2__) + set(ARCH_FLAGS_MS_avx -arch:AVX) + set(ARCH_FLAGS_MS_avx2 -arch:AVX2) + set(ARCH_FLAGS_MS_avx512 -arch:AVX512) - function(target_set_arch TARGET MODE ARCH) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") set(CLANG 1) else () @@ -44,8 +45,10 @@ if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)") endif() endif () if (MSVC AND NOT CLANG) + message(STATUS "ARCH_FLAGS_MS_${ARCH} = ${ARCH_FLAGS_MS_${ARCH}}") target_compile_options(${TARGET} ${MODE} ${ARCH_FLAGS_MS_${ARCH}}) else() + message(STATUS "ARCH_FLAGS_GNU_${ARCH} = ${ARCH_FLAGS_GNU_${ARCH}}") target_compile_options(${TARGET} ${MODE} ${ARCH_FLAGS_GNU_${ARCH}}) endif () endfunction() diff --git a/include/kfr/base/univector.hpp b/include/kfr/base/univector.hpp @@ -464,6 +464,8 @@ struct univector<T, tag_dynamic_vector> { return index < this->size() ? this->operator[](index) : fallback_value; } + using univector_base<T, univector, is_vec_element<T>::value>::operator=; + univector& operator=(const univector&) = default; template <typename Input, KFR_ENABLE_IF(is_input_expression<Input>::value)> KFR_MEM_INTRINSIC univector& operator=(Input&& input) { diff --git a/include/kfr/cometa.hpp b/include/kfr/cometa.hpp @@ -1988,7 +1988,6 @@ CMT_INTRINSIC constexpr Tout pack_elements(Arg x, Args... args) enum class special_constant { - undefined, default_constructed, infinity, neg_infinity, @@ -2018,12 +2017,6 @@ struct special_value { switch (c) { - CMT_PRAGMA_GNU(GCC diagnostic push) - CMT_PRAGMA_GNU(GCC diagnostic ignored "-Wuninitialized") - CMT_PRAGMA_GNU(GCC diagnostic ignored "-Wmaybe-uninitialized") - case special_constant::undefined: - return T{}; - CMT_PRAGMA_GNU(GCC diagnostic pop) case special_constant::default_constructed: return T{}; case special_constant::infinity: diff --git a/include/kfr/dsp/units.hpp b/include/kfr/dsp/units.hpp @@ -39,10 +39,16 @@ using sample_rate_t = double; namespace intrinsics { +template <typename T1, typename T2> +KFR_INTRINSIC common_type<T1, T2> fix_nans(const T1& val, const T2& replacement) +{ + return select(val != val, replacement, val); +} + template <typename T, typename TF = flt_type<T>> KFR_INTRINSIC TF amp_to_dB(const T& amp) { - return log(static_cast<TF>(abs(amp))) * subtype<TF>(8.6858896380650365530225783783322); + return fix_nans(log(static_cast<TF>(abs(amp))) * subtype<TF>(8.6858896380650365530225783783322), -c_infinity<T>); // return T( 20.0 ) * log10( level ); } @@ -56,7 +62,7 @@ KFR_INTRINSIC TF dB_to_amp(const T& dB) template <typename T, typename TF = flt_type<T>> KFR_INTRINSIC TF amp_to_dB(const T& amp, const T& offset) { - return log_fmadd(static_cast<TF>(abs(amp)), subtype<TF>(8.6858896380650365530225783783322), offset); + return fix_nans(log_fmadd(static_cast<TF>(abs(amp)), subtype<TF>(8.6858896380650365530225783783322), offset), -c_infinity<T>); // return T( 20.0 ) * log10( level ); } diff --git a/include/kfr/io/tostring.hpp b/include/kfr/io/tostring.hpp @@ -44,8 +44,6 @@ struct representation<cometa::special_value> using cometa::special_constant; switch (value.c) { - case special_constant::undefined: - return "undefined"; case special_constant::default_constructed: return "default_constructed"; case special_constant::infinity: diff --git a/include/kfr/math/impl/select.hpp b/include/kfr/math/impl/select.hpp @@ -319,6 +319,11 @@ KFR_INTRINSIC vec<T, N> select(const vec<bit<T>, N>& m, const T& x, const vec<T, return select(m, vec<T, N>(x), y); } #endif +template <typename T1, typename T2> +KFR_INTRINSIC common_type<T1, T2> select(bool m, const T1& x, const T2& y) +{ + return m ? x : y; +} } // namespace intrinsics KFR_I_FN(select)