Movatterモバイル変換


[0]ホーム

URL:


Version:0.3.21
Date:2025-01-08
Title:Functions to Inline C, C++, Fortran Function Calls from R
Imports:methods
Suggests:Rcpp, tinytest
Description:Functionality to dynamically define R functions and S4 methods with 'inlined' C, C++ or Fortran code supporting the .C and .Call calling conventions.
License:LGPL-2 |LGPL-2.1 |LGPL-3 [expanded from: LGPL]
Copyright:Oleg Sklyar, 2005-2010 and other authors per their commits
LazyLoad:yes
URL:https://github.com/eddelbuettel/inline,https://dirk.eddelbuettel.com/code/inline.html
BugReports:https://github.com/eddelbuettel/inline/issues
NeedsCompilation:no
Packaged:2025-01-08 22:04:33 UTC; edd
Author:Oleg Sklyar [aut], Dirk EddelbuettelORCID iD [aut, cre], Romain FrancoisORCID iD [aut], Mike Smith [ctb], Duncan Murdoch [ctb], Karline SoetaertORCID iD [ctb], Johannes RankeORCID iD [ctb]
Maintainer:Dirk Eddelbuettel <edd@debian.org>
Repository:CRAN
Date/Publication:2025-01-09 13:00:02 UTC

Functions to Inline C, C++, Fortran Function Calls from R

Description

Functionality to dynamically define R functions and S4 methods with 'inlined' C, C++ or Fortran code supporting the .C and .Call calling conventions.

Maintainer

Dirk Eddelbuettel <edd@debian.org>

Author(s)

Oleg Sklyar [aut], Dirk Eddelbuettel [aut, cre] (<https://orcid.org/0000-0001-6419-907X>), Romain Francois [aut] (<https://orcid.org/0000-0002-2444-4226>), Mike Smith [ctb], Duncan Murdoch [ctb], Karline Soetaert [ctb] (<https://orcid.org/0000-0003-4603-7100>), Johannes Ranke [ctb] (<https://orcid.org/0000-0003-4371-6538>)

See Also

cfunction,cxxfunction


Inline C, C++, Fortran function calls from R

Description

Functionality to dynamically define R functions and S4 methods with in-lined C,C++ or Fortran code supporting .C and .Call calling conventions.

Usage

  cfunction(sig=character(), body=character(), includes=character(),            otherdefs=character(),            language=c("C++", "C", "Fortran", "F95", "ObjectiveC", "ObjectiveC++"),            verbose=FALSE,            convention=c(".Call", ".C", ".Fortran"),            Rcpp=FALSE,            cppargs=character(), cxxargs=character(), libargs=character(),            dim=NULL, implicit=NULL, module=NULL, name=NULL)  ## S4 methods for signatures  #  f='character', sig='list', body='list'  #  f='character', sig='character', body='character'  setCMethod(f, sig, body, ...)  ## Further arguments:  #  setCMethod(f, sig, body, includes="", otherdefs="", cpp=TRUE,  #  verbose=FALSE, where=topenv(.GlobalEnv), ...)

Arguments

f

A single character value ifsig andbody are character vectorsor a character vector of the same length and the length ofsig orbody with the name(s) of methods to create.

sig

A match of formal argument names for the function with thecharacter-string names of corresponding classes. Alternatively,a named list of such character vectors. The names of the list elements willbe used as function names (see example). Ifsig is not a list,the function name used in the code can be specified by thenameargument.

body

A character vector with C, C++ or Fortran code omitting functiondeclaration (only the body, i.e. in case of C starting after the functionopening curly bracket and ending before the closing curly bracket,brackets excluded). In case ofsetCMethod with signaturelist – a list of such character vectors.

includes

A character vector of additional includes and preprocessorstatements etc that will be put between the R includes and the user function(s).

otherdefs

A characted vector with the code for any further definitions offunctions, classes, types, forward declarations, namespace usage clauses etcwhich is inserted between the includes and the declarations of the functionsdefined insig.

language

A character value that specifies the source language of theinline code. The possible values forlanguage include all thosesupported byR CMD SHLIB on any platform, which are currently C,C++, Fortran, F95, ObjectiveC and ObjectiveC++; they may not all be supportedon your platform. One can specify the language either in full as above, orusing any of the following case insensitive shortened forms:c, cpp, c++, f, f95, objc, objcpp, objc++. Defaults toC++.

verbose

IfTRUE prints the compilation output, the sourcecode of the resulting program and the definitions of all declaredmethods. IfFALSE, the function is silent, but it prints compilerwarning and error messages and the source code if compilation fails.

convention

Which calling convention to use? See the Details section.

Rcpp

IfTRUE adds inclusion ofRcpp.h toincludes, also queries theRcpp package aboutthe location of header and library files and sets environmentvariablesPKG_CXXFLAGS andPKG_LIBS accordingly so thatthe R / C++ interface provided by theRcpp package can beused. Default value isFALSE.

cppargs

Optional character vector of tokens to be passed tothe compiler via thePKG_CPPFLAGS environmentvariable. Elements should be fully formed as for examplec("-I/usr/local/lib/foo", "-DDEBUG") and are passed along verbatim.

cxxargs

Optional character vector of tokens to be passed tothe compiler via thePKG_CXXFLAGS environmentvariable. Elements should be fully formed as for examplec("-I/usr/local/lib/foo", "-DDEBUG") and are passed along verbatim.

libargs

Optional character vector of tokens to be passed to thecompiler via thePKG_LIBS environment variable. Elements shouldbe fully formed as for examplec("-L/usr/local/lib/foo -lfoo", "--lpthread") and are passed along verbatim.

dim

Optional character vector defining the dimensionality of thefunction arguments. Of same length assig. Fortran or F95 only.

implicit

A character vector defining the implicit declaration inFortran or F95; the default is to use the implicit typing rules for Fortran,which isinteger for names starting with the lettersI throughN, andreal for names beginning with any other letter.AsR passes double precision, this is not the best choice.Safest is to chooseimplicit = "none" which will require all namesin the subroutine to be explicitly declared.

module

Name(s) of any modules to be used in theFortran orF95 subroutine.

name

Function name to be used in the code. Only used ifsig isnot a list. This is useful if the DLL created is to be used in conjunctionwith theode function of thedeSolve package.

...

Reserved.

Details

To declare multiple functions in the same library one can usesetCMethodsupplying lists of signatures and implementations. In this case, provide asmany method names inf as you define methods. Avoid clashes when selectingnames of the methods to declare, i.e. if you provide the same name several timesyou must ensure that signatures are different but can share the same generic!

The source code in thebody should not include the header or"front-matter" of the function or the close, e.g. in C or C++ itmust start after the C-function opening curly bracket and end beforethe C-function closing curly bracket, brackets should not beincluded. The header will be automatically generated from the R-signatureargument. Arguments will will carry the same name as used in the signature,so avoid variable names that are not legal in the target language(e.g. names with dots).

C/C++: Ifconvention == ".Call" (the default), the.Call mechanismis used and its result is returned directly as the result of the call of thegenerated function. As the last line of the generated C/C++ code areturn R_NilValue; is added in this case and a warning is generatedin case the user has forgotten to provide a return value. To suppress thewarning and still return NULL, addreturn R_NilValue; explicitly.

Special care is needed with types, memory allocation and protection– exactly the same as if the code was not inline: see theWriting R Extension manual for information on.Call.

Ifconvention == ".C" orconvention == ".Fortran", the.C or.Fortran mechanism respectively isused, and the return value is a list containing all arguments.

Attached R includes includeR.h for".C", andadditionallyRdefines.h andR_ext\Error.h for".Call".

Value

Ifsig is a single character vector,cfunction returns a singlefunction; if it is a list, it returns a list of functions.

setCMethod declares new methods with given names and signatures andreturns invisibleNULL.

Author(s)

Oleg Sklyar, Duncan Murdoch, Mike Smith, Dirk Eddelbuettel

See Also

Foreign Function Interface

Examples

x <- as.numeric(1:10)n <- as.integer(10)## Not run: ## A simple Fortran example - n and x: assumed-size vectorcode <- "      integer i      do 1 i=1, n(1)    1 x(i) = x(i)**3"cubefn <- cfunction(signature(n="integer", x="numeric"), code, convention=".Fortran")print(cubefn)cubefn(n, x)$x## Same Fortran example - now n is one numbercode2 <- "      integer i      do 1 i=1, n    1 x(i) = x(i)**3"cubefn2 <- cfunction(signature(n="integer", x="numeric"), implicit = "none",  dim = c("", "(*)"), code2, convention=".Fortran")cubefn2(n, x)$x## Same in F95, now x is fixed-size vector (length = n)code3 <- "x = x*x*x"cubefn3 <- cfunction(sig = signature(n="integer", x="numeric"), implicit = "none",  dim = c("", "(n)"), code3, language="F95")cubefn3(20, 1:20)print(cubefn3)## Same example in Ccode4 <- "      int i;      for (i = 0; i < *n; i++)        x[i] = x[i]*x[i]*x[i];"cubefn4 <- cfunction(signature(n="integer", x="numeric"), code4, language = "C", convention = ".C")cubefn4(20, 1:20)## Give the function in the source code a namecubefn5 <- cfunction(signature(n="integer", x="numeric"), code4, language = "C", convention = ".C",  name = "cubefn")code(cubefn5)## End(Not run) ## use of a module in F95modct <- "module modctsdouble precision, parameter :: pi = 3.14159265358979double precision, parameter :: e = 2.71828182845905end"getconstants <- "x(1) = pix(2) = e"cgetcts <- cfunction(getconstants, module = "modcts", implicit = "none",  includes = modct, sig = c(x = "double"), dim = c("(2)"), language = "F95")cgetcts(x = 1:2)print(cgetcts)## Use of .C convention with C code## Defining two functions, one of which calls the othersigSq <- signature(n="integer", x="numeric")codeSq <- "  for (int i=0; i < *n; i++) {    x[i] = x[i]*x[i];  }"sigQd <- signature(n="integer", x="numeric")codeQd <- "  squarefn(n, x);  squarefn(n, x);"fns <- cfunction( list(squarefn=sigSq, quadfn=sigQd),                  list(codeSq, codeQd),                  convention=".C")squarefn <- fns[["squarefn"]]quadfn <- fns[["quadfn"]]squarefn(n, x)$xquadfn(n, x)$x## Alternative declaration using 'setCMethod'setCMethod(c("squarefn", "quadfn"), list(sigSq, sigQd),           list(codeSq, codeQd), convention=".C")squarefn(n, x)$xquadfn(n, x)$x## Use of .Call convention with C code## Multyplying each image in a stack with a 2D Gaussian at a given positioncode <- "  SEXP res;  int nprotect = 0, nx, ny, nz, x, y;  PROTECT(res = Rf_duplicate(a)); nprotect++;  nx = INTEGER(GET_DIM(a))[0];  ny = INTEGER(GET_DIM(a))[1];  nz = INTEGER(GET_DIM(a))[2];  double sigma2 = REAL(s)[0] * REAL(s)[0], d2 ;  double cx = REAL(centre)[0], cy = REAL(centre)[1], *data, *rdata;  for (int im = 0; im < nz; im++) {    data = &(REAL(a)[im*nx*ny]); rdata = &(REAL(res)[im*nx*ny]);    for (x = 0; x < nx; x++)      for (y = 0; y < ny; y++) {        d2 = (x-cx)*(x-cx) + (y-cy)*(y-cy);        rdata[x + y*nx] = data[x + y*nx] * exp(-d2/sigma2);      }  }  UNPROTECT(nprotect);  return res;"funx <- cfunction(signature(a="array", s="numeric", centre="numeric"), code)x <- array(runif(50*50), c(50,50,1))res <- funx(a=x, s=10, centre=c(25,15))if (interactive()) image(res[,,1])## Same but done by registering an S4 methodsetCMethod("funy", signature(a="array", s="numeric", centre="numeric"), code, verbose=TRUE)res <- funy(x, 10, c(35,35))if (interactive()) { x11(); image(res[,,1]) }

inline C++ function

Description

Functionality to dynamically define an R function with inlined C++ codeusing the.Call calling convention.

Thercpp() wrapper sets the plugin to the “Rcpp” valuesuitable for usingRcpp.

Usage

cxxfunction(sig = character(), body = character(),             plugin = "default", includes = "",             settings = getPlugin(plugin), ..., verbose = FALSE)rcpp(..., plugin="Rcpp")

Arguments

sig

Signature of the function. A named character vector

body

A character vector with C++ code to include in the body of the compiled C++ function

plugin

Name of the plugin to use. SeegetPlugin for details about plugins.

includes

User includes, inserted after the includes provided by the plugin.

settings

Result of the call to the plugin

...

Further arguments to the plugin

verbose

verbose output

Value

A function

See Also

cfunction

Examples

## Not run: # default pluginfx <- cxxfunction(signature(x = "integer", y = "numeric"),           "return Rf_ScalarReal(INTEGER(x)[0] * REAL(y)[0]);")fx(2L, 5)# Rcpp pluginif (requireNamespace("Rcpp", quietly=TRUE)) {    fx <- cxxfunction(signature(x = "integer", y = "numeric"),                       "return wrap( as<int>(x) * as<double>(y));",                      plugin = "Rcpp" )    fx(2L, 5)    ## equivalent shorter form using rcpp()    fx <- rcpp(signature(x = "integer", y = "numeric"),               "return wrap(as<int>(x) * as<double>(y));")}# RcppArmadillo pluginif (requireNamespace(RcppArmadillo)) {    fx <- cxxfunction(signature(x = "integer", y = "numeric"),                      "int dim = as<int>(x);       arma::mat z = as<double>(y) * arma::eye<arma::mat>(dim, dim);       return wrap(arma::accu(z));",                      plugin = "RcppArmadillo")    fx(2L, 5)}## End(Not run)

Retrieve the dynamic library (or DLL) associated with a package of a function generated by cfunction

Description

ThegetDynLib function retrieves the dynamic library (or DLL) associated with a package or with a function generated bycfunction

Methods

signature(x = "CFunc")

Retrieves the dynamic library associated with the function generated bycfunction. The library is dynamically loaded if necessary.

signature(x = "CFuncList")

Retrieves the dynamic library associated with a set of functions generated bycfunction. The library is dynamically loaded if necessary.

signature(x = "character")

Retrieves the dynamic library of the given name. This typically refers to package names, but can be any name of the list returned bygetLoadedDLLs

See Also

getLoadedDLLs,dyn.load

Examples

## Not run: getDynLib( "base" )f <- cfunction( signature() , "return R_NilValue ;" )getDynLib( f )## End(Not run)

Internals

Description

Aliases required for 'R CMD check' but those no-one will ever search for.Here to prevent the mess of the index. The corresponding items have helpaliases without method signature!


Generate the skeleton of a package

Description

Generate the skeleton of a package

Methods

signature(name = "ANY", list = "ANY")

Standard method. Seepackage.skeleton

signature(name = "character", list = "CFunc")

Method for a single generated bycfunctionorcxxfunction

signature(name = "character", list = "CFuncList")

Method for a set functions generated bycfunctionorcxxfunction

Examples

## Not run: fx <- cxxfunction(signature(x = "integer", y = "numeric"),          "return Rf_ScalarReal( INTEGER(x)[0] * REAL(y)[0]);")package.skeleton("foo", fx)functions <- cxxfunction(list(ff = signature(),                               gg = signature(x = "integer", y = "numeric")),                          c("return R_NilValue ;",                           "return Rf_ScalarReal(INTEGER(x)[0] * REAL(y)[0]);"))package.skeleton("foobar", functions)## End(Not run)

Plugin system for cxxfunction

Description

cxxfunction uses a plugin system to assembly the code that it compiles. These functions allow to register and get plugins by their name.

Usage

getPlugin(name, ...)registerPlugin(name, plugin)

Arguments

name

name of the plugin.

...

Further argments to pass to the plugin.

plugin

plugin function.

Details

plugins are functions that return a list with :

includes

mandatory. it is included at the top of the compiled file bycxxfunction

body

optional. a function that takes one argument (the body of the c++ function) and returneda modified version of the body. The "Rcpp" plugin uses this to surround the code with theBEGIN_RCPP andEND_RCPP macros

LinkingTo

optional. character vector containing the list of packagesthat the code needs to link to. This adds the include path of the given packages. The "Rcpp" and "RcppArmadillo" plugins use this.

env

optional. named list of environment variables. For example, the "Rcpp" plugin uses this to add Rcpp user library to thePKG_LIBS environmentvariable.

plugins can be manually registered using theregisterPluginfunction. Alternatively, a package may supply an inline plugin implicitely by defining a function calledinlineCxxPlugin, which does not necessarily need to be exported from the namespace of the package.

Known packages implementing this scheme includeRcpp andRcppArmadillo.

Value

getPlugin retrieves the plugin and invokes it with the... arguments

registerPlugin does not return anything.

See Also

cxxfunction

Examples

## Not run: getPlugin( "Rcpp" )## End(Not run)

Printing, reading and writing compiled function objects

Description

moveDLL moves the DLL used by a compiled function to a user definedlocation.

writeCFunc saves aCFunc object after the DLL has been moved tothe desired location usingmoveDLL.

readCFunc reads aCFunc object that has been saved usingwriteCFunc.

Theprint andcode methods respectively print the entireobject or only the code parts.

Usage

moveDLL(x, ...)## S4 method for signature 'CFunc'moveDLL(x, name, directory, unload = FALSE, overwrite = FALSE, verbose = FALSE)writeCFunc(x, file)readCFunc(file)## S4 method for signature 'CFunc'print(x)## S4 method for signature 'CFuncList'print(x)## S4 method for signature 'CFunc'code(x, linenumbers = TRUE)## S4 method for signature 'CFuncList'code(x, linenumbers = TRUE)

Arguments

x

ACFunc orCFuncList object as created bycfunction

name

The base of the file name that the DLL should be moved to. The file nameextension will depend on the operating system used

directory

The directory that the DLL should be written to

unload

In case the new path constructed fromname anddirectory points to a loaded DLL, should we unload it?

overwrite

In case there is a file at the new path constructed fromname anddirectory should we overwrite that file?

verbose

Should we print a message stating where the DLL was copiedif the operation was successful?

file

The file path for writing and reading the object generated bycfunction. Consider using a file name extension like.rda or.RData to indicate that this is a serializedR object.

linenumbers

IfTRUE all code lines will be numbered.

...

May be used in future methods

Details

If you move the DLL to a user defined location withmoveDLL, this willkeep an on-disk copy of the DLL which will prevent it from being lost atsession termination - unless written to the sessiontempdir.Saving and reloading theCFunc object with standard tools likesave orsaveRDS will still loose the pointer tothe DLL. However, when the DLL has been moved usingmoveDLL,CFunc objects can be saved bywriteCFunc and restored byreadCFunc.

Value

FunctionreadDynLib returns aCFunc object.

FunctionwriteDynLib returns the name of the.CFunc file thatwas created.

Note

Author(s)

Karline Soetaert and Johannes Ranke

See Also

getDynLib

Examples

x <- as.numeric(1:10)n <- as.integer(10)code <- "      integer i      do 1 i=1, n(1)    1 x(i) = x(i)**3"cubefn <- cfunction(signature(n="integer", x="numeric"), code,  convention=".Fortran")code(cubefn)cubefn(n, x)$x## Not run: # The following code is exempted from the automated tests of example code, as# it writes to the users home directory.# The following writes the DLL, e.g. cubefn.so on Linux/Unix or cubefn.dll# on WindowsmoveDLL(cubefn, name = "cubefn", directory = "~")path <- file.path("~", "cubefn.rda")writeCFunc(cubefn, path)rm(cubefn)# Now you can start a fresh R session and load the functionlibrary(inline)path <- file.path("~", "cubefn.rda")cfn <- readCFunc(path)cfn(3, 1:3)$x## End(Not run)

[8]ページ先頭

©2009-2025 Movatter.jp