Skip to content

Commit

Permalink
issue p12tic#107
Browse files Browse the repository at this point in the history
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
ThomasRetornaz committed Apr 9, 2018
1 parent f57deb0 commit 3d9fb98
Show file tree
Hide file tree
Showing 50 changed files with 3,735 additions and 2,733 deletions.
85 changes: 46 additions & 39 deletions simdpp/algorithm/all_of.h
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
Expand All @@ -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
80 changes: 42 additions & 38 deletions simdpp/algorithm/any_of.h
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
Expand All @@ -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
47 changes: 24 additions & 23 deletions simdpp/algorithm/copy.h
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
Expand All @@ -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
15 changes: 8 additions & 7 deletions simdpp/algorithm/copy_n.h
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
Expand All @@ -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
83 changes: 42 additions & 41 deletions simdpp/algorithm/count.h
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
Expand All @@ -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
Loading

0 comments on commit 3d9fb98

Please sign in to comment.