1
1

Fix argument checks for [i]neighbor_alltoall{v|w}

This fixes a bug introduced in :
 - r31815 (trunk) 
 - r31853 (v1.8 branch)

cmr=v1.8.2:reviewer=bosilca

This commit was SVN r31888.

The following SVN revision numbers were found above:
  r31815 --> open-mpi/ompi@8bafe06c57
  r31853 --> open-mpi/ompi@bff944d766
Этот коммит содержится в:
Gilles Gouaillardet 2014-05-23 08:19:17 +00:00
родитель de15b623b5
Коммит 40f3b849eb
7 изменённых файлов: 227 добавлений и 102 удалений

Просмотреть файл

@ -12,6 +12,8 @@
# All rights reserved.
# Copyright (c) 2013 Los Alamos National Security, LLC. All rights
# reserved.
# Copyright (c) 2014 Research Organization for Information Science
# and Technology (RIST). All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
@ -23,10 +25,13 @@
headers += \
communicator/communicator.h \
communicator/comm_request.h
communicator/comm_request.h \
communicator/comm_helpers.h
libmpi_la_SOURCES += \
communicator/comm_init.c \
communicator/comm.c \
communicator/comm_cid.c \
communicator/comm_request.c
communicator/comm_request.c \
communicator/comm_helpers.c

78
ompi/communicator/comm_helpers.c Обычный файл
Просмотреть файл

@ -0,0 +1,78 @@
/*
* Copyright (c) 2006 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2006 The Technical University of Chemnitz. All
* rights reserved.
* Copyright (c) 2014 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
*
* Author(s): Torsten Hoefler <htor@cs.indiana.edu>
*
*/
#include "comm_helpers.h"
int ompi_comm_neighbors_count(MPI_Comm comm, int *indegree, int *outdegree, int *weighted) {
int res;
if (OMPI_COMM_IS_CART(comm)) {
int ndims;
res = MPI_Cartdim_get(comm, &ndims) ;
if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Cartdim_get() (%i)\n", res); return res; }
/* outdegree is always 2*ndims because we need to iterate over empty buffers for MPI_PROC_NULL */
*outdegree = *indegree = 2*ndims;
*weighted = 0;
} else if (OMPI_COMM_IS_GRAPH(comm)) {
int rank, nneighbors;
MPI_Comm_rank(comm, &rank);
res = MPI_Graph_neighbors_count(comm, rank, &nneighbors);
if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Graph_neighbors_count() (%i)\n", res); return res; }
*outdegree = *indegree = nneighbors;
*weighted = 0;
} else if (OMPI_COMM_IS_DIST_GRAPH(comm)) {
res = MPI_Dist_graph_neighbors_count(comm, indegree, outdegree, weighted);
} else {
return MPI_ERR_ARG;
}
return MPI_SUCCESS;
}
int ompi_comm_neighbors(MPI_Comm comm, int maxindegree, int sources[], int sourceweights[], int maxoutdegree, int destinations[], int destweights[]) {
int res;
int index = 0;
int indeg, outdeg, wgtd;
res = ompi_comm_neighbors_count(comm, &indeg, &outdeg, &wgtd);
if (MPI_SUCCESS != res) {
return res;
}
if(indeg > maxindegree && outdeg > maxoutdegree) return MPI_ERR_TRUNCATE; /* we want to return *all* neighbors */
if (OMPI_COMM_IS_CART(comm)) {
int ndims, i, rpeer, speer;
res = MPI_Cartdim_get(comm, &ndims);
if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Cartdim_get() (%i)\n", res); return res; }
for(i = 0; i<ndims; i++) {
res = MPI_Cart_shift(comm, i, 1, &rpeer, &speer);
if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Cart_shift() (%i)\n", res); return res; }
sources[index] = destinations[index] = rpeer; index++;
sources[index] = destinations[index] = speer; index++;
}
} else if (OMPI_COMM_IS_GRAPH(comm)) {
int rank;
MPI_Comm_rank(comm, &rank);
res = MPI_Graph_neighbors(comm, rank, maxindegree, sources);
if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Graph_neighbors_count() (%i)\n", res); return res; }
for(int i=0; i<maxindegree; i++) destinations[i] = sources[i];
} else if (OMPI_COMM_IS_DIST_GRAPH(comm)) {
res = MPI_Dist_graph_neighbors(comm, maxindegree, sources, sourceweights, maxoutdegree, destinations, destweights);
if (MPI_SUCCESS != res) { printf("MPI Error in MPI_Graph_neighbors_count() (%i)\n", res); return res; }
} else {
return MPI_ERR_ARG;
}
return MPI_SUCCESS;
}

41
ompi/communicator/comm_helpers.h Обычный файл
Просмотреть файл

@ -0,0 +1,41 @@
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* Author(s): Torsten Hoefler <htor@cs.indiana.edu>
*
* $HEADER$
*/
#ifndef __TOPO_HELPERS_H__
#define __TOPO_HELPERS_H__
#include "ompi_config.h"
#include "mpi.h"
#include "ompi/include/ompi/constants.h"
#include "ompi/communicator/communicator.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
int ompi_comm_neighbors_count(MPI_Comm comm, int *indegree, int *outdegree, int *weighted);
int ompi_comm_neighbors(MPI_Comm comm, int maxindegree, int sources[], int sourceweights[], int maxoutdegree, int destinations[], int destweights[]);
#ifdef __cplusplus
}
#endif
#endif

Просмотреть файл

@ -28,6 +28,7 @@
#include "ompi/mpi/c/bindings.h"
#include "ompi/runtime/params.h"
#include "ompi/communicator/communicator.h"
#include "ompi/communicator/comm_helpers.h"
#include "ompi/errhandler/errhandler.h"
#include "ompi/datatype/ompi_datatype.h"
#include "ompi/memchecker.h"
@ -48,8 +49,8 @@ int MPI_Ineighbor_alltoallv(const void *sendbuf, const int sendcounts[], const i
const int rdispls[], MPI_Datatype recvtype, MPI_Comm comm,
MPI_Request *request)
{
int i, size, err;
size_t sendtype_size, recvtype_size;
int i, err;
int indegree, outdegree, weighted;
MEMCHECKER(
ptrdiff_t recv_ext;
@ -63,16 +64,20 @@ int MPI_Ineighbor_alltoallv(const void *sendbuf, const int sendcounts[], const i
memchecker_comm(comm);
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for ( i = 0; i < size; i++ ) {
/* check if send chunks are defined. */
memchecker_call(&opal_memchecker_base_isdefined,
(char *)(sendbuf)+sdispls[i]*send_ext,
sendcounts[i], sendtype);
/* check if receive chunks are addressable. */
memchecker_call(&opal_memchecker_base_isaddressable,
(char *)(recvbuf)+rdispls[i]*recv_ext,
recvcounts[i], recvtype);
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
if (MPI_SUCCESS == err) {
for ( i = 0; i < outdegree; i++ ) {
/* check if send chunks are defined. */
memchecker_call(&opal_memchecker_base_isdefined,
(char *)(sendbuf)+sdispls[i]*send_ext,
sendcounts[i], sendtype);
}
for ( i = 0; i < indegree; i++ ) {
/* check if receive chunks are addressable. */
memchecker_call(&opal_memchecker_base_isaddressable,
(char *)(recvbuf)+rdispls[i]*recv_ext,
recvcounts[i], recvtype);
}
}
);
@ -94,22 +99,16 @@ int MPI_Ineighbor_alltoallv(const void *sendbuf, const int sendcounts[], const i
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
}
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for (i = 0; i < size; ++i) {
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
for (i = 0; i < outdegree; ++i) {
OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtype, sendcounts[i]);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
}
for (i = 0; i < indegree; ++i) {
OMPI_CHECK_DATATYPE_FOR_RECV(err, recvtype, recvcounts[i]);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
}
if (MPI_IN_PLACE != sendbuf && !OMPI_COMM_IS_INTER(comm)) {
int me = ompi_comm_rank(comm);
ompi_datatype_type_size(sendtype, &sendtype_size);
ompi_datatype_type_size(recvtype, &recvtype_size);
if ((sendtype_size*sendcounts[me]) != (recvtype_size*recvcounts[me])) {
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TRUNCATE, FUNC_NAME);
}
}
}
OPAL_CR_ENTER_LIBRARY();

Просмотреть файл

@ -28,6 +28,7 @@
#include "ompi/mpi/c/bindings.h"
#include "ompi/runtime/params.h"
#include "ompi/communicator/communicator.h"
#include "ompi/communicator/comm_helpers.h"
#include "ompi/errhandler/errhandler.h"
#include "ompi/datatype/ompi_datatype.h"
#include "ompi/memchecker.h"
@ -48,8 +49,8 @@ int MPI_Ineighbor_alltoallw(const void *sendbuf, const int sendcounts[], const M
const MPI_Aint rdispls[], const MPI_Datatype recvtypes[], MPI_Comm comm,
MPI_Request *request)
{
int i, size, err;
size_t sendtype_size, recvtype_size;
int i, err;
int indegree, outdegree, weighted;
MEMCHECKER(
ptrdiff_t recv_ext;
@ -57,20 +58,26 @@ int MPI_Ineighbor_alltoallw(const void *sendbuf, const int sendcounts[], const M
memchecker_comm(comm);
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for ( i = 0; i < size; i++ ) {
memchecker_datatype(sendtypes[i]);
memchecker_datatype(recvtypes[i]);
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
if (MPI_SUCCESS == err) {
for ( i = 0; i < outdegree; i++ ) {
memchecker_datatype(sendtypes[i]);
ompi_datatype_type_extent(sendtypes[i], &send_ext);
ompi_datatype_type_extent(recvtypes[i], &recv_ext);
ompi_datatype_type_extent(sendtypes[i], &send_ext);
memchecker_call(&opal_memchecker_base_isdefined,
(char *)(sendbuf)+sdispls[i]*send_ext,
sendcounts[i], sendtypes[i]);
memchecker_call(&opal_memchecker_base_isaddressable,
(char *)(recvbuf)+sdispls[i]*recv_ext,
recvcounts[i], recvtypes[i]);
memchecker_call(&opal_memchecker_base_isdefined,
(char *)(sendbuf)+sdispls[i]*send_ext,
sendcounts[i], sendtypes[i]);
}
for ( i = 0; i < indegree; i++ ) {
memchecker_datatype(recvtypes[i]);
ompi_datatype_type_extent(recvtypes[i], &recv_ext);
memchecker_call(&opal_memchecker_base_isaddressable,
(char *)(recvbuf)+sdispls[i]*recv_ext,
recvcounts[i], recvtypes[i]);
}
}
);
@ -92,22 +99,16 @@ int MPI_Ineighbor_alltoallw(const void *sendbuf, const int sendcounts[], const M
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
}
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for (i = 0; i < size; ++i) {
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
for (i = 0; i < outdegree; ++i) {
OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtypes[i], sendcounts[i]);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
}
for (i = 0; i < indegree; ++i) {
OMPI_CHECK_DATATYPE_FOR_RECV(err, recvtypes[i], recvcounts[i]);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
}
if (MPI_IN_PLACE != sendbuf && !OMPI_COMM_IS_INTER(comm)) {
int me = ompi_comm_rank(comm);
ompi_datatype_type_size(sendtypes[me], &sendtype_size);
ompi_datatype_type_size(recvtypes[me], &recvtype_size);
if ((sendtype_size*sendcounts[me]) != (recvtype_size*recvcounts[me])) {
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TRUNCATE, FUNC_NAME);
}
}
}
OPAL_CR_ENTER_LIBRARY();

Просмотреть файл

@ -31,6 +31,7 @@
#include "ompi/errhandler/errhandler.h"
#include "ompi/datatype/ompi_datatype.h"
#include "ompi/memchecker.h"
#include "ompi/communicator/comm_helpers.h"
#if OPAL_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
#pragma weak MPI_Neighbor_alltoallv = PMPI_Neighbor_alltoallv
@ -48,7 +49,8 @@ int MPI_Neighbor_alltoallv(const void *sendbuf, const int sendcounts[], const in
const int recvcounts[], const int rdispls[],
MPI_Datatype recvtype, MPI_Comm comm)
{
int i, size, err;
int i, err;
int indegree, outdegree, weighted;
size_t sendtype_size, recvtype_size;
bool zerosend=true, zerorecv=true;
@ -64,16 +66,20 @@ int MPI_Neighbor_alltoallv(const void *sendbuf, const int sendcounts[], const in
memchecker_comm(comm);
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for ( i = 0; i < size; i++ ) {
/* check if send chunks are defined. */
memchecker_call(&opal_memchecker_base_isdefined,
(char *)(sendbuf)+sdispls[i]*send_ext,
sendcounts[i], sendtype);
/* check if receive chunks are addressable. */
memchecker_call(&opal_memchecker_base_isaddressable,
(char *)(recvbuf)+rdispls[i]*recv_ext,
recvcounts[i], recvtype);
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
if (MPI_SUCCESS == err) {
for ( i = 0; i < outdegree; i++ ) {
/* check if send chunks are defined. */
memchecker_call(&opal_memchecker_base_isdefined,
(char *)(sendbuf)+sdispls[i]*send_ext,
sendcounts[i], sendtype);
}
for ( i = 0; i < indegree; i++ ) {
/* check if receive chunks are addressable. */
memchecker_call(&opal_memchecker_base_isaddressable,
(char *)(recvbuf)+rdispls[i]*recv_ext,
recvcounts[i], recvtype);
}
}
);
@ -101,31 +107,25 @@ int MPI_Neighbor_alltoallv(const void *sendbuf, const int sendcounts[], const in
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
}
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for (i = 0; i < size; ++i) {
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
for (i = 0; i < outdegree; ++i) {
OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtype, sendcounts[i]);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
}
for (i = 0; i < indegree; ++i) {
OMPI_CHECK_DATATYPE_FOR_RECV(err, recvtype, recvcounts[i]);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
}
if (MPI_IN_PLACE != sendbuf && !OMPI_COMM_IS_INTER(comm)) {
int me = ompi_comm_rank(comm);
ompi_datatype_type_size(sendtype, &sendtype_size);
ompi_datatype_type_size(recvtype, &recvtype_size);
if ((sendtype_size*sendcounts[me]) != (recvtype_size*recvcounts[me])) {
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TRUNCATE, FUNC_NAME);
}
}
}
/* Do we need to do anything? */
ompi_datatype_type_size(sendtype, &sendtype_size);
ompi_datatype_type_size(recvtype, &recvtype_size);
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
if (0 != recvtype_size) {
for (i = 0; i < size; ++i) {
for (i = 0; i < indegree; ++i) {
if (0 != recvcounts[i]) {
zerorecv = false;
break;
@ -135,7 +135,7 @@ int MPI_Neighbor_alltoallv(const void *sendbuf, const int sendcounts[], const in
if (MPI_IN_PLACE == sendbuf) {
zerosend = zerorecv;
} else if (0 != sendtype_size) {
for (i = 0; i < size; ++i) {
for (i = 0; i < outdegree; ++i) {
if (0 != sendcounts[i]) {
zerosend = false;
break;

Просмотреть файл

@ -31,6 +31,7 @@
#include "ompi/errhandler/errhandler.h"
#include "ompi/datatype/ompi_datatype.h"
#include "ompi/memchecker.h"
#include "ompi/communicator/comm_helpers.h"
#if OPAL_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
#pragma weak MPI_Neighbor_alltoallw = PMPI_Neighbor_alltoallw
@ -48,7 +49,8 @@ int MPI_Neighbor_alltoallw(const void *sendbuf, const int sendcounts[], const MP
const int recvcounts[], const MPI_Aint rdispls[],
const MPI_Datatype recvtypes[], MPI_Comm comm)
{
int i, size, err;
int i, err;
int indegree, outdegree, weighted;
size_t sendtype_size, recvtype_size;
bool zerosend=true, zerorecv=true;
@ -58,20 +60,24 @@ int MPI_Neighbor_alltoallw(const void *sendbuf, const int sendcounts[], const MP
memchecker_comm(comm);
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for ( i = 0; i < size; i++ ) {
memchecker_datatype(sendtypes[i]);
memchecker_datatype(recvtypes[i]);
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
if (MPI_SUCCESS == err) {
for ( i = 0; i < outdegree; i++ ) {
memchecker_datatype(sendtypes[i]);
ompi_datatype_type_extent(sendtypes[i], &send_ext);
ompi_datatype_type_extent(recvtypes[i], &recv_ext);
ompi_datatype_type_extent(sendtypes[i], &send_ext);
memchecker_call(&opal_memchecker_base_isdefined,
(char *)(sendbuf)+sdispls[i]*send_ext,
sendcounts[i], sendtypes[i]);
memchecker_call(&opal_memchecker_base_isaddressable,
(char *)(recvbuf)+sdispls[i]*recv_ext,
recvcounts[i], recvtypes[i]);
memchecker_call(&opal_memchecker_base_isdefined,
(char *)(sendbuf)+sdispls[i]*send_ext,
sendcounts[i], sendtypes[i]);
}
for ( i = 0; i < indegree; i++ ) {
memchecker_datatype(recvtypes[i]);
ompi_datatype_type_extent(recvtypes[i], &recv_ext);
memchecker_call(&opal_memchecker_base_isaddressable,
(char *)(recvbuf)+sdispls[i]*recv_ext,
recvcounts[i], recvtypes[i]);
}
}
);
@ -99,28 +105,23 @@ int MPI_Neighbor_alltoallw(const void *sendbuf, const int sendcounts[], const MP
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
}
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for (i = 0; i < size; ++i) {
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
for (i = 0; i < outdegree; ++i) {
OMPI_CHECK_DATATYPE_FOR_SEND(err, sendtypes[i], sendcounts[i]);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
}
for (i = 0; i < indegree; ++i) {
OMPI_CHECK_DATATYPE_FOR_RECV(err, recvtypes[i], recvcounts[i]);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
}
if (MPI_IN_PLACE != sendbuf && !OMPI_COMM_IS_INTER(comm)) {
int me = ompi_comm_rank(comm);
ompi_datatype_type_size(sendtypes[me], &sendtype_size);
ompi_datatype_type_size(recvtypes[me], &recvtype_size);
if ((sendtype_size*sendcounts[me]) != (recvtype_size*recvcounts[me])) {
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TRUNCATE, FUNC_NAME);
}
}
}
/* Do we need to do anything? */
size = OMPI_COMM_IS_INTER(comm)?ompi_comm_remote_size(comm):ompi_comm_size(comm);
for (i = 0; i < size; ++i) {
err = ompi_comm_neighbors_count(comm, &indegree, &outdegree, &weighted);
OMPI_ERRHANDLER_CHECK(err, comm, err, FUNC_NAME);
for (i = 0; i < indegree; ++i) {
ompi_datatype_type_size(recvtypes[i], &recvtype_size);
if (0 != recvtype_size && 0 != recvcounts[i]) {
zerorecv = false;
@ -130,7 +131,7 @@ int MPI_Neighbor_alltoallw(const void *sendbuf, const int sendcounts[], const MP
if (MPI_IN_PLACE == sendbuf) {
zerosend = zerorecv;
} else {
for (i = 0; i < size; ++i) {
for (i = 0; i < outdegree; ++i) {
ompi_datatype_type_size(sendtypes[i], &sendtype_size);
if (0 != sendtype_size && 0 != sendcounts[i]) {
zerosend = false;