C++ 中的 MATLAB 张量索引
MATLAB Tensor Indexing in C++
我正在尝试加载包含 C++ 中已知维度张量的 .mat 文件; 144x192x256
.
我已将读取操作的线性索引调整为与 MATLAB 中一样的主要列。但是我仍然遇到内存访问问题。
void FeatureLoader::readMat(const std::string &fname, Image< std::vector<float> > *out) {
//Read MAT file.
const char mode = 'r';
MATFile *matFile = matOpen(fname.c_str(), &mode);
if (matFile == NULL) {
throw std::runtime_error("Cannot read MAT file.");
}
//Copy the data from column major to row major storage.
float *newData = newImage->GetData();
const mxArray *arr = matGetVariable(matFile, "map");
if (arr == NULL) {
throw std::runtime_error("Cannot read variable.");
}
double *arrData = (double*)mxGetPr(arr);
#pragma omp parallel for
for (int i = 0; i < 144; i++) {
#pragma omp parallel for
for (int j = 0; j < 192; j++) {
for (int k = 0; k < 256; k++) {
int rowMajIdx = (i * 192 + j) * 256 + k;
int colMajIdx = (j * 144 + i) * 256 + k;
newData[rowMajIdx] = static_cast<float>(arrData[colMajIdx]);
}
}
}
}
在上面的代码片段中,我是否可以像 C++ 中的扁平化 3D 数组一样线性访问数据?例如:-
idx_row_major = (x*WIDTH + y)*DEPTH + z
idx_col_major = (y*HEIGHT + x)*DEPTH + z
这是 MATLAB 使用的底层表示吗?
行长和列长的索引有一些错误Idx
。此外,由于随机内存访问,天真地访问数据可能会导致非常慢的时间(内存延迟是关键!)。
从 MATLAB 传递到 C++ 类型(从 3D 到 1D)的最佳方法是遵循以下示例。
在这个例子中,我们说明了如何从 MATLAB 中获取双实型 3D 矩阵,并将其传递给 C double*
数组。
此示例的主要目的是展示如何从 MATLAB MEX 数组中获取数据,并突出显示矩阵存储和处理中的一些小细节。
matrixIn.cpp
#include "mex.h"
void mexFunction(int nlhs , mxArray *plhs[],
int nrhs, mxArray const *prhs[]){
// check amount of inputs
if (nrhs!=1) {
mexErrMsgIdAndTxt("matrixIn:InvalidInput", "Invalid number of inputs to MEX file.");
}
// check type of input
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])){
mexErrMsgIdAndTxt("matrixIn:InvalidType", "Input matrix must be a double, non-complex array.");
}
// extract the data
double const * const matrixAux= static_cast<double const *>(mxGetData(prhs[0]));
// Get matrix size
const mwSize *sizeInputMatrix= mxGetDimensions(prhs[0]);
// allocate array in C. Note: its 1D array, not 3D even if our input is 3D
double* matrixInC= (double*)malloc(sizeInputMatrix[0] *sizeInputMatrix[1] *sizeInputMatrix[2]* sizeof(double));
// MATLAB is column major, not row major (as C). We need to reorder the numbers
// Basically permutes dimensions
// NOTE: the ordering of the loops is optimized for fastest memory access!
// This improves the speed in about 300%
const int size0 = sizeInputMatrix[0]; // Const makes compiler optimization kick in
const int size1 = sizeInputMatrix[1];
const int size2 = sizeInputMatrix[2];
for (int j = 0; j < size2; j++)
{
int jOffset = j*size0*size1; // this saves re-computation time
for (int k = 0; k < size0; k++)
{
int kOffset = k*size1; // this saves re-computation time
for (int i = 0; i < size1; i++)
{
int iOffset = i*size0;
matrixInC[i + jOffset + kOffset] = matrixAux[iOffset + jOffset + k];
}
}
}
// we are done!
// Use your C matrix here
// free memory
free(matrixInC);
return;
}
需要注意的相关概念:
MATLAB 矩阵在内存中都是一维的,无论它们在 MATLAB 中使用时有多少维。对于 C/C++ 库中的大多数(如果不是全部)主矩阵表示也是如此,因为允许优化和更快的执行。
您需要在循环中显式地将矩阵从 MATLAB 复制到 C。
MATLAB 矩阵以列优先顺序存储,就像在 Fortran 中一样,但 C/C++ 和大多数现代语言都是行优先的。置换输入矩阵很重要,否则数据看起来会完全不同。
本例相关函数为:
mxIsDouble
检查输入是否为 double
类型。
mxIsComplex
检查输入是实数还是虚数。
mxGetData
returns 指向输入数组中真实数据的指针。 NULL
如果没有真实数据。
mxGetDimensions
returns 指向 mwSize
数组的指针,每个索引中的维度大小。
我正在尝试加载包含 C++ 中已知维度张量的 .mat 文件; 144x192x256
.
我已将读取操作的线性索引调整为与 MATLAB 中一样的主要列。但是我仍然遇到内存访问问题。
void FeatureLoader::readMat(const std::string &fname, Image< std::vector<float> > *out) {
//Read MAT file.
const char mode = 'r';
MATFile *matFile = matOpen(fname.c_str(), &mode);
if (matFile == NULL) {
throw std::runtime_error("Cannot read MAT file.");
}
//Copy the data from column major to row major storage.
float *newData = newImage->GetData();
const mxArray *arr = matGetVariable(matFile, "map");
if (arr == NULL) {
throw std::runtime_error("Cannot read variable.");
}
double *arrData = (double*)mxGetPr(arr);
#pragma omp parallel for
for (int i = 0; i < 144; i++) {
#pragma omp parallel for
for (int j = 0; j < 192; j++) {
for (int k = 0; k < 256; k++) {
int rowMajIdx = (i * 192 + j) * 256 + k;
int colMajIdx = (j * 144 + i) * 256 + k;
newData[rowMajIdx] = static_cast<float>(arrData[colMajIdx]);
}
}
}
}
在上面的代码片段中,我是否可以像 C++ 中的扁平化 3D 数组一样线性访问数据?例如:-
idx_row_major = (x*WIDTH + y)*DEPTH + z
idx_col_major = (y*HEIGHT + x)*DEPTH + z
这是 MATLAB 使用的底层表示吗?
行长和列长的索引有一些错误Idx
。此外,由于随机内存访问,天真地访问数据可能会导致非常慢的时间(内存延迟是关键!
从 MATLAB 传递到 C++ 类型(从 3D 到 1D)的最佳方法是遵循以下示例。
在这个例子中,我们说明了如何从 MATLAB 中获取双实型 3D 矩阵,并将其传递给 C double*
数组。
此示例的主要目的是展示如何从 MATLAB MEX 数组中获取数据,并突出显示矩阵存储和处理中的一些小细节。
matrixIn.cpp
#include "mex.h"
void mexFunction(int nlhs , mxArray *plhs[],
int nrhs, mxArray const *prhs[]){
// check amount of inputs
if (nrhs!=1) {
mexErrMsgIdAndTxt("matrixIn:InvalidInput", "Invalid number of inputs to MEX file.");
}
// check type of input
if( !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])){
mexErrMsgIdAndTxt("matrixIn:InvalidType", "Input matrix must be a double, non-complex array.");
}
// extract the data
double const * const matrixAux= static_cast<double const *>(mxGetData(prhs[0]));
// Get matrix size
const mwSize *sizeInputMatrix= mxGetDimensions(prhs[0]);
// allocate array in C. Note: its 1D array, not 3D even if our input is 3D
double* matrixInC= (double*)malloc(sizeInputMatrix[0] *sizeInputMatrix[1] *sizeInputMatrix[2]* sizeof(double));
// MATLAB is column major, not row major (as C). We need to reorder the numbers
// Basically permutes dimensions
// NOTE: the ordering of the loops is optimized for fastest memory access!
// This improves the speed in about 300%
const int size0 = sizeInputMatrix[0]; // Const makes compiler optimization kick in
const int size1 = sizeInputMatrix[1];
const int size2 = sizeInputMatrix[2];
for (int j = 0; j < size2; j++)
{
int jOffset = j*size0*size1; // this saves re-computation time
for (int k = 0; k < size0; k++)
{
int kOffset = k*size1; // this saves re-computation time
for (int i = 0; i < size1; i++)
{
int iOffset = i*size0;
matrixInC[i + jOffset + kOffset] = matrixAux[iOffset + jOffset + k];
}
}
}
// we are done!
// Use your C matrix here
// free memory
free(matrixInC);
return;
}
需要注意的相关概念:
MATLAB 矩阵在内存中都是一维的,无论它们在 MATLAB 中使用时有多少维。对于 C/C++ 库中的大多数(如果不是全部)主矩阵表示也是如此,因为允许优化和更快的执行。
您需要在循环中显式地将矩阵从 MATLAB 复制到 C。
MATLAB 矩阵以列优先顺序存储,就像在 Fortran 中一样,但 C/C++ 和大多数现代语言都是行优先的。置换输入矩阵很重要,否则数据看起来会完全不同。
本例相关函数为:
mxIsDouble
检查输入是否为double
类型。mxIsComplex
检查输入是实数还是虚数。mxGetData
returns 指向输入数组中真实数据的指针。NULL
如果没有真实数据。mxGetDimensions
returns 指向mwSize
数组的指针,每个索引中的维度大小。