Thread: matrix multipilation with mpi

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    11

    Smile matrix multipilation with mpi

    i have a code which has 2 static matrices ,i want it read 2 matrices from 2 files matrix 1 in file 1 matrix 2 in file and file formate
    //**********************************
    Objective
    The objective of the project is to perform matrix multiplication using the parallel computing
    frameworks : MPI
    File Formats
    The program must be standard as follows:
    • There are two input files. File 1 contains matrix 1, file 2 contains matrix 2. There is one output
    file, containing the output matrix.
    • Each of these files follows a standard format: At the beginning of the file there is the size of the
    square matrix, followed by a tab, then all the matrix elements row by row separated by a tab.
    Example:
    This matrix:
    1.1 2.3 4.5
    8.0 9 4.4
    2.5 7.0 6.8
    should be saved in a file as follows:
    3 1.1 2.3 4.5 8.0 9 4.4 2.5 7.0 6.8
    • The program should execute using the following command:
    matrixmul.exe C:\matrix1.txt C:\matrix2.txt C:\matrixout.txt
    //***********************************************
    my code have some error and i don't understand the error and how to solve it , please
    help me

    //********************************************
    Code:
    #include "mpi.h"
    #include <stdio.h>
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include<string>
    using namespace std;
         int NRA ;		/* number of rows in matrix A */
    	 int NCA ;		/* number of columns in matrix A */
         int NCB ;	   /* number of columns in matrix B */
    
    #define MASTER 0		/* taskid of first task */
    #define FROM_MASTER 1		/* setting a message type */
    #define FROM_WORKER 2		/* setting a message type */
    MPI_Status status;
    void resalt_matrix(double **&array_ptr,int NRA)
    {
    	            array_ptr=new double*[NRA]; //creates a new array of pointers to int objects
    				for(int i=0; i<NRA; ++i)
    				array_ptr[i]=new double[NRA];
    }
    void reading (string path,double **&array_ptr,int& NRA,int & NCA)
    {
    	ifstream inFile;
        double x=0;
    	int size=0;
    	bool var=true;
    	int c1=0,c2=0,count=0;
    	//double **array_ptr;   //two * are needed because it is a pointer to a point
        inFile.open(path);
        if (!inFile) 
    	{
            cout << "Unable to open file";
            exit(1); // terminate with error
        }
    	else
    	{
    		while (inFile >> x) 
    		{
    			if(var==true)
    			{
    			    size= x;
    				NRA=size;
    				NCA=size;
    				NCB=size;
    				size=0;
    				array_ptr=new double*[NRA]; //creates a new array of pointers to int objects
    				for(int i=0; i<NRA; i++)
    				array_ptr[i]=new double[NRA];
    				var=false;
    				break;
    				
    			}
    			
    		}
    		
    		while(inFile >> x)
    		{
    			/*if(var==false)
    			{
    				var==true;	
    			}
    			else
    			{*/
    			array_ptr[ c1 ][ c2 ]=x;
                   if( inFile ) 
    			   {
    							c2=c2+1;
    							if( c2 == NRA ) 
    							{                            
    								++c1;                   // Move to next row
    								c2 = 0;              
    							}
    			   }
    //}
    			}
    		}
    		inFile.close();
    		for(int i=0;i<NRA;i++)
    		{
    			cout<<endl;
    			for(int j=0;j<NRA;j++)
    				cout<<array_ptr[i][j]<<"	";
    		}
    		cout<<endl;
    	
    
    }
    
    void main(int argc, char **argv) 
    {
    int numtasks,			/* number of tasks in partition */
        myid,			/* a task identifier */
        numworkers,			/* number of worker tasks */
        source,			/* task id of message source */
        dest,			/* task id of message destination */
        nbytes,			/* number of bytes in message */
        mtype,			/* message type */
        intsize,			/* size of an integer in bytes */
        dbsize,			/* size of a double float in bytes */
        rows,                      	/* rows of matrix A sent to each worker */
        averow, extra, offset,      /* used to determine rows sent to each worker */
        i, j, k,			/* misc */
        count;
    double **a=0;		/* matrix A to be multiplied */
    double **b=0;      	/* matrix B to be multiplied */
    double **c=0;        /* result matrix C */
    
    
    intsize = sizeof(int);
    dbsize = sizeof(double);
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
    numworkers = 4;
    
    /**************************** master task ************************************/
    if (myid == MASTER) 
    {
    reading("E:\\ahmed.txt",a,NRA,NCA);
    reading("E:\\matrix.txt",b,NCA,NCB);
    resalt_matrix(c,NCA);
      printf("Number of worker tasks = %d\n",numworkers);
       for (i=0; i<NRA; i++)
       { 
        printf("\n"); 
        for (j=0; j<NCB; j++) 
          printf("%f   ", a[i][j]);
        }
      printf ("\n");
      for (i=0; i<NRA; i++) { 
        printf("\n"); 
        for (j=0; j<NCB; j++) 
          printf("%f   ", b[i][j]);
        }
      printf ("\n");
    
      /* send matrix data to the worker tasks */
      averow = NRA/numworkers;
      extra = NRA%numworkers;
      offset = 0;
      mtype = FROM_MASTER;
      for (dest=1; dest<=numworkers; dest++) {			
        rows = (dest <= extra) ? averow+1 : averow;   	
        printf("   sending %d rows to task %d\n",rows,dest);
        MPI_Send(&offset, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
        MPI_Send(&rows, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
        count = rows*NCA;
    	MPI_Send(&a[offset][0], count, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
    	//MPI::COMM_WORLD.Send(&a[offset][0],count,MPI::DOUBLE,dest,0);
        count = NCA*NCB;
        MPI_Send(&b, count, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
    
        offset = offset + rows;
        }
    
      /* wait for results from all worker tasks */
      mtype = FROM_WORKER;
      for (i=1; i<=numworkers; i++)	{			
        source = i;
        MPI_Recv(&offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
        MPI_Recv(&rows, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
        count = rows*NCB;
        MPI_Recv(&c[offset][0], count, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD, 
                   &status);
     
        }
    
      /* print results */
      printf("Here is the result matrix\n");
      for (i=0; i<NRA; i++) { 
        printf("\n"); 
        for (j=0; j<NCB; j++) 
          printf("%f   ", c[i][j]);
        }
      printf ("\n");
    
      }  /* end of master section */
    
    
    
    /**************************** worker task ************************************/
    if (myid > MASTER) {
      mtype = FROM_MASTER;
      source = MASTER;
      printf ("Master =%d, mtype=%d\n", source, mtype);
      MPI_Recv(&offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
      printf ("offset =%d\n", offset);
      MPI_Recv(&rows, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
      printf ("row =%d\n", rows);
      count = rows*NCA;
      MPI_Recv(&a, count, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD, &status);
      printf ("a[0][0] =%e\n", a[0][0]);
      count = NCA*NCB;
      MPI_Recv(&b, count, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD, &status);
      printf ("b=\n");
      for (k=0; k<NCB; k++)
        for (i=0; i<rows; i++) {
          c[i][k] = 0.0;
          for (j=0; j<NCA; j++)
            c[i][k] = c[i][k] + a[i][j] * b[j][k];
          }
    
      mtype = FROM_WORKER;
      printf ("after computer\n");
      MPI_Send(&offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
      MPI_Send(&rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
      MPI_Send(&c, rows*NCB, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD);
      printf ("after send\n");
    
      }  /* end of worker */
      MPI_Finalize();
    } /* of main */

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you're not going to tell us what the error is, then we're not going to understand it either.

  3. #3
    Registered User
    Join Date
    Dec 2010
    Posts
    11
    the( ahmed matrix_mul.cpp) run with no error and give me the result matrix ,in it the 2 martices have fixed size and values

    the(matrix mul_project.cpp) is the same code of the (ahmed matrix_mul.cpp) but i exchange fixed matrices with dynamic matrices i reads it from files , ahmed.txt matrix.txt put the 2 files in any path and exchang the path in my code , there is some errors in it why ???


    look at th image in attach files it is the error message in cmd run for (matrix mul_project.cpp).

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, the screenshot says "the system cannot find the file specified". So make sure you typed the program name correctly and are in the right directory, I guess.

  5. #5
    Registered User
    Join Date
    Dec 2010
    Posts
    11
    yes, the path has error and i typed it true agian but output has some error i want to help in it

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Well, just looking at the screenshot you called MPI_Recv with a count of 0 somehow, which was unfortunate as you appear to have actually sent data. Is 186 a line number? I don't feel like counting lines above to see where line 186 is. Since you have four workers and only three rows in your matrix, one worker won't get any work, I guess, so you need to be sure to handle that correctly.

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Worker tasks are trying to MPI_Recv into "a" and "b" - which haven't been allocated.

    The way you are allocating the matrices now (array of arrays), you will only be able to send/recv one row at a time. To send/recv multiple rows at once, you will need to allocate your matrices as contiguous memory.
    Question 6.16
    [13] Operator overloading Updated! , C++ FAQ

    gg

  8. #8
    Registered User
    Join Date
    Dec 2010
    Posts
    11
    i don't understand the problem with this error. the error in (matrices a&b) or in send&recive??!!
    in anther program in image attach (it deal with the same problem but with static matrices ,fixed size and static values ) it send and recive in the same way i send and recive
    this code in (ahmed matrix_mul.cpp) in firest attachs files
    and the code with the error (matrix mul_project.cpp),if you want to see them...,
    the code of (ahmed matrix_mul.cpp) i want it read matrix a from a.txt and read matrix b from b.txt

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by ahmed eltaher View Post
    i don't understand the problem with this error. the error in (matrices a&b) or in send&recive??!!
    Yes.

    Your arrays a and b are allocated in the reading function. But the reading function is only called in the if(myid == MASTER) part of the code. Any attempt to use a and b in the if(myid > MASTER) part of the code is going to Not Work At All, unless you allocate the necessary space in the > MASTER section of the code. (This shouldn't really be a surprise -- you should basically always be allocating buffers as needed when doing a receive, no matter what kind of communication you're doing.)

    When using dynamic arrays, rows are not stored next to each other as they are in static arrays. So (for instance) if you wanted to send two rows of these 3x3 matrices, you couldn't just pick a starting point and send 48 bytes; you would have to get the first row and send 24 bytes, then find the second row and send 24 bytes from there.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting Matrix
    By alex 2010 in forum C++ Programming
    Replies: 0
    Last Post: 06-24-2010, 09:40 AM
  2. C - access violation
    By uber in forum C Programming
    Replies: 2
    Last Post: 07-08-2009, 01:30 PM
  3. Matrix Help
    By HelpmeMark in forum C++ Programming
    Replies: 27
    Last Post: 03-06-2008, 05:57 PM
  4. What is a matrix's purpose in OpenGL
    By jimboob in forum Game Programming
    Replies: 5
    Last Post: 11-14-2004, 12:19 AM

Tags for this Thread