Параллельный рабочий в пространстве имен - PullRequest
0 голосов
/ 10 марта 2019

Этот пример является продолжением предыдущего сообщения.Я пытаюсь переместить Parallel Worker в свой собственный файл cpp и объявить его в заголовочном файле.

Вызов функции 'mypackage' в публичном работнике

Дваошибки следующие: 1) тип переменной 'ExampleInternal :: PARALLEL_WORKER' является абстрактным классом

, и в моем невоспроизводимом примере: 2) ошибка: ожидается безусловный идентификатор для 'ExampleInternal :: PARALLEL_WORKER {'строка в файле Parallel_worker.cpp.

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

ExampleInternal.h

#ifndef ExampleInternal_H
#define ExampleInternal_H

namespace ExampleInternal{

#include <RcppArmadillo.h>
#include <RcppParallel.h>

double myfunc3(arma::vec vec_in){

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

struct PARALLEL_WORKER : RcppParallel::Worker{};

}


#endif

Parallel_Worker.cpp

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

using namespace RcppParallel;
using namespace ExampleInternal;

namespace ExampleInternal{

ExampleInternal::PARALLEL_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);

    // Create a loop that runs through a selected section of the total Boot_reps
    for( int k = begin; k < end; k ++){
      engine.seed(k);
      arma::vec index = input;
      std::shuffle( index.begin(), index.end(), engine);

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

};

} //Close Namespace

Parallel_func.cpp

#include <RcppArmadillo.h>
#include <RcppParallel.h>
#include "ExampleInternal.h"
using namespace ExampleInternal;

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

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

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

Ответы [ 2 ]

1 голос
/ 10 марта 2019

Вам необходимо правильно разделить объявление и определение вашей структуры. Объявление в заголовочном файле содержит переменные-члены и сигнатуры методов.

namespace ExampleInternal{

struct PARALLEL_WORKER : RcppParallel::Worker{
  const arma::vec &input;
  arma::vec &output;

  PARALLEL_WORKER(const arma::vec &input, arma::vec &output);
  void operator()(std::size_t begin, std::size_t end);

};
}

В файле cpp вы затем определяете свои методы:

namespace ExampleInternal{

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

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

    std::mt19937 engine(1);

    // Create a loop that runs through a selected section of the total Boot_reps
    for( std::size_t k = begin; k < end; k ++){
      engine.seed(k);
      arma::vec index = input;
      std::shuffle( index.begin(), index.end(), engine);

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


} //Close Namespace

Мне пришлось сделать еще несколько изменений, чтобы все скомпилировалось без предупреждений (функция, определенная в заголовке, должна быть inline и т. Д.). Полная информация на https://github.com/rstub/stackoverflow/tree/master/55082456. Обратите внимание, что некоторые изменения имеют смысл в контексте атрибутов Rcpp вне пакета. Кстати, поскольку вы не предоставляете тестовые данные, я проверил только компиляцию, а не правильную работу.

0 голосов
/ 13 марта 2019

Просто как продолжение.Чтобы переместить myfunc3 в отдельный файл .cpp, мне потребовалось включить заголовок RcppParallel в файл myfunc3.cpp.Мне также не нужно было добавлять 'inline'.

myfunc3.cpp

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

using namespace arma;

namespace ExampleInternal{

double myfunc3(arma::vec vec_in){

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

} // Close namespace

и ExampleInternal.h

#ifndef ExampleInternal_H
#define ExampleInternal_H

namespace ExampleInternal{

#include <RcppArmadillo.h>
#include <RcppParallel.h>

double myfunc3(arma::vec vec_in);

struct PARALLEL_WORKER : RcppParallel::Worker{
  const arma::vec &input;
  arma::vec &output;
  PARALLEL_WORKER( const arma::vec &input, arma::vec &output);
  void operator()(std::size_t begin, std::size_t end);
};

}

#endif
...