Statistical programming, matrix languages, and more

Interrupting IML

Reply
Frequent Contributor
Posts: 143

Interrupting IML

In general when I press the Break button to interrupt a CPU intensive IML program, I find that it is extremely unresponsive.  If I am patient it will run for many minutes before it releases control back to me, so instead I resort to killing SAS in the Windows Task Manager, but only provided I have remembered to save what I was doing!

I have fudged a way around this.  In my main program loop, I am considering using syntax like:

    do i = 1 to 1E10;
      if mod(i, 1E5) = 0 then do;
        call push("resume;");
        pause;
      end;
      < do stuff here >
    end;

In my tests, this does make IML much more responsive to pressing the break button. But you either have to put up with the flood of notes to the log window, or kill notes for the whole program.  Is there a better way?  A system option perhaps? A different way of structuring my IML program?  I am using 9.4 in Windows 7.

SAS Super FREQ
Posts: 3,620

Re: Interrupting IML

That's an interesting problem (and solution).  When your program is deep inside a compuational routine (say, an eigenvector computation), it can't check for an interrupt.  So the more efficient your code is, the worse this problem will be.

I think you can use the EXECUTE statement to implement the flavor or your solution without experiencing the NOTES/Log problem.  I don't think the statement that you execute is important, but try this:

   if mod(i, 1E5) = 0 then do;

     call execute("_t=time();");

   end;

Frequent Contributor
Posts: 143

Re: Interrupting IML

Thanks Rick, the call execute trick does work for me.

I suspect IML on my machine is checking for interrupts less frequently than you imagine.  If  I run :

    do i = 1 to 2E8;

      j = i;

    end;

then it takes a little less than 30 secs CPU to complete without interruption.   However if  I press the break button 2 seconds into the run, it appears to ignore it until the loop has completed, since the log always reports about the same CPU time after "user asked for termination".

SAS Super FREQ
Posts: 3,620

Re: Interrupting IML

Oh, I realize that IML doesn't check for interrupts very frequently. By design, IML is optimized to execute quickly. It compiles the entire DO loop and then executes it as a unit.  That is why a DO loop in IML is not as expensive as in some other matrix-vector languages.

You might also try CALL EXECUTE(";"), which would have no side effects. [Untested idea.]

Another thought: You could write a macro that would replace the single loop with multiple loops. For example,

%SplitLoops(i=1 to 1E8,  10, <code>);

could resolve to 10 DO loops that each execute <code>. The first loop is i=1 to 1e7, the next is i=1e7+1 to 2e7, and so forth.

You might find it interesting that SAS/IML Studio, which has a client-server architecture, handles interrupts differently.  Programs that are submitted through SAS/IML Studio check for interrupts more frequently, and therefore are more responsive to user interruptions.  This suggests that you might want to use SAS/IML Studio to test and debug your IML program.

Frequent Contributor
Posts: 143

Re: Interrupting IML

Thanks, I think have a much better understanding now.  Is it the case that nested loops get compiled as a single unit and therefore can not be interrupted?  So the loop slicing trick will only work on the outer most loop?

Now I know the issues, I think I am comfortable managing it myself with call execute. The empty command does work by the way, so if I use:

DoEvents=";";

and then at various points later on:


call execute(DoEvents);

it should make the purpose clear to others.

SAS Super FREQ
Posts: 3,620

Re: Interrupting IML

Yes, nested loops get compiled and executed as a unit, so you would want to break up the outermost loop.

Ask a Question
Discussion stats
  • 5 replies
  • 410 views
  • 1 like
  • 2 in conversation