Объявление функции в написанном пользователем заголовке / пространстве имен в Rcpp - PullRequest
0 голосов
/ 28 августа 2018

Этот вопрос действительно является продолжением предыдущего вопроса, Вызов функции 'mypackage' для публичного работника . И я подозреваю, что, задавая его, нужно получить более глубокое понимание.

Ошибка

невозможно загрузить общий объект "в" ParallelExample.so '

Что я пытаюсь сделать, так это вызвать внутри себя Cpp-функцию в R-пакете. Для этого я написал и добавил файл заголовка в каталог src и определил пространство имен в этом заголовке. Ошибка компиляции происходит с кодом ниже:

Тем не менее, я нашел два решения этой проблемы.

  1. Определите функцию в заголовочном файле вместо того, чтобы только объявить ее.
  2. Оставить пространство имен вне файла заголовка.

Исходя из проведенного мною исследования cpp по этой теме, оно кажется выполнимым и обычным (для объявления функции в пространстве имен в заголовочном файле) вне Rcpp. Что, заставляет меня задуматься, если это просто проблема с компилятором Mac или функцией Rcpp.

Сначала файл cpp:

#include <RcppArmadillo.h>
#include "ExampleInternal.h"
// [[Rcpp::export]]
double myfunc(arma::vec vec_in){

  int Len = arma::size(vec_in)[0];
  return (vec_in[0] +vec_in[1])/Len;
}

Второй, Cpp:

#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
#include <random>

using namespace RcppParallel;

struct PARALLEL_WORKER : public Worker{

  const arma::vec &input;
  arma::vec &output;

  PARALLEL_WORKER(const arma::vec &input, arma::vec &output) : input(input), output(output) {}

  void operator()(std::size_t begin, std::size_t end){


    std::mt19937 engine(1);

    for( int k = begin; k < end; k ++){
      engine.seed(k);
      arma::vec index = input;
      std::shuffle( index.begin(), index.end(), engine);

      output[k] = ExampleInternal::myfunc(index);
  }
}

};

// [[Rcpp::export]]
arma::vec Parallelfunc(int Len_in){

  arma::vec input = arma::regspace(0, 500);
  arma::vec output(Len_in);

  PARALLEL_WORKER  parallel_woker(input, output);
  parallelFor( 0, Len_in, parallel_woker);
  return output;
}

И, наконец, файл внутреннего заголовка, также в каталоге src:

#ifndef EXAMPLEINTERNAL_H
#define EXAMPLEINTERNAL_H

#include <RcppArmadillo.h>
#include <Rcpp.h>

namespace ExampleInternal{

double myfunc(arma::vec vec_in);

}

#endif

1 Ответ

0 голосов
/ 28 августа 2018

Вы объявляете и вызываете функцию ExampleInternal::myfunc, но затем определяете функцию myfunc в глобальном пространстве имен. Это не соответствует, и я совершенно уверен, что остальная часть сообщения об ошибке, которое вы не видите, указывает, что ExampleInternal::myfunc не был найден в файле so.

Решение: использовать то же пространство имен при определении функции:

#include <RcppArmadillo.h>
#include "ExampleInternal.h"
namespace ExampleInternal {

double myfunc(arma::vec vec_in){

  int Len = arma::size(vec_in)[0];
  return (vec_in[0] +vec_in[1])/Len;
}

}

Я также удалил аннотацию для экспорта функции. Кстати, не включайте RcppAramdillo.h и Rcpp.h.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...