Command timeouts in Julia - julia

I have a Julia script that repeatedly calls a C++ program to perform an optimization. The C++ program writes a text file, then I have Julia read the results and decide what to do next. The problem is that occasionally (maybe 1 in 1000+ times) the C++ program freezes (the optimization probably gets stuck), and my entire script hangs indefinitely, making it very difficult for the script to make it through all necessary program calls. Is there a way I can add a timeout, so that if the program has not finished within 10 minutes I can restart with a new guess value?
Simplified example:
for k = 1:10
run(`program inputs`)
end
Desired:
max_runtime = 10*60 # 10 minutes
for k = 1:10
run(`program inputs`,max_runtime)
end
Alternative:
max_runtime = 10*60 # 10 minutes
for k = 1:10
deadline(function,max_runtime)
end

How about something like:
max_runtime = 10*60 # 10 minutes
for k = 1:10
proc = spawn(`program inputs`)
timedwait(() -> process_exited(proc), max_runtime)
if process_running(proc)
kill(proc)
end
end

Related

How to store the output of #time to a variable?

Is possible to store the time displayed with #time in a variable ?
For example the following code
for i in 1:10
#time my_function(i)
end
displays the wall time of my function my_function, but I would like to store the number of milliseconds in an array instead, in order to display it in a plot showing the evolution of the execution time regarding the parameter i.
The simplest is to use #elapsed, e.g.:
julia> [#elapsed rand(5^i) for i in 1:10]
10-element Vector{Float64}:
3.96e-6
4.64e-7
7.55e-7
3.909e-6
4.43e-6
1.5367e-5
7.0791e-5
0.000402877
0.001831287
0.071062595
and if you use BenchmarkTools.jl then there is also #belapsed macro there for more accurate benchmarking than #elapsed.
EDIT:
#time: is printing the time it took to execute, the number of allocations, and the total number of bytes its execution caused to be allocated, before returning the value of the expression. Any time spent garbage collecting (gc) or compiling is shown as a percentage.
#elapsed: discarding the resulting value, instead returning the number of seconds it took to execute as a floating-point number
I would like to add another example using #elapsed begin to show how it can be used to time multiple lines of code:
dt = #elapsed begin
x = 1
y = 2
z = x^2 + y
print(z)
end
Additionally, if this is not for benchmarking code and you just want time as an output you can alternatively use time():
t = time()
x = 1
y = 2
z = x^2 + y
print(z)
dt = time() - t

Writing a chunk of MPI distributed data via hdf5 in fortran

I have a 3d array distributed into different MPI processes:
real :: DATA(i1:i2, j1:j2, k1:k2)
where i1, i2, ... are different for each MPI process, but the MPI grid is cartesian.
For simplicity let's assume I have a 120 x 120 x 120 array, and 27 MPI processes distributed as 3 x 3 x 3 (so that each processor has an array of size 40 x 40 x 40).
Using hdf5 library I need to write only a slice of that data, say, a slice that goes through the middle perpendicular to the second axis. The resulting (global) array would be of size 120 x 1 x 120.
I'm a bit confused on how to properly use the hdf5 here, and how to generalize full DATA writing (which I can do). The problem is, not each MPI thread is going to be writing. For instance, in the case above, only 9 processes will have to write something, others (which are on the +/-x and +/-z edges of the cube) will not have to, since they don't contain any chunk of the slab I need.
I tried the chunking technique described here, but it looks like that's just for a single thread.
Would be very grateful if the hdf5 community can help me in this :)
When writing an HDF5 dataset in parallel, all MPI processes must participate in the operation (even if a certain MPI process does not have values to write).
If you are not bound to a specific library, take a look at HDFql. Based on what I could understand from the use-case you have posted, here goes an example on how to write data in parallel in Fortran using HDFql.
PROGRAM Example
! use HDFql module (make sure it can be found by the Fortran compiler)
USE HDFql
! declare variables
REAL(KIND=8), DIMENSION(40, 40, 40) :: values
CHARACTER(2) :: start
INTEGER :: state
INTEGER :: x
INTEGER :: y
INTEGER :: z
! create an HDF5 file named "example.h5" and use (i.e. open) it in parallel
state = hdfql_execute("CREATE AND USE FILE example.h5 IN PARALLEL")
! create a dataset named "dset" of data type double of three dimensions (size 120x120x120)
state = hdfql_execute("CREATE DATASET dset AS DOUBLE(120, 120, 120)");
! populate variable "values" with certain values
DO x = 1, 40
DO y = 1, 40
DO z = 1, 40
values(z, y, x) = hdfql_mpi_get_rank() * 100000 + (x * 1600 + y * 40 + z)
END DO
END DO
END DO
! register variable "values" for subsequent use (by HDFql)
state = hdfql_variable_register(values)
IF (hdfql_mpi_get_rank() < 3) THEN
! insert (i.e. write) values from variable "values" into dataset "dset" using an hyperslab in function of the MPI rank (each rank writes 40x40x40 values)
WRITE(start, "(I0)") hdfql_mpi_get_rank() * 40
state = hdfql_execute("INSERT INTO dset(" // start // ":1:1:40) IN PARALLEL VALUES FROM MEMORY 0")
ELSE
! if MPI rank is equal or greater than 3 nothing is written
state = hdfql_execute("INSERT INTO dset IN PARALLEL NO VALUES")
END IF
END PROGRAM
Please check HDFql reference manual to get additional information on how to work with HDF5 files in parallel (i.e. with MPI) using this library.

R - Sys.time() and as.POSIXct() issue [duplicate]

I want to run a R code at a specific time that I need.
And after the process finished, I want to terminate the R session.
If a code is as below,
tm<-Sys.time()
write.table(tm,file='OUT.TXT', sep='\t');
quit(save = "no")
What should I do to run this code at "2012-04-18 17:25:40".
I need your help. Thanks in advance.
It is easiest to use the Task Scheduler of Windows, or a cron job under Linux. There you can specify a command or program that should be run at a certain time you specify.
If somehow you cannot use the cron job service and have to schedule within R, the following R code shows how to wait a specific amount of time so as to execute at a pre-specified target time.
stop.date.time.1 <- as.POSIXct("2012-12-20 13:45:00 EST") # time of last afternoon execution.
stop.date.time.2 <- as.POSIXct("2012-12-20 7:45:00 EST") # time of last morning execution.
NOW <- Sys.time() # the current time
lapse.time <- 24 * 60 * 60 # A day's worth of time in Seconds
all.exec.times.1 <- seq(stop.date.time.1, NOW, -lapse.time) # all of afternoon execution times.
all.exec.times.2 <- seq(stop.date.time.2, NOW, -lapse.time) # all of morning execution times.
all.exec.times <- sort(c(all.exec.times.1, all.exec.times.2)) # combine all times and sort from recent to future
cat("To execute your code at the following times:\n"); print(all.exec.times)
for (i in seq(length(all.exec.times))) { # for each target time in the sequence
## How long do I have to wait for the next execution from Now.
wait.time <- difftime(Sys.time(), all.exec.times[i], units="secs") # calc difference in seconds.
cat("Waiting for", wait.time, "seconds before next execution\n")
if (wait.time > 0) {
Sys.sleep(wait.time) # Wait from Now until the target time arrives (for "wait.time" seconds)
{
## Put your execution code or function call here
}
}
}

How do you do parallel matrix multiplication in Julia?

Is there a good way to do parallel matrix multiplication in julia? I tried using DArrays, but it was significantly slower than just a single-thread multiplication.
Parallel in what sense? If you mean single-machine, multi-threaded, then Julia does this by default as OpenBLAS (the underlying linear algebra library used) is multithreaded.
If you mean multiple-machine, distributed-computing-style, then you will be encountering a lot of communications overhead that will only be worth it for very large problems, and a customized approach might be needed.
The problem is most likely that direct (maybe single-threaded) matrix-multiplication is normally performed with an optimized library function. In the case of OpenBLAS, this is already multithreaded. For arrays with size 2000x2000, the simple matrixmultiplication
#time c = sa * sb;
results in 0.3 seconds multithreaded and 0.7 seconds singlethreaded.
Splitting of a single dimension in multiplication the times get even worse and reach around 17 seconds in singlethreaded mode.
#time for j = 1:n
sc[:,j] = sa[:,:] * sb[:,j]
end
shared arrays
The solution to your problem might be the use of shared arrays, which share the same data across your processes on a single computer. Please note that shared arrays are still marked as experimental.
# create shared arrays and initialize them with random numbers
sa = SharedArray(Float64,(n,n),init = s -> s[localindexes(s)] = rand(length(localindexes(s))))
sb = SharedArray(Float64,(n,n),init = s -> s[localindexes(s)] = rand(length(localindexes(s))))
sc = SharedArray(Float64,(n,n));
Then you have to create a function, which performs a cheap matrix multiplication on a subset of the matrix.
#everywhere function mymatmul!(n,w,sa,sb,sc)
# works only for 4 workers and n divisible by 4
range = 1+(w-2) * div(n,4) : (w-1) * div(n,4)
sc[:,range] = sa[:,:] * sb[:,range]
end
Finally, the main process tells the workers to work on their part.
#time #sync begin
for w in workers()
#async remotecall_wait(w, mymatmul!, n, w, sa, sb, sc)
end
end
which takes around 0.3 seconds which is the same time as the multithreaded single-process time.
It sounds like you're interested in dense matrices, in which case see the other answers. Should you be (or become) interested in sparse matrices, see https://github.com/madeleineudell/ParallelSparseMatMul.jl.

I want to run a R code at a specific time

I want to run a R code at a specific time that I need.
And after the process finished, I want to terminate the R session.
If a code is as below,
tm<-Sys.time()
write.table(tm,file='OUT.TXT', sep='\t');
quit(save = "no")
What should I do to run this code at "2012-04-18 17:25:40".
I need your help. Thanks in advance.
It is easiest to use the Task Scheduler of Windows, or a cron job under Linux. There you can specify a command or program that should be run at a certain time you specify.
If somehow you cannot use the cron job service and have to schedule within R, the following R code shows how to wait a specific amount of time so as to execute at a pre-specified target time.
stop.date.time.1 <- as.POSIXct("2012-12-20 13:45:00 EST") # time of last afternoon execution.
stop.date.time.2 <- as.POSIXct("2012-12-20 7:45:00 EST") # time of last morning execution.
NOW <- Sys.time() # the current time
lapse.time <- 24 * 60 * 60 # A day's worth of time in Seconds
all.exec.times.1 <- seq(stop.date.time.1, NOW, -lapse.time) # all of afternoon execution times.
all.exec.times.2 <- seq(stop.date.time.2, NOW, -lapse.time) # all of morning execution times.
all.exec.times <- sort(c(all.exec.times.1, all.exec.times.2)) # combine all times and sort from recent to future
cat("To execute your code at the following times:\n"); print(all.exec.times)
for (i in seq(length(all.exec.times))) { # for each target time in the sequence
## How long do I have to wait for the next execution from Now.
wait.time <- difftime(Sys.time(), all.exec.times[i], units="secs") # calc difference in seconds.
cat("Waiting for", wait.time, "seconds before next execution\n")
if (wait.time > 0) {
Sys.sleep(wait.time) # Wait from Now until the target time arrives (for "wait.time" seconds)
{
## Put your execution code or function call here
}
}
}

Resources