View source: R/externalCalls.R
| nimbleExternalCall | R Documentation |
Given C header information, a function that takes scalars or pointers can be called from a compiled nimbleFunction. If non-scalar return values are needed, an argument can be selected to behave as the return value in nimble.
nimbleExternalCall(
prototype,
returnType,
Cfun,
headerFile,
oFile,
where = getNimbleFunctionEnvironment()
)
prototype |
Argument type information. This can be provided as an R function using |
returnType |
Return object type information. This can be provided similarly to |
Cfun |
Name of the external function (character). |
headerFile |
Name (possibly including file path) of the header file where Cfun is declared. |
oFile |
Name (possibly including path) of the .o file where Cfun has been compiled. Spaces in the path may cause problems. |
where |
An optional |
The only argument types allowed in Cfun are double, int, and bool, corresponding to nimbleFunction types double, integer, and logical, respectively.
If the dimensionality is greater than zero, the arguments in Cfun should be pointers. This means it will typically be necessary to pass additional integer arguments telling Cfun the size(s) of non-scalar arguments.
The return argument can only be a scalar or void. Since non-scalar arguments are passed by pointer, you can use an argument to return results from Cfun. If you wish to have a nimbleFunction that uses one argument of Cfun as a return object, you can wrap the result of nimbleExternalCall in another nimbleFunction that allocates the return object. This is useful for using Cfun in a nimbleModel. See example below.
Note that a nimbleExternalCall can only be executed in a compiled nimbleFunction, not an uncompiled one.
If you have problems with spaces in file paths (e.g. for oFile), try compiling everything locally by including dirName = "." as an argument to compileNimble.
Note that if you use Rcpp to generate object files, NIMBLE's use of the --preclean option to R CMD SHLIB can cause failures, so you may need to run nimbleOptions(precleanCompilation=FALSE) to prevent removal of needed object files.
A nimbleFunction that takes the indicated input arguments, calls Cfun, and returns the result.
Perry de Valpine
nimbleRcall for calling arbitrary R code from compiled nimbleFunctions.
## Not run:
sink('add1.h')
cat('
extern "C" {
void my_internal_function(double *p, double*ans, int n);
}
')
sink()
sink('add1.cpp')
cat('
#include <cstdio>
#include "add1.h"
void my_internal_function(double *p, double *ans, int n) {
printf("In my_internal_function\\n");
/* cat reduces the double slash to single slash */
for(int i = 0; i < n; i++)
ans[i] = p[i] + 1.0;
}
')
sink()
system('g++ add1.cpp -c -o add1.o')
Radd1 <- nimbleExternalCall(function(x = double(1), ans = double(1),
n = integer()){}, Cfun = 'my_internal_function',
headerFile = file.path(getwd(), 'add1.h'), returnType = void(),
oFile = file.path(getwd(), 'add1.o'))
## If you need to use a function with non-scalar return object in model code,
## you can wrap it in another nimbleFunction like this:
model_add1 <- nimbleFunction(
run = function(x = double(1)) {
ans <- numeric(length(x))
Radd1(x, ans, length(x))
return(ans)
returnType(double(1))
})
demoCode <- nimbleCode({
for(i in 1:4) {x[i] ~ dnorm(0,1)} ## just to get a vector
y[1:4] <- model_add1(x[1:4])
})
demoModel <- nimbleModel(demoCode, inits = list(x = rnorm(4)),
check = FALSE, calculate = FALSE)
CdemoModel <- compileNimble(demoModel, showCompilerOutput = TRUE)
## End(Not run)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.