Making a fitfunction multithreaded
andyfaff
You should note that significant speedups are only obtained when the fitfunction to be calculated takes a long time. If it is too quick then the thread overhead will kill you. Test the speedups before you use code exclusively
Function myfitfunc_wrapper(w, yy, xx) : fitfunc
Wave w, yy, xx
Multithread yy = myfitfunc_kernel(w, xx)
End
Threadsafe function myfitfunc_kernel(w, xx)
Wave w
variable xx
//your code goes here
return w[0] + sqrt(xx) * w[1] * sin(xx) * cos(x) * ln(x)
End
Wave w, yy, xx
Multithread yy = myfitfunc_kernel(w, xx)
End
Threadsafe function myfitfunc_kernel(w, xx)
Wave w
variable xx
//your code goes here
return w[0] + sqrt(xx) * w[1] * sin(xx) * cos(x) * ln(x)
End
-OR-
Function myfitfunc_AAO_wrapper(w, yy, xx) : fitfunc
Wave w, yy, xx
variable nt = ThreadProcessorCount
variable tgID = ThreadGroupCreate(nt)
variable ii, startP, perT, remainingP
perT = floor(dimsize(yy, 0) / nt)
remainingP = dimsize(yy, 0)
make/n=(nt)/free/wave theDataY, theDataX
for(ii = 0 ; ii < nt ; ii+=1)
if(ii < nt -1)
theDataY[ii] = newfreewave(0x04, perT)
theDataX[ii] = newfreewave(0x04, perT)
else
theDataY[ii] = newfreewave(0x04, remainingP)
theDataX[ii] = newfreewave(0x04, remainingP)
endif
Wave yyy = theDataY[ii]
Wave xxx = theDataX[ii]
yyy = yy[p+startP]
xxx = xx[p+startP]
startP += perT
remainingP -= perT
ThreadStart tgID, ii, myfitfunc_AAO_kernel(w, theDataY[ii], theDataX[ii])
WaveClear yyy, xxx
endfor
variable finished = ThreadGroupWait(tgID, inf)
finished = threadgrouprelease(tgID)
//now copy back into structure wave
startP = 0
perT = floor(dimsize(yy, 0) / nt)
remainingP = dimsize(yy, 0)
for(ii = 0 ; ii < nt ; ii+=1)
Wave yyy = theDataY[ii]
yy[startP, startP+numpnts(yyy)] = yyy[p-startP]
Waveclear yyy
startP += perT
remainingP -= perT
endfor
End
Threadsafe function myfitfunc_AAO_kernel(w, yy, xx)
Wave w, yy, xx
//your code goes here
yy = w[0] + w[1] * sqrt(xx) * sin(xx) * cos(x) * ln(x)
End
Wave w, yy, xx
variable nt = ThreadProcessorCount
variable tgID = ThreadGroupCreate(nt)
variable ii, startP, perT, remainingP
perT = floor(dimsize(yy, 0) / nt)
remainingP = dimsize(yy, 0)
make/n=(nt)/free/wave theDataY, theDataX
for(ii = 0 ; ii < nt ; ii+=1)
if(ii < nt -1)
theDataY[ii] = newfreewave(0x04, perT)
theDataX[ii] = newfreewave(0x04, perT)
else
theDataY[ii] = newfreewave(0x04, remainingP)
theDataX[ii] = newfreewave(0x04, remainingP)
endif
Wave yyy = theDataY[ii]
Wave xxx = theDataX[ii]
yyy = yy[p+startP]
xxx = xx[p+startP]
startP += perT
remainingP -= perT
ThreadStart tgID, ii, myfitfunc_AAO_kernel(w, theDataY[ii], theDataX[ii])
WaveClear yyy, xxx
endfor
variable finished = ThreadGroupWait(tgID, inf)
finished = threadgrouprelease(tgID)
//now copy back into structure wave
startP = 0
perT = floor(dimsize(yy, 0) / nt)
remainingP = dimsize(yy, 0)
for(ii = 0 ; ii < nt ; ii+=1)
Wave yyy = theDataY[ii]
yy[startP, startP+numpnts(yyy)] = yyy[p-startP]
Waveclear yyy
startP += perT
remainingP -= perT
endfor
End
Threadsafe function myfitfunc_AAO_kernel(w, yy, xx)
Wave w, yy, xx
//your code goes here
yy = w[0] + w[1] * sqrt(xx) * sin(xx) * cos(x) * ln(x)
End
-OR- if you wanted to do a structure fit
Structure fitfuncStruct
Wave w
wave y
wave x[50]
int16 numVarMD
wave ffsWaves[50]
wave ffsTextWaves[10]
variable ffsvar[5]
string ffsstr[5]
nvar ffsnvars[5]
svar ffssvars[5]
funcref allatoncefitfunction ffsfuncrefs[10]
uint32 ffsversion // Structure version.
EndStructure
Threadsafe Function allatoncefitfunction(w,y,x)
Wave w,y,x
//you need this to act as a signature for the fitfuncStruct
//it needs to be threadsafe
End
Threadsafe function myfitfunc_AAO_kernel(w, yy, xx)
Wave w, yy, xx
//your code goes here
yy = w[0] + w[1] * sqrt(xx) * sin(xx) * cos(x) * ln(x)
End
Function myfitfunc_AAO_wrapper(s) : fitfunc
Struct fitfuncStruct &s
//work out how many points per thread
variable nt = ThreadProcessorCount
variable tgID = ThreadGroupCreate(nt)
variable ii, startP, perT, remainingP, finished
perT = floor(dimsize(s.y, 0) / nt)
remainingP = dimsize(s.y, 0)
//create waveref waves to hold references to the y and x waves to be distributed amongst each thread.
//you could create more than y and x if your function took more arguments
make/n=(nt)/free/wave theDataY, theDataX
//create the coefficients wave to be sent to all the threads, as you can't pass in s.w to a thread
Wave theCoefs = s.w
//this is the function we are going to pass the coefficients, and y and x waves onto.
//-It doesn't have to be an allatoncefitfunction it can be any function type you want (so long as it doesn't take structures).
//- It needs to be threadsafe!
//- the function can take as many parameters as you want, but you'll have to create a free wave for each of them (like theCoefs) to
// be passed into the thread.
Funcref allatoncefitfunction theFitFunction = s.ffsfuncrefs[0]
for(ii = 0 ; ii < nt ; ii+=1)
if(ii < nt -1)
theDataY[ii] = newfreewave(0x04, perT)
theDataX[ii] = newfreewave(0x04, perT)
else
theDataY[ii] = newfreewave(0x04, remainingP)
theDataX[ii] = newfreewave(0x04, remainingP)
endif
Wave yyy = theDataY[ii]
Wave xxx = theDataX[ii]
yyy = s.y[p+startP]
xxx = s.x[0][p+startP]
startP += perT
remainingP -= perT
//NOTE that you can't pass in a structure parameter in a threadstart operation. See:
//DisplayHelptopic "Threadstart"
// for more information
ThreadStart tgID, ii, myfitfunc_AAO_kernel(theCoefs, yyy, xxx)
WaveClear yyy, xxx
endfor
finished = ThreadGroupWait(tgID, inf)
finished = threadgrouprelease(tgID)
//now copy back into structure wave
startP = 0
perT = floor(dimsize(s.y, 0) / nt)
remainingP = dimsize(s.y, 0)
for(ii = 0 ; ii < nt ; ii+=1)
Wave yyy = theDataY[ii]
s.y[startP, startP+numpnts(yyy)] = yyy[p-startP]
Waveclear yyy
startP += perT
remainingP -= perT
endfor
End
Wave w
wave y
wave x[50]
int16 numVarMD
wave ffsWaves[50]
wave ffsTextWaves[10]
variable ffsvar[5]
string ffsstr[5]
nvar ffsnvars[5]
svar ffssvars[5]
funcref allatoncefitfunction ffsfuncrefs[10]
uint32 ffsversion // Structure version.
EndStructure
Threadsafe Function allatoncefitfunction(w,y,x)
Wave w,y,x
//you need this to act as a signature for the fitfuncStruct
//it needs to be threadsafe
End
Threadsafe function myfitfunc_AAO_kernel(w, yy, xx)
Wave w, yy, xx
//your code goes here
yy = w[0] + w[1] * sqrt(xx) * sin(xx) * cos(x) * ln(x)
End
Function myfitfunc_AAO_wrapper(s) : fitfunc
Struct fitfuncStruct &s
//work out how many points per thread
variable nt = ThreadProcessorCount
variable tgID = ThreadGroupCreate(nt)
variable ii, startP, perT, remainingP, finished
perT = floor(dimsize(s.y, 0) / nt)
remainingP = dimsize(s.y, 0)
//create waveref waves to hold references to the y and x waves to be distributed amongst each thread.
//you could create more than y and x if your function took more arguments
make/n=(nt)/free/wave theDataY, theDataX
//create the coefficients wave to be sent to all the threads, as you can't pass in s.w to a thread
Wave theCoefs = s.w
//this is the function we are going to pass the coefficients, and y and x waves onto.
//-It doesn't have to be an allatoncefitfunction it can be any function type you want (so long as it doesn't take structures).
//- It needs to be threadsafe!
//- the function can take as many parameters as you want, but you'll have to create a free wave for each of them (like theCoefs) to
// be passed into the thread.
Funcref allatoncefitfunction theFitFunction = s.ffsfuncrefs[0]
for(ii = 0 ; ii < nt ; ii+=1)
if(ii < nt -1)
theDataY[ii] = newfreewave(0x04, perT)
theDataX[ii] = newfreewave(0x04, perT)
else
theDataY[ii] = newfreewave(0x04, remainingP)
theDataX[ii] = newfreewave(0x04, remainingP)
endif
Wave yyy = theDataY[ii]
Wave xxx = theDataX[ii]
yyy = s.y[p+startP]
xxx = s.x[0][p+startP]
startP += perT
remainingP -= perT
//NOTE that you can't pass in a structure parameter in a threadstart operation. See:
//DisplayHelptopic "Threadstart"
// for more information
ThreadStart tgID, ii, myfitfunc_AAO_kernel(theCoefs, yyy, xxx)
WaveClear yyy, xxx
endfor
finished = ThreadGroupWait(tgID, inf)
finished = threadgrouprelease(tgID)
//now copy back into structure wave
startP = 0
perT = floor(dimsize(s.y, 0) / nt)
remainingP = dimsize(s.y, 0)
for(ii = 0 ; ii < nt ; ii+=1)
Wave yyy = theDataY[ii]
s.y[startP, startP+numpnts(yyy)] = yyy[p-startP]
Waveclear yyy
startP += perT
remainingP -= perT
endfor
End
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
Thanks!
Riccardo
May 14, 2010 at 03:11 pm - Permalink
Can't promise I can solve your problem, but I'll have a look.
May 15, 2010 at 04:34 am - Permalink
May 17, 2010 at 12:59 am - Permalink