R: Преимущества использования подпрограммы Fortran с .Call и C/С++-оболочкой вместо .Fortran?

У меня есть R-пакет, который использует множество подпрограмм Fortran для вложенных циклов рекурсивных вычислений линейной алгебры (в зависимости от BLAS и LAPACK-подпрограмм). В качестве интерфейса с Fortran я использую функцию .Fortran. Я просто прочитал сообщение Джонатана Каллахана об использовании .Call вместо .C в случае подпрограмм, написанных на C/С++, и это заставило меня думать, что это будет лучше использовать интерфейс .Call также при использовании подпрограмм Fortran, написав простую оболочку в C, которая затем вызывает подпрограммы Fortran?

Как сказано, мои коды Fortran довольно просты в том смысле, что я просто играю с многомерными массивами типа double или integer. Но я узнал, что я должен написать довольно много проверок на стороне R, чтобы гарантировать, что все не сбой из-за того, что я случайно забыл изменить режим хранения какой-либо матрицы на целое число или размеры какой-либо матрицы были изменены и т.д.

Подпрограммы записываются как F90/95.

Ответы

Ответ 1

Если вы работаете с большим набором данных, может быть преимущество..Call может быть намного быстрее, потому что вы не копируете данные каждый раз, когда вызываете функцию. В случае, описанном в этом вопросе, такого преимущества не будет, поскольку в примечаниях к выпуску R 2.15.1 указано

.C() и .Fortran() делают меньше копий: аргументы, которые являются необработанными, логическими, целочисленными, реальными или сложными векторами и являются неназванными, не копируются перед вызовом и (именованные или нет) не копируются после вызов. Списки больше не копируются (они должны использоваться только для чтения в коде C).

Переключение на .Call означает, что вы отказываетесь от удобства интерфейса .Fortran. Вы передавали бы SEXP в код C, делали какие-либо проверки/манипулирования данными с помощью (пугающего и плохо документированного) R API, а затем вызывали функцию Fortran из C. Любой, кто работает с вашим кодом, должен будет понять R API и C/Fortran.

Ответ 2

R пакет dotCall64 может быть интересной альтернативой. Он предоставляет .C64() который является расширенной версией интерфейса внешних функций, то есть .C() и .Fortran().

Интерфейс .C64() может использоваться для взаимодействия как кода Fortran, так и кода C/C++. Это

  • имеет аналогичное использование как .C() и .Fortran()
  • предоставляет механизм, позволяющий избежать ненужных копий аргументов только для чтения и только для записи
  • поддерживает длинные векторы (векторы с более чем 2 ^ 31-1 элементов)
  • поддерживает аргументы 64-битного целого типа

Следовательно, можно избежать ненужных копий аргументов только для чтения, избегая интерфейса .Call() в сочетании с функцией-оболочкой C.

Некоторые ссылки:

Я один из авторов dotCall64 и спама.