What does OpenMP structured-block mean in fortran? - syntax

What does openMP structured-block mean in fortran?
Using the sections construct as an example:
!$omp sections
!$omp section
structured-block
!$omp section
structured-block
...
!$omp end sections
Can I have multiple commands under each section like this?
!$omp sections
!$omp section
command 1
command 2
command 3
!$omp section
command 4
command 5
command 6
...
!$omp end sections
Is this a correct use of the sections construct and more specifically "structured-block"?

A "block of executable statements with a single entry at the top and a single exit at the bottom" means that you do not use goto to transfer control to a label inside the block and do not use goto to transfer control to a label outside the block.
!$omp section
call foo()
bar = baz
qux = bar
!$omp section
...
is fine if foo() returns.
!$omp section
bar = foo()
if (bar == baz) then
goto qux
end if
!$omp section
...
qux: ...
is not fine.
You can have a loop inside as long as its entire body is contained in the block and you can call functions and subroutines as long as they return.

Related

Ruby: Forwarding variable number of parameters including optional block to a different function

I'm using a library function, which can be called in various ways - with a variable number of parameters, a block, or both, i.e. all of the following calls are valid:
libfunc
libfunc(1,2,3)
libfunc { 1 }
libfunc(1,2,3,4,5) { 6 }
Now I would write a function, which accepts the identical parameters as libfunc, invokes libfunc with these parameters (including the block), but does some preprocessing and postprocessing around this.
I ended up with this code:
def mylibfunc(*args)
# .... do preprocessing
if block_given?
libfunc(*args) {yield}
else
libfunc(*args)
end
# .... do postprocessing
end
I find this design ugly. Isn't there a way to write this in a more concise way, avoiding the block_given? query?
You can indicate a block argument by & and pass it to the other method:
def mylibfunc(*args, &block)
libfunc(*args, &block)
end

Ruby while and cond related clarification

In the following code:
def my_while(cond, &body)
while cond.call
body.call
end
end
a = 0
my_while -> { a < 3 } do
puts a
a += 1
end
What is the purpose of
def my_while(cond, &body)
while cond.call
body.call
and how is that affecting the loop?
The arguments to my_while are being processed as blocks.
The cond argument, which is the comparison { a < 3 }, is being executed by the call as the test condition in the while within the function. Each time that is true, the second argument, &body, is being executed.
It's a really complicated way of writing a while loop but is apparently being used to demonstrate passing around code blocks which can be quite useful in metaprogramming applications.

Ruby Variable Reference Issue

I am not fluent in ruby and am having trouble with the following code example. I want to pass the array index to the thread function. When I run this code, all threads print "4". They should instead print "0 1 2 3 4" (in any order).
It seems that the num variable is being shared between all iterations of the loop and passes a reference to the "test" function. The loop finishes before the threads start and num is left equal to 4.
What is going on and how do I get the correct behavior?
NUM_THREADS = 5
def test(num)
puts num.to_s()
end
threads = Array.new(NUM_THREADS)
for i in 0..(NUM_THREADS - 1)
num = i
threads[i] = Thread.new{test(num)}
end
for i in 0..(NUM_THREADS - 1)
threads[i].join
end
Your script does what I would expect in Unix but not in Windows, most likely because the thread instantiation is competing with the for loop for using the num value. I think the reason is that the for loop does not create a closure, so after finishing that loop num is equal to 4:
for i in 0..4
end
puts i
# => 4
To fix it (and write more idiomatic Ruby), you could write something like this:
NUM_THREADS = 5
def test(num)
puts num # to_s is unnecessary
end
# Create an array for each thread that runs test on each index
threads = NUM_THREADS.times.map { |i| Thread.new { test i } }
# Call the join method on each thread
threads.each(&:join)
where i would be local to the map block.
"What is going on?" => The scope of num is the main environment, so it is shared by all threads (The only thing surrounding it is the for keyword, which does not create a scope). The execution of puts in all threads was later than the for loop on i incrementing it to 4. A variable passed to a thread as an argument (such as num below) becomes a block argument, and will not be shared outside of the thread.
NUM_THREADS = 5
threads = Array.new(NUM_THREADS){|i| Thread.new(i){|num| puts num}}.each(&:join)

What does Ruby's BEGIN do?

What does BEGIN mean in Ruby, and how is it called? For example, given this code:
puts "This is sentence 1."
BEGIN {
puts "This is sentence 2."
}
why is puts "This is sentence 2." executed first?
BEGIN and END set up blocks that are called before anything else gets executed, or after everything else, just before the interpreter quits.
For instance, running this:
END { puts 'END block' }
puts 'foobar'
BEGIN { puts 'BEGIN block' }
Outputs:
BEGIN block
foobar
END block
Normally we'd use a bit more logical order for the BEGIN and END blocks, but that demonstrates what they do.
From the Ruby docs for the BEGIN keyword:
BEGIN: Designates, via code block, code to be executed unconditionally before sequential execution of the program begins. Sometimes used to simulate forward references to methods.
BEGIN and END Blocks
Every Ruby source file can declare blocks of code to be run as the file is being loaded (the BEGIN blocks) and after the program has finished executing (the END blocks).
BEGIN {
begin block code
}
END {
end block code
}
A program may include multiple BEGIN and END blocks. BEGIN blocks are executed in the order they are encountered. END blocks are executed in reverse order.
You can find almost the same post in "Does begin . . . end while denote a 'block'?".
Read more about blocks on tutorialspoint

re-design this parallel pseudo code more DRY

I have in mind a design problem that does not look like complex, but I can't find by myself a way to solve it. I would like to follow as much as possible the DRY principle.
I have got two functions. One is the basic version of the algorithm, the other one is an improvement with parallel programming. They are two, and my aim is to write only one of them with an additional parameter, e.g., "parallel". Here the pseudo codes.
fun1 ()
loop for par1 times
do_work()
fun2 ()
loop for par1 times
run new thread
do_work()
Currently I have coded
if parallel == 0
fun1 ()
else
fun2 ()
What I want is something like
fun ()
loop for par1 times
run new thread if parallel > 0 #Ruby's syntax-like
do_work()
I was wondering if Ruby may help me solving this issue. I am a newbie of Ruby so I am not sure its functional programming could make the difference.
Just like this:
def fun(parallel=false)
if parallel
# called as fun(true)
else
# called as fun
end
end
parallel=false sets the default argument value if no argument is passed.
Or you could use an options hash to pass the parameters more explicitly
def fun(options={})
parallel = option[:parallel] || false
if parallel
# called as fun(parallel: true)
else
# called as fun
end
end
Another approach is to always run do_work() in a thread and to wait for the thread to finish depending on the parallel parameter.
def fun(parallel=false)
workers = []
par1.times do
worker = Thread.new { do_work() }
worker.join if parallel
workers << worker
end
workers.each(&:join)
end

Resources