Hi all,
I want to monitor the loop process to know to what extent has the loop finished. For example, I have to do a 10000 times loop, and the approximately time is around 5~8 hours, I want to periodically check how many times has the loop finished. I see the blog posted by Rick Wicklin "Using the MOD function as a debugging tool",
proc iml;
do i = 1 to 100;
x = sum(1:i);
if mod(i,10)=0 then do; /* print every 10 iterations */
print i x;
end;
end;
I want to do something like that, but the problem is that it only prints i and x after it is entirely finished. Is there any method which can print the i periodically during the processing? Thanks!
I don't know of an easy way to do this in PROC IML for the ODS output destinations. It's not just the DO loop that is causing this. When you submit a block of statements, the ODS system buffers up the output displays the output when the computations finish.
In the SAS/IML Studio application you can do this by using the PRINTNOW statement: The PRINTNOW Statement
Here is a work-around that might be helpful. If you only want to print out scalar quantities, you can use the PUT statement to output scalar quantities to the SAS Log. This should suffice for printing an iteration number:
proc iml;
start Report; /* print status to SAS Log */
file log;
put i x; /* works only for scalar values */
finish;
do i = 1 to 10;
x = sum(1:i);
if mod(i,2)=0 then do; /* print every 2 iterations */
run Report;
end;
call sleep(0.5,1); /* wait for 0.5 seconds */
end;
print i x;
Are you sure that PROC IML ". . . only prints i and x after it is entirely finished"? The example given would be expected to run very quickly so that it may only seem as if PROC IML prints the results only after it is entirely finished. If your own example that loops 10,000 times takes 5 hours [=300 minutes = 18,000 seconds] to complete, each loop takes an average of about 1.8 seconds to complete. Using MOD(i,10) would print after each 10 loops or 18 seconds, which you should be able to monitor by viewing the SAS output; bump it up to MOD(i, 100) to view this output every 3 minutes.
The OP is correct.
I remember writing a program a long time ago (I think I was working on a DEC Alpha with SAS 6 or 7), that used call push() and then a window statement to report monitoring stats when the user interrupted the program. Could something like that still work, or has the advent of ODS changed things?
You can still PAUSE and ask the user to continue:
PAUSE "Submit 'RESUME;' to continue";
That will flush the output buffer. However, I assumed the OP wanted a continuous monitor process that does not wait for human input.
I don't know of an easy way to do this in PROC IML for the ODS output destinations. It's not just the DO loop that is causing this. When you submit a block of statements, the ODS system buffers up the output displays the output when the computations finish.
In the SAS/IML Studio application you can do this by using the PRINTNOW statement: The PRINTNOW Statement
Here is a work-around that might be helpful. If you only want to print out scalar quantities, you can use the PUT statement to output scalar quantities to the SAS Log. This should suffice for printing an iteration number:
proc iml;
start Report; /* print status to SAS Log */
file log;
put i x; /* works only for scalar values */
finish;
do i = 1 to 10;
x = sum(1:i);
if mod(i,2)=0 then do; /* print every 2 iterations */
run Report;
end;
call sleep(0.5,1); /* wait for 0.5 seconds */
end;
print i x;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.