nimbleExternalCall: Create a nimbleFunction that wraps a call to external...

View source: R/externalCalls.R

nimbleExternalCallR Documentation

Create a nimbleFunction that wraps a call to external compiled code


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.


  where = getNimbleFunctionEnvironment()



Argument type information. This can be provided as an R function using nimbleFunction type declarations or as a list of nimbleType objects.


Return object type information. This can be provided similarly to prototype as either a nimbleFunction type declaration or as a nimbleType object. In the latter case, the name will be ignored. If there is no return value, this should be void().


Name of the external function (character).


Name (possibly including file path) of the header file where Cfun is declared.


Name (possibly including path) of the .o file where Cfun has been compiled. Spaces in the path may cause problems.


An optional where argument passed to setRefClass for where the reference class definition generated for this nimbleFunction will be stored. This is needed due to R package namespace issues but should never need to be provided by a user.


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.


A nimbleFunction that takes the indicated input arguments, calls Cfun, and returns the result.


Perry de Valpine

See Also

nimbleRcall for calling arbitrary R code from compiled nimbleFunctions.


## Not run: 
 extern "C" {
 void my_internal_function(double *p, double*ans, int n);
 #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;
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))
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)

nimble documentation built on March 18, 2022, 8:03 p.m.