Skip to content

Commit 211bc83

Browse files
committed
add 'for_each' helper algorithm
1 parent e22d4e0 commit 211bc83

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

examples/boost-simd-for-each.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// [[Rcpp::depends(RcppParallel)]]
2+
#define RCPP_PARALLEL_USE_SIMD
3+
#include <RcppParallel.h>
4+
#include <Rcpp.h>
5+
using namespace Rcpp;
6+
7+
// Product of squared deviations
8+
class Accumulator
9+
{
10+
public:
11+
12+
Accumulator() : result_(1.0) {}
13+
14+
template <typename T>
15+
void operator()(const T& data)
16+
{
17+
result_ *= boost::simd::prod(data);
18+
}
19+
20+
operator double() const {
21+
return result_;
22+
}
23+
24+
private:
25+
double result_;
26+
};
27+
28+
// [[Rcpp::export]]
29+
double vectorProd(NumericVector x) {
30+
auto accumulator = Accumulator();
31+
boost::simd::for_each(x.begin(), x.end(), accumulator);
32+
return accumulator;
33+
}
34+
35+
/*** R
36+
x <- 1:16
37+
vectorProd(x)
38+
*/

inst/include/RcppParallel/SIMD.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@
3838
#include <RcppParallel/simd/adaptors.h>
3939

4040
#include <RcppParallel/simd/map_reduce.h>
41+
#include <RcppParallel/simd/for_each.h>
4142

4243
#endif /* RCPP_PARALLEL_SIMD_H */
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef RCPP_PARALLEL_SIMD_FOR_EACH_H
2+
#define RCPP_PARALLEL_SIMD_FOR_EACH_H
3+
4+
namespace boost {
5+
namespace simd {
6+
7+
template <typename T, typename F>
8+
void for_each(const T* it, const T* end, F& f)
9+
{
10+
typedef boost::simd::pack<T> vT;
11+
static const std::size_t N = vT::static_size;
12+
const T* aligned_begin = std::min(boost::simd::align_on(it, N * sizeof(T)), end);
13+
const T* aligned_end = aligned_begin + (end - aligned_begin) / N * N;
14+
15+
for (; it != aligned_begin; ++it)
16+
f(*it);
17+
18+
for (; it != aligned_end; it += N)
19+
f(boost::simd::aligned_load<vT>(it));
20+
21+
for (; it != end; ++it)
22+
f(*it);
23+
}
24+
25+
} // namespace simd
26+
} // namespace boost
27+
28+
#endif /* RCPP_PARALLEL_SIMD_FOR_EACH_H */

0 commit comments

Comments
 (0)