Reputation: 710
In RStudio in Windows 10 I wrote a function that performs calculations in parallel, like the following:
doSomething = function(a, b, c) {
# Inner function that does the actual work when parallelised
work = function (a, b, c) {
# Do something
e = func1(a, b)
f = func2(c)
result = e + f
return(result)
}
# Carry out work in parallel
cl = makeCluster(6)
registerDoParallel(cl)
output = foreach(i = 1:10, .packages=c("foo", "bar")) %dopar%
work(a, b, c)
stopCluster(cl)
return(output)
}
This works fine and dandy if I load the function into memory from an R script; however, I want to include it in a package that I am writing. As such, in the package file, I am careful to identify the namespace of the external functions and refer to their packages in the DESCRIPTION
file. For example:
doSomething = function(a, b, c) {
# Inner function that does the actual work when parallelised
work = function (a, b, c) {
# Do something
e = foo::func1(a, b)
f = bar::func2(c)
result = e + f
return(result)
}
# Carry out work in parallel
cl = parallel::makeCluster(6)
doParallel::registerDoParallel(cl)
output = foreach::foreach(i = 1:10, .packages=c("foo", "bar")) %dopar%
work(a, b, c)
parallel::stopCluster(cl)
return(output)
}
and in the DESCRIPTION
file:
...
Imports:
foo,
bar,
doParallel,
foreach,
parallel
(Edit) the NAMESPACE
file contains the following:
# Generated by roxygen2 (4.1.1): do not edit by hand
export(doSomething)
The problem is, when I build my package and run the function out of the package, I get the following error and execution stops:
Error in doSomething(a, b, c):
could not find function "%dopar%"
Since %dopar%
is an operator, not a function, I can't prepend it with foreach::
in my package function.
I am not sure what I need to do to get it to work properly. Furthermore 95% of similar problems I've read about are caused by an omission from .packages()
causing the error, not the %dopar%
operator itself not being recognised. That would not appear to be the cause here.
Please help!
Upvotes: 10
Views: 12549
Reputation: 2085
I found myself in a similar situation, and I was having difficulty doing something like foreach::%dopar%
. So, using Mr. Flick's comments I just updated my function documentation to include a line like @importFrom foreach %dopar%
In other words, your function can look like this so you cna use %dopar% without ::
operator:
#' Do a thing
#'
#' @param first
#' @param second
#' @returns stuff
#' @export
#' @importFrom foreach %dopar%
foo <- function(first, second){
# I can just use %dopar% without :: operator
cl <- parallel::makeCluster(parallel::detectCores() - 1)
doParallel::registerDoParallel(cl)
# foreach::`%dopar%`(
foreach::foreach(i = 1:nrow(everyCombo), .combine = 'c') %dopar% {
.
.
.
}
parallel::stopCluster(cl)
}
Then call devtools::document()
, and it will take care of the rest.
Upvotes: 0
Reputation: 297
Quick fix for problem with foreach %dopar% is to reinstall these packages:
install.packages("doSNOW")
install.packages("doParallel")
install.packages("doMPI")
Above packages are responsible for parallelism in R. Bug which existed in old versions of these packages is now removed. I should mention that it will most likely help even though you are not using these packages in your project/package directly.
Upvotes: 1