R cpp ошибка сегментации, создающая матрицу броненосца - PullRequest
0 голосов
/ 06 февраля 2020

Мне очень тяжело отлаживать эту ошибку. Ситуация следующая:

  1. У меня есть довольно маленькая библиотека C ++, все содержится в каталоге 'sr c' (и его подпапках), который ссылается на armadillo
  2. используя pybind11, я успешно создал Python привязку для библиотеки
  3. при использовании R cpp для привязки к R, точно такой же код, который запускается в автономных исполняемых файлах C ++ и pybinded функциях, неожиданно завершает работу

Кроме того, я попытался создать MWE для демонстрации ошибки, но, похоже, она работает нормально!

Вот файл, используемый для генерации python привязки

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>

#include <armadillo>
#include <tuple>
#include "my_class.hpp"

std::tuple<std::vector<double>, std::vector<std::vector<double>>, double>
runFromPython(std::vector<double> data, int nrep, double theta,
          double sigma, double m0, double k0, double a0, double b0,
          double eps, int p, std::string dist="sorting") {

    arma::vec datavec = arma::conv_to<arma::vec>::from(data);

    Myclass abc(datavec, theta, sigma, eps, a0, b0, k0, m0, dist);
    std::tuple<arma::vec, arma::mat, double> out = abc.run(nrep);

    int nrows = std::get<1>(out).n_rows;
    std::vector<std::vector<double>> parts(nrows);
    for (int i=0; i < nrows; i++) {
        parts[i] = arma::conv_to<std::vector<double>>::from(
            std::get<1>(out).row(i));
    }

    return std::make_tuple(
        arma::conv_to<std::vector<double>>::from(std::get<0>(out)),
        parts,
        std::get<2>(out));
}

PYBIND11_MODULE(mod, m) {
    m.doc() = "aaa";

    m.def("runFromPython", &runFromPython,
          "...");

}

Здесь вместо этого находится 'rcpp_functions. cpp', который помещается в src /

#include "RcppArmadillo.h"
// [[Rcpp::depends(RcppArmadillo)]]

#include <tuple>
#include "my_class.hpp"

// [[Rcpp::export]]
Rcpp::List runAbcMCMC_univ_R(
          Rcpp::NumericVector data, int nrep=1, double theta=1.0,
          double sigma=0.2, double m0=0.0, double k0=0.5, double a0=2.0,
          double b0=2.0, double eps=10.0, int p=1,
          std::string dist="sorting") {
  arma::vec datavec(data.begin(), data.size(), false);
  Myclass abc(
      datavec, theta, sigma, eps, a0, b0, k0, m0, dist);
  std::tuple<arma::vec, arma::mat, double> out = abc.run(nrep);

  Rcpp::List res;
  res["1"] = std::get<0>(out);
  res["2"] = std::get<1>(out);
  res["3"] = std::get<2>(out);
  return res;
}

Я пытаюсь собрать пакет из R, используя следующие команды

pkgbuild::clean_dll()
Rcpp::compileAttributes(".")
devtools::load_all()

Ошибка сегментации возникает при вызове конструктора класса ab c (...)

Вот странная часть: если я смотрю на размер data внутри конструктора класса, он говорит мне, что это ОГРОМНАЯ матрица, даже если я передаю вектор всего 100 элементов из R

Конструктор выглядит следующим образом:

Myclass::Myclass(const arma::mat &data_, double theta, double sigma, double eps0,
                 double a0, double b0, double k0, double m0, std::string distance) {

   Rcpp::Rcout << "data_: " << data_.n_rows << " x " << data_.n_cols << std::endl;
   this->data = data;
}

Запуск R с отладчиком gbd, отображаемая информация:

data_: 4294967396 x 281479271678052

error: Mat::init(): requested size is too large

Так что в принципе у меня нет подсказка о том, как действовать.

Было бы здорово, если бы кто-то с большим опытом, чем я, занимался разработкой с R cpp, мог указать мне правильное направление.

Большое спасибо!

...