Skip to content

Commit 6f2434d

Browse files
committed
initial commit
0 parents  commit 6f2434d

File tree

12,723 files changed

+397522
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

12,723 files changed

+397522
-0
lines changed

.Rbuildignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
^.*\.Rproj$
2+
^\.Rproj\.user$
3+
^patch/
4+
^nt2/

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.Rproj.user
2+
.Rhistory
3+
.RData
4+
5+
/nt2

DESCRIPTION

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Package: RcppNT2
2+
Title: 'Rcpp' Integration for the 'NT2' Scientific Computing Library
3+
Version: 0.1.0
4+
Authors@R: c(
5+
person("Kevin", "Ushey", email = "[email protected]", role = c("aut", "cre")),
6+
person("Joel", "Falcou", role = "aut", comment = "Author of NT2"))
7+
Description: The 'Numerical Template Toolbox (NT2)' is an open source C++
8+
library aimed at simplifying the development, debugging and optimization of
9+
high-performance computing applications.
10+
URL: https://github.com/RcppCore/RcppNT2
11+
BugReports: https://github.com/RcppCore/RcppNT2/issues
12+
Depends:
13+
R (>= 3.1.0)
14+
License: BSL-1.0
15+
SystemRequirements: C++11
16+
RoxygenNote: 5.0.1

NAMESPACE

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Generated by roxygen2: do not edit by hand
2+

R/plugin.R

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Inline plugin used by 'Rcpp::sourceCpp()'.
2+
inlineCxxPlugin <- function() {
3+
list(
4+
env = list(
5+
PKG_CXXFLAGS = paste("$(CXX1XSTD)")
6+
),
7+
includes = "#include <RcppNt2.h>"
8+
)
9+
}

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
RcppNT2
2+
=======
3+
4+
## Overview
5+
6+
The [Numerical Template Toolbox (NT<sup>2</sup>)](https://github.com/jfalcou/nt2)
7+
is an Open Source C++ library aimed at simplifying the development, debugging
8+
and optimization of high-performance computing applications by providing a
9+
Matlab like syntax that eases the transition between prototype and actual
10+
application.
11+
12+
`RcppNT2` bundles the `NT<sup>2</sup>` library, and provides a number of helper
13+
wrappers, to make it easy to use in your own R packages.

RcppNT2.Rproj

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Version: 1.0
2+
3+
RestoreWorkspace: No
4+
SaveWorkspace: No
5+
AlwaysSaveHistory: Default
6+
7+
EnableCodeIndexing: Yes
8+
UseSpacesForTab: Yes
9+
NumSpacesForTab: 2
10+
Encoding: UTF-8
11+
12+
RnwWeave: Sweave
13+
LaTeX: pdfLaTeX
14+
15+
AutoAppendNewline: Yes
16+
StripTrailingWhitespace: Yes
17+
18+
BuildType: Package
19+
PackageUseDevtools: Yes
20+
PackageInstallArgs: --no-multiarch --with-keep.source
21+
PackageRoxygenize: rd,collate,namespace

inst/configure/configure.R

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
NT2_URL <- "https://github.com/jfalcou/nt2"
2+
COMMIT <- "f19e80f55cad6db21ccb3c7f216efecf45c91250"
3+
4+
# Helpers
5+
pathProg <- function(name) {
6+
prog <- Sys.which(name)
7+
if (!nzchar(prog))
8+
stop("No program named '", name, "' on the PATH!", call. = FALSE)
9+
prog
10+
}
11+
12+
cmakeDef <- function(name, value) {
13+
sprintf("-D%s=%s", name, value)
14+
}
15+
16+
cmake <- pathProg("cmake")
17+
make <- pathProg("make")
18+
git <- pathProg("git")
19+
patch <- pathProg("patch")
20+
21+
# End helpers
22+
23+
owd <- getwd()
24+
25+
# Check out the 'nt2' sources
26+
if (!dir.exists("nt2"))
27+
system2(git, c("clone", NT2_URL))
28+
setwd("nt2")
29+
30+
# Check out the relevant commit
31+
system2(git, c("checkout", COMMIT))
32+
33+
# Prepare installation directory
34+
if (dir.exists("install"))
35+
unlink("install", recursive = TRUE)
36+
dir.create("install")
37+
installDir <- file.path(getwd(), "install")
38+
39+
# Enter 'nt2' directory, and check out relevant commit
40+
if (dir.exists("build"))
41+
unlink("build", recursive = TRUE)
42+
dir.create("build")
43+
setwd("build")
44+
45+
# Call cmake to prepare the build
46+
system2(cmake, c(
47+
"..",
48+
cmakeDef("CMAKE_INSTALL_PREFIX", installDir)
49+
))
50+
51+
# Call 'make', 'make install' to build and install
52+
system2(make)
53+
system2(make, "install")
54+
55+
# Go back to parent directory
56+
setwd(owd)
57+
58+
# Copy all of the relevant headers over
59+
includePath <- file.path(installDir, "include")
60+
from <- list.files(includePath, full.names = TRUE)
61+
to <- file.path("inst/include")
62+
if (!dir.exists(to))
63+
dir.create(to, recursive = TRUE)
64+
file.copy(from, to, recursive = TRUE)
65+
66+
# Apply all of our patches
67+
patches <- list.files("patch", full.names = TRUE)
68+
for (patch in patches) {
69+
system2(patch, c("-p1", "<", patch))
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Print the SIMD capabilities of your processor.
2+
3+
// [[Rcpp::depends(RcppNt2)]]
4+
#include <RcppNt2.h>
5+
using namespace RcppNt2;
6+
7+
#include <Rcpp.h>
8+
using namespace Rcpp;
9+
10+
#include <boost/simd/sdk/simd/extensions/meta/tags.hpp>
11+
#include <boost/simd/sdk/config/is_supported.hpp>
12+
#include <boost/config.hpp>
13+
14+
// Try playing around with the '-march' flag to see what support is detected.
15+
// Note that most modern processors will implement instructions up to SSE3,
16+
// but certain AVX and FMA instructions are only available on newer CPUs.
17+
18+
// [[Rcpp::export]]
19+
void simd_capabilities() {
20+
21+
using boost::simd::is_supported;
22+
using namespace boost::simd::tag;
23+
24+
std::cout << "SIMD Capabilities\n"
25+
<< "=================\n\n";
26+
27+
std::cout << "AVX2: " << is_supported<avx2_>() << "\n"
28+
<< "AVX: " << is_supported<avx_>() << "\n"
29+
<< "FMA4: " << is_supported<fma4_>() << "\n"
30+
<< "FMA3: " << is_supported<fma3_>() << "\n"
31+
<< "SSE4a: " << is_supported<sse4a_>() << "\n"
32+
<< "SSE4_2: " << is_supported<sse4_2_>() << "\n"
33+
<< "SSE4_1: " << is_supported<sse4_1_>() << "\n"
34+
<< "SSE3: " << is_supported<sse3_>() << "\n"
35+
<< "SSE2: " << is_supported<sse2_>() << "\n"
36+
<< "SSE: " << is_supported<sse_>() << "\n";
37+
}
38+
39+
/***R
40+
simd_capabilities()
41+
*/
42+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Demonstrates how Boost.SIMD could be used to compute the dot product
2+
// of two vectors, using a lower-level iteration over packs.
3+
//
4+
// See: http://nt2.metascale.fr/doc/html/tutorials/processing_data_the_simd_way.html
5+
6+
// [[Rcpp::depends(RcppNt2)]]
7+
#include <RcppNt2.h>
8+
using namespace RcppNt2;
9+
10+
#include <Rcpp.h>
11+
using namespace Rcpp;
12+
13+
template <typename Value>
14+
Value simd_dot_impl(Value* first1, Value* last1, Value* first2)
15+
{
16+
using boost::simd::sum;
17+
using boost::simd::pack;
18+
19+
typedef pack<Value> packed_type;
20+
packed_type tmp;
21+
22+
// Let's consider that (last1-first1) is divisible by the size of the pack.
23+
while (first1 != last1)
24+
{
25+
// Load current values from the datasets
26+
packed_type x1 = boost::simd::load<packed_type>(first1);
27+
packed_type x2 = boost::simd::load<packed_type>(first2);
28+
29+
// Computation
30+
tmp = tmp + x1 * x2;
31+
32+
// Advance to the next SIMD vector
33+
first1 += packed_type::static_size;
34+
first2 += packed_type::static_size;
35+
}
36+
37+
return sum(tmp);
38+
}
39+
40+
// [[Rcpp::export]]
41+
double simd_dot(NumericVector lhs, NumericVector rhs)
42+
{
43+
return simd_dot_impl(
44+
REAL(lhs),
45+
REAL(lhs) + lhs.size(),
46+
REAL(rhs)
47+
);
48+
}
49+
50+
/*** R
51+
set.seed(123)
52+
lhs <- rnorm(1024 * 1000)
53+
rhs <- rnorm(1024 * 1000)
54+
stopifnot(all.equal(simd_dot(lhs, rhs), sum(lhs * rhs)))
55+
56+
library(microbenchmark)
57+
microbenchmark(
58+
simd = simd_dot(lhs, rhs),
59+
R = sum(lhs * rhs)
60+
)
61+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Showcases how a stateful functor can be used with `simdFor()`,
2+
// for arbitrary operations over a range of values.
3+
4+
// [[Rcpp::depends(RcppParallel)]]
5+
#define RCPP_PARALLEL_USE_SIMD
6+
#include <RcppParallel.h>
7+
using namespace RcppParallel;
8+
9+
#include <Rcpp.h>
10+
using namespace Rcpp;
11+
12+
// Product of squared deviations
13+
class Accumulator
14+
{
15+
public:
16+
17+
Accumulator() : result_(1.0) {}
18+
19+
template <typename T>
20+
void operator()(const T& data)
21+
{
22+
result_ *= boost::simd::prod(data);
23+
}
24+
25+
operator double() const {
26+
return result_;
27+
}
28+
29+
private:
30+
double result_;
31+
};
32+
33+
// [[Rcpp::export]]
34+
double simdProd(NumericVector x) {
35+
return simdFor(x.begin(), x.end(), Accumulator());
36+
}
37+
38+
/*** R
39+
x <- 1:16
40+
stopifnot(all.equal(prod(x), simdProd(x)))
41+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// The 'hello world' of Boost.SIMD, showing how packs can be
2+
// used and manipulated at a low level.
3+
//
4+
// See: http://nt2.metascale.fr/doc/html/tutorials/simd_hello_world.html
5+
6+
// [[Rcpp::depends(RcppParallel)]]
7+
#define RCPP_PARALLEL_USE_SIMD
8+
#include <RcppParallel.h>
9+
using namespace RcppParallel;
10+
11+
#include <Rcpp.h>
12+
using namespace Rcpp;
13+
14+
// [[Rcpp::export]]
15+
void HelloWorld()
16+
{
17+
typedef boost::simd::pack<float> p_t;
18+
19+
p_t res;
20+
p_t u(10);
21+
p_t r = boost::simd::splat<p_t>(11);
22+
23+
res = (u + r) * 2.f;
24+
25+
Rcout << res << std::endl;
26+
}
27+
28+
/*** R
29+
HelloWorld()
30+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Shows how 'simdMapReduce()' can be used to efficiently
2+
// transform and accumulate values.
3+
4+
// [[Rcpp::depends(RcppParallel)]]
5+
#define RCPP_PARALLEL_USE_SIMD
6+
#include <RcppParallel.h>
7+
using namespace RcppParallel;
8+
9+
#include <Rcpp.h>
10+
using namespace Rcpp;
11+
12+
class SumOfSquaresReducer
13+
{
14+
public:
15+
16+
explicit SumOfSquaresReducer(double mean)
17+
: mean_(mean)
18+
{}
19+
20+
template <typename T>
21+
void map(const T& self, T* pBuffer)
22+
{
23+
*pBuffer += boost::simd::sqr(self - mean_);
24+
}
25+
26+
template <typename T, typename U>
27+
void reduce(const T& data, U* pBuffer)
28+
{
29+
*pBuffer += boost::simd::sum(data);
30+
}
31+
32+
private:
33+
double mean_;
34+
};
35+
36+
// [[Rcpp::export]]
37+
double simdVar(NumericVector x)
38+
{
39+
double total = simdReduce(x.begin(), x.end(), 0.0, simd_ops::plus());
40+
double n = x.size();
41+
double mean = total / n;
42+
43+
double ssq = simdMapReduce(x.begin(), x.end(), 0.0, SumOfSquaresReducer(mean));
44+
45+
return ssq / (n - 1);
46+
}
47+
48+
/*** R
49+
set.seed(123)
50+
x <- rnorm(1024)
51+
stopifnot(all.equal(var(x), simdVar(x)))
52+
library(microbenchmark)
53+
microbenchmark(var(x), simdVar(x))
54+
*/

0 commit comments

Comments
 (0)