commit 0d5f6b08a8a2655a5071337a90335f37474a649c
parent d3391550a2a5b64ef163c98fad37636030d310d9
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Thu, 27 Dec 2018 01:31:01 +0000
Partial compatibility for Visual Studio 2017
Diffstat:
17 files changed, 103 insertions(+), 47 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -40,6 +40,7 @@ include(sources.cmake)
add_definitions(-D_ENABLE_EXTENDED_ALIGNED_STORAGE)
option(ENABLE_TESTS "Enable tests and examples. This changes many compiler flags" OFF)
+option(ENABLE_DFT "Enable DFT and related algorithms" ON)
set(KFR_DFT_SRC
${CMAKE_CURRENT_SOURCE_DIR}/include/kfr/dft/impl/dft-src.cpp
@@ -99,8 +100,10 @@ add_library(kfr INTERFACE)
target_sources(kfr INTERFACE ${KFR_SRC})
target_include_directories(kfr INTERFACE include)
-add_library(kfr_dft ${KFR_DFT_SRC})
-target_link_libraries(kfr_dft kfr)
+if (ENABLE_DFT)
+ add_library(kfr_dft ${KFR_DFT_SRC})
+ target_link_libraries(kfr_dft kfr)
+endif()
add_library(kfr_io ${KFR_IO_SRC})
target_link_libraries(kfr_io kfr)
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
@@ -28,7 +28,12 @@ add_executable(window window.cpp)
target_link_libraries(window kfr)
add_executable(fir fir.cpp)
-target_link_libraries(fir kfr kfr_dft)
+
+target_link_libraries(fir kfr)
+if (ENABLE_DFT)
+ target_link_libraries(fir kfr_dft)
+ target_compile_definitions(fir PRIVATE -DHAVE_DFT)
+endif ()
add_executable(sample_rate_conversion sample_rate_conversion.cpp)
target_link_libraries(sample_rate_conversion kfr kfr_io)
@@ -36,5 +41,7 @@ target_link_libraries(sample_rate_conversion kfr kfr_io)
add_executable(sample_rate_converter sample_rate_converter.cpp)
target_link_libraries(sample_rate_converter kfr kfr_io)
-add_executable(dft dft.cpp)
-target_link_libraries(dft kfr kfr_dft)
+if (ENABLE_DFT)
+ add_executable(dft dft.cpp)
+ target_link_libraries(dft kfr kfr_dft)
+endif ()
diff --git a/examples/fir.cpp b/examples/fir.cpp
@@ -5,7 +5,9 @@
*/
#include <kfr/base.hpp>
+#ifdef HAVE_DFT
#include <kfr/dft.hpp>
+#endif
#include <kfr/dsp.hpp>
#include <kfr/io.hpp>
@@ -128,6 +130,7 @@ int main()
plot_save("filtered_noise2", filtered_noise2, "title='Filtered noise 2', div_by_N=True");
#endif
+#ifdef HAVE_DFT
// --------------------------------------------------------------------------------------
// ---------------------- Convolution filter (optimized using DFT) ----------------------
// --------------------------------------------------------------------------------------
@@ -143,6 +146,7 @@ int main()
// Plot results, same as filtered_noise2
plot_save("filtered_noise3", filtered_noise3, "title='Filtered noise 3', div_by_N=True");
#endif
+#endif
return 0;
}
diff --git a/include/kfr/base/memory.hpp b/include/kfr/base/memory.hpp
@@ -27,6 +27,7 @@
#include "read_write.hpp"
#include "types.hpp"
+#include <algorithm>
#include <atomic>
#include <memory>
diff --git a/include/kfr/base/pointer.hpp b/include/kfr/base/pointer.hpp
@@ -42,7 +42,7 @@ namespace internal
template <typename Expression, typename T, size_t key = 0>
KFR_SINTRIN bool invoke_substitute(Expression& expr, expression_pointer<T>&& new_pointer,
- csize_t<key> = csize_t<key>{});
+ csize_t<key> = {});
}
template <typename T, size_t N = maximum_expression_width>
diff --git a/include/kfr/base/simd_clang.hpp b/include/kfr/base/simd_clang.hpp
@@ -29,6 +29,8 @@
#include "platform.hpp"
#include "types.hpp"
+#if CMT_COMPILER_CLANG
+
CMT_PRAGMA_MSVC(warning(push))
CMT_PRAGMA_MSVC(warning(disable : 4324))
@@ -344,3 +346,5 @@ constexpr inline vec<T, csum<size_t, Ns...>()> concat(const vec<T, Ns>&... vs) n
} // namespace kfr
CMT_PRAGMA_MSVC(warning(pop))
+
+#endif
diff --git a/include/kfr/base/univector.hpp b/include/kfr/base/univector.hpp
@@ -374,6 +374,10 @@ struct univector<T, tag_dynamic_vector> : std::vector<T, allocator<T>>,
: std::vector<T, allocator<T>>(other.begin(), other.end())
{
}
+ template <typename Allocator>
+ constexpr univector(const std::vector<T, Allocator>&) = delete;
+ template <typename Allocator>
+ constexpr univector(std::vector<T, Allocator>&&) = delete;
constexpr static bool size_known = false;
constexpr static bool is_array = false;
constexpr static bool is_array_ref = false;
diff --git a/include/kfr/base/vec.hpp b/include/kfr/base/vec.hpp
@@ -128,14 +128,14 @@ constexpr inline size_t scale_get_index(size_t counter, size_t groupsize, size_t
}
template <size_t counter, size_t groupsize, size_t... indices>
-constexpr inline size_t scale_get_index()
+constexpr inline size_t scale_get_index(csizes_t<indices...>)
{
return scale_get_index(counter, groupsize, csizes_t<indices...>().get(csize_t<counter / groupsize>()));
}
template <size_t... indices, size_t... counter, size_t groupsize = sizeof...(counter) / sizeof...(indices)>
constexpr inline auto scale_impl(csizes_t<indices...> ind, csizes_t<counter...> cnt) noexcept
- -> csizes_t<scale_get_index<counter, groupsize, indices...>()...>
+ -> csizes_t<scale_get_index<counter, groupsize>(ind)...>
{
return {};
}
diff --git a/include/kfr/cometa.hpp b/include/kfr/cometa.hpp
@@ -253,14 +253,15 @@ namespace ops
{
struct empty
{
+ constexpr empty() noexcept {}
};
} // namespace ops
template <typename T, T val>
struct cval_t : ops::empty
{
- constexpr static T value = val;
- constexpr cval_t() noexcept = default;
+ constexpr static T value = val;
+ constexpr cval_t() noexcept {}
constexpr cval_t(const cval_t&) noexcept = default;
constexpr cval_t(cval_t&&) noexcept = default;
typedef T value_type;
@@ -359,6 +360,9 @@ struct get_nth<0, T, first, rest...>
constexpr static T value = first;
};
+template <size_t index, typename T>
+struct get_nth_e;
+
template <size_t index, typename... Types>
struct get_nth_type;
@@ -406,7 +410,7 @@ struct cvals_t : ops::empty
return &arr[0];
}
template <size_t... indices>
- constexpr cvals_t<T, details::get_nth<indices, T, values...>::value...> operator[](
+ constexpr cvals_t<T, details::get_nth_e<indices, type>::value...> operator[](
cvals_t<size_t, indices...>) const
{
return {};
@@ -427,6 +431,15 @@ struct cvals_t<T> : ops::empty
constexpr static size_t size() { return 0; }
};
+namespace details
+{
+template <size_t index, typename T, T... vals>
+struct get_nth_e<index, cvals_t<T, vals...>>
+{
+ constexpr static T value = get_nth<index, T, vals...>::value;
+};
+} // namespace details
+
template <bool... values>
using cbools_t = cvals_t<bool, values...>;
@@ -1658,8 +1671,6 @@ constexpr bool is_sequence(csizes_t<number, numbers...>)
return details::test_sequence<number, 1 + sizeof...(numbers)>(csizes_t<number, numbers...>()).value;
}
-#ifdef CMT_COMPILER_GNU
-
template <typename T, T val>
constexpr cval_t<T, val> cval{};
@@ -1727,7 +1738,6 @@ template <size_t size, unsigned start = 0, ptrdiff_t step = 1>
constexpr cvalseq_t<unsigned, size, start, step> cuintseq{};
template <typename... List>
constexpr indicesfor_t<List...> indicesfor{};
-#endif
// Workaround for GCC 4.8
template <typename T>
diff --git a/include/kfr/cometa/array.hpp b/include/kfr/cometa/array.hpp
@@ -51,8 +51,8 @@ public:
constexpr array_ref(std::array<T, N>& arr) noexcept : m_data(arr.data()), m_size(N)
{
}
- template <typename... Ts>
- constexpr array_ref(const std::vector<T, Ts...>& vec) noexcept : m_data(vec.data()), m_size(vec.size())
+ template <typename Alloc>
+ constexpr array_ref(const std::vector<T, Alloc>& vec) noexcept : m_data(vec.data()), m_size(vec.size())
{
}
diff --git a/include/kfr/data/sincos.hpp b/include/kfr/data/sincos.hpp
@@ -33,11 +33,7 @@ namespace data
{
template <typename T>
-constexpr T c_sin_table[65];
-
-// data generated by mpfr
-template <>
-constexpr f32 c_sin_table<f32>[65] = {
+constexpr T c_sin_table[65] = {
/* sin(2*pi* 0/ 256) */ f32(0.0),
/* sin(2*pi* 1/ 256) */ f32(0.02454122852291228803173452945928292506547),
/* sin(2*pi* 2/ 256) */ f32(0.04906767432741801425495497694268265831475),
diff --git a/include/kfr/dft/impl/dft-impl.hpp b/include/kfr/dft/impl/dft-impl.hpp
@@ -504,22 +504,25 @@ static void dft_stage_fixed_initialize(dft_stage<T>* stage, size_t width)
}
}
-template <typename T, size_t radix>
+template <typename T, size_t fixed_radix>
struct dft_stage_fixed_impl : dft_stage<T>
{
dft_stage_fixed_impl(size_t radix_, size_t iterations, size_t blocks)
{
this->name = type_name<decltype(*this)>();
- this->radix = radix;
+ this->radix = fixed_radix;
this->blocks = blocks;
this->repeats = iterations;
this->recursion = false; // true;
- this->data_size =
- align_up((this->repeats * (radix - 1)) * sizeof(complex<T>), platform<>::native_cache_alignment);
+ this->data_size = align_up((this->repeats * (fixed_radix - 1)) * sizeof(complex<T>),
+ platform<>::native_cache_alignment);
}
- constexpr static size_t width =
- radix >= 7 ? fft_vector_width<T> / 2 : radix >= 4 ? fft_vector_width<T> : fft_vector_width<T> * 2;
+ constexpr static size_t rradix = fixed_radix;
+
+ constexpr static size_t width = fixed_radix >= 7
+ ? fft_vector_width<T> / 2
+ : fixed_radix >= 4 ? fft_vector_width<T> : fft_vector_width<T> * 2;
virtual void do_initialize(size_t size) override final { dft_stage_fixed_initialize(this, width); }
DFT_STAGE_FN
@@ -529,40 +532,41 @@ struct dft_stage_fixed_impl : dft_stage<T>
const size_t Nord = this->repeats;
const complex<T>* twiddle = ptr_cast<complex<T>>(this->data);
- const size_t N = Nord * this->radix;
+ const size_t N = Nord * fixed_radix;
CMT_LOOP_NOUNROLL
for (size_t b = 0; b < this->blocks; b++)
{
- butterflies(Nord, csize<width>, csize<radix>, cbool<inverse>, out, in, twiddle, Nord);
+ butterflies(Nord, csize<width>, csize<fixed_radix>, cbool<inverse>, out, in, twiddle, Nord);
in += N;
out += N;
}
}
};
-template <typename T, size_t radix>
+template <typename T, size_t fixed_radix>
struct dft_stage_fixed_final_impl : dft_stage<T>
{
dft_stage_fixed_final_impl(size_t radix_, size_t iterations, size_t blocks)
{
this->name = type_name<decltype(*this)>();
- this->radix = radix;
+ this->radix = fixed_radix;
this->blocks = blocks;
this->repeats = iterations;
this->recursion = false;
this->can_inplace = false;
}
- constexpr static size_t width =
- radix >= 7 ? fft_vector_width<T> / 2 : radix >= 4 ? fft_vector_width<T> : fft_vector_width<T> * 2;
+ constexpr static size_t width = fixed_radix >= 7
+ ? fft_vector_width<T> / 2
+ : fixed_radix >= 4 ? fft_vector_width<T> : fft_vector_width<T> * 2;
DFT_STAGE_FN
template <bool inverse>
KFR_INTRIN void do_execute(complex<T>* out, const complex<T>* in, u8*)
{
const size_t b = this->blocks;
- const size_t size = b * radix;
+ const size_t size = b * fixed_radix;
- butterflies(b, csize<width>, csize<radix>, cbool<inverse>, out, in, b);
+ butterflies(b, csize<width>, csize<fixed_radix>, cbool<inverse>, out, in, b);
}
};
diff --git a/include/kfr/dft/impl/dft-templates.hpp b/include/kfr/dft/impl/dft-templates.hpp
@@ -24,6 +24,7 @@
See https://www.kfrlib.com for details.
*/
+#ifdef FLOAT
#include "../fft.hpp"
namespace kfr
@@ -42,3 +43,5 @@ template void dft_plan_real<FLOAT>::from_fmt(kfr::complex<FLOAT>* out, const kfr
template void dft_plan_real<FLOAT>::to_fmt(kfr::complex<FLOAT>* out, kfr::dft_pack_format fmt) const;
} // namespace kfr
+
+#endif
diff --git a/include/kfr/dft/impl/ft.hpp b/include/kfr/dft/impl/ft.hpp
@@ -1677,15 +1677,15 @@ KFR_INTRIN void spec_generic_butterfly_w(csize_t<radix>, cbool_t<inverse>, compl
template <typename T, bool inverse, typename Tstride = csize_t<1>>
KFR_INTRIN void generic_butterfly(size_t radix, cbool_t<inverse>, complex<T>* out, const complex<T>* in,
- complex<T>* temp, const complex<T>* twiddle, Tstride ostride = Tstride{})
+ complex<T>* temp, const complex<T>* twiddle, Tstride ostride = {})
{
- constexpr size_t width = platform<T>::vector_width;
-
cswitch(csizes_t<11, 13>(), radix,
[&](auto radix_) CMT_INLINE_LAMBDA {
+ constexpr size_t width = platform<T>::vector_width;
spec_generic_butterfly_w<width>(radix_, cbool_t<inverse>(), out, in, twiddle, ostride);
},
[&]() CMT_INLINE_LAMBDA {
+ constexpr size_t width = platform<T>::vector_width;
generic_butterfly_w<width>(radix, cbool_t<inverse>(), out, in, twiddle, ostride);
});
}
diff --git a/include/kfr/ext/double_double.hpp b/include/kfr/ext/double_double.hpp
@@ -38,10 +38,17 @@ struct double_double
const double cc = ((((x.hi - u.hi) - u.lo) + x.lo) - c * y.lo) / y.hi;
return { c, cc };
}
- constexpr bool isinf() const noexcept { return std::isinf(hi); }
- constexpr bool isnan() const noexcept { return std::isnan(hi) || std::isnan(lo); }
- constexpr double ulp(float value) const noexcept
+#if defined _MSC_VER && !defined __clang__
+#define DOUBLEDOUBLE_CONSTEXPR
+#else
+#define DOUBLEDOUBLE_CONSTEXPR constexpr
+#endif
+
+ DOUBLEDOUBLE_CONSTEXPR bool isinf() const noexcept { return std::isinf(hi); }
+ DOUBLEDOUBLE_CONSTEXPR bool isnan() const noexcept { return std::isnan(hi) || std::isnan(lo); }
+
+ DOUBLEDOUBLE_CONSTEXPR double ulp(float value) const noexcept
{
if (std::isnan(value) && isnan())
return 0.0;
@@ -51,7 +58,7 @@ struct double_double
return 1.0;
return (double_double(value) - *this) / double_double(std::nexttoward(value, 0.0));
}
- constexpr double ulp(double value) const noexcept
+ DOUBLEDOUBLE_CONSTEXPR double ulp(double value) const noexcept
{
if (std::isnan(value) && isnan())
return 0.0;
diff --git a/include/kfr/io/audiofile.hpp b/include/kfr/io/audiofile.hpp
@@ -64,6 +64,9 @@ struct audio_format
struct audio_format_and_length : audio_format
{
using audio_format::audio_format;
+#ifdef CMT_COMPILER_MSVC
+ audio_format_and_length() noexcept {}
+#endif
audio_format_and_length(const audio_format& fmt) : audio_format(fmt) {}
imax length = 0; // in samples
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
@@ -41,10 +41,15 @@ set(ALL_TESTS_CPP
all_tests.cpp
base_test.cpp
complex_test.cpp
- dft_test.cpp
dsp_test.cpp
expression_test.cpp
- intrinsic_test.cpp io_test.cpp resampler_test.cpp)
+ intrinsic_test.cpp
+ io_test.cpp
+ resampler_test.cpp)
+
+if (ENABLE_DFT)
+ list(APPEND ALL_TESTS_CPP dft_test.cpp)
+endif ()
if (MPFR_FOUND AND GMP_FOUND)
list(APPEND ALL_TESTS_CPP transcendental_test.cpp)
@@ -54,8 +59,10 @@ endif ()
add_executable(all_tests ${ALL_TESTS_CPP})
target_compile_definitions(all_tests PRIVATE KFR_NO_MAIN)
-target_link_libraries(all_tests kfr kfr_dft)
-target_link_libraries(all_tests kfr kfr_dft kfr_io)
+if (ENABLE_DFT)
+ target_link_libraries(all_tests kfr kfr_dft)
+endif ()
+target_link_libraries(all_tests kfr kfr_io)
if (MPFR_FOUND AND GMP_FOUND)
add_definitions(-DHAVE_MPFR)
@@ -65,7 +72,10 @@ endif ()
function(add_x86_test NAME FLAGS)
separate_arguments(FLAGS)
- add_executable(all_tests_${NAME} ${ALL_TESTS_CPP} ${KFR_DFT_SRC} ${KFR_IO_SRC})
+ add_executable(all_tests_${NAME} ${ALL_TESTS_CPP} ${KFR_IO_SRC})
+ if (ENABLE_DFT)
+ target_sources(all_tests_${NAME} PRIVATE ${KFR_DFT_SRC})
+ endif ()
target_compile_options(all_tests_${NAME} PRIVATE ${FLAGS})
target_compile_definitions(all_tests_${NAME} PRIVATE KFR_NO_MAIN)
target_link_libraries(all_tests_${NAME} kfr)