Футарк в пакете R через Rcpp

#c #r #rcpp #futhark

#c #r #rcpp #футарк

Вопрос:

Я хотел бы вызывать функции, написанные на небольшом функциональном языке программирования Futhark на R через Rcpp. Это работает, потому что компилятор Futhark может генерировать код C, а библиотеки C могут быть доступны в R через Rcpp.

Мне удалось создать рабочий прототип здесь: https://github.com/nevrome/R.futhark.example

Теперь мне интересно, смогу ли я упростить цикл разработки и уменьшить количество шаблонного / оберточного кода, который я должен вручную писать для отдельных функций.

Вот мой общий рабочий процесс (Futhark -> C -> C -> R) с примером:

futhark_test.fut: файл кода Futhark, написанный вручную. Он компилируется в C (futhark_test.h и futhark_test.c) с помощью компилятора Futhark ( futhark c --library ... )

 let main (x: i32) (y: i32): i32 =
  x * 2   y * 3
  

futhark_bridge_c_cpp.c: код C для переноса функции C в futhark_test.c, созданный компилятором Futhark

 #include <R.h>
#include <Rinternals.h>
#include "futhark_test.h"

int32_t futhark_entry_main_c(int32_t a, int32_t b) {
  struct futhark_context_config *cfg = futhark_context_config_new();
  struct futhark_context *ctx = futhark_context_new(cfg);
  int32_t res;
  futhark_entry_main(ctx, amp;res, a, b);
  return res;
}
  

futhark_bridge_rcpp.cpp : C код для переноса функции C и управления взаимодействием с R

 #include "Rcpp.h"
using namespace Rcpp;

extern "C" int32_t futhark_entry_main_c(int32_t a, int32_t b);

//' Call C function
//' @export
// [[Rcpp::export]]
SEXP futhark_entry_main_cpp(SEXP a, SEXP b) {
  int32_t a_mod = Rcpp::as<int32_t>(a);
  int32_t b_mod = Rcpp::as<int32_t>(b);
  int32_t ab = futhark_entry_main_c(a_mod, b_mod);
  return Rcpp::wrap(ab);
}
  

Rcpp автоматически ( Rcpp::compileAttributes() ) создает RcppExports.cpp и RcppExports.R из futhark_bridge_rcpp.cpp и я могу вызвать функцию, первоначально написанную на Футарке, через futhark_entry_main_cpp(1, 2) in R.

Чтобы автоматизировать процесс разработки, я создал сборку R-скрипта.R со следующей последовательностью команд

 devtools::document()
Rcpp::compileAttributes()
system("cd src amp;amp; futhark c --library futhark_test.fut")
devtools::install()
  

Это позволяет мне изменять код Futhark, запускать эти команды, а затем проверять результат в R. Конечно, только если я не изменяю интерфейс функции Futhark. Если я это сделаю, мне придется редактировать как код C, так и код-оболочку C .

Есть ли способ уменьшить сложность этого процесса и есть ли у моего решения какие-либо очевидные недостатки?

Комментарии:

1. Я думаю, что это разумный вопрос. Я также думаю, что разумно задать вопрос «почему вы это делаете?». Кажется маловероятным, что эффективность, о которой говорится на домашней странице futhark, переживет поездку через C transpiler и компилятор c . Я готов поспорить, что компилятор C умнее, чем futhark -> C transpiler при оптимизации кода. То, что вы делаете, довольно сложно, и я думаю, что ваш рабочий процесс просто соответствует этому. Я не думаю, что существует простой способ разрешить изменение интерфейса вашей функции futhark без изменения вашего кода на C . Для меня это выглядит нормально.

2. Хорошо — большое вам спасибо за эту оценку! Приятно знать, что я не упустил из виду никаких очевидных вещей и могу продолжать экспериментировать! Я делаю это в основном для того, чтобы немного лучше ознакомиться с функциональным программированием, а интеграция с R помогает мне использовать Futhark в других побочных проектах. Конечно, я надеялся, что смогу получить доступ к его функциям распараллеливания, но я понимаю ваш аргумент о том, что я, скорее всего, потеряю эффективность. Это нормально — скорость не была моей главной заботой.

3. R также имеет интерфейс к OpenCL , поэтому вы также можете использовать компилятор Futhark -> OpenCL.

4. Круто! Это может сделать это усилие действительно полезным с точки зрения производительности, или?