Thread: Basic MPI

  1. #1
    Registered User
    Join Date
    Feb 2013
    Posts
    100

    Basic MPI

    I wrote a program which sends a starting and ending range to other processes and the processes calculate the prime numbers in that range and return the count of prime numbers to the head process, process 0. But this is not working properly at the moment. I realize I still have to split up the range based on how many processes I have...I still have not figured out how I want to set that up. If you see anything wrong with what I've got at the moment, I'd appreciate your opinion. Thanks!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <mpi.h>
    
    int isPrime(int num);
    
    int main(int argc, char **argv){
    
      int myID;
      int numProcs;
      int primeCount = 0;
      
     // printf("The starting and ending values are: %d %d\n", starting, ending);
      
      MPI_Init(&argc, &argv);
      MPI_Comm_size(MPI_COMM_WORLD, &myID);
      MPI_Comm_rank(MPI_COMM_WORLD, &numProcs);
      
      if(myID == 0) { // Process 0 (head process)
        int starting = 10;
        int ending = 100;
        MPI_Status status;
        for(int i = 1; i < numProcs; i++){
            MPI_Send(&starting, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
            MPI_Send(&ending, 1, MPI_INT, i, 2, MPI_COMM_WORLD);
        }
        int total = 0;
        for (int i = 1; i < numProcs; i++) {
           int primeCount;
           MPI_Recv(&primeCount, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &status); // blocking
           total += primeCount;
        }
        
        } else { // All other processes
          MPI_Status status;
          int starting, ending;
          for(int i = 1; i < numProcs; i++){
            MPI_Recv(&starting, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &status); // blocking
            MPI_Recv(&ending, 1, MPI_INT, i, 2, MPI_COMM_WORLD, &status); // blocking
          }
          for (int i = starting; i < ending; i++) {
            if(isPrime(i)){
                primeCount++;
            }
           MPI_Send(&primeCount, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
        }
    
        printf("Prime count: %d\n", primeCount);
      }
        MPI_Finalize();
    }
    
    
    
        int isPrime(int num){
            for (int i = 2; i < num; i++){
                if (num % i == 0 && i != num) return 0;
            }
            return 1;
        }
    My output right now is:
    Prime count: 1
    Prime count: 1

    and then it freezes

  2. #2
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Code:
        int isPrime(int num){
            for (int i = 2; i < num; i++){
                if (num % i == 0 && i != num) return 0;
            }
            return 1;
        }
    Seems wasteful to divide each number by 4,6,8 ...

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The way you have it at the moment, all children expect a large number of messages.
    Code:
          for(int i = 1; i < numProcs; i++){
            MPI_Recv(&starting, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &status); // blocking
            MPI_Recv(&ending, 1, MPI_INT, i, 2, MPI_COMM_WORLD, &status); // blocking
          }
    Just delete the loop altogether.
    MPI_Recv(&starting, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &status); // blocking
    MPI_Recv(&ending, 1, MPI_INT, i, 2, MPI_COMM_WORLD, &status); // blocking

    It's going to get run in multiple MPI processes for you.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Feb 2013
    Posts
    100
    That makes sense Salem, thank you, but now it's going through and giving me zero as the result. Here is my revised code:

    Code:
    int main(int argc, char **argv){
      int myID;
      int numProcs;
      
      MPI_Init(&argc, &argv);
      MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
      MPI_Comm_rank(MPI_COMM_WORLD, &myID);
     
      if(myID == 0) { // Process 0 (head process)
        int starting = 10;
     int ending = 100;
     printf("The starting and ending values are: %d %d\n", starting, ending);
     MPI_Status status;
     for(int i = 1; i < numProcs; i++){
      MPI_Send(&starting, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
      MPI_Send(&ending, 1, MPI_INT, i, 2, MPI_COMM_WORLD);
     }
     int totalPrime = 0;
     int primeCount = 0;
        for (int i = 1; i < numProcs; i++) {
           MPI_Recv(&primeCount, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &status);
           totalPrime += primeCount;
        }
     printf("Prime count: %d\n", totalPrime);
     } else { // All other processes
       MPI_Status status;
       int starting, ending;
       int localPrimeCount = 0;
       MPI_Recv(&starting, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
       MPI_Recv(&ending, 1, MPI_INT, 0, 2, MPI_COMM_WORLD, &status); 
       for (int i = starting; i < ending; i++) {
      if(isPrime(i)){
       localPrimeCount++;
      }
        MPI_Send(&localPrimeCount, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
     }
      }
        MPI_Finalize();
    }

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    For a start you could check the return values of MPI_Send and MPI_Recv:
    Code:
    if (MPI_Send(...) != MPI_SUCCESS)
        // we have a problem
    You could also check the status structure and the actual values you send/recieve.

    In general, you should learn to debug parallel processes.

    Bye, Andreas

  6. #6
    Registered User
    Join Date
    Feb 2013
    Posts
    100
    Quote Originally Posted by AndiPersti View Post
    For a start you could check the return values of MPI_Send and MPI_Recv:
    Code:
    if (MPI_Send(...) != MPI_SUCCESS)
        // we have a problem
    You could also check the status structure and the actual values you send/recieve.

    In general, you should learn to debug parallel processes.

    Bye, Andreas
    When I get a moment I will do that, thank you for the recommendation

  7. #7
    Registered User
    Join Date
    Feb 2013
    Posts
    100
    I solved the problem, the only thing not working now is my ranges, all the recipients calculate 21 prime numbers resulting in 63...I want to split the range up into three parts. I'm having trouble writing an algorithm which takes care of this, here is what I have atm:
    Code:
        for(int i = 1; i < numProcs; i++){
           starting = (i-1 * (range/numProcs));
            ending = (i) * (range/numProcs);
            MPI_Send(&starting, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
            MPI_Send(&ending, 1, MPI_INT, i, 2, MPI_COMM_WORLD);
        }
    Last edited by johngoodman; 04-29-2013 at 08:38 PM.

  8. #8
    Registered User
    Join Date
    Feb 2013
    Posts
    100
    Never mind, solved it

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Basic C
    By toddeeeEEee in forum C Programming
    Replies: 7
    Last Post: 12-05-2011, 12:50 AM
  2. C++ basic
    By artoke in forum C++ Programming
    Replies: 8
    Last Post: 04-28-2007, 02:20 PM
  3. vc++ basic help
    By gooddevil in forum C++ Programming
    Replies: 2
    Last Post: 05-16-2004, 11:01 AM
  4. m$vc++6 basic help
    By CobraCC in forum C++ Programming
    Replies: 4
    Last Post: 03-29-2003, 04:41 PM
  5. basic
    By srinu in forum C Programming
    Replies: 3
    Last Post: 02-13-2003, 08:21 AM