I have a code, which counts the average value of integers in MPI:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi.h>
#include <assert.h>
// Average method
int compute_avg(int *array, int num_elements) {
int sum = 0;
int i;
for (i = 0; i < num_elements; i++) {
sum += array[i];
}
return sum / num_elements;
}
int main(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "Usage: avg num_elements_per_proc\n");
exit(1);
}
int num_elements_per_proc = atoi(argv[1]);
MPI_Init(NULL, NULL);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// Create array with integers
int *nums = NULL;
if (world_rank == 0) {
for (int i =0; i<5; i++){
nums[i] = i;
}
}
// Subtable from any processes
int *sub_nums = (int *)malloc(sizeof(int) * num_elements_per_proc);
assert(sub_nums != NULL);
// distribution numbers for all processes
MPI_Scatter(nums, num_elements_per_proc, MPI_INT, sub_nums,
num_elements_per_proc, MPI_INT, 0, MPI_COMM_WORLD);
// Count avg subtable
int sub_avg = compute_avg(sub_nums, num_elements_per_proc);
// Collectiong averages
int *sub_avgs = NULL;
if (world_rank == 0) {
sub_avgs = (int *)malloc(sizeof(int) * world_size);
assert(sub_avgs != NULL);
}
MPI_Gather(&sub_avg, 1, MPI_INT, sub_avgs, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Calculates the overall average
if (world_rank == 0) {
int avg = compute_avg(sub_avgs, world_size);
printf("Avg of all elements is %d\n", avg);
// Obliczenie średniej na danych oryginalnych i wyświetlenie.
int original_data_avg =
compute_avg(nums, num_elements_per_proc * world_size);
printf("Avg computed across original data is %d\n", original_data_avg);
}
// free memory
if (world_rank == 0) {
free(nums);
free(sub_avgs);
}
free(sub_nums);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return 0;
}
When i try to run this (mpirun -c 4 avg 4), i`m getting the error list:
[mangeke-mpi-2431940:03372] * Process received signal *
[mangeke-mpi-2431940:03372] Signal: Segmentation fault (11)
[mangeke-mpi-2431940:03372] Signal code: Address not mapped (1)
[mangeke-mpi-2431940:03372] Failing at address: (nil)
[mangeke-mpi-2431940:03372] * End of error message *
How i can fix this problem?
As Hristo comments, the nums is initialized to NULL. If you explore the core file generated with the debugger, it raises the following statement
Core was generated by `./m 4'. Program terminated with signal SIGSEGV,
Segmentation fault.
#0 0x0000000000408809 in main (argc=2, argv=0x7ffd4fc87e68) at m.cxx:36 36 nums[i] = i;
if you change the following code as shown below you'll get to make it run without segfaulting.
....
// Create array with integers
int nums[num_elements_per_proc]; // <<-- change here
if (world_rank == 0) {
for (int i =0; i<5; i++){
nums[i] = i;
}
}
....
// free memory
if (world_rank == 0) {
// free(nums); // <<-- change here, free not needed
free(sub_avgs);
}
Related
Im practising in parallel programming using MPI and i developed a programm that is calculating the average and how many numbers of the array are greater or fewer than the average. Unfortunately when im trying to run it on linux ubuntu system i get this *Caught signal 11 (Segmentation fault: address not mapped to object at address 0xff00000107), backtrace(tid: 5699).
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc, char** argv){
int p, plithos, i, k, count_max,count_min, sunexeia;
int *pinakas;
int *final_res;
int loc_matrix[100];
int loc_num;
int my_rank;
int root, local_sum, sum, j, source;
int tag1=50;
int tag2=60;
int tag3=70;
int tag4=80;
float average;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
if (my_rank == 0) {
printf("please give the size of the array: ");
scanf("%d", &plithos);
pinakas = (int *) malloc(plithos * sizeof(int));
for (i = 0; i < plithos; i++) {
printf("Give the %d number: ", i);
scanf("%d", &pinakas[i]);
}
}
root = 0;
MPI_Bcast(&plithos, 1, MPI_INT, root, MPI_COMM_WORLD); // here we are sending the size of the array to the processors
loc_num = plithos / p;
root = 0;
MPI_Scatter(&pinakas, loc_num, MPI_INT, &loc_matrix, loc_num, MPI_INT, root, MPI_COMM_WORLD); // here we are sending the amount of tasks that every processor must have
local_sum=0; // here all processors will calculate their sums
if (my_rank == 0) {
int start = 0;
int end = loc_num;
for (i = start; i < end; i++){
local_sum += pinakas[i];
}
}
else{
int start = my_rank * loc_num;
int end = my_rank + loc_num;
for (i = start; i < end; i++){
local_sum += pinakas[i];
}
}
MPI_Reduce(&local_sum, &sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); //here with the reduce we are caclulating all the sums from all processors
if (my_rank == 0) { // processor 0 finds the average
average = (double)sum / plithos;
printf("The average is: %f\n", average);
}
root = 0;
MPI_Bcast(&average, 1, MPI_FLOAT, root, MPI_COMM_WORLD); //edo stelnoume tin mesi timi stis upoloipes diergasies
if (my_rank = 0){ //edo h diergasia 0 tha upologisei posa stoixeia exoun min kai max > tou average
for(i=0; i<plithos; i++){
if(pinakas[i]> average){
count_max = count_max +1;
}
if(pinakas[i]< average){
count_min = count_min +1;
}
}
printf("To plithos ton stoixeion pou exoun megaluteri timi apo tin mesi timi einai: %d", count_max);
printf("To plithos ton stoixeion pou exoun mikroteri timi apo tin mesi timi einai: %d", count_min);
}
MPI_Finalize();
}
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.
I am trying to implement a map where keys are numbers mapping into unique numbers. In other words, each process holds a set of numbers in an array that map into another set of numbers in another array held by the same process. The mappings need to be unique across all the process. I passed around a struct with the mappings to create mappings for each of the processes. However, this is not parallel, as I sequentially send information through processes. I request help from all of you wonderful programmers of the internet for how all processes can look at a specific variable at the same time? The following is the code I am currently working with. Thanks in advance and for all the support I have received till now.
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct map{ //saves all the mappings
int keys[25];
int values[25];
int grow;
};
struct map rmap; //global map
void mapadd(int key, int value){ //adding values to map
rmap.keys[rmap.grow] = key;
rmap.values[rmap.grow] = value;
rmap.grow++;
}
int mapper(int key){ //get value from key
for(int h=0; h<sizeof(rmap.keys)/sizeof(int); h++){
if(rmap.keys[h] == key){
return rmap.values[h];
}
}
return 0;
}
int finder(int list[], int val, int mem){ //see if a value is in array
for(int l=0; l<mem; l++){
if(list[l] == val){
return 1;
}
}
return 0;
}
int main(int argc, char** argv){
// Initialize the MPI environment
MPI_Init(NULL, NULL);
// Find out rank, size
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
srand(time(0));
rmap.grow = 0;
int dim[world_size];
int maxdim = 0;
for(int s=0; s<world_size; s++){
dim[s] = (rand()%10) + 1;
if(dim[s]>maxdim){
maxdim = dim[s];
}
}
int nums[world_size][maxdim];
int labels[world_size][maxdim];
for(int u=0; u<world_size; u++){
for(int d=0; d<dim[u]; d++){
labels[u][d] = 0;
nums[u][d] = 0;
}
}
for(int t=0; t<world_size; t++){
for(int i=0; i<dim[t]; i++){
nums[t][i] = rand()%26 + 1;
//printf("%d\n", nums[t][i]);
}
}
if(world_rank!=0){
MPI_Recv(&rmap.keys, 25, MPI_INT, world_rank-1, 0,
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&rmap.values, 25, MPI_INT, world_rank-1, 0,
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
for(int j=0; j<dim[world_rank]; j++){
if(labels[world_rank][j] == 0){
if(finder(rmap.keys, nums[world_rank][j], 25)==1){
//printf("%s", "exist");
labels[world_rank][j] = mapper(nums[world_rank][j]);
}
else{
//printf("%s", "not");
labels[world_rank][j] = (rand()%50) + 1;
mapadd(nums[world_rank][j], labels[world_rank][j]);
/*for(int o=0; o<25; o++){
printf("%d - %d", rmap.keys[o], rmap.values[o]);
}*/
}
}
}
if(world_rank<world_size-1){
MPI_Send(&rmap.keys, 25, MPI_INT, world_rank+1, 0, MPI_COMM_WORLD);
MPI_Send(&rmap.values, 25, MPI_INT, world_rank+1, 0, MPI_COMM_WORLD);
}
for(int rank=0; rank<world_size; rank++){
if(rank==world_rank){
for(int k=0; k<dim[rank]; k++){
printf("Process #%d: %d --> %d\n", rank, nums[rank][k], labels[rank][k]);
}
}
}
MPI_Finalize();
return 0;
}
Hallo Iam trying to make a simlpe parralel program in C language uing MPI. Program should find maximum in array. Root process should send chunks of array to all processes using MPI_Scatter and then gather results by MPI_Gather. When I run the program i get general error like this:
Perhaps this Unix error message will help:
Unix errno: 14
Bad address
I know that there is some problem with MPI_Scatter and MPI_Gather or with the values I am sending to this functions.
I was trying to find the solution, but I found nothing what could be useful.
Here is my code:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 9
int max(int *buf, int N){
int i;
int value = 0;
for(i=0; i<N; i++){
if (buf[i]>value){
value = buf[i];
}
}
return value;
}
int main(int argc, char** argv)
{ int size, rank;
int slave;
int *buf;
int *buf1;
int *buf2;
int i, n, value;
MPI_Status status;
/* Initialize MPI */
MPI_Init(NULL, NULL);
/*
* Determine size in the world group.
*/
MPI_Comm_size(MPI_COMM_WORLD, &size);
if ((BUFSIZE % size) != 0) {
printf("Wrong Bufsize ");
return(0);
}
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank==0) {
buf = (int *)malloc(BUFSIZE*sizeof(int));
buf2 = (int *)malloc(size*sizeof(int));
printf("\n Generated array: \n");
for(i=0; i<BUFSIZE; i++){
buf[i] = rand() % 20;
printf("%d, ", buf[i]);
}
printf("\n");
printf("\n Sending values to processes:");
printf("\n -----------------------------");
}
buf1 = (int *)malloc((BUFSIZE/size)*sizeof(int));
MPI_Scatter(buf, BUFSIZE/size, MPI_INT, buf1, BUFSIZE/size, MPI_INT, 0, MPI_COMM_WORLD);
value = max(&buf1[0], BUFSIZE/size);
printf("\n Max from rocess %d : %d \n", rank, max(&buf1[0], BUFSIZE/size));
MPI_Gather(&value, 1, MPI_INT, buf2, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0){
printf("\n Max value: %d", max(&buf2[0], size));
}
MPI_Finalize();
return(0);
}
Initialize your pointers to NULL, and track them.
use buf1 instead of &buf1[0], is more clear.
free your buffers before MPI_Finalize() with:
if(bufferPionter != NULL) free(bufferPionter);
If something is wrong with a pointer will crash in the free call. In the max function, If all your numbers are less than zero the maximun is zero. i fix that.
int max(int *buf, int N){
int i;
int value = N? buf[0] : 0;
for(i=0; i<N; i++){
if (buf[i]>value){
value = buf[i];
}
}
return value;
}
Best regards!
I am trying to write a multi threaded program that takes a list of numbers from the command line and calculates various statistical values eg average, sum etc using separate worker threads. i have created three threads in this program and it compiles but i get errors. I am new to C and thread programming, please guide me in passing data to the thread for calculations?
This is my code:
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#define NUM_THREAD 3
int average, min, max;
void *
doSomeThing(void *param)
{
//int *id_ptr, taskid;
int *argv = (int *) param;
sleep(1);
//id_ptr=(int *) threadid;
//taskid= *id_ptr;
int j;
int sum = 0;
int upper = atoi(param);
sleep(1);
pthread_t id = pthread_self();
unsigned long i = 0;
if (id = 1) {
int i;
for (i = 0; i < upper; i++) {
sum += argv[i];
}
printf("sum of no's is :\n", sum);
}
if (id = 2) {
printf("\n Second thread processing\n");
}
if (id = 3) {
printf("\n Third thread processing\n");
}
for (i = 0; i < -1; i++);
{
pthread_exit(NULL);
}
}
int
main(int argc, char *argv[])
{
pthread_t threads[NUM_THREAD];
pthread_attr_t attr;
int *taskid[NUM_THREAD];
int i = 0;
int t;
int err;
//int input,a;
if (argc != 2) {
fprintf(stderr, "usage: a.out <integer value>\n");
return -1;
}
/*
printf("how many no's do u want to evaluate?:\n");
scanf("%d", &input);
printf("Enter the no's:\n");
for (a = 0; a < input; a++) {
arr[a] = (int) malloc(sizeof(int));
scanf("%d", &arr[a]);
printf("data:", &arr[a]);
}
*/
pthread_attr_init(&attr);
for (t = 0; t < NUM_THREAD; t++) {
taskid[t] = (int *) malloc(sizeof(int));
*taskid[t] = t;
printf("In main: creating thread %d\n", t);
err = pthread_create(&threads[t], &attr, doSomeThing, argv[1]);
if (err) {
printf("Error; return code from pthread_create() is %d\n",
err);
exit(-1);
}
}
for (t = 0; t < NUM_THREAD; t++) {
pthread_join(threads[t], NULL);
printf("Joining thread %d\n", t);
}
pthread_exit(NULL);
}
What makes you think pthread_create assigns a nice little number like 1, 2, 3 as a thread_id? When you call pthread_self(), it is unlikely that you will get 1, 2, or 3. Also you should eventually free the memory you obtained from malloc.
My suggestion is that you write a separate function for average, max, and min and call pthread_create explicitly 3 times passing in the 3 separate functions instead of using one function to do all.