How to get the number of physical machine in MPI
Asked Answered
L

2

6

I can use MPI_Comm_size to get the number of total processors. But how can I get the number of real physical machine?

Lialiabilities answered 6/12, 2015 at 7:49 Comment(1)
In MPI, every core gets a rank between 0 and size-1. Is that what you're looking for?Pressmark
W
8

If by physical machine you mean a set of processing elements, sharing a common memory address space, then the MPI-3 split-by-type operation MPI_COMM_SPLIT_TYPE could be used to portably obtain the number of such machines:

int getNodeCount(void)
{
   int rank, is_rank0, nodes;
   MPI_Comm shmcomm;

   MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0,
                       MPI_INFO_NULL, &shmcomm);
   MPI_Comm_rank(shmcomm, &rank);
   is_rank0 = (rank == 0) ? 1 : 0;
   MPI_Allreduce(&is_rank0, &nodes, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
   MPI_Comm_free(&shmcomm);
   return nodes;
}

And in Fortran:

subroutine getNodeCount(count)
  use mpi
  implicit none
  integer, intent(out) :: count
  integer :: shmcomm, rank, is_rank0, ierr

  call MPI_COMM_SPLIT_TYPE(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, &
                           MPI_INFO_NULL, shmcomm, ierr)
  call MPI_COMM_RANK(shmcomm, rank, ierr)
  if (rank == 0) then
     is_rank0 = 1
  else
     is_rank0 = 0
  end if
  call MPI_ALLREDUCE(is_rank0, count, 1, MPI_INTEGER, MPI_SUM, &
                     MPI_COMM_WORLD, ierr)
  call MPI_COMM_FREE(shmcomm, ierr)
end subroutine getNodeCount

The function first splits the world communicator into groups of ranks capable of creating shared memory regions, i.e. one group per physical machine (give the definition above). It then counts the number of such groups by summing the number of rank-0 entities. Due to the use of collective operations, the function must be called by all ranks in the world group.

Disclaimer: untested code - use at your own risk.

Were answered 6/12, 2015 at 13:55 Comment(0)
C
1

A small function like this one (not tested so might need adjustments) should do it. It relies on MPI_get_processor_name() which returns a unique string per compute node.

int getNodesNumer() {
    int rank, size;
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    MPI_Comm_size( MPI_COMM_WORLD, &size );
    char names[size][MPI_MAX_PROCESSOR_NAME];
    int len;
    MPI_Get_processor_name( names[rank], &len );
    MPI_Allgather( MPI_IN_PLACE, 0, 0, names[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, MPI_COMM_WORLD );
    int indexes[size];
    int count = 0;
    for ( int i = 0; i < size; i++ ) {
        int found = 0;
        for ( int j = 0; j < count; j++ ) {
            if ( strncmp( names[i], names[indexes[j]], MPI_MAX_PROCESSOR_NAME ) == 0 ) {
                found = 1;
                break;
            }
        }
        if ( found == 0 ) {
            indexes[count++] = i;
        }
    }
    return count;
}
Chomp answered 6/12, 2015 at 9:36 Comment(1)
You might wish to correct the position of the first ) in the line containing the strncmp call.Were

© 2022 - 2024 — McMap. All rights reserved.