| dotCall64 {dotCall64} | R Documentation |
.C64 can be used to call compiled and loaded C functions and Fortran subroutines.
It works similar to .C and .Fortran, and
supports long vectors, i.e., vectors with more than 2^31-1 elements,
does the necessary castings to expose the R representation of "64-bit integers" (numeric vectors) to 64-bit integers arguments of the compiled function; int64_t types in C and integer (kind = 8) in Fortran,
provides a mechanism the control the duplication of the R objects exposed to the compiled code,
checks if the provided R objects are of the expected type and coerces the R object if necessary.
Compared to .C, .C64 has the additional arguments SIGNATURE, INTENT and VERBOSE.
SIGNATURE specifies the types of the arguments of the compiled function.
INTENT indicates whether the compiled function "reads", "writes", or "read and writes" the R objects passed
to the compiled function. This is then used to duplicates R objects if (and only if) necessary.
.C64(.NAME, SIGNATURE, ..., INTENT = NULL, NAOK = FALSE, PACKAGE = "",
VERBOSE = getOption("dotCall64.verbose"))
.NAME |
a character vector of length 1. Specifies the name of the compiled function to be called. |
SIGNATURE |
a character vector of the same length as the number of arguments of the compiled function.
Accepted strings are |
... |
arguments passed to the compiled function. One R object for each argument. Up to 65 arguments are supported. |
INTENT |
a character vector of the same length as the number of arguments of the compiled code.
Accepted strings are |
NAOK |
logical vector of length 1. If |
PACKAGE |
character vector of length 1. Specifies where to search for the function given in |
VERBOSE |
Numeric vector of length 1. If |
A list similar to the ... list of arguments passed in (including
any names given to the arguments), but reflecting any changes made
by the compiled C or Fortran code.
F. Gerber, K. Moesinger, and R. Furrer, "dotCall64: An efficient interface to compiled C/C++ and Fortran code supporting long vectors", submitted to the Rjournal, 2016.
F. Gerber, K. Moesinger, and R. Furrer, "Extending R packages to support 64-bit compiled code: An illustration with spam64 and GIMMS NDVI 3g data", submitted to Computers & Geoscience, 2015.
## Consider the following C function, which is included
## in the dotCall64 package:
## void get_c(double *input, int *index, double *output) {
## output[0] = input[index[0] - 1];
## }
##
## We can use .C64() the call it from R:
.C64("get_c", SIGNATURE = c("double", "integer", "double"),
input = 1:10, index = 9, output = double(1))$output
## Not run:
## 'input' can be a long vector
x_long <- double(2^31) ## requires 16 GB RAM
x_long[9] <- 9; x_long[2^31] <- -1
.C64("get_c", SIGNATURE = c("double", "integer", "double"),
input = x_long, index = 9, output = double(1))$output
## Since 'index' is of type 'signed int' resulting in a 32-bit integer,
## it can only capture integers op to 2^31-1. To extend this,
## we define the C function as follows:
## #include <stdint.h> // defines the int64_t type
## void get64_c(double *input, int64_t *index, double *output) {
## output[0] = input[index[0] - 1];
## }
## We can use .C64() to call the function from R.
.C64("get64_c", SIGNATURE = c("double", "int64", "double"),
input = x_long, index = 2^31, output = double(1))$output
## Note that .C64() takes 2^31 as double and casts it to int64_t
## before calling the C function get64_c().
## The performance of the previous call can be improved with
## additional options:
.C64("get64_c", SIGNATURE = c("double", "int64", "double"),
x = x_long, i = 2^31, r = numeric_dc(1), INTENT = c("r", "r", "w"),
NAOK = TRUE, PACKAGE = "dotCall64", VERBOSE = 0)$r
## Consider the same function defined in Fortran:
## subroutine get64_f(input, index, output)
## double precision :: input(*), output(*)
## integer (kind = 8) :: index ! specific to GFortran
## output(1) = input(index)
## end
## The function is provided in dotCall64 and can be called with
.C64("get64_f", SIGNATURE = c("double", "int64", "double"),
input = x_long, index = 2^31, output = double(1))$output
## End(Not run)