Why is OpenMP in a mex file only producing 1 thread? - matlab

I am new to OpenMP. I have the following code which compiles fine using Matlab mex configured with MSVS2010. The computer has 8 processors available (which I checked also by using matlabpool).
#include "mex.h"
#include <omp.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//Takes a uint8 input array and uint32 index array and preallocated uint8 array the same
//size as the first one and copies the data over using the indexed mapping
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
{
uint N = mxGetN(prhs[0]);
mexPrintf("n=%i\n", N); mexEvalString("drawnow");
uchar *input = (uchar*)mxGetData(prhs[0]);
uint *index = (uint*)mxGetData(prhs[1]);
uchar *output = (uchar*)mxGetData(prhs[2]);
uint nThreads, tid;
#pragma omp parallel private(tid) shared(input, index, output, N, nThreads) num_threads(8)
{
tid = omp_get_thread_num();
if (tid==0) {
nThreads = omp_get_num_threads();
}
for (int i=tid*N/nThreads;i<tid*N/nThreads+N/nThreads;i++){
output[i]=input[index[i]];
}
}
mexPrintf("nThreads = %i\n",nThreads);mexEvalString("drawnow");
}
The output I get is
n=600000000
nThreads = 1
Why is only one thread being created despite me requesting 8?

Sigh. Typical, spend hours trying and failing and then find the answer 5 minutes after posting to SO.
The file needs to be mexed with openmp support
mex mexIndexedCopy.cpp COMPFLAGS="/openmp $COMPFLAGS"

Related

No Symbols Loaded: libmex.pdb not loaded (throw_segv_longjmp_seh_filter() = EXCEPTION_CONTINUE_SEARCH : C++ exception)

In order to create a MEX function and use it in my MATLAB code, like this:
[pow,index] = mx_minimum_power(A11,A12,A13,A22,A23,A33);
I've created the file mx_minimum_power.cpp and written the following code in it:
#include <math.h>
#include <complex>
#include "mex.h"
#include "matrix.h"
#include "cvm.h"
#include "blas.h"
#include "cfun.h"
using std::complex;
using namespace cvm;
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
const int arraysize = 62172;
const int matrixDimention = 3;
float *inMatrixA11 = (float *)mxGetPr(prhs[0]);
complex<float> *inMatrixA12 = (complex<float> *)mxGetPr(prhs[1]);
complex<float> *inMatrixA13 = (complex<float> *)mxGetPr(prhs[2]);
float *inMatrixA22 = (float *)mxGetPr(prhs[3]);
complex<float> *inMatrixA23 = (complex<float> *)mxGetPr(prhs[4]);
float *inMatrixA33 = (float *)mxGetPr(prhs[5]);
basic_schmatrix< float, complex<float> > A(matrixDimention);
int i = 0;
for (i = 0; i < arraysize; i++)
{
A.set(1, 1, inMatrixA11[i]);
A.set(1, 2, inMatrixA12[i]);
A.set(1, 3, inMatrixA13[i]);
A.set(2, 2, inMatrixA22[i]);
A.set(2, 3, inMatrixA23[i]);
A.set(3, 3, inMatrixA33[i]);
}
}
And then in order to be able to debug the code, I've created the mx_minimum_power.pdb and mx_minimum_power.mexw64 files, using the following code in the Matlab Command Window:
mex -g mx_minimum_power.cpp cvm_em64t_debug.lib
The files blas.h, cfun.h, cvm.h and cvm_em64t_debug.lib are in the same directory as mx_minimum_power.cpp.
They are the headers and library files of the CVM Class Library.
Then I've attached MATLAB.exe to Visual Studio 2013, using the way explained here.
and have set a breakpoint at line40:
When I run my MATLAB code, there's no error until the specified line.
But if I click on the Step Over button, I'll encounter the following message:
With the following information added to the Output:
First-chance exception at 0x000007FEFCAE9E5D in MATLAB.exe: Microsoft C++ exception: cvm::cvmexception at memory location 0x0000000004022570.
> throw_segv_longjmp_seh_filter()
throw_segv_longjmp_seh_filter(): C++ exception
< throw_segv_longjmp_seh_filter() = EXCEPTION_CONTINUE_SEARCH
Can you suggest me why libmex.pdb is needed at that line and how should I solve the issue?
If I stop debugging, I'll get the following information in MATLAB Command Window:
Unexpected Standard exception from MEX file.
What() is:First index value 0 is out of [1,4) range
Right before pressing the step over button, we have the following values for A11[0],A12[0],A13[0],A22[0],A23[0],A33[0]:
that are just right as my expectations, according to what MATLAB passes to the MEX function:
Maybe the problem is because of wrong allocation for matrix A, it is as follows just before pressing the step over button.
The problem occurs because we have the following code in lines 48 to 53 of the cvm.h file:
// 5.7 0-based indexing
#if defined (CVM_ZERO_BASED)
# define CVM0 TINT_ZERO //!< Index base, 1 by default or 0 when \c CVM_ZERO_BASED is defined
#else
# define CVM0 TINT_ONE //!< Index base, 1 by default or 0 when \c CVM_ZERO_BASED is defined
#endif
That makes CVM0 = 1 by default. So if we press the Step Into(F11) button at the specified line two times, we will get into line 34883 of the file cvm.h:
basic_schmatrix& set(tint nRow, tint nCol, TC c) throw(cvmexception)
{
this->_set_at(nRow - CVM0, nCol - CVM0, c);
return *this;
}
Press Step Into(F11) at line this->_set_at(nRow - CVM0, nCol - CVM0, c); and you'll go to the definition of the function _set_at:
// sets both elements to keep matrix hermitian, checks ranges
// zero based
void _set_at(tint nRow, tint nCol, TC val) throw(cvmexception)
{
_check_lt_ge(CVM_OUTOFRANGE_LTGE1, nRow, CVM0, this->msize() + CVM0);
_check_lt_ge(CVM_OUTOFRANGE_LTGE2, nCol, CVM0, this->nsize() + CVM0);
if (nRow == nCol && _abs(val.imag()) > basic_cvmMachMin<TR>()) { // only reals on main diagonal
throw cvmexception(CVM_BREAKS_HERMITIANITY, "real number");
}
this->get()[this->ld() * nCol + nRow] = val;
if (nRow != nCol) {
this->get()[this->ld() * nRow + nCol] = _conjugate(val);
}
}
pressing Step Over(F10) button,you'll get the result:
so in order to get nRow=1 and nCol=1 and not nRow=0 and nCol=0, which is out of the range [1,4), you should write that line of code as:
A.set(2, 2, inMatrixA11[i]);

Mex-call-to-matlab-firls-do-not-work

In the code below "h_fir" is giving all zeros differently from the equivalent Matlab code.
"L" = 204621
This is a function inside a mex file. The call from Matlab is working well and it come back well.
Can you devise the reason?
Matlab 2015a
Below a minimal example.
Thanks
Luis Gonçalves
#include "C:\Program Files\MATLAB\MATLAB Production Server\R2015a\extern\include\mex.h"
#include "C:\Program Files\MATLAB\MATLAB Production Server\R2015a\extern\include\matrix.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include <time.h>
#include <string.h>
#define MAX(p,q) ((p>q)?p:q)
void example(mxArray *,double, double);
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double v,f_simb,ts,vkmh,fd,c,R,p,q,fc,pqmax;
mxArray *h_fir;
int g2;
double *a3,*a4;
ts=10e-3;
vkmh=50;
c=3e8;
fc=2e9;
f_simb=1/ts;
v=vkmh/3.6;
fd=v/c*fc;
R=f_simb/(fd*110.5);
p = 100.0;
q = (double)(int)(p/R+0.5);
if (q<0.001)
q= 1.0;
h_fir= mxCreateDoubleMatrix(1,(int)(2.0*10.0*MAX(p,q) + 1.5),mxCOMPLEX);
example(h_fir,p,q);
a3 = mxGetPr(h_fir);
a4=mxGetPi(h_fir);
for(g2=102306-10;g2<102306+10;g2++)
mexPrintf("%e %e\n",a3[g2],a4[g2]);
return;
}
void example(mxArray *h_fir,double p, double q)
{
double N,pqmax,fc,L;
mxArray *L1,*ARRAY1,*ARRAY2;
double *array1,*array2,*hr,*hi;
mxArray *ppFevalRhs[3];
mxArray *ppFevalRhsin[1], *OUT1;
int i1,i2,*l1;
const size_t dims[2]={1,1};
N = 10.0;
pqmax = MAX(p,q);
fc = 1.0/2.0/pqmax;
L = 2.0*N*pqmax + 1.0;
L1 = mxCreateNumericArray(2, dims,mxINT32_CLASS, mxREAL);
l1 = (int *)mxGetData(L1);
*l1= (int)(L-1);
ppFevalRhs[0]=L1;
ARRAY1 = mxCreateDoubleMatrix(4, 1, mxCOMPLEX);
array1 = mxGetPr(ARRAY1);
array1[0]= 0;
array1[1]= 2.0*fc;
array1[2]= 2.0*fc;
array1[3]= 1;
array1 = mxGetPi(ARRAY1);
array1[0]= 0;
array1[1]= 0;
array1[2]= 0;
array1[3]= 0;
ppFevalRhs[1]=ARRAY1;
ARRAY2 = mxCreateDoubleMatrix(4, 1, mxCOMPLEX);
array2 = mxGetPr(ARRAY2);
array2[0]= 1;
array2[1]= 1;
array2[2]= 0;
array2[3]= 0;
array2 = mxGetPi(ARRAY2);
array2[0]= 0;
array2[1]= 0;
array2[2]= 0;
array2[3]= 0;
ppFevalRhs[2]=ARRAY2;
ppFevalRhsin[0]=h_fir;
if (mexCallMATLAB(1, ppFevalRhsin, 3, ppFevalRhs, "firls")!=0)
mexPrintf("firls error\n");
mxDestroyArray(L1);
mxDestroyArray(ARRAY1);
mxDestroyArray(ARRAY2);
}
The output variables of a matlab function called from mex are created by matlab and do not needed to be allocated before. The previous allocated pointer passed to matlab is overwritten by matlab. That is why the code above do not works.

Error 0x4000001e in Intel Advisor XE: Can not load raw collector data

I'm using Intel Advisor XE, part of Parallel Studio XE 2013 with Ubuntu 2014. Program for Prime number is as:
#include "stdio.h"
#include "stdlib.h"
int isPrime(long unsigned int x)
{
long unsigned int i;
for (i = 2; i < x; i += 1)
{
if(x%i==0)
return 0;
}
if(i==x)
return i;
}
int main (int argc, char *argv[])
{
double tic=omp_get_wtime();
long unsigned int i,num;
num=999999;
for (i = 1; i <= num; i += 1)
{
if(isPrime(i)) printf("\t%lu",i);
}
return 0;
}
I run this program with both icc and gcc and tested it on Intel Parallel Studio XE Advisor XE 2013. It went well with resulting hotspots and resultant tree like . Now when I added Annotation code something like
#include "stdio.h"
#include "stdlib.h"
#include "/opt/intel/advisor_xe_2013/include/advisor-annotate.h"
int isPrime(long unsigned int x)
{
long unsigned int i;
for (i = 2; i < x; i += 1)
{
if(x%i==0)
return 0;
}
if(i==x)
return i;
}
int main (int argc, char *argv[])
{
long unsigned int i,num;
num=999999;
ANNOTATE_SITE_BEGIN( MySite1 ); //Loop control statement to begin a parallel code region (parallel site).
for (i = 1; i <= num; i += 1)
{
ANNOTATE_ITERATION_TASK( MyTask1 ); // This annotation identifies an entire body as a task.
if(isPrime(i)) printf("\t%lu",i);
}
ANNOTATE_SITE_END(); // End the parallel code region, after task execution completes
return 0;
}
It gave me error like "Can not load row collector data."
I'm uploading images for the result. which seems like no errors but at last it shows like
Note 1 /proc/sys/kernel/yama/ptrace_scope has been updated to 0.
Note 2 I have set up LibPath LD_LIBRARY_PATH:/opt/intel/advisor_xe_2013/include
PS I tried for fibonacci of 6 digit number, and got the same result saying NO DATA
The problem was with compilation, I played around various options and tried using -I option with GCC and ICC to include library path, which I mentioned for header file, i.e. /opt/intel/advisor_xe_2013/include/ and also linked libraries using -ldl option which solved problem.

Unable to link external lib (CLAPACK) using MATLAB mex

I'm new to mex and this problem spent me days but I still cannot figure out what to do.
I create la_test.cpp file to test one of the subroutines in CLAPCK: cgemm_ (complex matrix-matrix multiplication). Here is the code:
#include "mex.h"
#include "matrix.h"
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <stdio.h>
#include "f2c.h"
#include "clapack.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
float *Xr,*Xi; // To store the input data
float *zsr,*zsi; // To store the output
long int m,n;
complex *A;
Xr = (float *) mxGetPr(prhs[0]);
Xi = (float *) mxGetPi(prhs[0]);
size_t K = mxGetNumberOfDimensions(prhs[0]);
const int *size = mxGetDimensions(prhs[0]);
m = mxGetM(prhs[0]);
n = mxGetN(prhs[0]);
A = new complex[m*n];
complex one = {1.0f, 0.0f}, zero = {0.0f, 0.0f};
for (int i=0; i<m; i++){
for (int j=0; j<n; j++){
complex rc = {Xr[j + n*i], Xi[j + n*i]};
A[j + n*i] = rc;
}
}
plhs[0] =(mxArray *) mxCreateDoubleMatrix( n, n, mxCOMPLEX );
zsr = (float *) mxGetPr(plhs[0]);
zsi = (float *) mxGetPi(plhs[0]);
complex *AtA = 0;
AtA = new complex[n*n];
char *chn = "N";
char *chc = "C";
cgemm_(chc, chn, &n, &n, &m, &one, A, &m, A, &m, &zero, AtA, &n);
for (int i=0; i<m; i++){
for (int j=0; j<n; j++){
zsr[j + n*i] = AtA[j + n*i].r;
zsi[j + n*i] = AtA[j + n*i].i;
}
}
}
Basically, I store input matrix into A and try to compute A'*A. Header files: f2c.h, clapack.h as well as three 64bit libraries: blas.lib, libf2c.lib and lapack.lib from http://icl.eecs.utk.edu/lapack-for-windows/clapack/index.html#install are all in the same file of la_test.cpp. I'm working on Windows 7 64bit system with matlab r2013a and Visual Studio 2012.
I have tried with both:
mex la_test.cpp lapack.lib libf2c.lib blas.lib
and
mex -llapack -llibf2c -lblas -L"C:\Users\Ziwu\Desktop\la_test" la_test.cpp
all with following error:
Creating library C:\Users\Ziwu\AppData\Local\Temp\mex_epl230\templib.x and object C:\Users\Ziwu\AppData\Local\Temp\mex_epl230\templib.exp
la_test.obj : error LNK2019: unresolved external symbol cgemm_ referenced in function mexFunction
la_test.mexw64 : fatal error LNK1120: 1 unresolved externals
I've checked on Internet for long time, but found no solution yet!
Please help me if you have any advice.

Error with OpenCV cvtColor in Matlab c++

I got the following error when I ran a c++ function in Matlab.
WARNING: Couldn't read movie file example.avi
Unexpected Standard exception from MEX file.
What()
is:/tmp/A3p1_2964_800/batserve/A3p1/maci64/OpenCV/modules/imgproc/src/color.cpp:3256:
error: (-215) scn == 3 || scn == 4 in function cvtColor
..
Error in rundemo (line 2)
r = facedetection(inputVideo);
Below is the code for facedetection.cpp
#include <iostream>
#include <vector>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include "mex.h"
using namespace std;
using namespace cv;
vector<Rect> detect(Mat img, CascadeClassifier face_cascade){
vector<Rect> faces;
Mat img_gray;
cvtColor(img, img_gray, COLOR_BGR2GRAY);
face_cascade.detectMultiScale(img_gray, faces, 1.1, 2);
return faces;
}
void mexFunction(int nlhs, mxArray *plhs[ ],int nrhs, const mxArray *prhs[ ]){
VideoCapture inputVideo(mxArrayToString(prhs[0]));
Mat img;
inputVideo >> img;
string face_cascade_name = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
face_cascade.load(face_cascade_name);
vector<Rect> rects = detect(img,face_cascade);
int numFaces = rects.size();
plhs[0] = (mxArray *) mxCreateNumericMatrix(numFaces,4,mxDOUBLE_CLASS,mxREAL);
double* outPtr = mxGetPr(plhs[0]);
for(int i = 0; i < numFaces; i++){
Rect rect = rects[i];
outPtr[i+0*numFaces] = rect.x;
outPtr[i+1*numFaces] = rect.y;
outPtr[i+2*numFaces] = rect.width;
outPtr[i+3*numFaces] = rect.height;
}
}
I guess there is something wrong in the path I assigned to the face_cascade_name. This code rans on a Windows computer with a different path, and then I changed it to the one shown because I use a Mac. This is the path to haarcascade_frontalface_alt.xml on my computer. Thank you for helping!
First, check that your video is being read in properly. You said the code works on windows. Make sure that your path to the video is correct.
In your mex function, add
Mat img;
inputVideo >> img;
// Add the following lines to check if img is valid
if (img.data == NULL)
{
printf("Video not read in properly\n");
exit(1);
}
Next, check the number of channels for img. If you run cvtColor(img, COLOR_BGR2GRAY), you need the number of channels to be 3.
printf("Number of channels for img: %d\n", img.channels());
If the number of channels is equal to 1, then your img is already single channel, which is why cvtColor is giving an error. So no color conversion is necessary in this case and you can just comment out the line for cvtColor and the error should be gone.
As a side note, to debug this, you might want to display a couple of frames of the video, i.e., display img for a few frames just to check that they look right.