diff options
Diffstat (limited to 'src/lib/netlist/plib/vector_ops.h')
-rw-r--r-- | src/lib/netlist/plib/vector_ops.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/lib/netlist/plib/vector_ops.h b/src/lib/netlist/plib/vector_ops.h new file mode 100644 index 00000000000..8043c48f61c --- /dev/null +++ b/src/lib/netlist/plib/vector_ops.h @@ -0,0 +1,151 @@ +// license:GPL-2.0+ +// copyright-holders:Couriersud +/* + * vector_ops.h + * + * Base vector operations + * + */ + +#ifndef PLIB_VECTOR_OPS_H_ +#define PLIB_VECTOR_OPS_H_ + +#include "pconfig.h" + +#include <algorithm> +#include <cmath> +#include <type_traits> + +#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) +#if !(__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 3)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif +#endif + +namespace plib +{ + template<typename VT, typename T> + void vec_set_scalar(const std::size_t n, VT &v, T && scalar) + { + const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar)); + for ( std::size_t i = 0; i < n; i++ ) + v[i] = s; + } + + template<typename VT, typename VS> + void vec_set(const std::size_t n, VT &v, const VS & source) + { + for ( std::size_t i = 0; i < n; i++ ) + v[i] = source[i]; + } + + template<typename T, typename V1, typename V2> + T vec_mult(const std::size_t n, const V1 & v1, const V2 & v2 ) + { + using b8 = T[8]; + PALIGNAS_VECTOROPT() b8 value = {0}; + for (std::size_t i = 0; i < n ; i++ ) + { + value[i & 7] += v1[i] * v2[i]; + } + return value[0] + value[1] + value[2] + value[3] + value[4] + value[5] + value[6] + value[7]; + } + + template<typename T, typename VT> + T vec_mult2(const std::size_t n, const VT &v) + { + using b8 = T[8]; + PALIGNAS_VECTOROPT() b8 value = {0}; + for (std::size_t i = 0; i < n ; i++ ) + { + value[i & 7] += v[i] * v[i]; + } + return value[0] + value[1] + value[2] + value[3] + value[4] + value[5] + value[6] + value[7]; + } + + template<typename T, typename VT> + T vec_sum(const std::size_t n, const VT &v) + { + if (n<8) + { + T value(0); + for (std::size_t i = 0; i < n ; i++ ) + value += v[i]; + + return value; + } + else + { + using b8 = T[8]; + PALIGNAS_VECTOROPT() b8 value = {0}; + for (std::size_t i = 0; i < n ; i++ ) + value[i & 7] += v[i]; + + return ((value[0] + value[1]) + (value[2] + value[3])) + ((value[4] + value[5]) + (value[6] + value[7])); + } + } + + template<typename VV, typename T, typename VR> + void vec_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar) + { + const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar)); + for ( std::size_t i = 0; i < n; i++ ) + result[i] = s * v[i]; + } + + template<typename VR, typename VV, typename T> + void vec_add_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar) + { + const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar)); + for ( std::size_t i = 0; i < n; i++ ) + result[i] += s * v[i]; + } + + template<typename T> + void vec_add_mult_scalar_p(const std::size_t n, T * result, const T * v, T scalar) + { + for ( std::size_t i = 0; i < n; i++ ) + result[i] += scalar * v[i]; + } + + template<typename R, typename V> + void vec_add_ip(const std::size_t n, R & result, const V & v) + { + for ( std::size_t i = 0; i < n; i++ ) + result[i] += v[i]; + } + + template<typename VR, typename V1, typename V2> + void vec_sub(const std::size_t n, VR & result, const V1 &v1, const V2 & v2) + { + for ( std::size_t i = 0; i < n; i++ ) + result[i] = v1[i] - v2[i]; + } + + template<typename V, typename T> + void vec_scale(const std::size_t n, V & v, T &&scalar) + { + const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar)); + for ( std::size_t i = 0; i < n; i++ ) + v[i] *= s; + } + + template<typename T, typename V> + T vec_maxabs(const std::size_t n, const V & v) + { + T ret = 0.0; + for ( std::size_t i = 0; i < n; i++ ) + ret = std::max(ret, std::abs(v[i])); + + return ret; + } +} // namespace plib + +#if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) +#if !(__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 3)) +#pragma GCC diagnostic pop +#endif +#endif + +#endif /* PLIB_VECTOR_OPS_H_ */ |