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 9dc5a34d8866c9e95ff8374914f177275689338a
parent fa7156ff4c124acc303f4e264770d4324e316bef
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Tue,  6 Dec 2022 08:49:44 +0000

Merge branch 'dev'

Diffstat:
Mdocs/docs/index.md | 1+
Adocs/docs/upgrade5.md | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdocs/mkdocs.yml | 4+++-
Minclude/kfr/base/basic_expressions.hpp | 2+-
Minclude/kfr/base/tensor.hpp | 2++
Minclude/kfr/base/univector.hpp | 22+++++++++++++++++++++-
Minclude/kfr/dsp/ebu.hpp | 4++--
Minclude/kfr/kfr.h | 2+-
8 files changed, 126 insertions(+), 6 deletions(-)

diff --git a/docs/docs/index.md b/docs/docs/index.md @@ -7,6 +7,7 @@ * [Basics](basics.md) * [Expressions](expressions.md) * [C API](capi.md) +* [Upgrade to KFR 5](upgrade5.md) ## Guides diff --git a/docs/docs/upgrade5.md b/docs/docs/upgrade5.md @@ -0,0 +1,95 @@ +# Upgrade to KFR 5 + +The KFR 5 release intoduced several changes to architecture, naming and semantics so any code using KFR needs to be adjusted. + +Here is the list of changes. + +### CMake variables now have `KFR_` prefix + +Examples of changes: +```cmake +ENABLE_DFT -> KFR_ENABLE_DFT +ENABLE_DFT_NP -> KFR_ENABLE_DFT_NP +ENABLE_DFT_MULTIARCH -> KFR_ENABLE_DFT_MULTIARCH +ENABLE_CAPI_BUILD -> KFR_ENABLE_CAPI_BUILD +DISABLE_CLANG_EXTENSIONS -> KFR_DISABLE_CLANG_EXTENSIONS +REGENERATE_TESTS -> KFR_REGENERATE_TESTS +CPU_ARCH -> KFR_ARCH +``` + +The following variables are unchanged. +``` +ENABLE_TESTS +ENABLE_EXAMPLES +KFR_EXTENDED_TESTS +KFR_STD_COMPLEX +``` + + +### Argument sizes must be equal + +`expression_function` arguments must have the same or compatible sizes (shapes). + +Previously, KFR allowed arguments with different sizes, effectively taking the minimum of +the sizes. From KFR 5 the sizes must be equal, or, alternatively, size of some arguments may be 1, values will be broadcasted to match the sizes of other arguments. + + +The operations on different arguments will result in the following shapes: +``` +`x` denotes any operator or function. +`inf` is `kfr::infinite_size` +{} x {} = {} # two scalars produce scalar too +{} x {2} = {2} # scalar broadcasted to 1-dim +{2,2} x {} = {2,2} # scalar broadcasted to 2-dims +{1} x {2} = {2} # broadcasted because size=1 +{2} x {3} = error in KFR 5, {2} in KFR 4 +{1,5} x {5,1} = {5,5} # row x column -> matrix +{5} x {5,1} = {5,5} # same with auto broadcasting +{inf} x {2} = {2} # infinite arguments are allowed everywhere +{inf,inf} x {5,1} = {5,1} # infinite arguments are allowed everywhere +{2,2} x {inf} = {2,2} # infinite arguments are allowed everywhere +{inf,inf} x {inf} = {inf,inf} # infinite arguments are allowed everywhere +``` + +The resulting shape can be tested with `internal_generic::common_shape` function. + +### Scalars are 0-dimensions values + +Scalars are now 0-dimensions values, use `dimensions<1>(scalar)` to change it to 1-dim infinite sequences as it was in KFR 4. + +In expressions, scalars are automatically broadcasted to higher dimensions as needed. + +### `std` aliases have been removed from `cometa` namespace + +Original std classes and variables should be used instead. `_t` (for types) or `_v` (values) suffix may be needed. + +Examples of code changes: +```c++ +cometa::invoke_result -> std::invoke_result_t +cometa::enable_if -> std::enable_if_t +cometa::common_type -> std::common_type_t +cometa::is_same -> std::is_same_v +cometa::is_invocable_r -> std::is_invocable_r_v +``` + +### All expressions and some classes have been moved out of `internal` namespace + +Examples of code changes: +``` +kfr::internal::biquad_state -> kfr::biquad_state +kfr::internal::expression_slice -> kfr::expression_slice +kfr::internal::expression_function -> kfr::expression_function +``` + +### Expressions 'pointers' have been renamed to 'handles'. + +``` +expression_pointer -> expression_handle +to_pointer -> to_handle +``` + +Also, handles now require their number of dimensions to be specified. + +### `expression_reduce` new template argument + +`expression_reduce` changed its prototype and now have Dims as its second template parameter. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml @@ -63,10 +63,12 @@ edit_uri: edit/master/docs/ nav: - KFR: - index.md + - whatsnew5.md - installation.md - basics.md - expressions.md - - whatsnew5.md + - capi.md + - upgrade5.md - DSP: - fir.md - bq.md diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp @@ -195,7 +195,7 @@ KFR_INTRINSIC vec<T, N> get_elements(const expression_slice<Arg>& self, const sh return static_cast<vec<T, N>>(get_elements(self.first(), index.add(self.start), sh)); } -template <typename Arg, index_t NDims, index_t Axis, size_t N, +template <typename Arg, index_t NDims, index_t Axis, size_t N, enable_if_output_expression<Arg>* = nullptr, typename T = typename expression_traits<expression_slice<Arg>>::value_type> KFR_INTRINSIC void set_elements(const expression_slice<Arg>& self, const shape<NDims>& index, const axis_params<Axis, N>& sh, const identity<vec<T, N>>& value) diff --git a/include/kfr/base/tensor.hpp b/include/kfr/base/tensor.hpp @@ -362,11 +362,13 @@ public: { this->~tensor(); new (this) tensor(src); + return *this; } tensor& operator=(tensor&& src) & { this->~tensor(); new (this) tensor(std::move(src)); + return *this; } #else tensor& operator=(const tensor& src) & = default; diff --git a/include/kfr/base/univector.hpp b/include/kfr/base/univector.hpp @@ -399,7 +399,7 @@ struct univector<T, tag_dynamic_vector> using std::vector<T, data_allocator<T>>::size; using std::vector<T, data_allocator<T>>::vector; using size_type = size_t; -#if !defined CMT_COMPILER_MSVC || defined CMT_COMPILER_CLANG +#if !defined CMT_COMPILER_IS_MSVC univector(univector& v) : univector(const_cast<const univector&>(v)) {} #endif univector(const univector& v) = default; @@ -449,7 +449,27 @@ struct univector<T, tag_dynamic_vector> return index < this->size() ? this->operator[](index) : fallback_value; } using univector_base<T, univector, is_vec_element<T>>::operator=; +#ifdef CMT_COMPILER_IS_MSVC + univector& operator=(const univector& other) + { + this->~univector(); + new (this) univector(other); + return *this; + } + univector& operator=(univector&& other) + { + this->~univector(); + new (this) univector(std::move(other)); + return *this; + } +#else univector& operator=(const univector&) = default; + univector& operator=(univector&&) = default; +#endif + KFR_MEM_INTRINSIC univector& operator=(univector& other) + { + return operator=(std::as_const(other)); + } template <typename Input, KFR_ACCEPT_EXPRESSIONS(Input)> KFR_MEM_INTRINSIC univector& operator=(Input&& input) { diff --git a/include/kfr/dsp/ebu.hpp b/include/kfr/dsp/ebu.hpp @@ -266,8 +266,8 @@ public: { KFR_LOGIC_CHECK(!channels.empty(), "channels must not be empty"); KFR_LOGIC_CHECK(sample_rate > 0, "sample_rate must be greater than 0"); - KFR_LOGIC_CHECK(packet_size_factor >= 1 && packet_size_factor <= 3, - "packet_size_factor must be in range [1..3]"); + KFR_LOGIC_CHECK(packet_size_factor >= 1 && packet_size_factor <= 6, + "packet_size_factor must be in range [1..6]"); for (Speaker sp : channels) { m_channels.emplace_back(sample_rate, sp, packet_size_factor, T(1)); diff --git a/include/kfr/kfr.h b/include/kfr/kfr.h @@ -34,7 +34,7 @@ #define KFR_VERSION_MAJOR 5 #define KFR_VERSION_MINOR 0 -#define KFR_VERSION_PATCH 0 +#define KFR_VERSION_PATCH 1 #define KFR_VERSION_LABEL "" #define KFR_VERSION_STRING \