【发布时间】:2016-03-10 23:21:06
【问题描述】:
我可以使用MPI_Comm_size 来获取处理器总数。
但是如何获取真实物理机的数量呢?
【问题讨论】:
-
在 MPI 中,每个核心在
0和size-1之间都有一个rank。这就是你要找的东西吗?
我可以使用MPI_Comm_size 来获取处理器总数。
但是如何获取真实物理机的数量呢?
【问题讨论】:
0 和 size-1 之间都有一个 rank。这就是你要找的东西吗?
如果物理机你的意思是一组处理元素,共享一个公共内存地址空间,那么MPI-3 split-by-type 操作MPI_COMM_SPLIT_TYPE可用于便携式获取此类机器的数量:
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;
}
在 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
该函数首先将世界通信器分成能够创建共享内存区域的等级组,即每台物理机器一组(给出上面的定义)。然后,它通过对 0 级实体的数量求和来计算此类组的数量。由于使用了集体操作,该函数必须被世界组中的所有等级调用。
免责声明:未经测试的代码 - 使用风险自负。
【讨论】:
一个像这样的小功能(未经测试,因此可能需要调整)应该可以做到。它依赖于MPI_get_processor_name(),它为每个计算节点返回一个唯一的字符串。
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;
}
【讨论】:
) 在包含strncmp 调用的行中的位置。