Permalink
Browse files

Partial compatibility for Visual Studio 2017

  • Loading branch information...
dlevin256 committed Dec 27, 2018
1 parent d339155 commit 0d5f6b08a8a2655a5071337a90335f37474a649c
@@ -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)
@@ -28,13 +28,20 @@ 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)

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 ()
@@ -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) ----------------------
// --------------------------------------------------------------------------------------
@@ -142,6 +145,7 @@ int main()
#if PYTHON_IS_INSTALLED
// Plot results, same as filtered_noise2
plot_save("filtered_noise3", filtered_noise3, "title='Filtered noise 3', div_by_N=True");
#endif
#endif

return 0;
@@ -27,6 +27,7 @@

#include "read_write.hpp"
#include "types.hpp"
#include <algorithm>
#include <atomic>
#include <memory>

@@ -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>
@@ -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
@@ -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;
@@ -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 {};
}
@@ -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>
@@ -51,8 +51,8 @@ struct array_ref
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())
{
}

@@ -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),
@@ -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);
}
};

@@ -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
@@ -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);
});
}
@@ -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;
@@ -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
Oops, something went wrong.

0 comments on commit 0d5f6b0

Please sign in to comment.