OpenMPI breaking out of a loop - openmpi

I'm having a hard time figuring out how to break out of a loop using OpenMPI in c.
Here's my loop
for( i=1; i<=steps;i++) {
do_calculation(psi,new_psi,&mydiff,i1,i2,j1,j2);
if (breakNow == 1) {
break;
}
diff = find_difference();
if(myid == mpi_master && i % iout == 0){
printf("%8d %15.5f\n",i,diff);
if (diff == 0.00) {
printf("DONE!");
breakNow = 1;
MPI_Bcast(&breakNow, 1, MPI_INT, mpi_master, MPI_COMM_WORLD);
}
}
}
I need to break all of the processors out of the loop when there is a difference of 0.00 but it seems like the breakNow variable isn't being broadcast to all the processors. Am I missing something?

MPI_Bcast is a collective operation. You need to call it in all processes in order for it to complete. In the process whose rank matches mpi_root the broadcast will behave like a send operation and in all other ranks it will behave as a receive operation.
Just move the call to MPI_Bcast outside of the conditional. May be the right place is just before the if (breakNow == 1) break; line.
Another suggestion: if find_difference returns the same value in all processes, you can do something similar to:
for (i = 1; i <= steps; i++) {
do_calculation(psi, new_psi, &mydiff, i1, i2, j1, j2);
diff = find_difference();
if (i % iout == 0) {
if (myid == mpi_master) {
printf("%8d %15.5f\n", i, diff);
if (diff == 0.00)
printf("DONE!");
}
if (diff == 0.00) break;
}
}
If find_difference only gives meaningful results in the master process, then modify as follows:
for (i = 1; i <= steps; i++) {
do_calculation(psi, new_psi, &mydiff, i1, i2, j1, j2);
diff = find_difference();
if (i % iout == 0) {
if (myid == mpi_master) {
printf("%8d %15.5f\n", i, diff);
if (diff == 0.00)
printf("DONE!");
}
MPI_Bcast(&diff, 1, MPI_DOUBLE, mpi_master, MPI_COMM_WORLD);
if (diff == 0.00) break;
}
}
(I have assumed that diff is of type double and preserved the original semantics of your code to check for zero difference once every iout steps)

Related

Complexity Analysis: Remove consecutive(3+) duplicates from string

I have written a solution for removing 3(let's call this k) or more consecutive same characters from string.
eg.
in: daabbcccbbaad out: dd
in: aaabbb out:
in: aaabbbc out: c
code:
void removeDup(string& s, int start) {
if (s.length() < 3) {
return;
}
if (start > s.length() - 2) return;
int count = 1;
char c = s[start];
int i = start + 1;
while (i < s.length() && s[i] == c) {
++count, ++i;
}
if (count >= 3) {
start = i - count - 2;
if (start < 0) start = 0;
s.erase(i - count, count);
} else {
start = i;
}
return removeDup(s, start);
}
For each match start pointer will move 2 step behind. Also problem size is reducing by no of matched characters.
I want to understand how to do complexity analysis for this. Also for any k(let's say k=n/2) how will the complexity change.
ps: if you have a better solution with constant space, kindly post.

Move a 2d point to a target point with certain speed through x or y axis

Given that moving a point A(x1,y1) to location (x2,y2) with a fixed speed, say 3 units(points) per sec.
The requirement is that the point A can only moves through x or y axis.
For example, A(0,0) moves to target(10,10) at 3units/sec. First starting move on x axis, after 1s, location of A becomes (3,0). Then becomes (9,0) after 3s. Now on the x axis, the A only needs to move 1 more unit and then move 2 units on the y axis, which becomes (10,2), then continue on the y axis, (10,5)...(10,8)
My question is: Is there any efficient way to achieve this? This is my logic:
while(the point is not arriving the target point) {
currentX = SourceX;
currentY = SourceY;
differenceOnXaxis=TargetX-currentX;
differenceOnYaxis=TargetY-currentY;
if(differenceOnXaxis == 0) {
if(differenceOnYaxis == 0) {
//Arrive at the target point
} else if (differenceOnYaxis >= MovingUnit){
currentY += MovingUnit;
} else if (0 <differenceOnYaxis < MovingUnit){
currentY += differenceOnYaxis;
} else if (-MovingUnit <differenceOnYaxis < 0) {
currentY += differenceOnYaxis;
} else if (differenceOnYaxis<= (-MovingUnit)) {
currentY -= MovingUnit;
}
} else if(differenceOnXaxis >= MovingUnit){
currentX += moving unit;
} else if (0< differenceOnXaxis < MovingUnit) {
currentX += differenceOnXaxis;
if(differenceOnYaxis > 0){
currentY += (MovingUnit - differenceOnXaxis)
} else if (differenceOnYaxis < 0) {
currentY += -(MovingUnit-differenceOnXaxis)
}
} else if (- MovingUnit < differenceOnXaxis < 0) {
currentX += differenceOnXaxis;
} else if (differenceOnXaxis <= (-MovingUnit)) {
currentX -= MovingUnit;
}
}

Where is the race condition?

I had a question on a test recently that basically said to make 3 concurrent processes execute some block of code in order.
Example of execution order incase that did not make sense:
P1
P2
P3
P1
P2
P3
...
For my answer I wrote this pseudo-ish code
shared s[2] = {-1,-1};
void Process1(){
while(1){
if(s[0] < 0 && s[1] < 0){
DO_CS;
s[0] = 1;
}
}
}
void Process2(){
while(1){
if(s[0] > 0 && s[1] < 0){
DO_CS;
s[1] = 1;
}
}
}
void Process3(){
int i = 0;
while(1){
if(s[1] > 0 && s[0] > 0){
DO_CS;
s[0] = -1;
s[1] = -1;
}
}
}
My teacher wrote race condition and circled the last line in the if statement on Process3 and drew an arrow to the conditional statement in process2.
I am having trouble seeing how this could cause a race condition. I am sure it is obvious but I just can't see it.
Thanks!
Consider the following order of events:
After some time, s = [1, 1].
Within Process2, the thread is in the midst of evaluating the expression in the if statement, and just passed the truthy condition s[0] > 0 and is about to continue.
Within Process3, you modify s to be [-1, -1].
Process2 evaluates the rest of the expression and goes into action before Process1.

Concurrency control algorithm

I am trying to modify a concurrency control algorithm to take advantage of priority of threads (i.e if lower priority thread and higher priority thread wants to enter critical section at same time, the higher priority thread goes in first, while the lower priority thread waits for certain no. of cycles).
Here is the modified algorithm:
procphase[i] = want_cr;
int j = turn;
do {
while (j != i) {
if (procphase[j] != out_cr)
{
if (procphase[j] == want_cr && thrd_prty[i]<thrd_prty[j])
{
if(turndown[i]<5)
{
turndown[i]=turndown[i]+1;
j=turn;
}
}
else if(procphase[j] ==claim_cr)
{
j=turn;
}
else{}
}
else j=(j+1)%n;
}
procphase[i] = claim_cr;
j = (j + 1) % n;
while (procphase[j] != claim_cr) j = (j + 1) % n;
} while (!(j == i && (turn == i || procphase[turn] == out_cr)));
turn = i;
The original algorithm is the Eisenberg McGuire algorithm,
but sometimes the algorithm is getting stuck in between and I could not find why.

Conways's Game of life array problems

I'm writing a Conway's life game for school. In the program I am having trouble with the arrays taking the values I am assigning them. At one point in the program they print out the value assigned to them (1) yet at the end of the program when I need to print the array to show the iterations of the game it shows an incredibly low number. The other trouble was I was encountering difficulties when putting in a loop that would ask if it wants you to run another iteration. So I removed it until the previous errors were fixed.
Im writing this with C++
#include <stdio.h>
int main (void)
{
int currentarray [12][12];
int futurearray [12][12];
char c;
char check = 'y';
int neighbors = 0;
int x = 0; // row
int y = 0; //column
printf("Birth an organism will be born in each empty location that has exactly three neighbors.\n");
printf("Death an organism with four or more organisms as neighbors will die from overcrowding.\n");
printf("An organism with fewer than two neighbors will die from loneliness.\n");
printf("Survival an organism with two or three neighbors will survive to the next generation.\n");
printf( "To create life input x, y coordinates.\n");
while ( check == 'y' )
{
printf("Enter x coordinate.\n");
scanf("%d", &x ); while((c = getchar()) != '\n' && c != EOF);
printf("Enter y coordinate.\n");
scanf("%d", &y ); while((c = getchar()) != '\n' && c != EOF);
currentarray [x][y] = 1;
printf ("%d\n", currentarray[x][y]);
printf( "Do you wish to enter more input? y/n.\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
}
// Note - Need to add a printf statement showing the array before changes are made after input added.
// check for neighbors
while(check == 'y')
{
for(y = 0; y <= 12; y++)
{
for(x = 0; x <= 12; x++)
{
//Begin counting number of neighbors:
if(currentarray[x-1][y-1] == 1) neighbors += 1;
if(currentarray[x-1][y] == 1) neighbors += 1;
if(currentarray[x-1][y+1] == 1) neighbors += 1;
if(currentarray[x][y-1] == 1) neighbors += 1;
if(currentarray[x][y+1] == 1) neighbors += 1;
if(currentarray[x+1][y-1] == 1) neighbors += 1;
if(currentarray[x+1][y] == 1) neighbors += 1;
if(currentarray[x+1][y+1] == 1) neighbors += 1;
//Apply rules to the cell:
if(currentarray[x][y] == 1 && neighbors < 2)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && neighbors > 3)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && (neighbors == 2 || neighbors == 3))
futurearray[x][y] = 1;
else if(currentarray[x][y] == 0 && neighbors == 3)
futurearray[x][y] = 1;
}
}
}
// Set the current array to the future and change the future to 0
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
}
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//print the current life board
printf("%d ", currentarray[x][y]);
}
}
}
// Have gone through one iteration of Life
//Ask to do another iteration
printf("Do you wish to continue y/n?\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
return 0;
}
You are defining your arrays as [12][12].
In your generation loop you walk from i = 0 to i <= 12, which is 13 steps instead of the 12 of the array. Additionally you are trying to access x-1 and y-1, which can be as low as -1. Again not inside your array.
Sometimes you get semi-useful values from within your array, but on some borders you are just accessing random data.
Try to correct your border.
You forgot to set neighbors to 0 before counting them.
Since this is C++ (not C), you might as well declare neighbors inside the loop body. Makes these kinds of issues easier to spot, too.
Also, is it me, or is that while loop never going to finish? Your braces are a mess, in general, as is your indentation. You could do yourself and us a favour by cleaning those up.
Obviously agree with all the above suggestions. One nice trick you might want to implement with Life is to create an extra border around your area. So if the user wants a 12x12 grid (and you should allow width/height to be specified and allocate memory dynamically) internally you hold a 14x14 grid corresponding to a border around the actual grid. Before running the calculation copy the top row to the bottom border, bottom row to the top border etc. Now you can run the main algorithm on the inner 12x12 grid without worrying about edge cases. This will enable your patterns to re-appear on the other side if they fall off the edge.
You're also forgetting to set the values of both arrays to zero. This will take care of the ridiculous number issue you're having. you can do that by copying this for loop:
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
and pasting it before the while loop but instead of setting currentarray[x][y] = futurearray[x][y], set it to 0. Also, if the coordinates are viewable locations instead of array co-ordinates, you'll want to change this:
printf ("%d\n", currentarray[x][y]);
to this:
printf ("%d\n", currentarray[x-1][y-1]);
I would also recommend putting a printf with a newline (\n) after each row has been printed and a tab (\t) after each item so that the formatting looks cleaner.

Resources