# Can't get right ranks when using non-blocking MPI.Irecv!()

**URL:** <https://discourse.julialang.org/t/cant-get-right-ranks-when-using-non-blocking-mpi-irecv/46361>\
**Category:** New to Julia\
**Tags:** mpi\
**Created:** [September 10, 2020, 6:43am UTC](https://discourse.julialang.org/t/cant-get-right-ranks-when-using-non-blocking-mpi-irecv/46361 "2020-09-10T06:43:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ke\_Gao](https://avatars.discourse-cdn.com/v4/letter/k/71e660/32.png) [@Ke\_Gao](https://discourse.julialang.org/u/Ke_Gao)\
**Post date:** [September 10, 2020, 6:43am UTC](https://discourse.julialang.org/t/cant-get-right-ranks-when-using-non-blocking-mpi-irecv/46361/1 "2020-09-10T06:43:56Z")

</div>

I am trying to let rank 0 get other rank indexes, but I got different results from `MPI.Irecv!()` and `MPI.Recv()` , and result from `MPI.Irecv!()` seems odd:

```julia
import MPI

function main()
    MPI.Init()
    comm = MPI.COMM_WORLD
    size = MPI.Comm_size(comm) 
    rank = MPI.Comm_rank(comm) 
    if rank==0
        buf = 10
        mid = [10]
        for i in 1:size-1
            MPI.Recv!(mid, i, 0, comm)
            println("mid: $mid")
            buf = mid[1]
            println("buf: $buf")
        end
    else
        MPI.Isend([rank], 0, 0, comm)
    end
    MPI.Finalize()
end 
main()

```

Which output：

```shell
mid: [1]
buf: 1
mid: [2]
buf: 2
mid: [3]
buf: 3

```

If I replace ` MPI.Recv!(mid, i, 0, comm)` by `MPI.Irecv!(mid, i, 0, comm)` , the output seemed not right:

```shell
mid: [10]
buf: 10
mid: [10]
buf: 10
mid: [10]
buf: 10

```

So my question is, why `mid` didn’t change when I use ` MPI.Irecv!()`, and how to get the right rank number with ` MPI.Irecv!()`?  
Thanks for any suggestions and answers!

---

<div class="post-metadata">

**Author:** ![jipolanco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jipolanco/32/12129_2.png) [@jipolanco](https://discourse.julialang.org/u/jipolanco)\
**Post date:** [September 10, 2020, 7:02am UTC](https://discourse.julialang.org/t/cant-get-right-ranks-when-using-non-blocking-mpi-irecv/46361/2 "2020-09-10T07:02:36Z")

</div>

`MPI.Irecv!` is a non-blocking operation, that is, it returns immediately without waiting for the operation to complete. So by the time you call `println(mid)`, data in `mid` has not been yet updated since the data has not been yet received.

Unlike its blocking variant (`MPI.Recv!`), `MPI.Irecv!` returns a “request”. At some point of your code, you need to wait for this request to complete, before you can operate on the received data. In your specific case, you want to do the following:

```julia
for i in 1:size-1
    req = MPI.Irecv!(mid, i, 0, comm)
    MPI.Wait!(req) # wait for operation to complete
    println("mid: $mid")
    buf = mid[1]
    println("buf: $buf")
end

```

Note that all of this also applies to `MPI.Isend`, which is also non-blocking.

---

<div class="post-metadata">

**Author:** ![Ke\_Gao](https://avatars.discourse-cdn.com/v4/letter/k/71e660/32.png) [@Ke\_Gao](https://discourse.julialang.org/u/Ke_Gao)\
**Post date:** [September 10, 2020, 7:45am UTC](https://discourse.julialang.org/t/cant-get-right-ranks-when-using-non-blocking-mpi-irecv/46361/3 "2020-09-10T07:45:14Z")

</div>

Got it, thank you for always helping me!

---

<div class="post-metadata">

**Author:** ![Ke\_Gao](https://avatars.discourse-cdn.com/v4/letter/k/71e660/32.png) [@Ke\_Gao](https://discourse.julialang.org/u/Ke_Gao)\
**Post date:** [September 14, 2020, 9:46am UTC](https://discourse.julialang.org/t/cant-get-right-ranks-when-using-non-blocking-mpi-irecv/46361/4 "2020-09-14T09:46:13Z")

</div>

Hi Polanco,  
I still have a question about the piece of code, I would appreciate it if you could help me.  
In the loop:

```nohighlight
req = MPI.Irecv!(mid, i, 0, comm)
MPI.Wait!(req) # wait for operation to complete
buf = mid[1]

```

It seems odd, I did it because when I try to get `buf` directly:

```nohighlight
req = MPI.Irecv!([buf], i, 0, comm)

```

I couldn’t get the result I wanted. Do you have any suggestions? Thank you！

---

<div class="post-metadata">

**Author:** ![jipolanco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jipolanco/32/12129_2.png) [@jipolanco](https://discourse.julialang.org/u/jipolanco)\
**Post date:** [September 14, 2020, 11:14am UTC](https://discourse.julialang.org/t/cant-get-right-ranks-when-using-non-blocking-mpi-irecv/46361/5 "2020-09-14T11:14:34Z")

</div>

Hi again,

Note that `buf` is immutable (it’s an `Int`), which is why you can’t pass it directly to `Irecv!` as a buffer.

When you wrap it in an array, as in `[buf]`, you’re passing `Irecv!` a single-element array. That function then replaces `buf` by the received value. Note that the _array_ is being modified, not `buf` itself (which, again, is immutable). In your last bit of code, you’re losing the received information since the array is anonymous. That’s why you need to attach the array to a variable (like `mid` in your previous code).

---

<div class="post-metadata">

**Author:** ![Ke\_Gao](https://avatars.discourse-cdn.com/v4/letter/k/71e660/32.png) [@Ke\_Gao](https://discourse.julialang.org/u/Ke_Gao)\
**Post date:** [September 15, 2020, 5:19am UTC](https://discourse.julialang.org/t/cant-get-right-ranks-when-using-non-blocking-mpi-irecv/46361/6 "2020-09-15T05:19:24Z")

</div>

Very clear, thank you!
