[Insight-developers] itkIsoContourDistanceImageFilter, Win32, Fixed, but additional th reading issues

Miller, James V (Research) millerjv at crd . ge . com
Wed, 20 Aug 2003 10:25:38 -0400


This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.

------_=_NextPart_001_01C36726.ED3E527A
Content-Type: text/plain;
	charset="iso-8859-1"

I modified the itkIsoContourDistanceImageFilter so the test will pass on
Windows.  The test for this class checks to make sure the pixels outside the
levelset and inside the level before and after the reinitialization have the
same sign.  In the narrow band case, not all the output pixels were visited
so there the comparisons were using uninitialized memory.  This caused the
test to fail.  I put code in the BeforeThreadedGenerateData() method to set
each pixel in the output levelset as either +FarValue, -FarValue or 0.
 
There is another problem with this algorithm that could appear when running
on multiple threads in the narrow band case.  The filter divides the narrow
band (list of indices) into a set of groups, specifying one group for each
thread.  This is nice.  However, the algorithm may set pixels in a 3x3x...
neighborhood of a narrow band pixel.  When running multiple threads this may
be a problem.  If threads of examining adjacent pixels (or pixels with a
radius of 2), the two threads may end up trying to set the same output pixel
at the same time.  This can cause a problem with memory integrity.  The
situation here could actually be more subtle because before each write
access to an output pixel, a comparison is done with a current calculated
value.
 
            if(fabs(val1_new) < fabs(outNeigIt.GetNext(n,1)))
              outNeigIt.SetNext(n,1,static_cast<PixelType>(val1_new) );

Consider a thread that is interrupted between the call to GetNext() and
SetNext().  If the conditional is evaluated as true, 
then the code wants to overwrite the pixel.  But if the thread is
interrupted after the conditional is satisfied but before the call to
SetNext(), another thread may come in and evaluate the same output pixel,
pass its conditional with a value of val1_new that is less than the first
thread, write the pixel out.  Then when the first thread awakes, it has
already satisfied its conditional so it writes it version of val1_new.  The
the first thread had a value of val1_new that is greater than the second
thread's, the output will be incorrect.
 
 
 
 

Jim Miller 
_____________________________________
Visualization & Computer Vision
GE Research
Bldg. KW, Room C218B
P.O. Box 8, Schenectady NY 12301

millerjv at research . ge . com <mailto:millerjv at research . ge . com> 

james . miller at research . ge . com
(518) 387-4005, Dial Comm: 8*833-4005, 
Cell: (518) 505-7065, Fax: (518) 387-6981 

 

------_=_NextPart_001_01C36726.ED3E527A
Content-Type: text/html;
	charset="iso-8859-1"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">


<META content="MSHTML 6.00.2800.1141" name=GENERATOR></HEAD>
<BODY>
<DIV><SPAN class=865111014-20082003><FONT size=2>I modified the 
itkIsoContourDistanceImageFilter so the test will pass on Windows.&nbsp; The 
test for this class checks to make sure the pixels outside the levelset and 
inside the level before and after the reinitialization have the same sign.&nbsp; 
In the narrow band case, not all the output pixels were visited so there the 
comparisons were using uninitialized memory.&nbsp; This caused the test to 
fail.&nbsp; I put code in the BeforeThreadedGenerateData() method to set each 
pixel in the output levelset as either +FarValue, -FarValue or 
0.</FONT></SPAN></DIV>
<DIV><SPAN class=865111014-20082003><FONT size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=865111014-20082003><FONT size=2>There is another problem with 
this algorithm that could appear when running on multiple threads in the narrow 
band case.&nbsp; The filter divides the narrow band (list of indices) into a set 
of groups, specifying one group for each thread.&nbsp; This is nice.&nbsp; 
However, the algorithm may set pixels in a 3x3x... neighborhood of a narrow band 
pixel.&nbsp; When running multiple threads this may be a problem.&nbsp; If 
threads of examining adjacent pixels (or pixels with a radius of 2), the two 
threads may end up trying to set the same output pixel at the same time.&nbsp; 
This can cause a problem with memory integrity.&nbsp; The situation here could 
actually be more subtle because before each write access to an output pixel, a 
comparison is done with a current calculated value.</FONT></SPAN></DIV>
<DIV><SPAN class=865111014-20082003><FONT size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=865111014-20082003><FONT 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
if(fabs(val1_new) &lt; 
fabs(outNeigIt.GetNext(n,1)))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
outNeigIt.SetNext(n,1,static_cast&lt;PixelType&gt;(val1_new) 
);<BR></FONT></SPAN></DIV>
<DIV><SPAN class=865111014-20082003><FONT size=2>Consider&nbsp;a thread that is 
interrupted between the call to GetNext() and SetNext().&nbsp; If the 
conditional is evaluated as true, </FONT></SPAN></DIV>
<DIV><SPAN class=865111014-20082003><FONT size=2>then the code wants to 
overwrite the pixel.&nbsp; But if the thread is interrupted after the 
conditional is satisfied but before the call to SetNext(), another thread may 
come in and evaluate the same output pixel, pass its conditional with a value of 
val1_new that is less than the first thread, write the pixel out.&nbsp; Then 
when the first thread awakes, it has already satisfied its conditional so it 
writes it version of val1_new.&nbsp; The the first thread had a value of 
val1_new that is greater than the second thread's, the output will be 
incorrect.</FONT></SPAN></DIV>
<DIV><SPAN class=865111014-20082003><FONT size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><SPAN class=865111014-20082003><FONT size=2>&nbsp;</DIV></FONT></SPAN>
<DIV><SPAN class=865111014-20082003><FONT size=2></FONT></SPAN>&nbsp;</DIV>
<DIV><FONT size=2></FONT>&nbsp;</DIV>
<DIV>
<P style="MARGIN: 0in 0in 0pt"><B><SPAN 
style="COLOR: navy; FONT-FAMILY: 'Comic Sans MS'">Jim Miller</SPAN></B> 
<BR><B><I><SPAN 
style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Arial">_____________________________________</SPAN></I></B><BR><EM><SPAN 
style="FONT-SIZE: 7.5pt; COLOR: black; FONT-FAMILY: Arial">Visualization &amp; 
Computer Vision</SPAN></EM><I><SPAN 
style="FONT-SIZE: 7.5pt; COLOR: black; FONT-FAMILY: Arial"><BR><EM>GE 
Research</EM><BR><EM>Bldg. KW, Room C218B</EM><BR><EM>P.O. Box 8, Schenectady NY 
12301</EM><BR><BR></SPAN></I><EM><U><SPAN 
style="FONT-SIZE: 7.5pt; COLOR: blue"><A 
href="mailto:millerjv at research . ge . com">millerjv at research . ge . com</A></SPAN></U></EM></P>
<P style="MARGIN: 0in 0in 0pt"><EM><U><SPAN 
style="FONT-SIZE: 7.5pt; COLOR: blue">james . miller at research . ge . com</SPAN></U></EM><BR><I><SPAN 
style="FONT-SIZE: 7.5pt; COLOR: black; FONT-FAMILY: Arial">(518) 387-4005, Dial 
Comm: 8*833-4005, </SPAN></I><BR><I><SPAN 
style="FONT-SIZE: 7.5pt; COLOR: black; FONT-FAMILY: Arial">Cell: (518) 505-7065, 
Fax: (518) 387-6981</SPAN></I> </P></DIV>
<DIV>&nbsp;</DIV></BODY></HTML>

------_=_NextPart_001_01C36726.ED3E527A--