Real-time output from engines in IPython parallel? - ipython

I am running a bunch of long-running tasks with IPython's great parallelization functionality.
How can I get real-time output from the ipengines' stdout in my IPython client?
E.g., I'm running dview.map_async(fun, lots_of_args) and fun prints to stdout. I would like to see the outputs as they are happening.
I know about AsyncResult.display_output(), but it's only available after all tasks have finished.

You can see stdout in the meantime by accessing AsyncResult.stdout, which will return a list of strings, which are the stdout from each engine.
The simplest case being:
print ar.stdout
You can wrap this in a simple function that prints stdout while you wait for the AsyncResult to complete:
import sys
import time
from IPython.display import clear_output
def wait_watching_stdout(ar, dt=1, truncate=1000):
while not ar.ready():
stdouts = ar.stdout
if not any(stdouts):
continue
# clear_output doesn't do much in terminal environments
clear_output()
print '-' * 30
print "%.3fs elapsed" % ar.elapsed
print ""
for eid, stdout in zip(ar._targets, ar.stdout):
if stdout:
print "[ stdout %2i ]\n%s" % (eid, stdout[-truncate:])
sys.stdout.flush()
time.sleep(dt)
An example notebook illustrating this function.
Now, if you are using older IPython, you may see an artificial restriction on access of the stdout attribute ('Result not ready' errors).
The information is available in the metadata, so you can still get at it while the task is not done:
rc.spin()
stdout = [ rc.metadata[msg_id]['stdout'] for msg_id in ar.msg_ids ]
Which is essentially the same thing that the ar.stdout attribute access does.

just in case somebody is still struggling with
getting ordinary print-outputs of the individual kernels:
I adapted minrk's answer such that i get the output of each
kernel as if it would have been a local one by constantly checking if the stdout of each kernel changes while the program is running.
asdf = dview.map_async(function, arguments)
# initialize a stdout0 array for comparison
stdout0 = asdf.stdout
while not asdf.ready():
# check if stdout changed for any kernel
if asdf.stdout != stdout0:
for i in range(0,len(asdf.stdout)):
if asdf.stdout[i] != stdout0[i]:
# print only new stdout's without previous message and remove '\n' at the end
print('kernel ' + str(i) + ': ' + asdf.stdout[i][len(stdout0[i]):-1])
# set stdout0 to last output for new comparison
stdout0 = asdf.stdout
else:
continue
asdf.get()
outputs will then be something like:
kernel0: message 1 from kernel 0
kernel1: message 1 from kernel 1
kernel0: message 2 from kernel 0
kernel0: message 3 from kernel 0
kernel1: message 2 from kernel 0
...

Related

How can you write a supply with a dynamic throttle?

For a chat bot I'm refactoring to not require locks for managing most of its state, the website it connects to via websocket throttles messages that can be received from regular users to a rate of 0.6s and voiced users to a rate of 0.3s, while administrators have no throttle. Whether or not a user is voiced or an administrator isn't known until some point well after the connection gets made; before then, everyone is considered a regular user.
Currently, I handle throttled messages by putting the react block for listening for messages in a loop that exits once the connection has been forcibly closed. When the throttle gets updated, I call done to enter the next iteration, which updates the whenever block for the supply for messages to send to have the updated throttle. This is terrible, racy code!
What can I do to (a) ensure the connection starts out with a 0.3s throttle that can be used immediately after a websocket connection gets made, (b) make it possible to call a method that updates this throttle when needed, and (c) not keep any state related to this throttle (which can be inferred by other means)?
Edit: I forgot to mention this earlier, but there are unthrottled messages for all types of users, not just administrators.
I found a way to do this using a combination of Supply.migrate, Supply.map, and Supply.merge. If I create suppliers for throttled messages, unthrottled messages, and throttle updates, I can map over the throttle updates supply with throttled message supplies throttled using any throttles emitted, call Supply.migrate on the resulting supply, and merge it with the unthrottled messages supply. This results in one supply that I can use to handle sending all types of messages:
react {
my Supplier:D $unthrottled .= new;
my Supplier:D $throttled .= new;
my Supplier:D $throttles .= new;
whenever Supply.merge(
$unthrottled.Supply,
$throttles.Supply.map({ $throttled.Supply.throttle: 1, $_ }).migrate,
) -> Str:D $message {
say sprintf '%s # %f', $message, now;
done if ++$ == 12;
}
$throttles.emit: 1.2;
$throttled.emit: "$_" for 1..3;
whenever Promise.in(1) {
$unthrottled.emit: "$_" for 7..9;
}
whenever Promise.in(5) {
$throttles.emit: 0.6;
$throttled.emit: "$_" for 4..6;
whenever Promise.in(1) {
$unthrottled.emit: "$_" for 10..12;
}
}
}
# OUTPUT:
# 1 # 1579731916.713831
# 7 # 1579731917.764047
# 8 # 1579731917.769012
# 9 # 1579731917.774584
# 2 # 1579731917.913512
# 3 # 1579731919.123057
# 4 # 1579731921.749377
# 5 # 1579731922.353073
# 10 # 1579731922.768212
# 11 # 1579731922.773777
# 12 # 1579731922.780446
# 6 # 1579731922.963087
Interesting. I gave it a go and from what I read in the documentation, which is sparse, something like the following should work:
my $s = Supply.from-list(^Inf);
my $control = Supplier.new.Supply;
my $throttle = $s.throttle( 10, 1, :$control );
react
{
whenever $throttle -> $n
{
$n.say
};
# change speed every 5 seconds
whenever Supply.interval(5) -> $x
{
"limit: { (1..10).pick }".say;
$control.emit( "limit: { (1..10).roll }" );
}
}
But it doesn't. The program freezes when it hits $control.emit( ... ). If you comment that out, it runs as expected. Relevant doc parts of the throttle method:
Produces a Supply from a given Supply, but makes sure the number of messages passed through, is limited.
[ ... ]
If the second positional parameter is a numeric value, it is interpreted as the time-unit (in seconds). If you specify .1 as the value, then it makes sure you don't
exceed the limit for every tenth of a second.
[ ... ]
The :control named parameter optionally specifies a Supply that you can use to
control the throttle while it is in operation. Messages that can be
sent, are strings in the form of "key:value".
[ ... ]
These messages can be sent to the :control Supply. A control message consists of a string of the form "key: value", e.g. "limit: 4".

Am trying to read a population_data.json file but when ever i run the code it doesn't display any data in the file and i don't get any Error too?

import json
#Load the data into a list.
filename = 'population_data.json'
with open(filename)as f:`enter code here`
pop_data = json.load(f)
enter code here
#Print the 2010 population data for each country.
for pop_dict in pop_data:`enter code here`
if pop_dict['Year'] == '2010':
country_name = pop_dict['Country Name']
population = int(float(pop_dict['Value']))
print(country_name + " : " + str(population))
Am trying to extract data from a population_data.json file, but whenever i run my code it doesn't show any result and i don't get any Errors, i have save the population data file in the same folder with the code but i still have that same problem, i don't get any result of the data in the shell. i would be glad if someone can help.Thank you .
enter code here
import json
#Load the data into a list.
filename = 'population_data.json'
with open(filename)as f:`enter code here`
pop_data = json.load(f)
enter code here
#Print the 2010 population data for each country.
for pop_dict in pop_data:`enter code here`
if pop_dict['Year'] == '2010':
country_name = pop_dict['Country Name']
population = int(float(pop_dict['Value']))
print(country_name + " : " + str(population))
I would suggest starting your script in the python debugger (pdb). You can start it either by starting your script like this:
python3 -m pdb your_script.py
or by importing the pdb module. Adding the following line into your python file (for example after import json, or any other):
import pdb; pdb.set_trace()
Once it is loaded, the debugger stops at the first instruction and shows the debugger promt (Pdb) . Continue execution line by line by typing next and hitting ENTER until you hit a line where something interesting is happening. The debugger prints always the next instruction and the script path and line.
Debugger output is added below, everything after (Pdb) you have to type and confirm with ENTER
(Pdb) next
> /path/to/your_script.py(7)<module>()
-> pop_data = json.load(f)
(Pdb) next
> /path/to/your_script.py(11)<module>()
-> for pop_dict in pop_data:
Now let the debugger print contents of a variable
(Pdb) p pop_data
{"Probably": "something", "you": "don't expect here"}
I suspect either the for loop yields 0 pop_dicts and therefore the loop body is never executed, or no pop_dict key Year has value 2010 and the if body is never executed.
Alternative to type next often (== single stepping): set a break point on a specific line (your_script.py:11), and continue execution until the breakpoint is hit
(Pdb) break your_script.py:11
Breakpoint 1 at /path/to/your_script.py:11
(Pdb) continue
> /path/to/your_script.py(11)<module>()
-> for pop_dict in pop_data:
(Pdb)
For additional debugger commands see pdb commands

Qbasic reading comport reply without newline

I'm working on reading device reply using QBasic. The problem is the qbasic wait for the newline or CHR$(13) before outputting the data but my device reply don't have CHR$(13) (example: "OK") so qbasic hang waiting for newline.
How can i get the reply or read comport even without newline? is this possible?
[EDIT]
CLS
OPEN "com2:9600,n,8,1,BIN,cs,ds,rs" FOR RANDOM AS #1
param$ ="Some data"
PRINT #1, param$
DO WHILE b$ <> "*CLOSE*"
INPUT #1, b$
PRINT b$
LOOP
That is my code but in that code it can't read *CLOSE* because no newline after *CLOSE*.
And another thing the device delay 5 sec before replying.
Could you give an example of your code? I suspect you are using INPUT#n , but maybe instead you should use INPUT$(x). I found an example here, see code below
a$ = ""
DO
IF LOC(1) THEN a$ = a$ + INPUT$(1, 1)
LOOP UNTIL INSTR(a$, "OK")
This code sample demonstrates accessing modem in Basic.
REM Reset modem source:
CLS
OPEN "COM2:9600,N,8,1,BIN,CS,DS,RS" FOR RANDOM AS #1
Reset$ = "ATZ" + CHR$(13) + CHR$(10)
PRINT #1, Reset$;
Inp$ = ""
DO
IF LOC(1) THEN
Inp$ = Inp$ + INPUT$(1, 1)
IF INSTR(Inp$, "OK") THEN
PRINT "Modem reset."
EXIT DO
END IF
END IF
LOOP
END

Different value when using fprintf or sprintf

I've written a function (my first, so don't be too quick to judge) in MATLAB, which is supposed to write a batch file based on 3 input parameters:
write_BatchFile(setup,engine,np)
Here setup consists of one or more strings, engine consists of one string only and np is a number, e.g.:
setup = {'test1.run';'test2.run';'test3.run'};
engine = 'Engine.exe';
np = 4; % number of processors/cores
I'll leave out the first part of my script, which is a bit more extensive, but in case necessary I can provide the entire script afterwards. Anyhow, once all 3 parameters have been determined, which it does successfully, I wrote the following, which is the last part of my script:
%==========================================================================
% Start writing the batch file
%==========================================================================
tmpstr = sprintf('\nWriting batch file batchRunMPI.bat...');
disp(tmpstr); clear tmpstr;
filename = 'batchRunMPI.bat';
fid = fopen(filename,'w');
fprintf(fid,'set OMP_NUM_THREADS=1\n');
for i = 1:length(setup);
fprintf(fid,'mpiexec -n %d -localonly "%s" "%s"\n',np,engine,setup{i});
fprintf(fid,'move %s.log %s.MPI_%d.log\n',setupname{i},setupname{i},np);
end
fclose all;
disp('Done!');
NOTE setupname follows using fileparts:
[~,setupname,setupext] = fileparts(setup);
However, when looking at the resulting batch file I end up getting the value 52 where I indicate my number of cores (= 4), e.g.:
mpiexec -n 52 -localonly "Engine.exe" "test1.run"
mpiexec -n 52 -localonly "Engine.exe" "test2.run"
mpiexec -n 52 -localonly "Engine.exe" "test3.run"
Instead, I'd want the result to be:
mpiexec -n 4 -localonly "Engine.exe" "test3.run", etc
When I check the value of np it returns 4, so I'm confused where this 52 comes from.
My feeling is that it's a very simple solution which I'm just unaware of, but I haven't been able to find anything on this so far, which is why I'm posting here. All help is appreciated!
-Daniel
It seems that at some stage np is being converted to a string. The character '4' has the integer value 52, which explains what you're getting. You've got a few options:
a) Figure out where np is being converted to a string and change it
b) the %d to a %s, so you get '4' instead of 52
c) change the np part of the printf statement to str2double(np).

Use of diff command from tcl script captures error 'child process exited abnormally'

In tcl script I am using diff command to compare the files line by line
if {[catch {eval exec "diff /tmp/tECSv2_P_HTTP_XHDR_URL_FUNC_12.itcl /tmp/tempReformat"} results]} {
puts "$results"
}
Output of diff command is obtained properly but it catches error 'child process exited abnormally'
Output:
==>tclsh diffUsingScript
992c992
< fail "Redirection is not reflected in css messages"
---
> fail "Redirection is not reflected in css messages"
child process exited abnormally
So whats going wrong due to which this error is obtained. I want diff operation to be error free in my tcl script
From my diff(1): "Exit status is 0 if inputs are the same, 1 if different, 2 if trouble."
Since non-zero returns are the usual way to report errors in shell scripts, tcl and diff disagree on the meaning of the return result. It's probably really convenient for writing shell scripts to know whether or not two files are different from the return value, but I don't see any mechanism to disable that from the manpage. (I'd rather use cmp -q for just getting whether or not two files are different, not sure why the diff people made the decision they did.)
But you can bludgeon this into working by appending ; true to your command.
A more artful way to make it work would be to error only on an exit code of 2: diff foo bar ; if [ $? -ne 2 ]; then true ; else false; fi;
Check the results with different filenames and echo $? after each test to see which ones are returning 0 (from true) and which ones are returning 1 (from false).
The way to handle this in Tcl is:
set rc [catch {exec diff f1 f2} output]
if {$rc == 0} {
puts "no difference"
} else {
if {[lindex $::errorCode 0] eq "CHILDSTATUS"} {
if {[lindex $::errorCode 2] == 1} {
puts "difference"
# show output without "child process exited abnormally" message
puts [string replace $output end-31 end ""]
} else {
puts "diff error: $output"
}
} else {
puts "error calling diff: $output"
}
}
See the discussion on the Tcl Wiki exec page.