[mpich-devel] MPIR_ERRTEST_ARGNULL and count=0 (or type_size=0)

Jeff Hammond jhammond at alcf.anl.gov
Wed May 29 07:41:38 CDT 2013


I see Jim used MPIR_ERRTEST_ARGNULL in (r)get_accumulate, which makes
sense (I am working on verifying that they should be in the others as
well).  However, these calls are not guarded by "if (count)", which
means that one presumably (I have not written a test for it but it
seems obvious) cannot use addr=NULL with count=0.  It seems to me that
0-byte transfers are find with NULL buffers (this was recently
verified for MPI_Ssend because it's a common way to implement p2p
synchronization).

It seems prudent to change something like this:

            MPIR_ERRTEST_COUNT(origin_count, mpi_errno);
            MPIR_ERRTEST_DATATYPE(origin_datatype, "origin_datatype",
mpi_errno);
            MPIR_ERRTEST_ARGNULL(origin_addr, "origin_addr", mpi_errno);

To this:

            MPIR_ERRTEST_COUNT(origin_count, mpi_errno);
            MPIR_ERRTEST_DATATYPE(origin_datatype, "origin_datatype",
mpi_errno);
            if (origin_count) MPIR_ERRTEST_ARGNULL(origin_addr,
"origin_addr", mpi_errno);

Then I got to thinking, what if someone - almost certainly not
intentionally but because of a general implementation - uses
MPI_Type_vector to create a zero-length vector type.  I don't see why
one can't do a count>0 transfer with with a NULL buffer if the
datatype is empty.

I wrote the following test of a 0-length vector and see that it works
just fine with bcast.

#include <stdio.h>
#include <stdlib.h>

#include <mpi.h>

int main(int argc, char ** argv) {
  int      rank, nproc;
  MPI_Datatype emptyvec;
  MPI_Aint lb, ext;

  MPI_Init(&argc, &argv);

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &nproc);

  if (rank == 0) printf("Starting MPI datatype test with %d
processes\n", nproc);

  MPI_Type_vector(0,0,0,MPI_DOUBLE,&emptyvec);
  MPI_Type_commit(&emptyvec);
  MPI_Type_get_extent(emptyvec, &lb, &ext);
  MPI_Type_size(emptyvec, &size);
  if (rank == 0) printf("lb = %zu ext = %zu size = %d \n", lb, ext, size);

  MPI_Bcast(NULL, 0, emptyvec, 0, MPI_COMM_WORLD);
  MPI_Bcast(NULL, 1, emptyvec, 0, MPI_COMM_WORLD);

  MPI_Type_free(&emptyvec);

  if (rank == 0) printf("Test complete: PASS.\n");

  MPI_Finalize();

  return 0;
}

 This suggests that it should be valid to use addr=NULL and count>0 as
long as the extent of the type is 0, hence the aforementioned code
should really be:

            int origin_datatype_size;
            ...
            MPIR_ERRTEST_COUNT(origin_count, mpi_errno);
            MPIR_ERRTEST_DATATYPE(origin_datatype, "origin_datatype",
mpi_errno);
            MPID_Datatype_get_size_macro(origin_datatype, origin_datatype_size);
            if (origin_count && origin_datatype_size)
MPIR_ERRTEST_ARGNULL(origin_addr, "origin_addr", mpi_errno);

Do people agree with this reasoning?

Thanks,

Jeff

-- 
Jeff Hammond
Argonne Leadership Computing Facility
University of Chicago Computation Institute
jhammond at alcf.anl.gov / (630) 252-5381
http://www.linkedin.com/in/jeffhammond
https://wiki.alcf.anl.gov/parts/index.php/User:Jhammond
ALCF docs: http://www.alcf.anl.gov/user-guides


More information about the devel mailing list