Open MPI logo

Open MPI Development Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Development mailing list

Subject: Re: [OMPI devel] failure withzero-lengthReduce()andbothsbuf=rbuf=NULL
From: Lisandro Dalcin (dalcinl_at_[hidden])
Date: 2010-02-11 11:53:15


On 11 February 2010 12:04, George Bosilca <bosilca_at_[hidden]> wrote:
>
> Therefore, we can argue as much as you want about what the correct arguments of a reduce call should be, a reduce(count=0) is one of the meaningless MPI calls and as such should not be tolerated.
>

Well, I have to disagree... I understand you (as an MPI implementor)
think that Reduce(count=0) could be meaningless and add complexity to
the implementation of MPI_Reduce()... But Reduce(count=0) could save
user code of special-casing the count==0 situation... after all,
zero-length arrays/sequences/containers do appear in actual codes...

> Anyway, this discussion diverged from its original subject. The standard is pretty clear on what set of arguments are valid, and the fact that the send and receive buffers should be different is one of the strongest requirement (and this independent on what count is).

Sorry.... If count=0, why sendbuf!=recvbuff is SO STRONGLY required? I
cannot figure out the answer...

> As a courtesy, Open MPI accepts the heresy of a count = zero, but there is __absolutely__ no reason to stop checking the values of the other arguments when this is true. If the user really want to base the logic of his application on such a useless and non-standard statement (reduce(0)) at least he has to have the courtesy to provide a valid set of arguments.

I'm still not convinced that recuce(0) is non-standard, as Jeff
pointer out, the standard says "non-negative integer". The later
comment is IMHO is not saying that count=0 is invalid, such a
conclusion is a misinterpretation. What's would be the rationale of
making Reduce(count=0) invalid, when all other
(communication+reductions) collective calls do not explicitly say that
count=0 is invalid, and "count" arguments are always described as
"non-negative integer" ??

>
> PS: If I can suggest a correct approach to fix the python bindings I would encourage you to go for the strongest and more meaningful approach, sendbuf should always be different that recvbuf (independent on the value of count).
>

I have the feeling that you think I'm bikeshedding because I'm lazy or
I have nothing more useful to do :-)... That's not the case... I'm the
developer of a MPI wrapper, it is not my business to impose arbitrary
restrictions on users... then I would like MPI implementations to
follow that rule... if count=0, I cannot see why I should restrict
user to pass sendbuf!=recvbuf ... moreover, in a dynamic language like
Python, things are not always obvious...

Let me show you a little Python experiment... Enter you python prompt,
and type this:

$ python
>>> from array import array
>>> a = array('i', []) # one zero-length array of integers (C-int)
>>> b = array('i', []) # other zero-length array
>>> a is b # are 'a' and 'b' the same object instance?
False
>>>

So far, so good.. we have two different arrays of integers, and their
length is zero...
Let's see the values of the (pointer, length), where the pointer is
represented as its integer value:

>>> a.buffer_info()
(0, 0)
>>> b.buffer_info()
(0, 0)
>>>

Now, suppose I do this:

>>> from mpi4py import MPI
>>> MPI.COMM_WORLD.Reduce(a, b, op=MPI.SUM, root=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "Comm.pyx", line 534, in mpi4py.MPI.Comm.Reduce (src/mpi4py.MPI.c:52115)
mpi4py.MPI.Exception: MPI_ERR_ARG: invalid argument of some other kind
>>>

Then a mpi4py user mail me asking: WTF? 'a' and 'b' were different
arrays, what's going on? why my call failed? And then I have to say:
this fails because of two implementation details... Built-in Python's
'array.array' instances have pointer=NULL when lenght=0, and your MPI
implementation requires sendbuf!=recvbuf, even if count=0 and
sendbuf=recvbuf=NULL... Again, you may still thing that
Reduce(count=0), or any other <MPI_Collective>(count=0) is a nonsense,
I may even agree with you... But IMHO that's not what the standard
says, but again, imposing restrictions user codes should not be our
business...

Geoge, what could I do here? Should I forcibly pass a different,fake
value enforcing sendbuff!=recvbuff myself when count=0? Would this be
portable? What if other MPI implementation in some platform decides to
complain because the fake value I'm passing does not represent a valid
address?

PS: Maintaining a MPI-2 binding for Python may requires a lot of care
and attention to little details. And I have to support, Python>=2.3
and the new Python 3; on Windows, Linux and OS X, with many of the
MPI-1 and MPI-2 implementations out there... Consistent behavior and
standard compliance on MPI implementations is FUNDAMENTAL to develop
portable wrappers for other languages... Unfortunately, things are not
so easy; mpi4py's source code and testsuite is plenty of "if OMPI" and
"if MPICH2"...

-- 
Lisandro Dalcin
---------------
Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
PTLC - Güemes 3450, (3000) Santa Fe, Argentina
Tel/Fax: +54-(0)342-451.1594