small multithread errors

ubi
Posts: 7
Joined: 2010-03-15
Location: France

To treat my data I have a matlab script written by a colleague which I translated into igor and adapted to my needs. The procedure is quite fit extensive. The result of both programs are in pretty good agreement (without surprise). To enhance the speed I use a multithreaded code. However the result obtained with igor multithreaded code is a little bit more noisy (for the same conditions as far as it is possible to manage them) as it is shown in the attached file while the "normal" gives exactly the same result as the matlab script.

To be a bit more precise: Each x point is the result of the the difference of two different datasets proceeded by the following function.

Threadsafe FUNCTION fitthematrix_realth(srcwv, tmpwv,outwv,row)
WAVE srcwv, tmpwv, outwv
variable row
variable i
		tmpwv = srcwv[row][p]
		CurveFit/N/Q/L=100000 /NTHR=1 poly 4,  tmpwv /D
		wave fit_dumper, M_Covar, W_coef, W_fitConstants, W_ParamConfidenceInterval, W_sigma
		wavestats/Q/M=1 fit_dumper
		outwv[row] = 0.0009 * V_minRowLoc
		killwaves/Z fit_dumper, M_Covar, W_coef, W_fitConstants, W_ParamConfidenceInterval, W_sigma
END

In the main function the loop which calls the fit procedure looks like, which is basically copy&pasted from the igor help files:

Variable n,actrow,nthreads= ThreadProcessorCount
Variable mt= ThreadGroupCreate(nthreads)
 
Variable ttime= stopMSTimer(-2)
for(actrow=0;actrow<DimSize(fieldwv,0);)
	for(n=0;n<nthreads;n+=1)
		ThreadStart mt,n, fitthematrix_realth(fieldwv, dumper,resultingfield,actrow)
		actrow+=1
		if( actrow >= DimSize(fieldwv,0) )
			break
		endif
	endfor
 
	do
		variable tgs= ThreadGroupWait(mt,1000)
	while( tgs != 0 )
endfor
variable dummy= ThreadGroupRelease(mt)
 
Variable mt2= ThreadGroupCreate(nthreads)
for(actrow=0;actrow<DimSize(zfieldwave,0);)
	for(n=0;n<nthreads;n+=1)
		ThreadStart mt2,n, fitthematrix_realth(zfieldwave, dumper,resultingnofield,actrow)
		actrow+=1
		if( actrow >= DimSize(zfieldwave,0) )
			break
		endif
	endfor
 
	do
		variable tgs2= ThreadGroupWait(mt2,1000)
	while( tgs != 0 )
endfor					
dummy= ThreadGroupRelease(mt2)

Where is my error?

igor diff

Posts: 836
Joined: 2007-06-29
Location: United States

I'm lousy at reading code like that and figuring out the bug. But if no one suggests anything, please send an Igor experiment to support@wavemetrics.com that contains the code above, a data set to use as input, and instructions for invoking it.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com


741
Posts: 187
Joined: 2009-03-22
Location: Belgium

ubi wrote:

Threadsafe FUNCTION fitthematrix_realth(srcwv, tmpwv,outwv,row)
WAVE srcwv, tmpwv, outwv
variable row
variable i
		tmpwv = srcwv[row][p]
		CurveFit/N/Q/L=100000 /NTHR=1 poly 4,  tmpwv /D
		wave fit_dumper, M_Covar, W_coef, W_fitConstants, W_ParamConfidenceInterval, W_sigma
		wavestats/Q/M=1 fit_dumper
		outwv[row] = 0.0009 * V_minRowLoc
		killwaves/Z fit_dumper, M_Covar, W_coef, W_fitConstants, W_ParamConfidenceInterval, W_sigma
END

- Why is tmpwv passed in as an argument? Each thread will overwrite tmpwv - its contents are undefined.
- You reference a wave called fit_dumper. I don't see one being created. Remember that all threads have their own data folder hierarchy, independent from the 'standard' Igor hierarchy.

That said, here's how I would implement it (note - I assume that your output is 1D and that there is one point for each row in the source matrix).

Threadsafe FUNCTION FitWorker(srcwv, row)
WAVE srcwv, tmpwv, outwv
variable row
variable i
 
CurveFit/N/Q/L=100000 /NTHR=1 poly 4,  srcwv[row][] /D
// do something with the results of the fit and WaveStats
return 0.0009 * V_minRowLoc
END
 
Function DoTheWork(srcWave)
wave srcWave
 
Make /O/N=(DimSize(srcWave, 0)) /D outputWave
 
MultiThread outputWave = FitWorker(srcWave, p)
End


[ last edited May 8, 2012 - 11:44 ]
ubi
Posts: 7
Joined: 2010-03-15
Location: France

741 wrote:

- Why is tmpwv passed in as an argument? Each thread will overwrite tmpwv - its contents are undefined.
- You reference a wave called fit_dumper. I don't see one being created. Remember that all threads have their own data folder hierarchy, independent from the 'standard' Igor hierarchy.

That said, here's how I would implement it (note - I assume that your output is 1D and that there is one point for each row in the source matrix).

Great that fixed the problem. Indeed I have to create tmpwv in the thread. However your suggestion seems to be a bit "lighter", I'll give a try.


Back to top