R: ¿Ventajas de usar una subrutina Fortran con.Call y C/C++ en lugar de.Fortran?
performance wrapper (2)
El paquete R dotCall64 podría ser una alternativa interesante. Proporciona .C64()
que es una versión mejorada de la Interfaz de función extranjera , es decir, .C()
y .Fortran()
.
La interfaz .C64()
se puede usar para conectar tanto el código Fortran como el código C / C ++. Eso
- tiene un uso similar a
.C()
y.Fortran()
- proporciona un mecanismo para evitar copias innecesarias de argumentos de solo lectura y de solo escritura
- admite vectores largos (vectores con más de 2 ^ 31-1 elementos)
- soporta argumentos de tipo entero de 64 bits
Por lo tanto, se pueden evitar las copias innecesarias de los argumentos de solo lectura al mismo tiempo que se evita la interfaz .Call()
en combinación con una función de envoltorio de C.
Algunos enlaces:
- El paquete R dotCall64 : https://CRAN.R-project.org/package=dotCall64
- Descripción de dotCall64 con ejemplos: https://doi.org/10.1016/j.softx.2018.06.002
- Una ilustración donde se usa dotCall64 para hacer que el paquete de álgebra R de matriz dispersa sea compatible con enormes matrices dispersas (más de 2 ^ 31-1 elementos distintos de cero): https://doi.org/10.1016/j.cageo.2016.11.015
Soy uno de los autores de dotCall64 y spam .
Tengo un paquete R que usa muchas subrutinas de Fortran para bucles anidados de cálculos de álgebra lineal recursiva (dependiendo en gran medida de las rutinas BLAS y LAPACK). Como una interfaz para Fortran, uso la función .Fortran
. Acabo de leer la publicación del blog de Jonathan Callahan sobre el uso de .Call
lugar de .C
en el caso de las subrutinas escritas en C / C ++, y me hizo pensar que sería mejor usar la interfaz de .Call
también cuando se usan las subrutinas de Fortran, escribiendo un simple envoltura en C que luego llama las subrutinas Fortran?
Como he dicho, mis códigos de Fortran son bastante simples en el sentido de que simplemente juego con matrices multidimensionales de tipo doble o entero. Pero he aprendido que debo escribir bastantes controles en el lado R para garantizar que no se bloquee todo debido a que accidentalmente olvidé cambiar el modo de almacenamiento de alguna matriz a entero o cambiaron las dimensiones de alguna matriz, etc.
Las subrutinas se escriben como F90 / 95.
Puede haber una ventaja si está trabajando con un conjunto de datos grande. .La llamada puede ser mucho más rápida porque no está copiando los datos cada vez que llama a la función. Para el caso descrito en esta pregunta, no habrá tal ventaja, porque el estado de las notas de la versión R 2.15.1
.C () y .Fortran () realizan menos copias: los argumentos en bruto, lógicos, enteros, vectores reales o complejos y sin nombre no se copian antes de la llamada, y (se nombra o no) no se copian después de la llamada. Las listas ya no se copian (se supone que se deben usar de solo lectura en el código C).
Cambiar a .Call significa renunciar a la comodidad de la interfaz .Fortran. Pasaría los SEXP al código C, realizaría cualquier comprobación / manipulación de los datos utilizando la API R (aterradora y no está bien documentada) y luego llamaría a una función Fortran desde C. Cualquier persona que trabaje con su código tendrá que entender La API R y la interoperabilidad C / Fortran.