Skip to content

Commit df887b4

Browse files
carlocastoldiCarlo Castoldi
and
Carlo Castoldi
authored
Add group functions (v2.0) (#521)
* add MPI_Group consts * add group APIs * add group docs * added MPI.Group-related functions to MPI.Comm interface * tests added for groups * fixes part of #514 * terminate group Co-authored-by: Carlo Castoldi <[email protected]>
1 parent cafcc04 commit df887b4

11 files changed

+279
-26
lines changed

deps/consts_microsoftmpi.jl

100644100755
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,20 @@ const MPI_COMM_NULL = reinterpret(Cint, 0x04000000)
99
const MPI_COMM_SELF = reinterpret(Cint, 0x44000001)
1010
const MPI_COMM_WORLD = reinterpret(Cint, 0x44000000)
1111

12+
const MPI_Group = Cint
13+
const MPI_GROUP_NULL = reinterpret(Cint, 0x08000000)
14+
const MPI_GROUP_EMPTY = reinterpret(Cint, 0x48000000)
15+
1216
const MPI_Info = Cint
1317
const MPI_INFO_NULL = reinterpret(Cint, 0x1c000000)
1418

1519
const MPI_Win = Cint
1620
const MPI_WIN_NULL = reinterpret(Cint, 0x20000000)
1721

22+
const MPI_Group = Cint
23+
const MPI_GROUP_NULL = reinterpret(Cint, 0x08000000)
24+
const MPI_GROUP_EMPTY = reinterpret(Cint, 0x48000000)
25+
1826
const MPI_Op = Cint
1927
const MPI_OP_NULL = reinterpret(Cint, 0x18000000)
2028
const MPI_MAX = reinterpret(Cint, 0x58000001)

deps/consts_mpich.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ const MPI_COMM_NULL = Cint(67108864)
2020
const MPI_COMM_SELF = Cint(1140850689)
2121
const MPI_COMM_WORLD = Cint(1140850688)
2222

23+
const MPI_Group = Cint
24+
const MPI_GROUP_NULL = Cint(134217728)
25+
const MPI_GROUP_EMPTY = Cint(1207959552)
26+
2327
const MPI_Errhandler = Cint
2428
const MPI_ERRORS_ARE_FATAL = Cint(0x54000000)
2529
const MPI_ERRORS_RETURN = Cint(0x54000001)

deps/consts_openmpi.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ const MPI_COMM_NULL = Cint(2)
2323
const MPI_COMM_SELF = Cint(1)
2424
const MPI_COMM_WORLD = Cint(0)
2525

26+
const MPI_Group = Ptr{Cvoid}
27+
MPI_Group_f2c(c::Cint) = ccall((:MPI_Group_f2c,libmpi),MPI_Group,(Cint,),c)
28+
const MPI_GROUP_NULL = Cint(0)
29+
const MPI_GROUP_EMPTY = Cint(1)
30+
2631
const MPI_Errhandler = Ptr{Cvoid}
2732
MPI_Errhandler_f2c(c::Cint) = ccall((:MPI_Errhandler_f2c,libmpi),MPI_Errhandler,(Cint,),c)
2833
const MPI_ERRORS_ARE_FATAL = Cint(1)

deps/gen_consts.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ MPI_handle = [
108108
:MPI_File => [
109109
:MPI_FILE_NULL,
110110
],
111+
:MPI_Group => [
112+
:MPI_GROUP_NULL,
113+
:MPI_GROUP_EMPTY
114+
],
111115
:MPI_Op => MPI_op_consts,
112116
:MPI_Datatype => MPI_datatype_consts
113117
]

docs/src/comm.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ each process a unique *rank* (see [`MPI.Comm_rank`](@ref)) taking an integer val
1010

1111
```@docs
1212
MPI.Comm
13-
MPI.Comparison
1413
```
1514

1615
## Constants
@@ -28,11 +27,15 @@ MPI.COMM_SELF
2827
MPI.Comm_size
2928
MPI.Comm_rank
3029
MPI.Comm_compare
30+
MPI.Comm_group
31+
MPI.Comm_remote_group
3132
```
3233

3334
### Constructors
3435

3536
```@docs
37+
MPI.Comm_create
38+
MPI.Comm_create_group
3639
MPI.Comm_dup
3740
MPI.Comm_get_parent
3841
MPI.Comm_spawn

docs/src/group.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Groups
2+
3+
An MPI group is a set of process identifiers identified by their *rank* (see
4+
[`MPI.Comm_rank`](@ref) and [`MPI.Group_rank`](@ref)). They are used within a
5+
communicator to describe the participants in a communication *universe*.
6+
7+
## Types and enums
8+
9+
```@docs
10+
MPI.Group
11+
MPI.Comparison
12+
```
13+
14+
## Constants
15+
16+
```@docs
17+
MPI.GROUP_NULL
18+
MPI.GROUP_EMPTY
19+
```
20+
21+
## Functions
22+
23+
### Operations
24+
25+
```@docs
26+
MPI.Group_size
27+
MPI.Group_rank
28+
MPI.Group_compare
29+
```
30+
31+
### Constructors
32+
33+
```@docs
34+
MPI.Group_difference
35+
MPI.Group_intersection
36+
MPI.Group_union
37+
MPI.Group_excl
38+
MPI.Group_incl
39+
```

src/MPI.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ include("implementations.jl")
4141
include("error.jl")
4242
include("handle.jl")
4343
include("info.jl")
44+
include("group.jl")
4445
include("comm.jl")
4546
include("environment.jl")
4647
include("datatypes.jl")

src/comm.jl

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,77 @@ function Comm_size(comm::Comm)
6868
Int(size[])
6969
end
7070

71+
"""
72+
Comm_group(comm::Comm)
73+
74+
Accesses the group associated with given communicator.
75+
76+
# External links
77+
$(_doc_external("MPI_Comm_group"))
78+
"""
79+
function Comm_group(comm::Comm)
80+
newgroup = Group()
81+
@mpichk ccall((:MPI_Comm_group, libmpi), Cint,
82+
(MPI_Comm, Ptr{MPI_Group}), comm, newgroup)
83+
finalizer(free, newgroup)
84+
newgroup
85+
end
86+
87+
"""
88+
Comm_remote_group(comm::Comm)
89+
90+
Accesses the remote group associated with the given inter-communicator.
91+
92+
# External links
93+
$(_doc_external("MPI_Comm_remote_group"))
94+
"""
95+
function Comm_remote_group(comm::Comm)
96+
newgroup = Group()
97+
@mpichk ccall((:MPI_Comm_remote_group, libmpi), Cint,
98+
(MPI_Comm, Ptr{MPI_Group}), comm, newgroup)
99+
finalizer(free, newgroup)
100+
newgroup
101+
end
102+
103+
"""
104+
Comm_create(comm::Comm, group::Group)
105+
106+
Collectively creates a new communicator.
107+
108+
# See also
109+
- [`MPI.Comm_create_group`](@ref) for the noncollective operation
110+
111+
# External links
112+
$(_doc_external("MPI_Comm_create"))
113+
"""
114+
function Comm_create(comm::Comm, group::Group)
115+
newcomm = Comm()
116+
@mpichk ccall((:MPI_Comm_create, libmpi), Cint,
117+
(MPI_Comm, MPI_Group, Ptr{MPI_Comm}),
118+
comm, group, newcomm)
119+
finalizer(free, newcomm)
120+
newcomm
121+
end
122+
123+
"""
124+
Comm_create_group(comm::Comm, group::Group, tag::Integer)
125+
126+
Noncollectively creates a new communicator.
127+
128+
# See also
129+
- [`MPI.Comm_create`](@ref) for the noncollective operation
130+
131+
# External links
132+
$(_doc_external("MPI_Comm_create_group"))
133+
"""
134+
function Comm_create_group(comm::Comm, group::Group, tag::Integer)
135+
newcomm = Comm()
136+
@mpichk ccall((:MPI_Comm_create_group, libmpi), Cint,
137+
(MPI_Comm, MPI_Group, Cint, Ptr{MPI_Comm}), comm, group, tag, newcomm)
138+
finalizer(free, newcomm)
139+
newcomm
140+
end
141+
71142
"""
72143
Comm_dup(comm::Comm)
73144
@@ -174,32 +245,10 @@ function universe_size()
174245
Int(unsafe_load(result[]))
175246
end
176247

177-
178-
"""
179-
Comparison
180-
181-
An enum denoting the result of [`Comm_compare`](@ref):
182-
183-
- `MPI.IDENT`: the objects are handles for the same object (identical groups and same contexts).
184-
185-
- `MPI.CONGRUENT`: the underlying groups are identical in constituents and rank order; these communicators differ only by context.
186-
187-
- `MPI.SIMILAR`: members of both objects are the same but the rank order differs.
188-
189-
- `MPI.UNEQUAL`: otherwise
190-
"""
191-
@enum Comparison begin
192-
IDENT = MPI_IDENT
193-
CONGRUENT = MPI_CONGRUENT
194-
SIMILAR = MPI_SIMILAR
195-
UNEQUAL = MPI_UNEQUAL
196-
end
197-
198-
199248
"""
200249
Comm_compare(comm1::Comm, comm2::Comm)::MPI.Comparison
201250
202-
Compare two communicators, returning an element of the [`Comparison`](@ref) enum.
251+
Compare two communicators and their underlying groups, returning an element of the [`Comparison`](@ref) enum.
203252
204253
# External links
205254
$(_doc_external("MPI_Comm_compare"))

src/group.jl

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
@mpi_handle Group
2+
3+
const GROUP_NULL = _Group(MPI_GROUP_NULL)
4+
const GROUP_EMPTY = _Group(MPI_GROUP_EMPTY)
5+
6+
Group() = Group(GROUP_NULL.val)
7+
8+
# int MPI_Group_range_excl(MPI_Group group, int n, int ranges[][3], MPI_Group *newgroup)
9+
# int MPI_Group_range_incl(MPI_Group group, int n, int ranges[][3], MPI_Group *newgroup)
10+
# int MPI_Group_translate_ranks(MPI_Group group1, int n, const int ranks1[], MPI_Group group2, int ranks2[])
11+
12+
function free(group::Group)
13+
if group.val != GROUP_NULL.val && !Finalized()
14+
@mpichk ccall((:MPI_Group_free, libmpi), Cint, (Ptr{MPI_Group},), group)
15+
end
16+
return nothing
17+
end
18+
19+
"""
20+
Group_size(group::Group)
21+
22+
The number of processes involved in group.
23+
24+
# External links
25+
$(_doc_external("MPI_Group_size"))
26+
"""
27+
function Group_size(group::Group)
28+
size = Ref{Cint}()
29+
@mpichk ccall((:MPI_Group_size, libmpi), Cint, (MPI_Group, Ptr{Cint}), group, size)
30+
Int(size[])
31+
end
32+
33+
"""
34+
Group_rank(group::Group)
35+
36+
The rank of the process in the particular group.
37+
38+
Returns an integer in the range `0:MPI.Group_size()-1`.
39+
40+
# External links
41+
$(_doc_external("MPI_Group_rank"))
42+
"""
43+
function Group_rank(group::Group)
44+
rank = Ref{Cint}()
45+
@mpichk ccall((:MPI_Group_rank, libmpi), Cint, (MPI_Group, Ptr{Cint}), group, rank)
46+
Int(rank[])
47+
end
48+
49+
"""
50+
Comparison
51+
52+
An enum denoting the result of [`Group_compare`](@ref) (and [`Comm_compare`](@ref)):
53+
54+
- `MPI.IDENT`: the objects are handles for the same object (identical groups and same contexts).
55+
56+
- `MPI.CONGRUENT`: the groups are identical in constituents and rank order; these ommunicators differ only by context.
57+
58+
- `MPI.SIMILAR`: members of both objects are the same but the rank order differs.
59+
60+
- `MPI.UNEQUAL`: otherwise
61+
"""
62+
@enum Comparison begin
63+
IDENT = MPI_IDENT
64+
CONGRUENT = MPI_CONGRUENT
65+
SIMILAR = MPI_SIMILAR
66+
UNEQUAL = MPI_UNEQUAL
67+
end
68+
69+
function Group_compare(group1::Group, group2::Group)
70+
result = Ref{Comparison}()
71+
@mpichk ccall((:MPI_Group_compare, libmpi), Cint,
72+
(MPI_Group, MPI_Group, Ptr{Comparison}), group1, group2, result)
73+
result[]
74+
end
75+
76+
function Group_difference(group1::Group, group2::Group)
77+
newgroup = Group()
78+
@mpichk ccall((:MPI_Group_difference, libmpi), Cint,
79+
(MPI_Group, MPI_Group, Ptr{MPI_Group}), group1, group2, newgroup)
80+
finalizer(free, newgroup)
81+
return newgroup
82+
end
83+
84+
function Group_intersection(group1::Group, group2::Group)
85+
newgroup = Group()
86+
@mpichk ccall((:MPI_Group_intersection, libmpi), Cint,
87+
(MPI_Group, MPI_Group, Ptr{MPI_Group}), group1, group2, newgroup)
88+
finalizer(free, newgroup)
89+
return newgroup
90+
end
91+
92+
function Group_union(group1::Group, group2::Group)
93+
newgroup = Group()
94+
@mpichk ccall((:MPI_Group_union, libmpi), Cint,
95+
(MPI_Group, MPI_Group, Ptr{MPI_Group}), group1, group2, newgroup)
96+
finalizer(free, newgroup)
97+
return newgroup
98+
end
99+
100+
function Group_excl(group::Group, ranks::Vector{Cint})
101+
newgroup = Group()
102+
@mpichk ccall((:MPI_Group_excl, libmpi), Cint,
103+
(MPI_Group, Cint, Ptr{Cint}, Ptr{MPI_Group}), group, length(ranks), ranks, newgroup)
104+
finalizer(free, newgroup)
105+
return newgroup
106+
end
107+
108+
function Group_incl(group::Group, ranks::Vector{Cint})
109+
newgroup = Group()
110+
@mpichk ccall((:MPI_Group_incl, libmpi), Cint,
111+
(MPI_Group, Cint, Ptr{Cint}, Ptr{MPI_Group}), group, length(ranks), ranks, newgroup)
112+
finalizer(free, newgroup)
113+
return newgroup
114+
end

src/io.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ Writes to `file` using the shared file pointer from `data`. `data` can be a
361361
[`Buffer`](@ref), or any object for which `Buffer(data)` is defined.
362362
363363
# See also
364-
- [`MPI.File.write_ordered`](@ref) for the noncollective operation
364+
- [`MPI.File.write_ordered`](@ref) for the collective operation
365365
366366
# External links
367367
$(_doc_external("MPI_File_write_shared"))
@@ -387,7 +387,7 @@ is a collective operation, so must be called on all ranks in the communicator on
387387
`file` was opened.
388388
389389
# See also
390-
- [`MPI.File.read_shared!`](@ref) for the non-collective operation
390+
- [`MPI.File.read_shared!`](@ref) for the noncollective operation
391391
392392
# External links
393393
$(_doc_external("MPI_File_read_ordered"))

test/test_group.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using Test
2+
using MPI
3+
4+
MPI.Init()
5+
6+
comm = MPI.COMM_WORLD
7+
grp = MPI.Comm_group(comm)
8+
@test MPI.Comm_size(comm) == MPI.Group_size(grp)
9+
@test MPI.Comm_rank(comm) == MPI.Group_rank(grp)
10+
@test MPI.Group_compare(grp, grp) === MPI.IDENT
11+
grp2 = MPI.Group_union(grp, MPI.GROUP_EMPTY)
12+
@test MPI.Group_compare(grp, grp2) === MPI.IDENT
13+
grp3 = MPI.Group_difference(grp, grp2)
14+
@test MPI.Group_compare(grp3, MPI.GROUP_EMPTY) === MPI.IDENT
15+
grp4 = MPI.Group_intersection(grp, grp2)
16+
@test MPI.Group_compare(grp4, MPI.GROUP_EMPTY) === MPI.UNEQUAL
17+
grp5 = MPI.Group_excl(grp, Int32[0])
18+
@test MPI.Group_size(grp5) == (MPI.Group_size(grp)-1)
19+
grp6 = MPI.Group_incl(grp, Int32[0])
20+
@test MPI.Group_size(grp6) == 1
21+
22+
# Don't free the other groups
23+
MPI.free(grp)
24+
25+
MPI.Finalize()
26+
@test MPI.Finalized()

0 commit comments

Comments
 (0)