collect result MPI C - c

hi guys i wanted to ask you for help with the array data collection, below there is my code and here what it should do
implementation of a parallel algorithm in which each
processor read a different size vector
M, carry out the sum of its elements in the memory
local and concatenate results in a contained vector
in the memory of each processor.
CODE
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
int * a;
int i, n;
MPI_Init (&argc, &argv);
MPI_Comm_size (MPI_COMM_WORLD, &nproc);
MPI_Comm_rank (MPI_COMM_WORLD,&menum);
printf("Insert the size of the array\n");
scanf ("%d", &n);
a = (int *) malloc(sizeof(int)*n);
printf("Size degli array inserito correttamente\n");
printf("Ora, inserire i %d elementi di a\n", n);
for(i = 0; i < n; i++)
scanf ("%d", &a[i]);
printf("Elementi di a inseriti correttamente\n");
float local_sum = 0;
int i;
for (i = 0; i < n; i++) {
local_sum += a[i]; \\
}
MPI_Allgather(&localsum,1,MPI_INT,localsum,1,MPI_INT,MPI_COMMON_WORLD);
MPI_Finalize();
}

Related

Copy of random matrix in C

Just as the title says, here I ask for two inputs in order to generate a matrix based on such inputs from the user, which then will be filled with random numbers up to the number 20.The problem is I can't wrap my head around the logic needed to generate an exact copy of this matrix without generating a second matrix with randomly generated numbers(again) so I can make useof the data stored in the copy.
(Edit)
I've added an image as reference of what I'm trying to achieve.
I tried to store the random values in a one dimensional array, so I can use them later, but I'm not sure if it is the right approach. I'm relatively new to coding and still struggling with the basics, so any help will be greatly appreciated.
HereĀ“s the code that generates the matrix and stores random int values in it.
#include <stdio.h>
#include<time.h>
int matrizAleatoria(int m, int n, int r);
int srand();
int rand();
int main()
{
int m, n;
printf("Introduce el numero de filas:\n");
scanf("%d", &m);
printf("Introduce el numero de columnas:\n");
scanf("%d", &n);
printf("\n");
srand(time(0));
int r = (rand()% 20);
matrizAleatoria(m, n, r);
printf("\n");
return 0;
}
int matrizAleatoria(int m, int n, int r)
{
int i, j, p = m * n;
int matriz1[m][n];
int serie[p];
for(i = 0; i<m; i++)
{
for(j = 0; j<n; j++)
{
matriz1[i][j] = r = (rand()% 20);
serie[i] = r;
printf("[ %-2d ] " , matriz1[i][j]);
}
printf("\n");
}
return serie[i];
}
You cannot return a variable-sized array from a function to outside scope. You have to implement 2-dimensional subscripts yourself and only work with pointers. Like this:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define SUBSCRIPT_2DIM_TO_1DIM(subscript1, subscript2, size2) \
((subscript1) * (size2) + (subscript2))
int* matrizAleatoria(int m, int n);
int main()
{
int m, n;
int* matriz1;
printf("Introduce el numero de filas:\n");
scanf("%d", &m);
printf("Introduce el numero de columnas:\n");
scanf("%d", &n);
printf("\n");
srand(time(0));
matriz1 = matrizAleatoria(m, n);
printf("\n");
// use matriz1 with SUBSCRIPT_2DIM_TO_1DIM
free(matriz1);
return 0;
}
int* matrizAleatoria(int m, int n)
{
int i, j, p = m * n;
// return matrix value, must free() in the caller
int *matriz1 = malloc(sizeof(int) * p);
for(i = 0; i<m; i++)
{
for(j = 0; j<n; j++)
{
matriz1[SUBSCRIPT_2DIM_TO_1DIM(i, j, n)] = rand()% 20;
printf("[ %-2d ] " , matriz1[SUBSCRIPT_2DIM_TO_1DIM(i, j, n)]);
}
printf("\n");
}
return(matriz1);
}

Finding the square sum of an array with pthreads in C

What I need to do is calculate the square sum of an array. The array and the number of threads must be given by the user, and we assume the number of elements and the number of threads are integrally divided.
My code doesn't even compile.. I know I have issues with the pointers, and I should place mutexes but I don't know where exactly. Can you point me to the right direction? I will appreciate it a lot.
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int part = 0;
int local_elements = 0;
void* square_sum(void* arg)
{
int local_sum = 0;
int *element_array[] = (int *)arg;
//Each thread computes its part
int thread_part = part++;
for (int i = thread_part * loc_elements; i < (thread_part + 1)*loc_elements; i++) {
local_sum += element_array[i] * element_array[i];
}
return (void*)&local_sum;
}
main()
{
int threads, total_elements;
int i;
int total_sum = 0;
printf("Give the number of threads: ");
scanf("%d", &threads);
printf("Give the number of the elements you want: ");
scanf("%d", &total_elements;)
int element_array[total_elements];
//How many elements each thread gets
local_elements = total_elements / threads;
printf("Give the %d elements \n", total_elements);
for (i = 0; i < total_elements; i++) {
printf("No. %d:", i);
scanf("%d", &element_array[i]);
}
pthread_t newthread[threads];
//Creating the threads
for (int i = 0; i < threads; i++) {
//The start routine gets the whole element_array
pthread_create(&newthread[i], NULL, square_sum, &element_array);
}
int loc_sum;
//Waiting for each thread to finish and creating the total_sum
for (int i = 0; i < threads; i++) {
pthread_join(newthread[i], &loc_sum);
total_sum += loc_sum;
}
printf("The total sum is: %d", &total_sum);
}

Control some code to be executed once in MPI

I can't control how to make to execute some code once using mpi
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#define N 10
#define ITERS 1
// N and ITERS might be input arguments
double **A;
int times = 0;
void initialize (double **A)
{
int i,j;
for(i =0; i < N+2 ; i++){
for(j =0; j < N+2 ; j++){
if(i== 0 || j == 0 || i == (N+1) || j == (N +1) )
A[i][j] = 0.0;
else
A[i][j] = rand() % 10 + 1;
}
}
}
int main(int argc, char * argv[]){
int MyProc, size,tag=1;
char msg='A', msg_recpt;
MPI_Status status;
double **received_array;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &MyProc);
MPI_Comm_size(MPI_COMM_WORLD, &size);
printf("Process # %d started \n", MyProc);
MPI_Barrier(MPI_COMM_WORLD);
int i;
/******Make it once*******/
if(times == 0){
printf("One time\n");
A = malloc((N+2) * sizeof(double *));
for (i=0; i<N+2; i++) {
A[i] = malloc((N+2) * sizeof(double));
}
initialize(A);
times ++;
}
/*************/
MPI_Barrier(MPI_COMM_WORLD);
}
MPI_Finalize();
}
I've tried with times variable as a flag but the make it once section it's executed once per process...everethig I've tried it's executed once per process ,I don't know what to try, I can't make it using the rank of teh process because I need the first procees to arrive executes the once section.

TeraSort Algorithm using MPICH2 in C

I am trying to implement TeraSort algorithm according to this paper in C using MPICH2. Currently I am using small dataset with values given in the paper and using 4 processors.
int main(int argc, char** argv) {
/********** Create and populate the array *********/
FILE *file = fopen("data.txt","r");
int n; //number of data values
fscanf(file,"%d",&n);
printf("%d",n);
int *original_array = malloc(n * sizeof(int));
int num,c;
int i=0;
while (fscanf(file, "%d", &num) == 1){
original_array[i] = num;
i++;
}
fclose(file);
/********* Finding max and min values ************/
int max = -32768; //change if "int" is changed
int min = 32767;
for(i=0; i<n; i++){
if(max < original_array[i]){
max = original_array[i];
}
if(min > original_array[i]){
min = original_array[i];
}
}
printf("%d", min);
printf("\n");
printf("%d", max);
/********** Initialize MPI **********/
int world_rank;
int world_size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
/********** FILE PLACEMENT **********/
int nodeDataSize = n/world_size;
printf("%d",nodeDataSize);
printf("\n");
MPI_Finalize();
All the values printed (n, min, max, nodeDataSize) are incorrect. The file data.txt contains space separated integers where the first integer gives the number of values. Can anyone tell me what's wrong?
This is what the data.txt file looks like:

how to store multiple arrays and make array of pointers to them

I don't have a lot of experience with pointers, but I want to try to make an array of pointers, each pointer pointing to a scanned string.
For example, you first input how many strings you want to scan (for example 5), and then I want to scan those strings and make an array of 5 pointers that point to those strings.
Because I didn't have a lot experience with something like this, I first tried it with normal arrays instead of strings, what I got is this:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
int **array(int m, int n) {
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=*array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
But here it's already going wrong, and I don't know why...
At the last printf, I always get wrong numbers, 0's and 17's...
Can someone explain me why this is and what I'm doing wrong? I think it's something with the returning of the array but I'm not sure..
If someone could explain this to me it would be great.
The problem with your code is the following:
// m = 3, n = 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j;
int **array = (int**)malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=(int*)malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
In the above example (m=3, n=5) you allocated 5 pointers to integers and then tried to populate them by allocating memory at each iteration in the inner-loop (WRONG). If you allocate new memory at each iteration, you're gonna lose the pointer to the previously allocated memory and the data you stored!
Plus the indices seem to be wrong for the inner and outer loop, a correct version of your code is:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
// 3, 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j, index;
int **array = (int**)malloc(n*sizeof(int*));
index = 0;
for (j=0; j<n; j++) {
array[j]=(int*)malloc(m * sizeof(int)); // Allocate once per each j
for (i=0; i<m; i++) {
array[j][i] = index++;
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, **p, k, i, j;
m = 3;
n = 5;
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the numbers are:\n");
for (j=0; j<n; j++)
for(i=0; i<m; i++)
printf("%d\n", p[j][i]);
return 0;
}
And the above version is STILL NOT CORRECT : You need to free the allocated memory!
I'll leave that as an exercise.. hint: you CAN'T simply do "free(p);" :]
Are you sure about this for loop? If you've the malloc inside the inner loop you're not creating a matrix because every time you override the same cells...
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
It should be something like:
int i, j;
int **array = malloc(n*sizeof(int*));
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
for (j=0; j<m; j++) {
scanf("%d", &array[i][j]);
printf("array[%d][%d] is scanned and has value %d\n", i, j, array[i][j]);
}
}
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
void *array(int m, int n) {
int i, j;
int (*array)[n] = malloc(sizeof(int [m][n]));//m*n*sizeof(int)
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=(int*)array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
#include <stdlib.h>
#include <stdio.h>
char **array(int m, int n) {
int i;
char **array = malloc(m*sizeof(char*));
for (i=0; i<m; ++i) {
array[i] = malloc(n*sizeof(char));//Fixed length : like char array[m][n] (char *array[m])
scanf("%s", array[i]);//!! There is no length constraints.
printf("array[%d] is scanned and has value %s\n", i, array[i]);
}
return array;
}
int main(int argc, char*argv[]){
int m, n, k;
char **p;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the string are:\n");
for (k=0; k<m; ++k) {
printf("%s\n", p[k]);
}
return 0;
}
I'm not sure if I do this smart, but I usually allocate the pointer array and then allocate the whole memory chunk to the first item. Then I get continuous memory for the data. Like:
_array = (float**) malloc( n * sizeof ( float * ));
assert ( _array != NULL );
_array[0] = (float*) malloc( n * m * sizeof ( float ));
assert ( _array[0] != NULL );
for ( idx = 0; idx < n; idx++ )
_array[ idx ] = _array[ 0 ] + idx * m;
(float instead of int in my case. And please don't comment on the return of malloc casting, nor on the silly user of assert())

Resources