LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

analysis library multithreading problem

Hi All,

 

I'm having problems running a function in more than one thread at the same time.

 

The error is returned from the analysis library, so I guess my first question is "Is the analysis library thread safe?" (Specifically, Vector & Matrix Algebra functions.) I have looked through the documentation and cant see a statment either way.

 

Although I have a workaround using locks placed around all analysis library calls, I'd like to get to the bottom of this - it's got me a little worried because I've multithreaded other programs using matrix functions from the analysis library...

Another reason is my propgram processes quite a bit of data, so I'm confident I'll get a noticable speed improvement if I could remove the locks.

 

I've coped a chunk of code below.

The function works fine if:

a) it is run in a single thread only,

OR

b) running in multiple threads with USE_THREAD_LOCKS defined.

 

The function dosent work when: 

Running concurrently in multple threads, and USE_THREAD_LOCKS is not defined.

In this situation, I get a fatal runtime error at one of the matrix functions -Transpose(), MatrixMul(), or InvMatrix(). The error does not always occur and is rarely in the same place, but always comes with a message about an undersize output array.

 

To give one example with some detail:

A fatal run time error occured at InvMatrix(), with pointer C highlighted and error message:

   "Array argument too small (72 bytes). Arguement must contain at least 168 bytes"

But C is appropriatley sized as 9 doubles, given the matrix size is 3x3.

While other threads are running my function at the time of the error, no other threads appear to be using the analsys library. 

 

I've looked over this code a hundered times, looking for unsafe variables but cant see anything.

 

Any ideas?

 

Diz.

 

void FitParabolasToPeaks (float *inArr, int sz, int *peaks, peakScoreData_t *score, int numPeaks, float *refinedPeakPos, float *refinedPeakHeight)
{
int i, iD, ip, allocSz;
double coeffs[3], B[9], C[9], sse, rSq, rmse;

	for(i=0;i<numPeaks;i++)
	{
		allocSz = 20+(int)score->params[i].widthAtQuarterMax;
		
		double ptsX[allocSz], ptsY[allocSz];
/*
here, data is added to ptsX and ptsY.
the value of ip is set to the number of datapoints.
*/ //LS SOLVER // MEMORY ALLOCATIONS (size r * c) double S[ip], A[ip*3], AT[3*ip], D[3*ip]; // POPULATE INPUT MATRIX // Obtain A and S, our input and vector matricies, A[numPts][3], S[numPts] for (iD=0;iD<ip;iD++) { A[iD*3 ] = ptsX[iD]*ptsX[iD]; //x^2 A[iD*3+1] = ptsX[iD]; //x A[iD*3+2] = 1.0; //1 S[iD] = ptsY[iD]; } // LS MATRIX SOLVE { #ifdef USE_THREAD_LOCKS int res; res = CmtGetLock (gg_lockAAL); #endif //notes on comment style: //a) var[rSIZE][cSIZE] - indicates size of matrix in [r][c] //b) {eqn}{var} - indicates that 'eqn' was calculated previously, and is stored in 'var' Transpose (A, ip, 3, AT); // Obtain A^T store in A^T[3][numPts] MatrixMul (AT, A, 3, ip, 3, B); // Obtain {A^T}{AT} * A, store in B [3][3] InvMatrix (B, 3, C); // Obtain {(A^T * A)}{B}^-1, store in C [3][3] MatrixMul (C, AT, 3, 3, ip, D); // Obtain {(A^T * A)^-1}{C} * A^T, store in D [numPts][3] MatrixMul (D, S, 3, ip, 1, coeffs); // Obtain {(A^T * A)^-1 * A^T}{D} * S, gives end result, coeffs[3] #ifdef USE_THREAD_LOCKS if (res==0) CmtReleaseLock (gg_lockAAL); #endif } /* ... do stuff with the result ... */
} //end i loop return; }

 

 

0 Kudos
Message 1 of 1
(3,845 Views)