<div dir="ltr"><div><div><div>Hi Bradley,<br><br>Great! That works on this toy example, I will use this technique on my filter.<br></div>For the record I post the code that works.<br><br></div>Could you suggest a documentation entry or somewhere in the code where I can learn about the architectural mechanism preventing circular execution? And strategies to trade off like this one?<br>
<br></div>Thank you very much<br></div><div class="gmail_extra"><br clear="all"><div><div dir="ltr">Nicolás Gallego-Ortiz<br>Université catholique de Louvain, Belgium<br></div></div>
<br><br><div class="gmail_quote">2014-06-20 15:19 GMT+02:00 Bradley Lowekamp <span dir="ltr"><<a href="mailto:blowekamp@mail.nih.gov" target="_blank">blowekamp@mail.nih.gov</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word">Hello,<div><br></div><div>There is some code in the pipeline architecture to prevent circular execution. I believe it has been used for more complex circular pipelines. But your case is a bit simplified and has a problem.</div>
<div><br></div><div>For your particular case the input image IS same as the output image. This does not surprise me that it breaks things and causes odd behavior.</div><div><br></div><div>I am not sure if the below pipeline is close to what you are trying to do in the end or not. But I'll suggest the following:</div>
<div><br></div><div>1) After getting the output, call tmpImage->DisconnectPipeline().</div><div>This will explicitly sever the pipeline, and allow you to manual place the output as a input.</div><div><br></div><div>2) Turn on InPlace for the AddImageFilter.</div>
<div> This will copy the buffer of input1 to the output and remove the need to allocate a new output.</div><div><br></div><div>Hope that helps,</div><div>Brad</div><div><br><div><div><div class="h5"><div>On Jun 20, 2014, at 4:35 AM, Nicolas Gallego <<a href="mailto:nicgallego@gmail.com" target="_blank">nicgallego@gmail.com</a>> wrote:</div>
<br></div></div><blockquote type="cite"><div><div class="h5"><div dir="ltr"><div><div><div><div>Good morning,<br><br></div>I have been coding a filter that implements an iterative procedure on images. I have tried the straight forward implementation of updating a temporal image on the recursion loop but results are wrong. The correct result is obtained when I explicitly unroll the pipeline although it becomes harder to code for more complex pipelines, and I am concerned about the scalability on the number of recursions.<br>
<br></div>Could you give me some ideas to work this point out. Is there a way to implement a straight forward way in itk? Here the code that illustrates the point on recursively adding images:<br><br></div>----- code 1 -------------<br>
<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>cout<span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"Recursion</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">on</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">image</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">pointer"</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>endl<span>;</span>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span>ImageType<span>::</span>Pointer<span style="color:rgb(192,192,192)"> </span><span>image1</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span>ImageType<span>::</span>New<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>image1</span><span>-></span>SetRegions<span>(</span><span style="color:rgb(192,192,192)"> </span><span>region</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>image1</span><span>-></span>Allocate<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>image1</span><span>-></span>FillBuffer<span>(</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">1</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span>AdderType<span>::</span>Pointer<span style="color:rgb(192,192,192)"> </span><span>adder</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span>AdderType<span>::</span>New<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adder</span><span>-></span>SetInput1<span>(</span><span style="color:rgb(192,192,192)"> </span><span>image1</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adder</span><span>-></span>SetInput2<span>(</span><span style="color:rgb(192,192,192)"> </span><span>image1</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adder</span><span>-></span>Update<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span>ImageType<span>::</span>Pointer<span style="color:rgb(192,192,192)"> </span><span>tmpImage</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span><span>adder</span><span>-></span>GetOutput<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>cout<span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"start:</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span>image1</span><span>-></span>GetPixel<span>(</span><span style="color:rgb(192,192,192)"> </span><span>index</span><span style="color:rgb(192,192,192)"> </span><span>)</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>endl<span>;</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">const</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">unsigned</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">short</span><span style="color:rgb(192,192,192)"> </span><span>N</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">10</span><span>;</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">for</span><span style="color:rgb(192,192,192)"> </span><span>(</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">unsigned</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">short</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span><span>;</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span style="color:rgb(192,192,192)"> </span><span><</span><span style="color:rgb(192,192,192)"> </span><span>N</span><span>;</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span>++</span><span style="color:rgb(192,192,192)"> </span><span>)</span><span style="color:rgb(192,192,192)"> </span><span>{</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adder</span><span>-></span>Update<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>tmpImage</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span><span>adder</span><span>-></span>GetOutput<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>cout<span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span>tmpImage</span><span>-></span>GetPixel<span>(</span><span style="color:rgb(192,192,192)"> </span><span>index</span><span style="color:rgb(192,192,192)"> </span><span>)</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>endl<span>;</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adder</span><span>-></span>SetInput1<span>(</span><span style="color:rgb(192,192,192)"> </span><span>tmpImage</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adder</span><span>-></span>SetInput2<span>(</span><span style="color:rgb(192,192,192)"> </span><span>image1</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>}</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>cout<span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>endl<span>;</span></pre>
</div>--- end of 1 --------------<br><br><div><div>Code 1 produces the following output:<br>-----------------------------------------------<br>Recursion on image pointer<br>start: 1<br>0 2<br>1 3<br>2 3<br>3 3<br>4 4<br>
5 4<br>
6 4<br>7 5<br>8 5<br>9 5<br>---------------------------------------------<br></div><div><br></div><div>The explicit pipeline unroll is illustrated in code 2<br></div><div><br>--- code 2 -----------------------------------------------<br>
<span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>cout<span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"Pipeline</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">explicit</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">unroll</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">recursion"</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>endl<span>;</span>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span><span style="color:rgb(128,0,128)">vector</span><span><</span><span style="color:rgb(192,192,192)"> </span>AdderType<span>::</span>Pointer<span style="color:rgb(192,192,192)"> </span><span>></span><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>(</span><span style="color:rgb(192,192,192)"> </span><span>N</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span style="color:rgb(0,0,128)">0</span><span>]</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span>AdderType<span>::</span>New<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span style="color:rgb(0,0,128)">0</span><span>]-></span>SetInput1<span>(</span><span style="color:rgb(192,192,192)"> </span><span>image1</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span style="color:rgb(0,0,128)">0</span><span>]-></span>SetInput2<span>(</span><span style="color:rgb(192,192,192)"> </span><span>image1</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>cout<span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"start:</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span>image1</span><span>-></span>GetPixel<span>(</span><span style="color:rgb(192,192,192)"> </span><span>index</span><span style="color:rgb(192,192,192)"> </span><span>)</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>endl<span>;</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">//</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">connections</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">for</span><span style="color:rgb(192,192,192)"> </span><span>(</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">unsigned</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">short</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">1</span><span>;</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span style="color:rgb(192,192,192)"> </span><span><</span><span style="color:rgb(192,192,192)"> </span><span>N</span><span>;</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span>++</span><span style="color:rgb(192,192,192)"> </span><span>)</span><span style="color:rgb(192,192,192)"> </span><span>{</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span>k</span><span>]</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span>AdderType<span>::</span>New<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span>k</span><span>]-></span>SetInput1<span>(</span><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span>k</span><span>-</span><span style="color:rgb(0,0,128)">1</span><span>]-></span>GetOutput<span>()</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span>k</span><span>]-></span>SetInput2<span>(</span><span style="color:rgb(192,192,192)"> </span><span>image1</span><span style="color:rgb(192,192,192)"> </span><span>);</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>}</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">//</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">execution</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span>N</span><span>-</span><span style="color:rgb(0,0,128)">1</span><span>]-></span>Update<span>();</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">for</span><span style="color:rgb(192,192,192)"> </span><span>(</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">unsigned</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">short</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span style="color:rgb(192,192,192)"> </span><span>=</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span><span>;</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span style="color:rgb(192,192,192)"> </span><span><</span><span style="color:rgb(192,192,192)"> </span><span>N</span><span>;</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span>++</span><span style="color:rgb(192,192,192)"> </span><span>)</span><span style="color:rgb(192,192,192)"> </span><span>{</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>cout<span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span>k</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span>adders</span><span>[</span><span>k</span><span>]-></span>GetOutput<span>()-></span>GetPixel<span>(</span><span style="color:rgb(192,192,192)"> </span><span>index</span><span style="color:rgb(192,192,192)"> </span><span>)</span><span style="color:rgb(192,192,192)"> </span><span><<</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,0,128)">std</span><span>::</span>endl<span>;</span></pre>
<pre style="margin:0px;text-indent:0px"><span style="color:rgb(192,192,192)"> </span><span>}</span></pre>
<br></div><div>--- end of code 2 --------------------------------------<br></div><div><br></div><div>Pipeline explicit unroll recursion<br>start: 1<br>0 2<br>1 3<br>2 4<br>3 5<br>4 6<br>5 7<br>6 8<br>7 9<br>8 10<br>9 11<br>
<div><div>------------------------------------<br><br></div><div>Find attached complete code file, thank you for your help<br><br>------<br clear="all"></div><div><div><div dir="ltr">Nicolás Gallego-Ortiz<br>Université catholique de Louvain, Belgium<br>
</div></div>
</div></div></div></div></div>
</div></div><span><recursionTest.cxx></span>_______________________________________________<br>Community mailing list<br><a href="mailto:Community@itk.org" target="_blank">Community@itk.org</a><br><a href="http://public.kitware.com/mailman/listinfo/community" target="_blank">http://public.kitware.com/mailman/listinfo/community</a><br>
</blockquote></div><br></div></div></blockquote></div><br></div>