<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: DS2 RUN method starting before INIT method is complete if the RUN method calls a thread in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/736396#M229397</link>
    <description>&lt;P&gt;I'm posting this to add to the knowledge base.&amp;nbsp; Tech support asked for the work around that Snoopy369 came up with.&amp;nbsp; I gave them the slightly simplified version at the bottom of this post.&amp;nbsp; Here is their explanation of why it works.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class="cs2654ae3a"&gt;&lt;SPAN class="cs1e88c66e1"&gt;&lt;SPAN style="font-size: 10.0pt;"&gt;The 5 threads that run the DS2 thread block are started during startup before the DS2 data block’s INIT method is called by the 1 thread running the DS2 DATA block.&amp;nbsp; If the DS2 thread block expects an argument value for a parameter, then the DS2 thread waits during its startup for the the DATA block thread to set the thread’s parameter values.&amp;nbsp; Eventually, the data block’s INIT method sets the thread’s parameter values, and then the DS2 thread block threads get the parameter values and finish their startup.&amp;nbsp; Note that if the DATA block does not call the SETPARMS method for whatever reason (maybe the SETPARMS call is inside an IF statement block that is bypassed), the SET FROM statement will set the thread’s parameter values to NULL or MISSING.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data intyears;
do LoopYear = 2001 to 2009;
    output;
  end;
run;

proc ds2;

  thread MyThread (int ready) / overwrite=yes;
    method init();

    end;
    method run();
      declare integer x y z;
      declare varchar(5000) tempstr;
      set intyears; 
      by  LoopYear;
      Do x = 1 to 100000;
        if mod(x,10000) = 0 then put 'Thread: ' LoopYear ':' x ;
      end;     
    end;
    method term();
    end;
  endthread;
  run;
  data _null_;
    dcl thread MyThread MyThread;
    declare integer x;
    method init();
      PUT 'Starting INIT';
      Do x = 1 to 800000;
        if mod(x,100000) = 0 then put 'Package: ' x;
      end;     
      MyThread.setparms(1);
       PUT 'Ending INIT';
    end;
    
    method run();
      set from MyThread threads=5;
    end;
    
    method term();
      PUT 'In Term';
    end;
    
  enddata;
run;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Thu, 22 Apr 2021 13:51:57 GMT</pubDate>
    <dc:creator>CurtisMackWSIPP</dc:creator>
    <dc:date>2021-04-22T13:51:57Z</dc:date>
    <item>
      <title>DS2 RUN method starting before INIT method is complete if the RUN method calls a thread</title>
      <link>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/734413#M228799</link>
      <description>&lt;P&gt;I am running a THREAD method within the RUN method of a DS2 DATA step.&amp;nbsp; I have code that executes in the INIT method.&amp;nbsp; The problem is that the threaded processes in the RUN method start before the the code in the INIT method has completed.&amp;nbsp; Is this by design?&amp;nbsp; It there a way to prevent it?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here some example code that demonstrates the issue.&amp;nbsp; It is vastly simplified for the real use case.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;
data intyears;
 do LoopYear = 2001 to 2009;
    output;
  end;
run;

proc ds2;
  thread MyThread / overwrite=yes;

    method init();

    end;
    method run();
      declare integer x y z;
      declare varchar(5000) tempstr;
      set intyears; 
      by  LoopYear;
      Do x = 1 to 100000;
        if mod(x,10000) = 0 then put 'Thread: ' LoopYear ':' x;
      end;     
    end;
    method term();
    end;
  endthread;

  data _null_;
    dcl thread MyThread MyThread;
    declare package myPackage myPackage();
    declare integer x;

    method init();
      PUT 'Starting INIT';
      Do x = 1 to 1000000;
        if mod(x,100000) = 0 then put 'Package: ' x;
      end;     
    end;
    
    method run();
      set from MyThread threads=5;
    end;
    
    method term();
      PUT 'In Term';
    end;
    
  enddata;
run;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Here is the log I get.&amp;nbsp; Notice that there are "Package: " lines well after the "Thread:" lines start.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;Starting INIT
Package: 100000
Package: 200000
Package: 300000
Package: 400000
Package: 500000
Package: 600000
Package: 700000
Thread: 2003 : 10000
Thread: 2003 : 20000
Thread: 2003 : 30000
Thread: 2003 : 40000
Thread: 2002 : 10000
Thread: 2004 : 10000
Thread: 2003 : 50000
Thread: 2001 : 10000
Thread: 2005 : 10000
Thread: 2003 : 60000
Thread: 2003 : 70000
Thread: 2003 : 80000
Thread: 2003 : 90000
Thread: 2002 : 20000
Thread: 2004 : 20000
Thread: 2003 : 100000
Thread: 2005 : 20000
Thread: 2001 : 20000
Thread: 2006 : 10000
Thread: 2006 : 20000
Thread: 2006 : 30000
Thread: 2006 : 40000
Thread: 2002 : 30000

Thread: 2004 : 30000
Thread: 2006 : 50000
Thread: 2005 : 30000
Thread: 2001 : 30000
Thread: 2006 : 60000
Thread: 2006 : 70000
Thread: 2006 : 80000
Thread: 2006 : 90000
Thread: 2002 : 40000
Thread: 2004 : 40000
Thread: 2005 : 40000
Thread: 2006 : 100000
Thread: 2001 : 40000
Thread: 2007 : 10000
Thread: 2004 : 50000
Thread: 2007 : 20000
Thread: 2004 : 60000
Thread: 2002 : 50000
Thread: 2007 : 30000
Thread: 2004 : 70000
Thread: 2005 : 50000
Thread: 2007 : 40000
Thread: 2001 : 50000
Thread: 2004 : 80000
Thread: 2007 : 50000
Thread: 2004 : 90000
Thread: 2002 : 60000
Thread: 2007 : 60000
Thread: 2004 : 100000
Thread: 2005 : 60000
Thread: 2007 : 70000
Thread: 2008 : 10000
Thread: 2001 : 60000
Thread: 2007 : 80000
Thread: 2002 : 70000
Thread: 2008 : 20000
Package: 800000
Thread: 2007 : 90000
Thread: 2005 : 70000
Thread: 2008 : 30000
Thread: 2007 : 100000
Thread: 2001 : 70000
Thread: 2008 : 40000
Thread: 2002 : 80000
Thread: 2009 : 10000
Thread: 2008 : 50000
Thread: 2005 : 80000
Thread: 2009 : 20000
Thread: 2008 : 60000
Thread: 2001 : 80000
Thread: 2009 : 30000
Thread: 2002 : 90000
Thread: 2008 : 70000
Thread: 2009 : 40000
Thread: 2005 : 90000
Thread: 2008 : 80000
Thread: 2009 : 50000
Thread: 2001 : 90000
4 The SAS System 17:46 Wednesday, April 14, 2021

Thread: 2008 : 90000
Thread: 2002 : 100000
Thread: 2009 : 60000
Thread: 2008 : 100000
Thread: 2005 : 100000
Thread: 2009 : 70000
Thread: 2009 : 80000
Thread: 2001 : 100000
Thread: 2009 : 90000
Thread: 2009 : 100000
Package: 900000
Package: 1000000
In Term&lt;/PRE&gt;
&lt;P&gt;I did try this without using threads and it doesn't do this.&amp;nbsp; It seems to me quite contrary to the purpose of the INIT method.&lt;/P&gt;
&lt;P&gt;Any Ideas?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 15 Apr 2021 18:59:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/734413#M228799</guid>
      <dc:creator>CurtisMackWSIPP</dc:creator>
      <dc:date>2021-04-15T18:59:29Z</dc:date>
    </item>
    <item>
      <title>Re: DS2 RUN method starting before INIT method is complete if the RUN method calls a thread</title>
      <link>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/734566#M228809</link>
      <description>&lt;P&gt;I'm not 100% sure of how this works behind the scenes, but - I suspect this could be an optimization.&lt;/P&gt;
&lt;P&gt;In your example, it does not matter one bit to DS2 what order things run in - nothing in INIT affects the threads.&lt;/P&gt;
&lt;P&gt;When I modify your code slightly, to add a parameter and a setparms, it works as expected - because now there is something related to the thread in INIT.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data intyears;
 do LoopYear = 2001 to 2009;
    output;
  end;
run;

proc ds2;

  thread MyThread (int a) / overwrite=yes;
    method init();

    end;
    method run();
      declare integer x y z;
      declare varchar(5000) tempstr;
      set intyears; 
      by  LoopYear;
      Do x = 1 to 100000;
        if mod(x,10000) = 0 then put 'Thread: ' LoopYear ':' x ' a: ' a;
      end;     
    end;
    method term();
    end;
  endthread;
  run;
  data _null_;
    dcl thread MyThread MyThread;
    declare integer x;
 	declare integer a;
    method init();
      PUT 'Starting INIT';
      Do x = 1 to 800000;
        if mod(x,100000) = 0 then put 'Package: ' x;
      end;     
      a = 100;
      MyThread.setparms(a);
	  PUT 'Ending INIT';
    end;
    
    method run();
      set from MyThread threads=5;
    end;
    
    method term();
      PUT 'In Term';
    end;
    
  enddata;
run;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This produces the expected output - INIT ends before the MyThread begins.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 15 Apr 2021 21:55:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/734566#M228809</guid>
      <dc:creator>snoopy369</dc:creator>
      <dc:date>2021-04-15T21:55:37Z</dc:date>
    </item>
    <item>
      <title>Re: DS2 RUN method starting before INIT method is complete if the RUN method calls a thread</title>
      <link>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/734600#M228812</link>
      <description>&lt;P&gt;That is a great work around!&amp;nbsp; It even makes some sense in why it works.&amp;nbsp; Thanks!&lt;/P&gt;
&lt;P&gt;I still think it is a very illogical way for things to work however &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 15 Apr 2021 22:17:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/734600#M228812</guid>
      <dc:creator>CurtisMackWSIPP</dc:creator>
      <dc:date>2021-04-15T22:17:36Z</dc:date>
    </item>
    <item>
      <title>Re: DS2 RUN method starting before INIT method is complete if the RUN method calls a thread</title>
      <link>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/735310#M229065</link>
      <description>&lt;P&gt;I heard back from tech support on this.&amp;nbsp; It is designed behavior.&amp;nbsp; The RUN method never waits for the INIT method to complete.&amp;nbsp; It only appears this way because the statements in that method usually complete quickly. Here it the direct quote.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class="cs2654ae3a"&gt;&lt;SPAN class="cs1e88c66e1"&gt;&lt;SPAN style="font-size: 10.0pt;"&gt;The 5 threads that run the DS2 thread block are started during startup of the DS2 program execution.&amp;nbsp; &amp;nbsp;The 5 threads running the DS2 thread block and the 1 thread running the DS2 data block all run concurrently after startup.&amp;nbsp; The only synchronization between the threads running the DS2 thread block and the thread running DS2 data block is at the SET FROM statement.&amp;nbsp; The DS2 data block thread will wait at the SET FROM statement for a DS2 thread block thread to output a row of data.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="cs2654ae3a"&gt;&lt;SPAN class="cs1e88c66e1"&gt;&lt;SPAN style="font-size: 10.0pt;"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="cs2654ae3a"&gt;&lt;SPAN class="cs1e88c66e1"&gt;&lt;SPAN style="font-size: 10.0pt;"&gt;Some of the changes between 9.4M5 and 9.4M6 have resulted in the DS2 thread block threads starting quicker and thus the overlap between the threads is more apparent, but there has always been some overlap.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;</description>
      <pubDate>Mon, 19 Apr 2021 16:02:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/735310#M229065</guid>
      <dc:creator>CurtisMackWSIPP</dc:creator>
      <dc:date>2021-04-19T16:02:48Z</dc:date>
    </item>
    <item>
      <title>Re: DS2 RUN method starting before INIT method is complete if the RUN method calls a thread</title>
      <link>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/736396#M229397</link>
      <description>&lt;P&gt;I'm posting this to add to the knowledge base.&amp;nbsp; Tech support asked for the work around that Snoopy369 came up with.&amp;nbsp; I gave them the slightly simplified version at the bottom of this post.&amp;nbsp; Here is their explanation of why it works.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class="cs2654ae3a"&gt;&lt;SPAN class="cs1e88c66e1"&gt;&lt;SPAN style="font-size: 10.0pt;"&gt;The 5 threads that run the DS2 thread block are started during startup before the DS2 data block’s INIT method is called by the 1 thread running the DS2 DATA block.&amp;nbsp; If the DS2 thread block expects an argument value for a parameter, then the DS2 thread waits during its startup for the the DATA block thread to set the thread’s parameter values.&amp;nbsp; Eventually, the data block’s INIT method sets the thread’s parameter values, and then the DS2 thread block threads get the parameter values and finish their startup.&amp;nbsp; Note that if the DATA block does not call the SETPARMS method for whatever reason (maybe the SETPARMS call is inside an IF statement block that is bypassed), the SET FROM statement will set the thread’s parameter values to NULL or MISSING.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data intyears;
do LoopYear = 2001 to 2009;
    output;
  end;
run;

proc ds2;

  thread MyThread (int ready) / overwrite=yes;
    method init();

    end;
    method run();
      declare integer x y z;
      declare varchar(5000) tempstr;
      set intyears; 
      by  LoopYear;
      Do x = 1 to 100000;
        if mod(x,10000) = 0 then put 'Thread: ' LoopYear ':' x ;
      end;     
    end;
    method term();
    end;
  endthread;
  run;
  data _null_;
    dcl thread MyThread MyThread;
    declare integer x;
    method init();
      PUT 'Starting INIT';
      Do x = 1 to 800000;
        if mod(x,100000) = 0 then put 'Package: ' x;
      end;     
      MyThread.setparms(1);
       PUT 'Ending INIT';
    end;
    
    method run();
      set from MyThread threads=5;
    end;
    
    method term();
      PUT 'In Term';
    end;
    
  enddata;
run;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 22 Apr 2021 13:51:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/DS2-RUN-method-starting-before-INIT-method-is-complete-if-the/m-p/736396#M229397</guid>
      <dc:creator>CurtisMackWSIPP</dc:creator>
      <dc:date>2021-04-22T13:51:57Z</dc:date>
    </item>
  </channel>
</rss>

