Skip to content

Commit e622894

Browse files
committed
add 'RcppParallel.package.skeleton()'
1 parent 1262e74 commit e622894

File tree

5 files changed

+225
-0
lines changed

5 files changed

+225
-0
lines changed

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ Collate:
3232
'build.R'
3333
'hooks.R'
3434
'options.R'
35+
'skeleton.R'

R/skeleton.R

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
RcppParallel.package.skeleton <- function(name = "anRpackage",
2+
example_code = TRUE,
3+
...)
4+
{
5+
# call Rcpp.package.skeleton() -- provide 'list' explicitly
6+
# and clean up after
7+
env <- new.env(parent = emptyenv())
8+
env$dummy <- NULL
9+
Rcpp::Rcpp.package.skeleton(
10+
name = name,
11+
attributes = FALSE,
12+
module = FALSE,
13+
example_code = FALSE,
14+
environment = env,
15+
list = "dummy",
16+
...
17+
)
18+
19+
# move to generated package directory
20+
owd <- setwd(name)
21+
on.exit(setwd(owd), add = TRUE)
22+
23+
# remove dummy stuff
24+
unlink("data/dummy.Rda")
25+
unlink("man/dummy.Rd")
26+
27+
message("\nAdding RcppParallel settings")
28+
29+
# update DESCRIPTION file
30+
desc <- read.dcf("DESCRIPTION", all = TRUE, keep.white = TRUE)
31+
version <- sprintf("RcppParallel (>= %s)", utils::packageVersion("RcppParallel"))
32+
33+
desc$Imports <- paste0(desc$Imports, ", ", version)
34+
message(" >> added Imports: ", desc$Imports)
35+
36+
desc$LinkingTo <- paste0(desc$LinkingTo, ", RcppParallel")
37+
message(" >> added LinkingTo: ", desc$LinkingTo)
38+
39+
desc$SystemRequirements <- "GNU make"
40+
message(" >> added SystemRequirements: GNU make")
41+
42+
write.dcf(desc, file = "DESCRIPTION", keep.white = TRUE)
43+
44+
# update NAMESPACE file
45+
message(" >> added importFrom(RcppParallel,RcppParallelLibs) directive to NAMESPACE")
46+
cat("importFrom(RcppParallel,RcppParallelLibs)",
47+
file = "NAMESPACE",
48+
sep = "\n",
49+
append = TRUE)
50+
51+
# write Makevars files
52+
dir.create("src", showWarnings = FALSE)
53+
54+
# src/Makevars
55+
message(" >> added src/Makevars")
56+
cat(
57+
c(
58+
'CXX_STD = CXX11',
59+
'PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "RcppParallel::RcppParallelLibs()")'
60+
),
61+
file = "src/Makevars",
62+
sep = "\n"
63+
)
64+
65+
# src/Makevars.win
66+
message(" >> added src/Makevars.win")
67+
cat(
68+
c(
69+
'CXX_STD = CXX11',
70+
'PKG_CXXFLAGS += -DRCPP_PARALLEL_USE_TBB=1',
71+
'PKG_LIBS += $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" -e "RcppParallel::RcppParallelLibs()")'
72+
),
73+
file = "src/Makevars.win",
74+
sep = "\n"
75+
)
76+
77+
# write an example script using RcppParallel
78+
if (example_code) {
79+
80+
message(" >> added example file src/vector-sum.cpp")
81+
file.copy(
82+
system.file("skeleton/vector-sum.cpp", package = "RcppParallel"),
83+
"src/vector-sum.cpp"
84+
)
85+
86+
message(" >> added example documentation man/vector-sum.Rd")
87+
file.copy(
88+
system.file("skeleton/vector-sum.Rd", package = "RcppParallel"),
89+
"man/vector-sum.Rd"
90+
)
91+
92+
message(" >> compiled Rcpp attributes")
93+
Rcpp::compileAttributes()
94+
}
95+
96+
TRUE
97+
}

inst/skeleton/vector-sum.Rd

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
\name{parallelVectorSum}
2+
\alias{parallelVectorSum}
3+
\docType{package}
4+
\title{
5+
Simple function using RcppParallel
6+
}
7+
\description{
8+
Simple function using RcppParallel
9+
}
10+
\usage{
11+
parallelVectorSum(x)
12+
}
13+
\arguments{
14+
\item{x}{A numeric vector.}
15+
}
16+
\examples{
17+
\dontrun{
18+
parallelVectorSum(1:20)
19+
}
20+
}

inst/skeleton/vector-sum.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// [[Rcpp::depends(RcppParallel)]]
2+
#include <Rcpp.h>
3+
#include <RcppParallel.h>
4+
5+
using namespace Rcpp;
6+
using namespace RcppParallel;
7+
8+
struct Sum : public Worker
9+
{
10+
// source vector
11+
const RVector<double> input;
12+
13+
// accumulated value
14+
double value;
15+
16+
// constructors
17+
Sum(const NumericVector input) : input(input), value(0) {}
18+
Sum(const Sum& sum, Split) : input(sum.input), value(0) {}
19+
20+
// accumulate just the element of the range I've been asked to
21+
void operator()(std::size_t begin, std::size_t end) {
22+
value += std::accumulate(input.begin() + begin, input.begin() + end, 0.0);
23+
}
24+
25+
// join my value with that of another Sum
26+
void join(const Sum& rhs) {
27+
value += rhs.value;
28+
}
29+
};
30+
31+
// [[Rcpp::export]]
32+
double parallelVectorSum(NumericVector x) {
33+
34+
// declare the SumBody instance
35+
Sum sum(x);
36+
37+
// call parallel_reduce to start the work
38+
parallelReduce(0, x.length(), sum);
39+
40+
// return the computed sum
41+
return sum.value;
42+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
\name{RcppParallel.package.skeleton}
2+
\alias{RcppParallel.package.skeleton}
3+
\title{
4+
Create a skeleton for a new package depending on RcppParallel
5+
}
6+
\description{
7+
\code{RcppParallel.package.skeleton} automates the creation of
8+
a new source package that intends to use features of RcppParallel.
9+
10+
It is based on the \link[utils]{package.skeleton} function
11+
which it executes first.
12+
}
13+
\usage{
14+
RcppParallel.package.skeleton(
15+
name = "anRpackage",
16+
example_code = TRUE,
17+
...
18+
)
19+
}
20+
\arguments{
21+
\item{name}{The name of your R package.}
22+
\item{example_code}{If \code{TRUE}, example C++ code using RcppParallel is added to the package.}
23+
\item{...}{Optional arguments passed to \link[Rcpp]{Rcpp.package.skeleton}.}
24+
}
25+
\details{
26+
In addition to \link[Rcpp]{Rcpp.package.skeleton} :
27+
28+
The \samp{DESCRIPTION} file gains an Imports line requesting that
29+
the package depends on RcppParallel and a LinkingTo line so that the package
30+
finds RcppParallel header files.
31+
32+
The \samp{NAMESPACE} gains a \code{useDynLib} directive as well
33+
as an \code{importFrom(RcppParallel, evalCpp} to ensure instantiation of RcppParallel.
34+
35+
The \samp{src} directory is created if it does not exists and
36+
a \samp{Makevars} file is added setting the environment variables
37+
\samp{PKG_LIBS} to accomodate the necessary flags to link with the RcppParallel library.
38+
39+
If the \code{example_code} argument is set to \code{TRUE},
40+
example files \samp{vector-sum.cpp} is created in the \samp{src} directory.
41+
\code{Rcpp::compileAttributes()} is then called to generate \code{src/RcppExports.cpp} and
42+
\code{R/RcppExports.R}. These files are given as an example and should
43+
eventually by removed from the generated package.
44+
}
45+
\value{
46+
Nothing, used for its side effects
47+
}
48+
\seealso{
49+
\link[utils]{package.skeleton}
50+
}
51+
\references{
52+
Read the \emph{Writing R Extensions} manual for more details.
53+
54+
Once you have created a \emph{source} package you need to install it:
55+
see the \emph{R Installation and Administration} manual,
56+
\code{\link{INSTALL}} and \code{\link{install.packages}}.
57+
}
58+
\examples{
59+
\dontrun{
60+
# simple package
61+
RcppParallel.package.skeleton( "foobar" )
62+
}
63+
}
64+
\keyword{ programming }
65+

0 commit comments

Comments
 (0)