1

I have this code and I try to make use of pthreads and MPI. I am facing a weird problem. dist.start and dist.end must be same in the pthread function but this does not happen. Anyone that knows what is the problem?

Sorry for my english.

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <mpi.h>

void *compute_multiplication(void *arg);

#define NUMTHRDS 2 
#define VECLEN 100
#define SUCCESS 1 
typedef struct
{
 int start;
 int end;
 int rank;
}DIST;
typedef struct
{
 double *a;
 double *b;
 double sum;
 int veclen;
}DOTDATA;

DOTDATA dotstr;
DIST dist;
pthread_t threads[NUMTHRDS];
pthread_mutex_t mutexsum;

int main(int argc, char *argv[])
{
 double *a;
 double *b;
 int i;
 int *status;
 int err;
 int rank;
 int size;
 int div;

 a = (double *)malloc(NUMTHRDS*VECLEN*sizeof(double));
 b = (double *)malloc(NUMTHRDS*VECLEN*sizeof(double));

 err = MPI_Init(&argc, &argv);
 if(err!=MPI_SUCCESS)
  MPI_Abort(MPI_COMM_WORLD, err);

 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 MPI_Comm_size(MPI_COMM_WORLD, &size);

 div = NUMTHRDS*VECLEN/size;

 for(i=0;i<VECLEN*NUMTHRDS;i++)
 {
  a[i] = 1.0;
  b[i] = 2*a[i];
 }

 dotstr.veclen = VECLEN;
 dotstr.a = a;
 dotstr.b = b;
 dotstr.sum = 0;

 pthread_mutex_init(&mutexsum,NULL);
 pthread_attr_t attr;
 pthread_attr_init(&attr);

 pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); 

 for(i=0;i<NUMTHRDS;i++)
 {
  if(i==0)
  {
   dist.start = rank*div;
  }
  if(i==1)
  {
   dist.start = dist.end;
  }
  dist.end = dist.start + div/2;
  dist.rank = rank;

  printf("rank:%d dists:%d diste1:%d\n",rank,dist.start,dist.end);

  pthread_create(&threads[i],&attr,compute_multiplication,&dist);
 }
 pthread_attr_destroy(&attr);

 for(i=0;i<NUMTHRDS;i++)
 {
  int err;
  pthread_join(threads[i],(void *) &status);
 }
 if(rank==0)
 {
  printf("SUM:%f\n",dotstr.sum);
 }

 free(a);
 free(b);

 pthread_mutex_destroy(&mutexsum);
 MPI_Finalize();
 return 0;
}

void *compute_multiplication(void *arg)
{
 int i;
 DIST* input = (DIST *)arg;
 int start = input->start;
 int end = input->end;
 int sum = 0;
 printf("(%d)%d %d\n",input->rank, start,end);

 //for(i=start;i<end;i++)
 //{
 // sum = sum + dotstr.a[i]*dotstr.b[i];
 //}
 //printf("dists:%d diste1:%d\n",dist.start,dist.end);

 pthread_mutex_lock(&mutexsum);

 dotstr.sum = sum;

 pthread_mutex_unlock(&mutexsum);
 pthread_exit((void*) 0);

}

1 Answer 1

3

Your dist argument to each thread is a pointer to the single global instance declared at the top-level. The thread you're creating will be spawned and read from that argument sometime later, when the loop in main has moved on and written different values into dist. You want a DIST instance per thread, such as by allocating an array of NUMTHRDS of them .

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.