Cant send the whole vector through MPI_send - c++

I have been trying to learn MPI. and when i try to run the following code i get the wrong output.
if (world_rank == 0){
vector<vector<double> > n(4,vector<double>(4));
srand(time(NULL));
for(int i=0; i<4 ;i++){
for(int j=0;j<4;j++){
n[i][j] = (double)rand()/RAND_MAX;
cout << n[i][j] << " ";
}
cout << endl;
}
MPI_Send((void*)&n[0][0],16*sizeof(double),MPI_BYTE,1,0,MPI_COMM_WORLD);
}else{
MPI_Status status;
vector<vector<double> > n(4,vector<double>(4));
MPI_Probe(0,0,MPI_COMM_WORLD,&status);
int size;
MPI_Get_count(&status,MPI_BYTE,&size);
cout << endl << size << endl;
MPI_Recv((void*)&n[0][0],16*sizeof(n[0][0]),MPI_BYTE,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
cout.flush();
cout << endl;
for(int i=0; i<4 ;i++){
for(int j=0;j<4;j++){
cout << n[i][j] << " ";
}
cout << endl;
}
}
i get all the double values except the last 3.
like this.
0.824468 0.752417 0.757125 0.470763
0.251683 0.703306 0.157991 0.764423
0.815327 0.0402807 0.897109 0.313816
0.997203 0.796665 0.0522305 0.797733
128
0.824468 0.752417 0.757125 0.470763
0.251683 0.703306 0.157991 0.764423
0.815327 0.0402807 0.897109 0.313816
0.997203 0 0 0
can anyone tell me why this is happening?
i ran the same code around a hundred times and still get the same output (of course with different values) but the last three always are 0.
but when i changed the size from 16 to 19 i get all the values.
i also have another doubt.
some times the outputs (values from node 0 and 1) get overlapped. can anyone tell me how to stop that or at least explain why that happens. i mean even though send and recv are blocking functions. how can the node 1's output get printed before node 0's

Your definition of the 2D data n as vector<vector<double> > makes it non-contiguous in memory. Therefore, you cannot transmit it simply using MPI (there are ways for doing it, but you'd better just making the memory contiguous instead).
To have your memory contiguous, you can declare your n like this (not tested):
vector<double> ndata(4*4); //contiguous storage of the actual data
vector<double*> n(4); //vector of pointers to access the actual data
for (int i=1; i<4; i++) //initialisation of the pointers to the data
n[i] = &ndata[4*i];
Of course, there are better ways of defining a contiguous storage for multidimensional arrays in C++, but this is just a quick fix for your immediate problem. See for example this answer for a better structure.
And BTW, your MPI_Send() and MPI_Recv() calls should use 4*4 MPI_DOUBLE instead of 4*4*sizeof(double) MPI_BYTE.

Related

Given the following piece of code, how many time the “cout” operation is executed

the question!!
Justify your answer.
for (int i = 0; i < 100; i++)
{
cout << i;
cout << 2 * i;
cout << 4-1;
}
the answer that I have!!!
assuming the cout for the following is 3 but since the output is long not so sure. 0031232433634835103612371438163918310203112231224313263142831530316323173431836319383204032142322443234632448325503265232754328563295833060331623326433366334683357033672337743387633978340803418234284343863448834590346923479434896349983501003511023521043531063541083551103561123571143581163591183601203611223621243631263641283651303661323671343681363691383701403711423721443731463741483751503761523771543781563791583801603811623821643831663841683851703861723871743881763891783901803911823921843931863941883951903961923971943981963991983
I'm pretty sure I'm wrong so someone pls help.
Let's run through the first interation, where i is 0:
for (int i = 0; i < 100; i++)
{
cout << i;
cout << 2 * i;
cout << 4-1;
}
Looks like for the first iteration through the loop, the cout operation is executed 3 times (because there are 3 cout statements).
Let's go another iteration. We have 3 more cout operations for a total of 6 so far.
Another iteration, another 3 more operations for a total of 9.
Looks like there are 3 cout operations performed for each iteration of the loop.
So to find the total, you should determine the maximum iterations of the loop, then multiply by 3.
If the owner's of the question are considering that a cout operation doesn't finish until the output is displayed, then that's difficult to answer. The answer could be zero if the buffers are not flushed. Could be one if the cout buffer is flushed only at the end of the program. Or the cout could flush its buffer when the buffer gets full; so this depends on the size of the buffer. Hard to answer without a clear definition of "a cout operation".

using arrays to solve an equation

so i wrote this code in c++ to solve this equation (x+y+z=30) where each of these variables has a limited amount of possible of values (1,3,5,7,9,11,13,15) so repetition is allowed and here's my code :
#include <iostream>
using namespace std;
int main()
{
int x[8]={1,3,5,7,9,11,13,15};
int y[8]={1,3,5,7,9,11,13,15};
int z[8]={1,3,5,7,9,11,13,15};
for (int i=0; i<8; i++)
{
for (int j=0; j<8; j++)
{
for (int k=0; k<8; j++)
{
if (x[i]+y[j]+z[k]==30)
{
cout << x[i] << "\n" << y[j] << "\n" << z[k]<< "\n"<< endl;
break;
}
}
}
}
}
now i don't know if this is the right way to approach it (I'm a beginner) but still this program did okay since it gave set of three number that did equal to 30 but it didn't stick to the possible values e.g (7,22,1), now that what you see their is the best i could come up with other attempts or fixes just made things worse e.g crashing or what so ever.
if you could help that would be great and most importantly tell me where i went wrong as this whole purpose of this is to learn not solve the problem.
thank you so much in advance !
You are using break statement which only breaks one of the loops. You have nested loops in your program, so i would recommend you to use goto: instead.
for (int i=0; i<8; i++)
{
for (int j=0; j<8; j++)
{
for (int k=0; k<8; j++)<----- it should be k++
{
if (x[i]+y[j]+z[k]==30)
{
goto stop;
}
}
}
}
stop:
cout << x[i] << "\n" << y[j] << "\n" << z[k]<< "\n"<< endl;
I actually ran the code and there is 2 more problems:
As mentioned on the answer below, it 3 odd numbers never add up to 30;
variables i , j and k need to be global variables. So initialize them before using in loops. Then it should work perfectly(if the number isn't even).
I don't see 22 in the values you initialized the arrays with. You also can just use one array with the possible values; 3 arrays are not needed.
I see that you only have odd integers as possible values. 3 odd integers can never sum up to an even integer like 30, so there is no solution to your problem as stated. The one solution you provided has 22 as one value, an even integer.

C++ program only lists last value entered into an array

I am trying to output the values present in the array, that are accepted during runtime, onto the console. But when I run this program I get the 5 values in the array as the last value only.
For example: if i give 0 1 2 3 4 as the five values for this program then the output is shown as 4 4 4 4 4.
#include "stdafx.h"
#include<iostream>
using namespace std;
int main()
{
int arrsize = 5;
int *ptr = new int[arrsize];
*ptr = 7;
cout << *ptr << endl;
cout << "enter 5 values:";
for (int i = 0; i < arrsize; i++)
{
cin >> *ptr;
cin.get();
}
cout << "the values in the array are:\n ";
for (int i = 0; i < arrsize; i++)
{
cout << *ptr << " ";
}
delete[] ptr;
cin.get();
return 0;
}
Both of your loops:
for (int i = 0; i < arrsize; i++)
...
loop over a variable i that is never used inside the loop. You are always using *ptr which refers always to the first element of the dynamically allocated array. You should use ptr[i] instead.
A part from that, dynamic allocation is an advanced topic. I'd recommend sticking with simpler and more commonly used things first:
std::cout << "Enter values:";
std::vector<int> array(std::istream_iterator<int>(std::cin), {});
std::cout << "\nThe values in the array are:\n";
std::copy(begin(array), end(array), std::ostream_iterator<int>(std::cout, " "));
Live demo
Following issues I think you could tackle:
The first include can be omitted I think. Your code works without that.
You use cin.get(), not sure why you need that. I think you can remove that. Even the one at the very end. You could put a cout << endl for the last newline. I am using Linux.
And use ptr like an array with index: ptr[i] in the loops as mentioned in the other answer. ptr[i] is equivalent to *(ptr+i). You have to offset it, otherwise you're overwriting the same value (that is why you get that result), because ptr points to the first element of the array.
P.S.: It seems that if you're using Windows (or other systems) you need the cin.get() to avoid the console to close down or so. So maybe you'd need to check it. See comments below.

Code crashes. Trying to remove characters from char array C

I am basically trying to store everything after a certain index in the array.
For example, I want to store a name which is declared as char name[10]. If the user inputs in say 15 characters, it will ignore the first five characters and store the rest in the char array, however, my program crashes.
This is my code
char name[10];
cout<< "Starting position:" << endl;
cin >> startPos;
for(int i= startPos; i< startPos+10; i++)
{
cout << i << endl; // THIS WORKS
cout << i-startPos << endl; // THIS WORKS
name[i-startPos] = name[i]; // THIS CRASHES
}
For example, if my name was McStevesonse, I want the program to just store everything from the 3rd position, so the end result is Stevesonse
I would really appreciate it if someone could help me fix this crash.
Thanks
Suppose i is equal to 3. In the last iteration of the loop, i is now equal to 12, so substituting 12 in for i, your last line reads
name[12-startPos] = name[12];
name[12] is out of bounds of the array. Based on what you have shown so far, there is nothing but garbage stored in name anyway before you start doing this assignment, so all you're doing is reorganizing garbage in the array.
Please in future: post full compilable example.
A simple answer is that your array maybe is out of bound, since you don't provide full example its hard to know exactly.
Here is a working example:
#include <iostream>
using namespace std;
int main() {
int new_length, startPos;
int length = 15;
char name[15]= "McStevesonse";
cout<< "Starting position:" << endl;
cin >> startPos;
if(new_length <1){ // you need to check for negative or zero value!!!
cout << "max starting point is " <<length-1 << endl;
return -1;
}
new_length=length-startPos;
char newname[new_length];
for(int i= 0; i<new_length; i++){
newname[i] = name[i+startPos]; // THIS CRASHES
}
cout << "old name: " << name << " new name: " << newname << endl;
return 0 ;
}
To put it simply, change this:
for(int i= startPos; i< startPos+10; i++)
To this:
for(int i= startPos; i<10; i++)
You should be fine with that.
Explanation:
At some point, when you use the your old loop, this name[i-startPos] = name[i] would eventually reach an array index out of bounds and causes the crash.
Don't forget to clean up/hide the garbage:
Doing so, would cause the output to produce some kind of garbage outputs. If you got a character array of 'ABCDEFGHIJ', and have chosen 3 as the starting position, the array would be arranged to 'DEFGHIJHIJ'. In your output, you should atleast hide the excess characters, or remove by placing \0's

c++ vector not updating in nested for loop

So I create and initialize a vector (of size nmask+3) to 0, and I assign an initial value to one of the elements. I then make a for loop that goes through the first nmask elements of the vector and assigns to each element an average of 26 other elements in the vector (defined by the 4D int array voxt, which contains vector addresses).
My problem is that when I check the values of nonzero elements in my vector (phi) within the nested loop (the first cout), the values are fine and what I expect. However, when the loop finishes going through all nmask elements (for (int i= 0; i<nmask; i++) exits), I check the nonzero elements of phi again, and they are all lost (reset to 0) except for the last non-zero element (and element tvox which is manually set to 1).
I feel that since phi is initialized outside of all the loops, there should be no resetting of values going on, and that any updated elements within the nested loop should remain updated upon exit of the loop. Any ideas as to what is going on / how to fix this? Code is below; I tried to comment in a sense of the outputs I'm getting. Thanks in advance.
vector<double> phi(nmask+3, 0); //vector with nmask+3 elements all set to 0 (nmask = 13622)
phi[tvox]= 1; //tvox is predefined address (7666)
for (int n= 0; n<1; n++)
{
vector<double> tempPhi(phi); //copy phi to tempPhi
for (int i= 0; i<nmask; i++)
{
for (int a= -1; a<=1; a++)
{
for (int b= -1; b<=1; b++)
{
for (int c= -1; c<=1; c++)
{
if (!(a==0 && b==0 && c==0))
{
//oneD26 is just (double) 1/26
phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
if (phi[i]!=0)
{
//this gives expected results: 27 nonzero elements (including tvox)
cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl;
}
}
}
}
}
}
phi[svox]= 0; //svox = 7681
phi[tvox]= 1;
for (int q= 0; q<nmask; q++)
{
//this gives only 2 nonzero values: phi[tvox] and phi[9642], which was the last nonzero value from 1st cout
if (phi[q]!=0)
cout << q << " " << phi[q] << endl;
}
}
Difficult to tell just what is going on, but the easiest explanation is that after phi[i] gets set to non-zero and displayed to cout, it gets set to zero again in one of the later iterations through the inner loops.
If you do some tracing and check phi[i] just before updating you'll see that you often overwrite a non-zero element with zero.
Note: I have no idea what your code does, this is pure Sherlock Holmes reasoning.. if after the loops you find only 2 non-zero elements then the only logical consequence is that after updating something to non-zero later in the loop you update it to zero.
phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
The nested for-loops using a, b, and c run for a combined 9 iterations with the same value of i. Since you overwrite phi[i] to a new value every time, you only retain the value from the last iteration where a, and c are all 1. If that last iteration happens to produce zero values, then phi[i] will have lots of zeroes. Perhaps you meant to do something like phi[i] += ... instead of phi[i] = ...?
I do suggest to replace the meat of the loop with something like
const boost::irange domain(-1,2);
for (int i: boost::irange(0, nmask)) for (int a: domain) for (int b: domain) for (int c: domain)
{
if (a==0 && b==0 && c==0)
continue;
//oneD26 is just (double) 1/26
phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
if (phi[i]!=0)
{
//this gives expected results: 27 nonzero elements (including tvox)
cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl;
}
}
Of course, for brevity I assume both boost/range.hpp and c++0x compiler. However, with trivial macro's you can achieve the same. That is without writing/using a proper combinations algorithm (why is that not in the standard, anyway).