multithreading issue with a for loop

I have a set of functions that takes image files, takes a line profile, fits the line profile to a line+gaussian function and writes the results. It works fine minus one issue. Below I have pasted a for loop that loops through all the images and performs the necessary steps. The loop works perfectly in the nonthreaded case. However, when I run it with multithreading the first loop(images 0,1,2,3) the program gives me 0 for all the fit parameters, and then it works fine for every loop after that. I can't figure out why the multithreading is having issues with the first set of images when the unthreaded code works fine.


If needs be I can post the rest of the code


    For(ii=0;ii<=Nmax;ii+=4)
   
            //Write loop strings
            If(mode==1)
                str0=num2str(ii)+".tif"
                str1=num2str(ii+1)+".tif"
                str2=num2str(ii+2)+".tif"
                str3=num2str(ii+3)+".tif"
            elseif(mode==0)
                str0=num2str(ii)+".jpg"
                str1=num2str(ii+1)+".jpg"
                str2=num2str(ii+2)+".jpg"
                str3=num2str(ii+3)+".jpg"
            endif


        cstr0="c_"+num2str(ii)
        cstr1="c_"+num2str(ii+1)
        cstr2="c_"+num2str(ii+2)
        cstr3="c_"+num2str(ii+3)
        estr0="e_"+num2str(ii)
        estr1="e_"+num2str(ii+1)
        estr2="e_"+num2str(ii+2)
        estr3="e_"+num2str(ii+3)
   
        if (doThreaded)
            //Parallel  fits on different cores
            ThreadStart tgID, 0, ProfileFit(Plane,W_coef1,$str0,W_err1,xtrace,ytrace)
            Duplicate/O W_coef1, $cstr0
            Duplicate/O W_err1, $estr0
               
            if(waveexists($str1)==1)   //in case wave doesn't exist.
                ThreadStart tgID, 1, ProfileFit(Plane,W_coef2,$str1,W_err2,xtrace,ytrace)
                Duplicate/O W_coef2, $cstr1
                Duplicate/O W_err2, $estr1
            else
                break
            endif
       
            if(waveexists($str2)==1)   //in case wave doesn't exist.
                ThreadStart tgID, 2, ProfileFit(Plane,W_coef3,$str2,W_err3,xtrace,ytrace)
                Duplicate/O W_coef3, $cstr2
                Duplicate/O W_err3, $estr2
            else
                break
            endif
       
            if(waveexists($str3)==1)   //in case wave doesn't exist.
                ThreadStart tgID, 3, ProfileFit(Plane,W_coef4,$str3,W_err4,xtrace,ytrace)
                Duplicate/O W_coef4, $cstr3
                Duplicate/O W_err4, $estr3
            else
                break
            endif
       
                // Wait for all threads to finish before starting another batch of threads
                do
                    Variable threadGroupStatus = ThreadGroupWait(tgID,100)
                while (threadGroupStatus != 0)
               
        else
            ProfileFit(Plane,W_coef1,$str0,W_err1,xtrace,ytrace)
            Duplicate/O W_coef1, $cstr0
            Duplicate/O W_err1, $estr0
            if(waveexists($str1)==1)   //in case wave doesn't exist.
                ProfileFit(Plane,W_coef2,$str1,W_err2,xtrace,ytrace)
                Duplicate/O W_coef2, $cstr1
                Duplicate/O W_err2, $estr1
            else
                break
            endif
       
            if(waveexists($str2)==1)   //in case wave doesn't exist.
                ProfileFit(Plane,W_coef3,$str2,W_err3,xtrace,ytrace)
                Duplicate/O W_coef3, $cstr2
                Duplicate/O W_err3, $estr2
            else
                break
            endif
       
            if(waveexists($str3)==1)   //in case wave doesn't exist.
                ProfileFit(Plane,W_coef4,$str3,W_err4,xtrace,ytrace)
                Duplicate/O W_coef4, $cstr3
                Duplicate/O W_err4, $estr3
            else
                break
            endif
        endif              
    endfor
Possibly you need to examine what is in W_coef1, W_coef2, W_coef3, W_coef4 on entry to the function. They should contain initial guesses.

If that is not the problem then I don't have enough information to diagnose this. I don't know where the W_ waves and the tgID variable come from.

I also don't know what you are doing with $cstr1, $cstr2, $cstr3, $cstr4 after the threads return.

I recommend that you package it up in the simplest possible experiment that shows the problem and attach the experiment here.
sleepingawake86 wrote:

            //Parallel  fits on different cores
            ThreadStart tgID, 0, ProfileFit(Plane,W_coef1,$str0,W_err1,xtrace,ytrace)
            Duplicate/O W_coef1, $cstr0
            Duplicate/O W_err1, $estr0



What is this supposed to do? It seems to me as if you're starting the thread, and then immediately you try to save the results using the Duplicate statement. But you seem to be missing that the main thread continues executing together with the newly spawned thread. So when your Duplicate executes, the worker thread probably hasn't had time to do the actual fit yet, and W_coef1 has not been touched. (I say 'probably' because in reality what happens is undefined - thread scheduling is up to the whims of the OS.)

Seems to me that what you need to do is to wait until the threads have finished executing (ThreadGroupWait), and then copy the fit results.

sleepingawake86 wrote:
I can't figure out why the multithreading is having issues with the first set of images when the unthreaded code works fine.

That's because by the time the algorithm starts on the second set of images, the threads you spawned to fit the first batch have finished, and therefore the W_Coefx waves contain the results for the previous batch. So things appear to be correct but you're actually saving the results for the previous batch! (with some non-determinism sprinkled in for good measure).


Ok, here is a pxp with all the necessary pieces. To save space I uploaded it with no data. Run the ModelData() function to make the model data for testing.

I moved the duplicates around like 741 suggested and that seemed to fix the first 4 values, but it messed up the last 4 now.

For each "image" the profile fit produces a coefficient wave "c_#" and an error wave "e_#" where # is the loop iteration. With the duplicate at the very end the program keeps missing the last 4 coef and error waves. When the duplicate was in the original position it made numbers 0-3 all zero.

Once again I have no issues with it when its unthreaded, just when its multithreading. Unthreaded is fine for a small data set like this example, but eventually I will be using around 500 images, so multithreading would be nice.
ForumsBatchProfFit.pxp (89.47 KB)
The break statements that you have here:
    if(waveexists($str1)==1)   //in case wave doesn't exist.
        ThreadStart tgID, 1, ProfileFit(Plane,W_coef2,$str1,W_err2,xtrace,ytrace)
    else
        break
    endif


will cause the ThreadGroupWait loop to be skipped. Just remove the else and the break for all three of them.

You will need tests before doing these statements:
    Duplicate/O W_coef2, $cstr1
    Duplicate/O W_err2, $estr1