forked from p12tic/libsimdpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Follow review * fix indent * add "fuzzing" tests for all algorithm * add TEST_EQUAL_COLLECTIONS * add nrt helpers for generating data (to be moved elsewhere ?)
- Loading branch information
1 parent
f57deb0
commit 3d9fb98
Showing
50 changed files
with
3,735 additions
and
2,733 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* Copyright (C) 2018 Povilas Kanapickas <[email protected]> | ||
Copyright (C) 2018 Thomas Retornaz <[email protected]> | ||
Distributed under the Boost Software License, Version 1.0. | ||
(See accompanying file LICENSE_1_0.txt or copy at | ||
|
@@ -17,53 +18,59 @@ | |
#include <simdpp/algorithm/helper_input_range.h> | ||
|
||
namespace simdpp { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
|
||
template<typename T, typename UnaryPredicate> | ||
bool all_of(T const* first, T const* last, UnaryPredicate pred) | ||
{ | ||
#ifndef NDEBUG //precondition debug mode | ||
if (!first) | ||
throw std::runtime_error("all_of - null ptr first."); | ||
if (!last) | ||
throw std::runtime_error("all_of - null ptr last."); | ||
template<typename T, typename UnaryPredicate> | ||
bool all_of(T const* first, T const* last, UnaryPredicate pred) | ||
{ | ||
#ifndef SIMDPP_DEBUG //precondition debug mode | ||
if (!first) | ||
throw std::runtime_error("all_of - null ptr first."); | ||
if (!last) | ||
throw std::runtime_error("all_of - null ptr last."); | ||
#endif | ||
|
||
using simd_type_T = typename typetraits<T>::simd_type; | ||
using simd_mask_T = typename typetraits<T>::simd_mask_type; | ||
using simd_type_T = typename simd_traits<T>::simd_type; | ||
using simd_mask_T = typename simd_traits<T>::simd_mask_type; | ||
|
||
//define loopcounter | ||
const auto simd_size = simd_type_T::base_length; | ||
//define loopcounter | ||
const auto simd_size = simd_type_T::base_length; | ||
|
||
//note enforce that input is aligned when we start the main simd loop | ||
const auto range = helper_input_range(first, last); | ||
const auto size_prologue_loop = range.first; | ||
const auto size_simd_loop = range.second; | ||
//note enforce that input is aligned when we start the main simd loop | ||
const auto range = helper_input_range(first, last); | ||
const auto size_prologue_loop = range.first; | ||
const auto size_simd_loop = range.second; | ||
|
||
//prologue | ||
auto lastprologue = first + size_prologue_loop; | ||
if(!std::all_of(first, lastprologue, pred)) return false; | ||
//prologue | ||
auto lastprologue = first + size_prologue_loop; | ||
if (!std::all_of(first, lastprologue, pred)) | ||
{ | ||
return false; | ||
} | ||
|
||
//simd loop | ||
auto i = size_prologue_loop; | ||
//workaraund not reduce_add for mask type | ||
const simd_type_T on = splat(T(1)); | ||
const simd_type_T off = splat(T(0)); | ||
for (; i < size_simd_loop; i += simd_size) | ||
{ | ||
simd_mask_T mask = pred(load(lastprologue)); | ||
const auto res = blend(on, off, mask); | ||
//simd loop | ||
auto i = size_prologue_loop; | ||
//workaraund not reduce_and for mask type | ||
const simd_type_T on = splat(T(1)); | ||
const simd_type_T off = splat(T(0)); | ||
for (; i < size_simd_loop; i += simd_size) | ||
{ | ||
simd_mask_T mask = pred(load(lastprologue)); | ||
const auto res = blend(on, off, mask); | ||
|
||
if (!reduce_and(res)) | ||
{ | ||
return false; | ||
} | ||
lastprologue += simd_size; | ||
} | ||
if(!std::all_of(lastprologue,last, pred)) return false; | ||
return true; | ||
} | ||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
if (!reduce_and(res)) | ||
{ | ||
return false; | ||
} | ||
lastprologue += simd_size; | ||
} | ||
if (!std::all_of(lastprologue,last, pred)) | ||
{ | ||
return false; | ||
} | ||
return true; | ||
} | ||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
} // namespace simdpp | ||
|
||
#endif //LIBSIMDPP_SIMDPP_ALGORITHM_ALL_OF_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* Copyright (C) 2018 Povilas Kanapickas <[email protected]> | ||
Copyright (C) 2018 Thomas Retornaz <[email protected]> | ||
Distributed under the Boost Software License, Version 1.0. | ||
(See accompanying file LICENSE_1_0.txt or copy at | ||
|
@@ -17,52 +18,55 @@ | |
#include <simdpp/algorithm/helper_input_range.h> | ||
|
||
namespace simdpp { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
|
||
template<typename T, typename UnaryPredicate> | ||
bool any_of(T const* first, T const* last, UnaryPredicate pred) | ||
{ | ||
#ifndef NDEBUG //precondition debug mode | ||
if (!first) | ||
throw std::runtime_error("any_of - null ptr first."); | ||
if (!last) | ||
throw std::runtime_error("any_of - null ptr last."); | ||
template<typename T, typename UnaryPredicate> | ||
bool any_of(T const* first, T const* last, UnaryPredicate pred) | ||
{ | ||
#ifndef SIMDPP_DEBUG //precondition debug mode | ||
if (!first) | ||
throw std::runtime_error("any_of - null ptr first."); | ||
if (!last) | ||
throw std::runtime_error("any_of - null ptr last."); | ||
#endif | ||
|
||
using simd_type_T = typename typetraits<T>::simd_type; | ||
using simd_mask_T = typename typetraits<T>::simd_mask_type; | ||
using simd_type_T = typename simd_traits<T>::simd_type; | ||
using simd_mask_T = typename simd_traits<T>::simd_mask_type; | ||
|
||
//define loopcounter | ||
const auto simd_size = simd_type_T::base_length; | ||
//define loopcounter | ||
const auto simd_size = simd_type_T::base_length; | ||
|
||
//note enforce that input is aligned when we start the main simd loop | ||
const auto range = helper_input_range(first, last); | ||
const auto size_prologue_loop = range.first; | ||
const auto size_simd_loop = range.second; | ||
//note enforce that input is aligned when we start the main simd loop | ||
const auto range = helper_input_range(first, last); | ||
const auto size_prologue_loop = range.first; | ||
const auto size_simd_loop = range.second; | ||
|
||
//prologue | ||
auto lastprologue = first + size_prologue_loop; | ||
if(std::any_of(first, lastprologue, pred)) return true; | ||
//prologue | ||
auto lastprologue = first + size_prologue_loop; | ||
if (std::any_of(first, lastprologue, pred)) | ||
{ | ||
return true; | ||
} | ||
|
||
//simd loop | ||
auto i = size_prologue_loop; | ||
//workaraund not test_bits_any for mask type | ||
const simd_type_T on = splat(T(1)); //TODO factorize | ||
const simd_type_T off = splat(T(0)); | ||
for (; i < size_simd_loop; i += simd_size) | ||
{ | ||
simd_mask_T mask = pred(load(lastprologue)); //TODO factorize | ||
const auto res = blend(on, off, mask); | ||
if (test_bits_any(res)) | ||
{ | ||
return true; | ||
} | ||
lastprologue += simd_size; | ||
} | ||
return std::any_of(lastprologue,last, pred); | ||
} | ||
//simd loop | ||
auto i = size_prologue_loop; | ||
//workaraund not test_bits_any for mask type | ||
const simd_type_T on = splat(T(1)); //TODO factorize | ||
const simd_type_T off = splat(T(0)); | ||
for (; i < size_simd_loop; i += simd_size) | ||
{ | ||
simd_mask_T mask = pred(load(lastprologue)); //TODO factorize | ||
const auto res = blend(on, off, mask); | ||
if (test_bits_any(res)) | ||
{ | ||
return true; | ||
} | ||
lastprologue += simd_size; | ||
} | ||
return std::any_of(lastprologue,last, pred); | ||
} | ||
|
||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
} // namespace simdpp | ||
|
||
#endif //LIBSIMDPP_SIMDPP_ALGORITHM_ANY_OF_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* Copyright (C) 2018 Povilas Kanapickas <[email protected]> | ||
Copyright (C) 2018 Thomas Retornaz <[email protected]> | ||
Distributed under the Boost Software License, Version 1.0. | ||
(See accompanying file LICENSE_1_0.txt or copy at | ||
|
@@ -15,29 +16,29 @@ Distributed under the Boost Software License, Version 1.0. | |
#include <simdpp/algorithm/transform.h> | ||
|
||
namespace simdpp { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
|
||
template<typename T> | ||
T* copy(T const* first, T const* last, T* out) | ||
{ | ||
struct UnaryOpCopy | ||
{ | ||
using simd_type_T = typename typetraits<T>::simd_type; | ||
SIMDPP_INL T operator()(T const &a) const noexcept | ||
{ | ||
return a; | ||
} | ||
|
||
SIMDPP_INL simd_type_T operator()(simd_type_T const &a) const noexcept | ||
{ | ||
return a; | ||
} | ||
}; | ||
|
||
return transform(first, last, out, UnaryOpCopy{}); | ||
} | ||
|
||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
|
||
template<typename T> | ||
T* copy(T const* first, T const* last, T* out) | ||
{ | ||
struct UnaryOpCopy | ||
{ | ||
using simd_type_T = typename simd_traits<T>::simd_type; | ||
SIMDPP_INL T operator()(T const &a) const noexcept | ||
{ | ||
return a; | ||
} | ||
|
||
SIMDPP_INL simd_type_T operator()(simd_type_T const &a) const noexcept | ||
{ | ||
return a; | ||
} | ||
}; | ||
|
||
return transform(first, last, out, UnaryOpCopy{}); | ||
} | ||
|
||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
} // namespace simdpp | ||
|
||
#endif //LIBSIMDPP_SIMDPP_ALGORITHM_COPY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* Copyright (C) 2018 Povilas Kanapickas <[email protected]> | ||
Copyright (C) 2018 Thomas Retornaz <[email protected]> | ||
Distributed under the Boost Software License, Version 1.0. | ||
(See accompanying file LICENSE_1_0.txt or copy at | ||
|
@@ -15,15 +16,15 @@ Distributed under the Boost Software License, Version 1.0. | |
#include <simdpp/algorithm/copy.h> | ||
|
||
namespace simdpp { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
|
||
template<typename T, typename Size> T* copy_n(T const* first, Size n, T* out) | ||
{ | ||
if (n <= Size(0)) return out; | ||
return copy(first, first + n, out); | ||
} | ||
template<typename T, typename Size> T* copy_n(T const* first, Size n, T* out) | ||
{ | ||
if (n <= Size(0)) return out; | ||
return copy(first, first + n, out); | ||
} | ||
|
||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
} // namespace simdpp | ||
|
||
#endif //LIBSIMDPP_SIMDPP_ALGORITHM_COPY_N_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* Copyright (C) 2018 Povilas Kanapickas <[email protected]> | ||
Copyright (C) 2018 Thomas Retornaz <[email protected]> | ||
Distributed under the Boost Software License, Version 1.0. | ||
(See accompanying file LICENSE_1_0.txt or copy at | ||
|
@@ -15,56 +16,56 @@ Distributed under the Boost Software License, Version 1.0. | |
#include <simdpp/algorithm/transform.h> | ||
|
||
namespace simdpp { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
namespace SIMDPP_ARCH_NAMESPACE { | ||
|
||
template<typename T, typename U> | ||
typename std::iterator_traits<const T*>::difference_type | ||
count(T const* first, T const* last, U val) | ||
{ | ||
#ifndef NDEBUG //precondition debug mode | ||
if (!first) | ||
throw std::runtime_error("count - null ptr first."); | ||
if (!last) | ||
throw std::runtime_error("count - null ptr last."); | ||
template<typename T, typename U> | ||
typename std::iterator_traits<const T*>::difference_type | ||
count(T const* first, T const* last, U val) | ||
{ | ||
#ifndef SIMDPP_DEBUG //precondition debug mode | ||
if (!first) | ||
throw std::runtime_error("count - null ptr first."); | ||
if (!last) | ||
throw std::runtime_error("count - null ptr last."); | ||
#endif | ||
|
||
using simd_type_T = typename typetraits<T>::simd_type; | ||
using simd_mask_T = typename typetraits<T>::simd_mask_type; | ||
using return_type = typename std::iterator_traits<const T*>::difference_type; | ||
if (first == last) return (return_type)0; | ||
//define loopcounter | ||
const auto simd_size = simd_type_T::base_length; | ||
using simd_type_T = typename simd_traits<T>::simd_type; | ||
using simd_mask_T = typename simd_traits<T>::simd_mask_type; | ||
using return_type = typename std::iterator_traits<const T*>::difference_type; | ||
if (first == last) return (return_type)0; | ||
//define loopcounter | ||
const auto simd_size = simd_type_T::base_length; | ||
|
||
//note enforce that input is aligned when we start the main simd loop | ||
const auto range = helper_input_range(first, last); | ||
const auto size_prologue_loop = range.first; | ||
const auto size_simd_loop = range.second; | ||
//note enforce that input is aligned when we start the main simd loop | ||
const auto range = helper_input_range(first, last); | ||
const auto size_prologue_loop = range.first; | ||
const auto size_simd_loop = range.second; | ||
|
||
//prologue | ||
auto lastprologue = first + size_prologue_loop; | ||
return_type res = std::count(first, lastprologue, val); | ||
//prologue | ||
auto lastprologue = first + size_prologue_loop; | ||
return_type res = std::count(first, lastprologue, val); | ||
|
||
//simd loop | ||
auto i = size_prologue_loop; | ||
//simd loop | ||
auto i = size_prologue_loop; | ||
|
||
//workaraund not reduce_add for mask type | ||
const simd_type_T on = splat(T(1)); | ||
const simd_type_T off = splat(T(0)); | ||
const simd_type_T valsimd = splat(U(val)); | ||
//workaraund not reduce_add for mask type | ||
const simd_type_T on = splat(T(1)); | ||
const simd_type_T off = splat(T(0)); | ||
const simd_type_T valsimd = splat(U(val)); | ||
|
||
for (; i < size_simd_loop; i += simd_size) | ||
{ | ||
const simd_type_T el = load(lastprologue); | ||
const simd_mask_T mask = cmp_eq(el, valsimd); | ||
const auto rescurrentsimd = blend(on, off, mask); | ||
res += (return_type)reduce_add(rescurrentsimd); | ||
lastprologue += simd_size; | ||
} | ||
res += std::count(lastprologue, last, val); | ||
return res; | ||
} | ||
for (; i < size_simd_loop; i += simd_size) | ||
{ | ||
const simd_type_T el = load(lastprologue); | ||
const simd_mask_T mask = cmp_eq(el, valsimd); | ||
const auto rescurrentsimd = blend(on, off, mask); | ||
res += (return_type)reduce_add(rescurrentsimd); | ||
lastprologue += simd_size; | ||
} | ||
res += std::count(lastprologue, last, val); | ||
return res; | ||
} | ||
|
||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
} // namespace SIMDPP_ARCH_NAMESPACE | ||
} // namespace simdpp | ||
|
||
#endif //LIBSIMDPP_SIMDPP_ALGORITHM_COUNT_H |
Oops, something went wrong.