Мне нужно получить доступ к массиву, который содержит данные матрицы MatrixBase Eigen.
Библиотека Eigen имеет метод data(), который возвращает указатель на массив, однако он доступен только из типа Matrix. MatrixBase не имеет аналогичного метода, хотя класс MatrixBase должен действовать как шаблон, а фактический тип должен быть просто матрицей. Если я попытаюсь получить доступ к MatrixBase.data(), я получаю ошибку времени компиляции:
template <typename ScalarA, typename Index, typename DerivedB, typename DerivedC>
void uscgemv(float alpha,
const USCMatrix<ScalarA,Index> &a,
const MatrixBase<DerivedB> &b,
const MatrixBase<DerivedC> &c_const)
{
//...some code
float * bMat = b.data();
///more code
}
Этот код создает следующую ошибку времени компиляции.
error: ‘const class Eigen::MatrixBase<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<float>, Eigen::Matrix<float, -1, 1> > > has no member named ‘data
float * bMat = b.data();
Поэтому я должен прибегать к трюкам, таким как...
float * bMat;
int bRows = b.rows();
int bCols = b.cols();
mallocPinnedMemory(&bMat, bRows*bCols*sizeof(float));
Eigen::Map<Matrix<float, Dynamic, Dynamic> > bmat_temp(bMat, bRows, bCols);
bmat_temp = b; //THis is SLOW, we should avoid it.
Затем я могу получить доступ к массиву bMat...
Эти копии назад и вперед являются самыми большими затратами на умножение матрицы gpu, поскольку я, по сути, должен сделать дополнительную копию, прежде чем даже справиться с устройством...
Я не могу использовать Eigen-magma, так как это разреженный матричный-в-странный формат для плотного матричного (или иногда векторного) умножения, поэтому я не могу использовать какие-либо функции автоматического gpu там. Также я бы скорее не объявлял матрицы как что-то еще, потому что это потребовало бы изменения МНОГО строк кода во всей программе (что я не писал).
EDIT: Было предложено статическое решение для литья:
float * bMat = (static_cast<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> >(b)).data();
Однако я получаю segfault при первой попытке доступа к элементу массива bMat.
EDIT 2: Я ищу нулевой способ копирования для доступа к базовым массивам. Мне нужно только читать b, но мне также нужно написать c. В настоящее время c не имеет ограничений со следующим макросом:
#define UNCONST(t,c,uc) Eigen::MatrixBase<t> &uc = const_cast<Eigen::MatrixBase<t>&>(c);
EDIT 3: После перекрестного перехода на Eigen Forums, похоже, я не могу сделать лучше, чем предлагаемый ответ.