Невозможно получить доступ к параметрам в коде C++ в параллельном коде, вызванном из Snow

Я разрабатываю параллельный код R с использованием пакета Snow, но при вызове кода C++ с использованием пакета Rcpp программа просто зависает и не отвечает.

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

    MyRFunction<-function(i) {
      n=i
      .Call("CppFunction",n,PACKAGE="MyPackage")
      }
    if (mpi) {
      cl<-getMPIcluster()
      clusterExport(cl, list("set.user.Random.seed"))  
      clusterEvalQ(cl, {library(Rcpp); NULL})
      out<-clusterApply(cl,1:mc.cores,MyRFunction)
      stopCluster(cl)
      }
    else
      out <- parallel::mclapply(1:mc.cores,MyRFunction)

В то время как моя функция C++ выглядит так...

    RcppExport SEXP CppFunction(SEXP n) {
      int n=as<int>(n);
      }

Если я запускаю его с mpi=false и mc.cores=[некоторое количество потоков], программа работает красиво, НО, если я запускаю его с mpi = true, поэтому, используя snow, программа просто зависает при int = as(n)????? С другой стороны, если я определю функцию C++ как...

    RcppExport SEXP CppFunction(SEXP n) {
      CharacterVector nn(n);
      int n=boost::lexical_cast<int>(nn[0]);
      }

Программа отлично работает на каждом потоке MPI?? Проблема в том, что он работает для целых чисел, двойных и т. Д., Но не для матриц. Кроме того, я должен использовать lexical_cast из пакета boost, чтобы он работал, поскольку<> этого не делает.

Кто-нибудь знает, почему это так, и чего мне здесь не хватает, чтобы я мог также загрузить свои матрицы?

2 ответа

Решение

Наконец, проблема была решена, и проблема, похоже, связана с getMPICluster(), который прекрасно работает для чистого кода R, но не так хорошо с Rcpp, как объяснено выше. Вместо этого используйте команду makeMPICluster

    mc.cores <- max(1, NumberOfNodes*CoresPerNode-1) # minus one for master
    cl <- makeMPIcluster(mc.cores)
    cat(sprintf("Running with %d workers\n", length(cl)))
    clusterCall(cl, function() { library(MyPackage); NULL })
    out<-clusterApply(cl,1:mc.cores,MyRFunction)
    stopCluster(cl)

Работает отлично! Проблема заключается в том, что вам нужно вручную определять количество узлов и ядер на узел в коде R, а не определять его с помощью команды mpirun.

Из вашего вопроса не совсем понятно, что вы делаете, но я бы порекомендовал

  • упрощение: снег, безусловно, работает и работает с Rcpp, как и с другими пакетами

  • пакеты доверия: я обнаружил, что параллельные вычисления проще, когда все узлы идентичны локальным наборам пакетов

  • будьте осторожны с потоками: если у вас есть проблемы с явным потоком в контексте снега, попробуйте сначала без него и добавьте его, как только сработает базовая механика

Другие вопросы по тегам