Sending Array to a Single Process - mpi

I have an array with size nx*ny. The data in the array is in nrows*ncols processes. I want to send all the various parts of the array to a single array in a single process, say process 0.
I do it this way: I perform two do loops one the on nrows with variable x and another one inside that on the ncols with variable y. In each loop I find the process that has the row and coloumn same as x and y and use mpi_isend to send the data to process 0 and after that, again inside the same loop process 0 recevies the subarray by mpi_irecv.
I actually tried this and the problem is process 0 keeps receiving data that are not still sent! I even tried using mpi_barrier without success. Below is my code. Can anyone help me please? Thanks.
do x=0,grid%nrows
do y=0,grid%ncols
! Finding the relevant process and sending
if ((grid%row==x) .and. (grid%col==y)) then
call MPI_ISEND(tempp,ctot,MPI_DOUBLE_PRECISION,0, &
& grid%proc,MPI_COMM_WORLD,ierr)
end if
! Process 0 receives data
if (grid%proc==0) then
call MPI_IRECV(temp0(2*grid%xl:2*grid%xl+2*grid%mx-1, &
& :,1:size(v%a,4)), &
& ctot,MPI_DOUBLE_PRECISION, &
& x*grid%ncols+y,x*grid%ncols+y,MPI_COMM_WORLD,stat,ierr)
end if
end do
end do

mpi_Irecv and mpi_Isend are non-blocking functions. This means, that these function calls return before the transmission is completed. To solve your problem, you can either
use the blocking versions, mpi_Recv and mpi_Send or
add mpi_Wait calls to your solution to wait for the non-blocking calls to finish.

Related

Comparing datetimes in delphi

I am developing a quizing game in Delphi and I would like to have a timer so that players don´t have unlimited time to answer the questions. I am using the function "Time" to get the current time but I don´t know how to convert it to something like an integer so that when let´s say 10 seconds have passed the player loses it´s chance. It would look like something like this:
Var
CurrentTime,Aux:TDateTime;
Begin
CurrentTime:=Time; //Current Time is assigned to a global variable.
Aux:=CurrentTime;
While (Aux-10000<=CurrentTime) do
Begin
if (Answer:=True) then //If the answer is already given by the player we break the while loop
Break;
Aux:=Time; //We refresh the auxilary variable
if (Aux-10000>=CurrentTime) then //We check if 10 seconds have passed
Begin
showmessage('You have taken too much time, your turn is lost');
exit; //We leave the script
end;
end;
end;
The problem is I can´t do arithmetic operations in DateTimes, as far as I know, So I need a different method for comparing the 2 different time instances. Any help would be appreciated, thanks!
TDate, TTime, and TDateTime are implemented using floating-point numbers, so you can perform arithmetic operations on them.
But you really shouldn't, in this case. The DateUtils unit has many functions for working with date/time values, eg:
uses
..., DateUtils;
var
StartTime, Aux: TDateTime;
begin
StartTime := Time();
Aux := StartTime;
...
while (not Answer) and (MillisecondsBetween(Aux, StartTime) < 10000) do
begin
Sleep(0);
Aux := Time();
end;
if (not Answer) then
begin
ShowMessage('You have taken too much time, your turn is lost');
Exit; //We leave the script
end;
...
end;
Note that this is not really a good use for TDateTime. Your calculations are relying on the system clock in local time being accurate and unchanging, but it can be changed dynamically while your code is running (user updates, network updates, daylight saving time change, etc), throwing off the results.
Consider using TStopWatch instead. It is intended for exactly this kind of use-case (determining elapsed time between actions), eg:
uses
..., System.Diagnostics;
var
SW: TStopWatch;
begin
SW := TStopWatch.StartNew;
...
while (not Answer) and (SW.ElapsedMilliseconds < 10000) do
Sleep(0);
if (not Answer) then
begin
ShowMessage('You have taken too much time, your turn is lost');
Exit; //We leave the script
end;
...
end;
Or, you could use TEvent instead, and have the answer signal the event when ready, eg:
uses
..., SyncObjs;
var
AnsweredEvent: TEvent;
...
// when the answer is submitted:
AnsweredEvent.SetEvent;
...
begin
AnsweredEvent.ResetEvent;
...
if AnsweredEvent.WaitFor(10000) <> wrSignaled then
begin
ShowMessage('You have taken too much time, your turn is lost');
Exit; //We leave the script
end;
end;
initialization
AnsweredEvent := TEvent.Create;
finalization
AnsweredEvent.Free;
I have written a few applications like this, using a TTimer. The timer's interval is set to 1000, which is equivalent to 1 second (you can use a different value); every time the timer's OnTimer event executes, a global variable is incremented which is then checked against the time limit (10 seconds?); if the variable equals this limit then first the timer is stopped, then the code performs whatever is necessary to transfer to the next person, or next question.
There should be similar code that executes when the person enters an answer as this code too needs to first save the answer then transfers to the next person. This portion should also stop the timer.
The 'show next question' part should restart the timer and reset the global variable only after the next question has been displayed, as it might take some time for it to be fetched.

Count attempts in airflow sensor

I have a sensor that waits for a file to appear in an external file system
The sensor uses mode="reschedule"
I would like to trigger a specific behavior after X failed attempts.
Is there any straightforward way to know how many times the sensor has already attempted to run the poke method?
My quick fix so far has been to push an XCom with the attempt number, and increase it every time the poke method returns False. Is there any built-in mechanism for this?
Thank you
I had a similar problem when sensor mode = "reschedule", trying to poke a different path to a file based on the current time without directly referencing pendulum.now or datetime.now
I used task_reschedules (as done in the base sensor operator to get try_number for reschedule mode https://airflow.apache.org/docs/apache-airflow/stable/_modules/airflow/sensors/base.html#BaseSensorOperator.execute)
def execute(self, context):
task_reschedules = TaskReschedule.find_for_task_instance(context['ti'])
self.poke_number = (len(task_reschedules) + 1)
super().execute(context)
then self.poke_number can be used within poke(), and current time is approximately execution_date + (poke_number * poke_interval).
Apparently, the XCom thing isn't working, because pushed XComs don't seem to be available between pokes; they always return undefined.
try_number inside task_instance doesn't help either, as pokes don't count as a new try number
I ended up computing the attempt number by hand:
attempt_no = math.ceil((pendulum.now(tz='utc') - kwargs['ti'].start_date).seconds / kwargs['task'].poke_interval)
The code will work fine as long as individual executions of the poke method don't last longer than the poke interval (which they shouldn't)
Best

How to send <n> requests (instead of sending for duration <d> seconds)

Current wrk configuration allows sending continuous requests for seconds (duration parameter).
Is there a way to use wrk to send requests and then exit.
My use case: I want to create large number of threads + connections (e.g. 1000 threads with 100 connections per thread) and send instantaneous bursts towards the server.
You can do it with LUA script:
local counter = 1
function response()
if counter == 100 then
wrk.thread:stop()
end
counter = counter + 1
end
Pass this script with -s command line parameter.
I make changes to wrk to introduce new knobs. Let me know if anyone is interested in the patch and I could post it.
I added a -r to send exactly requests and bail out.
Artem,
I have this code-change in my fork:
https://github.com/bhakta0007/wrk

Idle time function on an Arduino

I want to add a timer to this function so that every time a uid is read it restarts and I can set another function to do a serial.write once a certain time is reached. Let's call this an idle time function. I cannot tie this to the ID read as I have 28 IDs potentially being read. I want to reset my audio player with an ASCII command via serial.write if no iud has been read for say longer than 180 seconds... Suggestions?
if(uid[0] == 0x64 && uid[1] == 0xBF && uid[2] == 0xD8 && uid[3] == 0x51)
{
//pause at beginning
delay (500);
//Serial.write("for Bässgen MM3210")
Serial.write("listplay 1 1");
Serial.write(13);
//pause at end
delay (3000);
}
You could assign each uid a value from the millis() call.
It basically counts the milliseconds since the chip turns on. It is stored in a long so it will reset to zero every 80 days or so I think (I never left it that long)
I did this to time a random array that was writing faster or slower based on how many pieces of data were in it. Instead of using delay() and counted loops, using millis() allowed me to jump in at a certain time.

Why does my concurrent Haskell program terminate prematurely?

I have a UDP server that reflects every ping message it receives (this works well I think). I the client side I would then like to do two things:
make sure that I fired off N (e.g. 10000) messages, and
count the number of correctly received responses.
It seems that either because of the nature of UDP or because of the forkIO thing, my client code below ends prematurely/does not do any counting at all.
Also I am very surprised to see that the function tryOnePing returns 250 times the Int 4. Why could this be?
main = withSocketsDo $ do
s <- socket AF_INET Datagram defaultProtocol
hostAddr <- inet_addr host
thread <- forkIO $ receiveMessages s
-- is there any better way to eg to run that in parallel and make sure
-- that sending/receiving are asynchronous?
-- forM_ [0 .. 10000] $ \i -> do
-- sendTo s "ping" (SockAddrInet port hostAddr)
-- actually this would be preferred since I can discard the Int 4 that
-- it returns but forM or forM_ are out of scope here?
let tryOnePing i = sendTo s "ping" (SockAddrInet port hostAddr)
pings <- mapM tryOnePing [0 .. 1000]
let c = length $ filter (\x -> x==4) pings
-- killThread thread
-- took that out to make sure the function receiveMessages does not
-- end prematurely. still seems that it does
sClose s
print c
-- return()
receiveMessages :: Socket -> IO ()
receiveMessages socket = forever $ do
-- also tried here forM etc. instead of forever but no joy
let recOnePing i = recv socket 1024
msg <- mapM recOnePing [0 .. 1000]
let r = length $ filter (\x -> x=="PING") msg
print r
print "END"
The main problem here is that when your main thread finishes, all other threads gets killed automatically. You have to get the main thread to wait for the receiveMessages thread, or it will in all likelyhood simply finish before any responses have been received. One simple way of doing this is to use an MVar.
An MVar is a synchronized cell that can either be empty or hold exactly one value. The current thread will block if it tries to take from an empty MVar or insert into a full one.
In this case, we don't care about the value itself, so we'll just store a () in it.
We'll start with the MVar empty. Then the main thread will fork off the receiver thread, send all the packets, and try to take the value from the MVar.
import Control.Concurrent.MVar
main = withSocketsDo $ do
-- prepare socket, same as before
done <- newEmptyMVar
-- we need to pass the MVar to the receiver thread so that
-- it can use it to signal us when it's done
forkIO $ receiveMessages sock done
-- send pings, same as before
takeMVar done -- blocks until receiver thread is done
In the receiver thread, we will receive all the messages and then put a () in the MVar to signal that we're done receiving.
receiveMessages socket done = do
-- receive messages, same as before
putMVar done () -- allows the main thread to be unblocked
This solves the main issue, and the program runs fine on my Ubuntu laptop, but there are a couple more things you want to take care of.
sendTo does not guarantee that the whole string will be sent. You'll have to check the return value to see how much was sent, and retry if not all of it was sent. This can happen even for a short message like "ping" if the send buffer is full.
recv requires a connected socket. You'll want to use recvFrom instead. (Although it still works on my PC for some unknown reason).
Printing to standard output is not synchronized, so you might want to alter this so that the MVar will be used to communicate the number of received packets instead of just (). That way, you can do all the output from the main thread. Alternatively, use another MVar as a mutex to control access to standard output.
Finally, I recommend reading the documentation of Network.Socket, Control.Concurrent and Control.Concurrent.MVar carefully. Most of my answer is stitched together from information found there.

Resources