| Type: | Package |
| Title: | Enhanced Foreign Function Interface Supporting Long Vectors |
| Version: | 1.2 |
| Date: | 2024-10-03 |
| Description: | Provides .C64(), which is an enhanced version of .C() and .Fortran() from the foreign function interface. .C64() supports long vectors, arguments of type 64-bit integer, and provides a mechanism to avoid unnecessary copies of read-only and write-only arguments. This makes it a convenient and fast interface to C/C++ and Fortran code. |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| URL: | https://git.math.uzh.ch/reinhard.furrer/dotCall64 |
| BugReports: | https://git.math.uzh.ch/reinhard.furrer/dotCall64/-/issues |
| Depends: | R (≥ 4.0) |
| Suggests: | microbenchmark, RhpcBLASctl, RColorBrewer, roxygen2, spam, testthat, |
| Collate: | 'vector_dc.R' 'dotCall64.R' 'zzz.R' |
| RoxygenNote: | 7.2.3 |
| NeedsCompilation: | yes |
| Packaged: | 2024-10-03 11:57:25 UTC; furrer |
| Author: | Kaspar Moesinger [aut],
Florian Gerber |
| Maintainer: | Reinhard Furrer <reinhard.furrer@uzh.ch> |
| Repository: | CRAN |
| Date/Publication: | 2024-10-04 17:10:05 UTC |
dotCall64 - Extended Foreign Function Interface
Description
.C64 can be used to call compiled and loaded C/C++ functions and Fortran subroutines.
.C64 is similar to .C and .Fortran, but
supports long vectors, i.e., vectors with more than
2^31-1elementsdoes the necessary castings to expose the R representation of "64-bit integers" (numeric vectors) to 64-bit integer arguments of the compiled function. The latter are int64_t in C code and integer (kind = 8) in Fortran code
provides a mechanism the control duplication of the R objects exposed to the compiled code
checks if the provided R objects are of the expected types and coerces them 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" to the R objects passed to the compiled function.
This information is then used to duplicate R objects if and only if necessary.
Usage
.C64(
.NAME,
SIGNATURE,
...,
INTENT = NULL,
NAOK = FALSE,
PACKAGE = "",
VERBOSE = getOption("dotCall64.verbose")
)
Arguments
.NAME |
character vector of length 1. Name of the compiled function to be called. |
SIGNATURE |
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 |
character vector of the same length as the number of arguments of the compiled function.
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 |
Value
list of R objects similar to the list of arguments specified as ... arguments.
The objects of the list reflect the changes made by the compiled C or Fortran function.
References
F. Gerber, K. Moesinger, R. Furrer (2018), dotCall64: An R package providing an efficient interface to compiled C, C++, and Fortran code supporting long vectors, SoftwareX 7, 217-221, https://doi.org/10.1016/j.softx.2018.06.002.
F. Gerber, K. Moesinger, and R. Furrer (2017), Extending R packages to support 64-bit compiled code: An illustration with spam64 and GIMMS NDVI3g data, Computer & Geoscience 104, 109-119, https://doi.org/10.1016/j.cageo.2016.11.015.
Examples
## 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() to call get_c() 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' (a 32-bit integer),
## it can only address the first 2^31-1 elements of 'input'.
## To also address elements beyond 2^31-1, we change the
## definition of the C function as follows:
## #include <stdint.h> // for int64_t
## void get64_c(double *input, int64_t *index, double *output) {
## output[0] = input[index[0] - 1];
## }
## Now, we can use .C64() to call get64_c() from R.
.C64("get64_c", SIGNATURE = c("double", "int64", "double"),
input = x_long, index = 2^31, output = double(1))$output
## Note that 2^31 is of type double and .C64() casts it into an
## int64_t type before calling the C function get64_c().
## The performance of the previous call can be improved by
## setting additional arguments:
.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)
Allocate vectors in .C64()
Description
vector_dc and its shortcuts numeric_dc and
integer_dc are helper functions used in calls to .C64.
They return an R object of class c("vector_dc", "list"),
which contains information on the type and length of the vector to allocate.
Using vector_dc together with INTENT = "w" argument of .C64
leads to performance gains by avoiding unnecessary castings and copies.
Usage
vector_dc(mode = "logical", length = 0L)
numeric_dc(length = 0)
integer_dc(length = 0)
Arguments
mode |
character vector of length 1. Storage mode of the vector. |
length |
numeric vector of length 1. Length of the vector. |
Value
object of class vector_dc and list.
Examples
vector_dc("integer", 20)