1
1
using Oceananigans. Grids: topology
2
2
using Oceananigans. Fields: validate_field_data, indices, validate_boundary_conditions
3
3
using Oceananigans. Fields: validate_indices, set_to_array!, set_to_field!
4
+ using CUDA: @allowscalar
5
+
6
+ using Oceananigans. Fields: ReducedAbstractField,
7
+ get_neutral_mask,
8
+ condition_operand,
9
+ initialize_reduced_field!,
10
+ filltype,
11
+ reduced_dimensions,
12
+ reduced_location
4
13
5
14
import Oceananigans. Fields: Field, location, set!
6
15
import Oceananigans. BoundaryConditions: fill_halo_regions!
@@ -95,63 +104,66 @@ function reconstruct_global_field(field::DistributedField)
95
104
return global_field
96
105
end
97
106
98
- function maybe_all_reduce! (op, f:: ReducedDistributedField , dims)
99
- reduced_dims = reduced_dimensions (f)
107
+ partition_dimensions (f:: DistributedField ) = partition_dimensions (architecture (f))
108
+ function partition_dimensions (arch:: Distributed )
109
+ R = ranks (arch)
110
+ dims = []
111
+ for r in eachindex (R)
112
+ if R[r] > 1
113
+ push! (dims, r)
114
+ end
115
+ end
116
+ return tuple (dims... )
117
+ end
118
+
119
+ function maybe_all_reduce! (op, f:: ReducedAbstractField )
120
+ reduced_dims = reduced_dimensions (f)
121
+ partition_dims = partition_dimensions (f)
100
122
101
- if any (reduced_dims .∈ tuple (dims ... ) )
123
+ if any ([dim ∈ partition_dims for dim in reduced_dims] )
102
124
all_reduce! (op, interior (f), architecture (f))
103
125
end
104
126
105
127
return f
106
128
end
107
129
108
- function maybe_all_reduce! (op, f:: ReducedDistributedField , :: Colon )
109
- all_reduce! (op, interior (f), architecture (f))
110
- return f
111
- end
112
-
113
130
# Allocating and in-place reductions
114
131
for (reduction, all_reduce_op) in zip ((:sum , :maximum , :minimum , :all , :any , :prod ),
115
- ( + , max, min, & , | , * ))
132
+ (: + , : max , : min , : & , : | , : * ))
116
133
117
134
reduction! = Symbol (reduction, ' !' )
118
135
119
136
@eval begin
120
-
121
137
# In-place
122
138
function Base. $ (reduction!)(f:: Function ,
123
139
r:: ReducedAbstractField ,
124
140
a:: DistributedField ;
125
141
condition = nothing ,
126
142
mask = get_neutral_mask (Base.$ (reduction!)),
127
- dims = :,
128
143
kwargs... )
129
144
130
145
operand = condition_operand (f, a, condition, mask)
131
146
132
147
Base.$ (reduction!)(identity,
133
148
interior (r),
134
149
operand;
135
- dims,
136
150
kwargs... )
137
151
138
- return maybe_all_reduce! (all_reduce_op, r, dims )
152
+ return maybe_all_reduce! ($ ( all_reduce_op) , r)
139
153
end
140
154
141
155
function Base. $ (reduction!)(r:: ReducedAbstractField ,
142
156
a:: DistributedField ;
143
157
condition = nothing ,
144
158
mask = get_neutral_mask (Base.$ (reduction!)),
145
- dims = :,
146
159
kwargs... )
147
160
148
161
Base.$ (reduction!)(identity,
149
162
interior (r),
150
163
condition_operand (a, condition, mask);
151
- dims,
152
164
kwargs... )
153
165
154
- return maybe_all_reduce! (all_reduce_op, r, dims )
166
+ return maybe_all_reduce! ($ ( all_reduce_op) , r)
155
167
end
156
168
157
169
# Allocating
@@ -168,10 +180,10 @@ for (reduction, all_reduce_op) in zip((:sum, :maximum, :minimum, :all, :any, :pr
168
180
initialize_reduced_field! (Base.$ (reduction!), identity, r, conditioned_c)
169
181
Base.$ (reduction!)(identity, interior (r), conditioned_c, init= false )
170
182
171
- maybe_all_reduce! (all_reduce_op, r, dims )
183
+ maybe_all_reduce! ($ ( all_reduce_op) , r)
172
184
173
185
if dims isa Colon
174
- return CUDA . @allowscalar first (r)
186
+ return @allowscalar first (r)
175
187
else
176
188
return r
177
189
end
0 commit comments