I have a 9x9 2D array. I fill the array with random numbers and then send the 1st 3 rows of the array to process with rank=1, 2nd 3 rows of the array to process with rank=2 and at last, the 3rd 3 rows of the array to process with rank=3. I mean each process will get 3 rows of the array.
After the respective rows of the main array are received by the process, it will calculate the histogram of the 3 rows which it received from the root process. Then return the histogram back to the root process. All the 3 processes will do this task.
The problem is that the process with rank=3 can not receive the rows which are sent by the root process. I could not figure it out why?
I would be very grateful if someone have a look at my code and find a solution for my problem.
Thanks in advance.
I am using MPI with c. here is my code
#include "mpi.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
int main(int argc, char* argv[])
{
int my_rank;
int p;
int i;
int k;
int m;
int tag=0;
int array[9][9];
int sub_array[3][9]; // 3 rows and 9 columns for each process
int c[20];
MPI_Status status;
// MPI_Datatype MPI_INT;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
MPI_Comm_size(MPI_COMM_WORLD,&p);
// MPI_Type_contiguous(9,MPI_INT,&MPI_INT);
// MPI_Type_commit(&MPI_INT);
srand(time(NULL));
for(i=0; i<20 ; i++)
c[i] = 0;
if(my_rank == 0)
{
for(i=0; i<9 ; i++)
for(k=0; k<9 ; k++)
{
array[i][k] = rand()%20+1; // fill the array with random numbers from 1 to 20;
}
for(i=0; i<9 ; i++)
{
printf("\n");
for(k=0; k<9 ; k++)
{
printf("%d ",array[i][k]); // prints the array here
}
}
// here each process will be sent 3 rows of the array;
for(i=0; i<3 ; i++)
MPI_Send(&(array[i][0]),9,MPI_INT,1,tag,MPI_COMM_WORLD); // 1st 3 rows of the array are sent to process 1
for(i=3; i<6 ; i++)
MPI_Send(&(array[i][0]),9,MPI_INT,2,tag,MPI_COMM_WORLD); // 2nd 3 rows of the array are sent to process 2
for(i=6; i<9 ; i++)
MPI_Send(&(array[i][0]),9,MPI_INT,3,tag,MPI_COMM_WORLD); // 3rd 3 rows of the array are sent to process 3
for (i=1;i<=3;i++)
MPI_Recv(&sub_array, 9, MPI_INT,i, 0, MPI_COMM_WORLD, &status); // root receives the subarrays from each node;
}
if(my_rank != 0)
{
// for the process with rank=1;
for(i=0; i<3 ; i++)
{
MPI_Recv(&(sub_array[i][0]),9,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
for(k=0; k<9 ; k++)
{
for(m=0 ; m<20 ; m++) // here the process with rank=1 calculates the histogram
{
if(sub_array[i][k] == m)
c[m]++;
}
}
}
// for the process with rank=2
for(i=3; i<6 ; i++)
{
MPI_Recv(&(sub_array[i][0]),9,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
for(k=0; k<9 ; k++)
{
for(m=0 ; m<20 ; m++) // here the process with rank=2 calculates the histogram
{
if(sub_array[i][k] == m)
c[m]++;
}
}
}
// for the process with rank=3
for(i=6; i<9 ; i++)
{
MPI_Recv(&(sub_array[i][0]),9,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
for(k=0; k<9 ; k++)
{
for(m=0 ; m<20 ; m++) // here the process with rank=3 calculates the histogram
{
if(sub_array[i][k] == m)
c[m]++;
}
}
}
}
// here the histogram must be printed.
for(k=0; k<20 ; k++)
{
printf("\n");
printf("%2d : ",k);
for(i=0 ; i<c[k] ; i++)
{
printf("=");
}
}
MPI_Finalize();
return 0;
}
#include <stdio.h>
#include <conio.h>
#include <time.h>
int main(int argc, char* argv)
{
int my_rank;
int p;
int Array[9];
int localArray[3];
int i;
int k;
int m;
int a[9][9];
int b[10][50];
int c[20];
MPI_Status status;
MPI_Datatype my_type;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
MPI_Comm_size(MPI_COMM_WORLD,&p);
MPI_Type_contiguous(9,MPI_INT,&my_type);
MPI_Type_commit(&my_type);
srand(time(NULL));
for(i=0; i<20 ; i++)
c[i] = 0;
if(my_rank == 0)
{
for(i=0; i<9 ; i++)
for(k=0; k<9 ; k++)
{
a[i][k] = rand()%20;
}
for(i=0; i<9 ; i++)
{
printf("\n");
for(k=0; k<9 ; k++)
{
printf("%d ",a[i][k]);
}
}
for(i=0; i<3 ; i++)
MPI_Send(&(a[i][0]),1,my_type,1,0,MPI_COMM_WORLD);
for(i=3; i<6 ; i++)
MPI_Send(&(a[i][0]),1,my_type,2,0,MPI_COMM_WORLD);
for(i=6; i<9 ; i++)
MPI_Send(&(a[i][0]),1,my_type,3,0,MPI_COMM_WORLD);
}
if(my_rank != 0)
{
for(i=0; i<3 ; i++)
{
MPI_Recv(&(b[i][0]),1,my_type,0,0,MPI_COMM_WORLD,&status);
}
for(i=0; i<3 ; i++)
for(k=0; k<9 ; k++)
{
for(m=0 ; m<20 ; m++)
{
if(b[i][k] == m)
c[m]++;
}
}
printf("\n \n ");
for(m=0 ; m<20 ; m++)
printf("%d ",c[m]);
for(i=3; i<6 ; i++)
{
MPI_Recv(&(b[i][0]),1,my_type,0,0,MPI_COMM_WORLD,&status);
}
for(i=0; i<3 ; i++)
for(k=0; k<9 ; k++)
{
for(m=0 ; m<20 ; m++)
{
if(b[i][k] == m)
c[m]++;
}
}
printf("\n \n ");
for(m=0 ; m<20 ; m++)
printf("%d ",c[m]);
for(i=0; i<3 ; i++)
{
MPI_Recv(&(b[i][0]),1,my_type,0,0,MPI_COMM_WORLD,&status);
}
for(i=0; i<3 ; i++)
for(k=0; k<9 ; k++)
{
for(m=0 ; m<20 ; m++)
{
if(b[i][k] == m)
c[m]++;
}
}
printf("\n \n ");
for(m=0 ; m<20 ; m++)
printf("%d ",c[m]);
}
for(k=0; k<20 ; k++)
{
printf("\n");
printf("%2d : ",k);
for(i=0 ; i<c[k] ; i++)
{
printf("=");
}
}
MPI_Finalize();
return 0;
}
#Colin D I edited the code above and it's working now BUT the problem is that 3.processor doesn't receive or 0.processor couldn't send the rows.I didn't achieve that.
In the following loop:
// for the process with rank=3
for(i=6; i<9 ; i++)
{
// snip
for(i=0; i<3 ; i++) // notice the reuse of the var i here!
//snip
}
In you loop, you are reassigning the value for i. this might be your problem. for the loops for procs with rank 1 and 2, you use a different variable k for this loop.
Related
For some reason, whenever I run this code, it just opens; loads for a sec; then closes without doing anything. Whenever I try to narrow it down to a piece of code, it makes absolutely no sense, like the line int dirX.
#include <iostream>
#include <queue>
using namespace std;
void solve()
{
// ENTER CODE BELOW
struct Loc
{
int x, y;
Loc (int xx=0, int yy=0) : x(xx), y(yy) {}
};
int n=0, currX=1002, currY=1002, dx[]={-1,1,0,0},dy[]={0,0,-1,1}; string str=""; bool isFence[2010][2010]; queue<Loc> q;
int ret=-1;
for (int i = 0; i < 2005; i++) {
for (int j = 0; j < 2005; j++) {
isFence[i][j]=false;
}
}
cin >> n >> str;
isFence[currX][currY]=true;
int dirX, dirY;
for (auto i : str)
{
dirX=0; dirY=0;
if (i=='N') dirX=-1;
else if (i=='S') dirX=1;
else if (i=='W') dirY=-1;
else dirY=1;
for (int j = 0; j < 2; j++) {
currX += dirX;
currY += dirY;
isFence[currX][currY]=true;
}
}
Loc curr; int nx, ny;
for (int i = 0; i < 2005; i++)
{
for (int j = 0; j < 2005; j++)
{
cout << isFence[i][j] << endl;
if (isFence[i][j]) continue;
ret++;
q = std::queue<Loc>();
q.push(Loc(i,j));
isFence[i][j]=true;
while (!q.empty())
{
curr = q.front(); q.pop();
for (int k = 0; k < 4; k++) {
nx = curr.x+dx[k]; ny=curr.y+dy[k];
if (nx >= 0 && nx < 2005 && ny >= 0 && ny<2005 && !isFence[nx][ny]) {
isFence[nx][ny]=true;
q.push(Loc(nx, ny));
}
}
}
}
}
cout << ret;
// ENTER CODE ABOVE
}
int main()
{
solve();
}
Also, the reason I have all my code in the solve() function was because this is an assignment and I have to do it this way.
Sidenote: I wrote this code very quickly, so it's very badly formatted.
I am trying to use Malloc function to dynamically allocate memory but I also want to specify my data entry for operation rather than taking the user input.
I have found this code here which works fine, but I am working with a large data set and taking user input is not an option, so I want to keep using MALLOC but also define the data set.
like instead of following,
//Input Matrix1
for (i = 0; i < r1; i++)
for (j = 0; j < c1; j++)
scanf_s("%d", &mat1[i][j]);
I want something like
//mat1[2][2] = { {1,2},{2,3} }
to be inputed in the code
What would be the way to do it? I would really appreciate some advice. Thanks
#include<stdio.h>
#include<stdlib.h>
int main() {
int **mat1, **mat2, **res, i, j,k, r1, c1, r2, c2;
printf("\nEnter the Order of the First matrix...\n");
scanf_s("%d %d", &r1, &c1);
printf("\nEnter the Order of the Second matrix...\n");
scanf_s("%d %d", &r2, &c2);
if (c1 != r2) {
printf("Invalid Order of matrix");
exit(EXIT_SUCCESS);
}
mat1 = (int**)malloc(r1 * sizeof(int*));
for (i = 0; i < c1; i++)
mat1[i] = (int*)malloc(c1 * sizeof(int));
mat2 = (int**)malloc(r2 * sizeof(int*));
for (i = 0; i < c2; i++)
mat2[i] = (int*)malloc(c2 * sizeof(int));
res = (int**)calloc(r1, sizeof(int*));
for (i = 0; i < c2; i++)
res[i] = (int*)calloc(c2, sizeof(int));
/**/
//Input Matrix1
for (i = 0; i < r1; i++)
for (j = 0; j < c1; j++)
scanf_s("%d", &mat1[i][j]);
//Input Matrix2
for (i = 0; i < r2; i++)
for (j = 0; j < c2; j++)
scanf_s("%d", &mat2[i][j]);
//Printing Input Matrix 1 and 2
printf("\n Entered Matrix 1: \n");
for (i = 0; i < r1; i++) {
for (j = 0; j < c1; j++)
printf("%d ", mat1[i][j]);
printf("\n");
}
printf("\n Entered Matrix 2: \n");
for (i = 0; i < r2; i++) {
for (j = 0; j < c2; j++)
printf("%d ", mat2[i][j]);
printf("\n");
}
//int mat1[2][2] = { {1,2},{2,3} };
//int mat2[2][2] = { {1,3},{2,4} };
//Computation
//Multiplication
for (i = 0; i < r1; i++) {
for (j = 0; j < c2; j++) {
res[i][j] = 0;
for (k = 0; k < c1; k++)
res[i][j] += mat1[i][k] * mat2[k][j];
}
printf("\n");
}
printf("\nThe Multiplication of two matrix is\n");
for (i = 0; i < r1; i++) {
printf("\n");
for (j = 0; j < c2; j++)
printf("%d\t", res[i][j]);
}
printf("\n");
/* Addition
for(i=0;i<r1;i++)
for(j=0;j<c2;j++)
res[i][j]=mat1[i][j]+mat2[i][j];
printf("\nThe Addition of two matrix is\n");
for(i=0;i<r1;i++){
printf("\n");
for(j=0;j<c2;j++)
printf("%d\t",res[i][j]);
}
*/
return 0;
}
Please specify the format of your input data. Is it a csv file?
You can only specify data in the format int b[4] = {1, 2, 3, 4} when the size of b is fixed, i.e. known at compile time. But if all you matrices are known at compile time anyway, why bother doing dynamic allocation?
Also I cleaned up your code a bit:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define index(x, y, r) (x+r*y)
struct matrix {
int cols;
int rows;
double * data;
};
void print_mat(struct matrix * mat) {
int i, j;
for (i = 0; i < mat->rows; i++) {
for (j = 0; j < mat->cols; j++) {
printf("%f \t", mat->data[index(i, j, mat->rows)]);
}
printf("\n");
}
}
int mat_alloc(struct matrix *mat) {
mat->data = (double*)malloc(mat->rows*mat->cols*sizeof(double));
}
int read_mat(struct matrix *mat) {
int i, j;
for (i = 0; i < mat->rows; i++) {
for (j = 0; j < mat->cols; j++) {
scanf("%lf", &(mat->data[index(i, j, mat->rows)]));
}
}
}
int multiply(struct matrix * a, struct matrix * b, struct matrix * res) {
if(a->cols != b->rows){
printf("Matrix dimensions do not match!\n");
return 0;
}
res->rows = a->rows;
res->cols = b->cols;
mat_alloc(res);
memset(res->data, 0, res->cols*res->rows*sizeof(double));
int i, j, k;
for (i = 0; i < res->rows; i++) {
for (j = 0; j < res->cols; j++) {
for (k = 0; k < a->cols; k++) {
res->data[index(i, j, res->rows)] += a->data[index(i, k, a->rows)] * b->data[index(k, j, b->rows)];
}
}
}
}
int main() {
struct matrix mat1, mat2, res;
printf("\nEnter the Order of the First matrix...\n");
scanf("%d %d", &mat1.rows, &mat1.cols);
printf("\nEnter the Order of the Second matrix...\n");
scanf("%d %d", &mat2.rows, &mat2.cols);
mat_alloc(&mat1);
mat_alloc(&mat2);
read_mat(&mat1);
read_mat(&mat2);
printf("Scanned matrices: \n");
print_mat(&mat1);
printf("\n");
print_mat(&mat2);
printf("\n");
multiply(&mat1, &mat2, &res);
printf("Calculated result: \n");
print_mat(&res);
return 0;
}
How to implement a round robin schedule for an array of 4 elements [1,2,3,4]? The result of the algorithm should be able to display, for each element, the list of the players it will face in chronological order:
(1: 4,2,3)
(2: 3,1,4)
(3: 2,4,1)
(4: 1,3,2)
Line 1: 4,2,3 means that the player (1) will face in order the players (4), (2) and (3).
Of the same way, line 2: 3,1,4 indicates that the player (2) will face in order the players (3), (1) and (2).
We have implemented this code but we encounter a bug when we start filling in the name of the player. Do you have any idea about this problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_MAX_LENGTH 20
#define NUM_MIN_PLAYERS 2
#define NUM_MAX_PLAYERS 20
enum Style
{
STYLE_COMPACT,
STYLE_TABLE
};
enum Format
{
FORMAT_ID,
FORMAT_NAME
};
struct PlayerList
{
unsigned int num_players;
char name[NUM_MAX_PLAYERS][NAME_MAX_LENGTH + 1];
};
struct Grid
{
unsigned int num_players;
unsigned int day[NUM_MAX_PLAYERS]
[NUM_MAX_PLAYERS];
};
void printList(struct PlayerList *list)
{
for (int i = 0; i < list->num_players; i++)
{
printf("%d:%s\n", i + 1, list->name[i]);
}
}
struct Grid calculer_berger(struct PlayerList *list)
{
struct Grid grid;
// algo pour remplir la grid
grid.num_players = list->num_players;
int i, j;
for (i = 0; i < list->num_players - 1; i++)
{
for (j = 0; j < list->num_players - 1; j++)
{
if (i == j)
{
/* edge cases */
grid.day[i][list->num_players - 1] = ((i + j) + (i + j) / list->num_players) % list->num_players;
grid.day[list->num_players - 1][j] = ((i + j) + (i + j) / list->num_players) % list->num_players;
grid.day[i][j] = 0;
}
else
{
grid.day[i][j] = ((i + j) + (i + j) / list->num_players) % list->num_players;
}
}
}
grid.day[0][list->num_players - 1] = list->num_players - 1;
grid.day[list->num_players - 1][list->num_players - 1] = 0;
grid.day[list->num_players - 1][0] = list->num_players - 1;
return grid;
}
void permuter(struct Grid *grid)
{
int tmp;
for (int i = 0; i < grid->num_players; i++)
{
for (int j = 1; j <= grid->num_players / 2; j++)
{
tmp = grid->day[i][j];
grid->day[i][j] = grid->day[i][grid->num_players - j];
grid->day[i][grid->num_players - j] = tmp;
}
}
}
void print_grid(struct Grid *grid, struct PlayerList *list)
{
for (int i = 0; i < grid->num_players; i++)
{
for (int j = 0; j < grid->num_players; j++)
{
if (j == 0)
{
printf("%d:", grid->day[i][j] + 1);
}
else
{
printf("%d", grid->day[i][j] + 1);
if (j < grid->num_players - 1)
{
printf(",");
}
}
}
printf("\n");
}
}
int main(int argc, char **argv)
{
struct PlayerList playerList;
char nom[NAME_MAX_LENGTH + 1];
int nbCharLu = 0;
while ((nbCharLu = fscanf(stdin, "%s", nom)) != -1)
{
strcpy(playerList.name[playerList.num_players], nom);
playerList.num_players++;
}
struct Grid myGrid = calculer_berger(&playerList);
printList(&playerList);
print_grid(&myGrid, &playerList);
printf("Apres la permut\n");
permuter(&myGrid);
print_grid(&myGrid, &playerList);
return 0;
}
Assuming you are storing the elements in an Integer array and that you would like to just display the results.
Here is one implementation....The code should accommodate "N" values because of the use of "sizeof"....
feel free to customize it further....
#include <stdio.h>
int main() {
int i,j;
int array[] = {1,2,3,4};
for(i = 0; i < sizeof(array)/sizeof(int);++i){
printf("(%d :",array[i]);
for(j = 0; j < sizeof(array)/sizeof(int);++j){
if(j == i)
continue;
printf("%d ",array[j]);
}
printf(")\n");
}
}
#include <stdio.h>
void main() {
int mid;
int num;
int j, temp;
int k = 0;
int num1;
int data[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
num = sizeof(data)/sizeof(int);
mid = (sizeof(data)/sizeof(int))/2;
while(k < num - 1){
printf("Round %d ( ",k+1);
num1 = num;
for(int i = 0;i < mid;i++,num1--) /*pairing the competitors in each round*/
printf("%d:%d ",data[i],data[num1-1]);
for(int i = 0,j = num-1; i < num -2;i++,j--){ /* fixing the first competitor and rotating the others clockwise*/
temp = data[j];
data[j] = data[j-1];
data[j-1] = temp;
}
printf(")\n");
k++;
}
}
I am getting a SIGABRT error here. I don't understand why. Please help me out with this. It runs fine on my computer but on submitting it, it gives a SIGABRT on the very first test case. The memory alloted is to the order of 10^5 only and I have used vectors, instead of arrays, even then it gives this error.
#include <bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d", &T);
while(T--){
string s;
cin>>s;
int N;
string str;
scanf("%d", &N);
vector <string> f;
for (int i=0; i<N; i++){
cin>>str;
f.push_back(str);
}
vector<int> op;
op.resize(10, 0);
for (int i=0; i<N; i++){
for (int j=0;j <10; j++){
op[i] *= 2;
op[i] += ((f[i][j] == '+')? 1: 0);
}
}
int sint=0;
for (int i=0; i<10; i++){
sint*=2;
sint += ((s[i] == 'b')? 1: 0);
}
int allb = 1023;
int tgt = allb ^ sint;
vector <long long int> prev, curr;
prev.resize(1027, 0);
curr.resize(1027, 0);
prev[op[0]] = 1;
prev[0] = 1;
curr[0] = 1;
curr[op[0]] = 1;
if (op[0] == 0){
curr[op[0]]++;
prev[op[0]]++;
}
for (int i=1; i<N; i++){
for (int j=0; j<=1023; j++){
curr[j] = (prev[j] + prev[j ^ op[i]])%1000000007;
}
for (int j=0; j<=1023; j++)
prev[j] = curr[j];
}
cout<<curr[tgt]<<endl;
}
}
//Hello, I was just writing this program and I couldn't figure out as to why my output isn't printing correctly. Answer should be 1,2,3,4,6 but it prints 2,1,4,3,6 instead. Thank a bunch.
#include <iostream>
using namespace std;
void bubblesort(int A[], int n)
{
for (int i =1; i< n-1; i++)
{
for (int j =0; j< n-i-1; j++)
{
if(A[i] > A[i+1])
{
swap(A[i], A[i+1]);
}
}
}
}
int main()
{
int A[] = {2,4,1,6,3};
bubblesort(A,5);
for(int i =0; i<5; i++)
{
cout<<A[i]<<" ";
}
}
you are not writing the outer loop correctly and swap with variable j as in follow code.
#include <iostream>
using namespace std;
//Bubble Sort
void bubble_sort (int arr[], int n)
{
for (int i = 0; i < n; ++i)
for (int j = 0; j < n - i - 1; ++j)
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
//Driver Function
int main()
{
int input_ar[] = {10, 50, 21, 2, 6, 66, 802, 75, 24, 170};
int n = sizeof (input_ar) / sizeof (input_ar[0]);
bubble_sort (input_ar, n);
cout << "Sorted Array : " << endl;
for (int i = 0; i < n; ++i)
cout << input_ar[i] << " ";
return 0;
}