@@ -40,12 +40,10 @@ Determines a list of tuples used to perform the read or write operations. The re
40
40
- `temp_indices` indices for reading from temp array
41
41
- `data_indices` indices for reading from data array
42
42
"""
43
- Base. @assume_effects :removable resolve_indices (a,i) = resolve_indices (a,i,batchstrategy (a))
44
- Base. @assume_effects :removable resolve_indices (a, i, batch_strategy) = _resolve_indices (eachchunk (a). chunks, i, (), (), (), (), (), batch_strategy)
45
- Base. @assume_effects :removable resolve_indices (a:: AbstractVector , i:: Tuple{AbstractVector{<:Integer}} , batch_strategy:: NoBatch ) = _resolve_indices (eachchunk (a). chunks, i, (), (), (), (), (), batch_strategy)
46
- Base. @assume_effects :removable resolve_indices (a:: AbstractVector , i:: Tuple{AbstractVector{<:Integer}} , batch_strategy:: ChunkRead ) = _resolve_indices (eachchunk (a). chunks, i, (), (), (), (), (), batch_strategy)
47
- Base. @assume_effects :removable resolve_indices (a:: AbstractVector , i:: Tuple{AbstractVector{<:Integer}} , batch_strategy:: SubRanges ) = _resolve_indices (eachchunk (a). chunks, i, (), (), (), (), (), batch_strategy)
48
- resolve_indices (a, :: Tuple{Colon} , _) = (length (a),), size (a), (Colon (),), (Colon (),), map (s-> 1 : s,size (a))
43
+ resolve_indices (a,i) = resolve_indices (a,i,batchstrategy (a))
44
+ resolve_indices (a, i, batch_strategy) = _resolve_indices (eachchunk (a). chunks, i, DiskIndex ((),(),(),(),()), batch_strategy)
45
+ resolve_indices (a:: AbstractVector , i:: Tuple{AbstractVector{<:Integer}} , batch_strategy) = _resolve_indices (eachchunk (a). chunks, i, DiskIndex ((), (), (), (), ()), batch_strategy)
46
+ resolve_indices (a, :: Tuple{Colon} , _) = DiskIndex ((length (a),), size (a), (Colon (),), (Colon (),), map (s-> 1 : s,size (a)))
49
47
resolve_indices (a, i:: Tuple{<:CartesianIndex} , batch_strategy= NoBatch ()) =
50
48
resolve_indices (a, only (i). I, batch_strategy)
51
49
function resolve_indices (a, i:: Tuple{<:AbstractVector{<:Integer}} , batchstrategy)
@@ -73,49 +71,65 @@ function need_batch_index(i, cs, batchstrat)
73
71
nb = (allow_multi || has_chunk_gap (approx_chunksize .(csnow), i)) && is_sparse_index (i; density_threshold= density_thresh)
74
72
nb, csrem
75
73
end
76
- function _resolve_indices (cs, i, output_size, temp_sizes, output_indices, temp_indices, data_indices, nb)
74
+
75
+
76
+ struct DiskIndex{N,M,A<: Tuple ,B<: Tuple ,C<: Tuple }
77
+ output_size:: NTuple{N,Int}
78
+ temparray_size:: NTuple{M,Int}
79
+ output_indices:: A
80
+ temparray_indices:: B
81
+ data_indices:: C
82
+ end
83
+ @inline function merge_index (a:: DiskIndex ,b:: DiskIndex )
84
+ DiskIndex (
85
+ (a. output_size... ,b. output_size... ),
86
+ (a. temparray_size... ,b. temparray_size... ),
87
+ (a. output_indices... ,b. output_indices... ),
88
+ (a. temparray_indices... ,b. temparray_indices... ),
89
+ (a. data_indices... ,b. data_indices... ),
90
+ )
91
+ end
92
+
93
+ function _resolve_indices (cs, i, indices_pre:: DiskIndex , nb:: ChunkStrategy )
77
94
inow = first (i)
78
- outsize, tempsize, outinds, tempinds, datainds, cs = process_index (inow, cs, nb)
79
- output_size = (output_size... , outsize... )
80
- output_indices = (output_indices... , outinds... )
81
- temp_sizes = (temp_sizes... , tempsize... )
82
- temp_indices = (temp_indices... , tempinds... )
83
- data_indices = (data_indices... , datainds... )
84
- _resolve_indices (cs, Base. tail (i), output_size, temp_sizes, output_indices, temp_indices, data_indices, nb)
85
- end
86
- _resolve_indices (:: Tuple{} , :: Tuple{} , output_size, temp_sizes, output_indices, temp_indices, data_indices, nb) = output_size, temp_sizes, output_indices, temp_indices, data_indices
95
+ indices_new, cs_rem = process_index (inow, cs, nb)
96
+ _resolve_indices (cs_rem, Base. tail (i), merge_index (indices_pre,indices_new), nb)
97
+ end
98
+ _resolve_indices (:: Tuple{} , :: Tuple{} , indices:: DiskIndex , nb:: ChunkStrategy ) = indices
87
99
# No dimension left in array, only singular indices allowed
88
- function _resolve_indices (:: Tuple{} , i, output_size, temp_sizes, output_indices, temp_indices, data_indices, nb )
100
+ function _resolve_indices (:: Tuple{} , i, indices_pre :: DiskIndex , nb :: ChunkStrategy )
89
101
inow = first (i)
90
102
(length (inow) == 1 && only (inow) == 1 ) || throw (ArgumentError (" Trailing indices must be 1" ))
91
- output_size = (output_size ... , size (inow)... )
92
- output_indices = (output_indices ... , size (inow) ... )
93
- _resolve_indices ((), Base. tail (i), output_size, temp_sizes, output_indices, temp_indices, data_indices , nb)
103
+ indices_new = DiskIndex ( size (inow),(), size (inow),(),() )
104
+ indices = merge_index (indices_pre,indices_new )
105
+ _resolve_indices ((), Base. tail (i), indices , nb)
94
106
end
95
107
# Still dimensions left, but no indices available
96
- function _resolve_indices (cs, :: Tuple{} , output_size, temp_sizes, output_indices, temp_indices, data_indices, nb)
108
+ function _resolve_indices (cs, :: Tuple{} , indices_pre :: DiskIndex , nb :: ChunkStrategy )
97
109
csnow = first (cs)
98
110
arraysize_from_chunksize (csnow) == 1 || throw (ArgumentError (" Indices can only be omitted for trailing singleton dimensions" ))
99
- data_indices = (data_indices... , 1 : 1 )
100
- temp_sizes = (temp_sizes... , 1 )
101
- temp_indices = (temp_indices... , 1 )
102
- _resolve_indices (Base. tail (cs), (), output_size, temp_sizes, output_indices, temp_indices, data_indices, nb)
111
+ indices_new = add_dimension_index (nb)
112
+ indices = merge_index (indices_pre,indices_new)
113
+ _resolve_indices (Base. tail (cs), (), indices, nb)
103
114
end
104
115
116
+ add_dimension_index (:: NoBatch ) = DiskIndex ((),(1 ,),(),(1 ,),(1 : 1 ,))
117
+ add_dimension_index (:: Union{ChunkRead,SubRanges} ) = DiskIndex ((),(1 ,),([()],),([(1 ,)],),([(1 : 1 ,)],))
118
+
105
119
106
120
# outsize, tempsize, outinds,tempinds,datainds,cs
107
121
process_index (i, cs, :: NoBatch ) = process_index (i, cs)
108
- process_index (inow:: Integer , cs) = ((), 1 , (), (1 ,), (inow: inow,), Base. tail (cs) )
122
+ process_index (inow:: Integer , cs) = DiskIndex ((), ( 1 ,), (), (1 ,), (inow: inow,)) , Base. tail (cs)
109
123
function process_index (:: Colon , cs)
110
124
s = arraysize_from_chunksize (first (cs))
111
- ( s,), (s,), (Colon (),), (Colon (),), (1 : s,), Base. tail (cs)
125
+ DiskIndex (( s,), (s,), (Colon (),), (Colon (),), (1 : s,) ,), Base. tail (cs)
112
126
end
113
- function process_index (i:: AbstractUnitRange , cs)
114
- ( length (i),), (length (i),), (Colon (),), (Colon (),), (i,), Base. tail (cs)
127
+ function process_index (i:: AbstractUnitRange{<:Integer} , cs, :: NoBatch )
128
+ DiskIndex (( length (i),), (length (i),), (Colon (),), (Colon (),), (i,) ), Base. tail (cs)
115
129
end
116
130
function process_index (i:: AbstractArray{<:Integer} , cs, :: NoBatch )
117
131
indmin, indmax = extrema (i)
118
- size (i), ((indmax - indmin + 1 ),), map (_-> Colon (),size (i)), ((i .- (indmin - 1 )),), (indmin: indmax,), Base. tail (cs)
132
+ DiskIndex ( size (i), ((indmax - indmin + 1 ),), map (_-> Colon (),size (i)), ((i .- (indmin - 1 )),), (indmin: indmax,) ), Base. tail (cs)
119
133
end
120
134
function process_index (i:: AbstractArray{Bool,N} , cs, :: NoBatch ) where {N}
121
135
csnow, csrem = splitcs (i, cs)
@@ -124,7 +138,7 @@ function process_index(i::AbstractArray{Bool,N}, cs, ::NoBatch) where {N}
124
138
indmin, indmax = cindmin. I, cindmax. I
125
139
tempsize = indmax .- indmin .+ 1
126
140
tempinds = view (i, range .(indmin, indmax)... )
127
- ( sum (i),), tempsize, (Colon (),), (tempinds,), range .(indmin, indmax), csrem
141
+ DiskIndex (( sum (i),), tempsize, (Colon (),), (tempinds,), range .(indmin, indmax) ), csrem
128
142
end
129
143
function process_index (i:: AbstractArray{<:CartesianIndex{N}} , cs, :: NoBatch ) where {N}
130
144
csnow, csrem = splitcs (i, cs)
@@ -133,14 +147,14 @@ function process_index(i::AbstractArray{<:CartesianIndex{N}}, cs, ::NoBatch) whe
133
147
indmin, indmax = cindmin. I, cindmax. I
134
148
tempsize = indmax .- indmin .+ 1
135
149
tempoffset = cindmin - oneunit (cindmin)
136
- tempinds = i .- tempoffset
150
+ tempinds = i .- ( CartesianIndex ( tempoffset),)
137
151
outinds = map (_-> Colon (),size (i))
138
- size (i), tempsize, outinds, (tempinds,), range .(indmin, indmax), csrem
152
+ DiskIndex ( size (i), tempsize, outinds, (tempinds,), range .(indmin, indmax) ), csrem
139
153
end
140
154
function process_index (i:: CartesianIndices{N} , cs, :: NoBatch ) where {N}
141
155
_, csrem = splitcs (i, cs)
142
156
cols = map (_ -> Colon (), i. indices)
143
- length .(i. indices), length .(i. indices), cols, cols, i. indices, csrem
157
+ DiskIndex ( length .(i. indices), length .(i. indices), cols, cols, i. indices) , csrem
144
158
end
145
159
splitcs (i:: AbstractArray{<:CartesianIndex} , cs) = splitcs (first (i). I, (), cs)
146
160
splitcs (i:: AbstractArray{Bool} , cs) = splitcs (size (i), (), cs)
@@ -149,6 +163,20 @@ splitcs(_, cs) = (first(cs),), Base.tail(cs)
149
163
splitcs (si, csnow, csrem) = splitcs (Base. tail (si), (csnow... , first (csrem)), Base. tail (csrem))
150
164
splitcs (:: Tuple{} , csnow, csrem) = (csnow, csrem)
151
165
166
+ # Determine wether output and temp array can a) be identical b) share memory through reshape or
167
+ # c) need to be allocated individually
168
+ function output_aliasing (di:: DiskIndex )
169
+ if all (i-> isa (i,Union{Int,AbstractUnitRange,Colon}),di. temparray_indices) &&
170
+ all (i-> isa (i,Union{Int,AbstractUnitRange,Colon}),di. output_indices)
171
+ if di. output_size == di. temparray_size
172
+ return :identical
173
+ else
174
+ return :reshapeoutput
175
+ end
176
+ else
177
+ return :noalign
178
+ end
179
+ end
152
180
153
181
154
182
function getindex_disk (a, i:: Union{Integer,CartesianIndex} ...)
@@ -162,6 +190,14 @@ function getindex_disk(a, i::Union{Integer,CartesianIndex}...)
162
190
readblock! (a, outputarray, j... )
163
191
only (outputarray)
164
192
end
193
+ function getindex_disk (a, i:: Integer )
194
+ checkscalar (i)
195
+ checkbounds (a,i)
196
+ outputarray = Array {eltype(a)} (undef, map (_ -> 1 , size (a))... )
197
+ j = map (k-> k: k,CartesianIndices (a)[i]. I)
198
+ readblock! (a, outputarray, j... )
199
+ only (outputarray)
200
+ end
165
201
166
202
function create_outputarray (out, a, output_size)
167
203
size (out) == output_size || throw (ArgumentError (" Expected output array size of $output_size " ))
@@ -171,17 +207,13 @@ create_outputarray(::Nothing, a, output_size) = Array{eltype(a)}(undef, output_s
171
207
172
208
getindex_disk (a, i... ) = getindex_disk! (nothing , a, i... )
173
209
174
- function _getindex_do_rest (out,a,output_size, temparray_size, output_indices, temparray_indices, data_indices)
175
-
176
- end
177
-
178
210
function getindex_disk_batch! (out,a,i)
179
- output_size, temparray_size, output_indices, temparray_indices, data_indices = resolve_indices (a, i)
180
- moutput_indices = MRArray (output_indices)
181
- mtemparray_indices = MRArray (temparray_indices)
182
- mdata_indicess = MRArray (data_indices)
183
- outputarray = create_outputarray (out, a, output_size)
184
- temparray = Array {eltype(a)} (undef, temparray_size... )
211
+ indices = resolve_indices (a, i)
212
+ moutput_indices = MRArray (indices . output_indices)
213
+ mtemparray_indices = MRArray (indices . temparray_indices)
214
+ mdata_indicess = MRArray (indices . data_indices)
215
+ outputarray = create_outputarray (out, a, indices . output_size)
216
+ temparray = Array {eltype(a)} (undef, indices . temparray_size... )
185
217
for ii in eachindex (moutput_indices)
186
218
data_indices = mdata_indicess[ii]
187
219
output_indices = moutput_indices[ii]
@@ -194,12 +226,20 @@ function getindex_disk_batch!(out,a,i)
194
226
end
195
227
196
228
function getindex_disk_nobatch! (out,a,i)
197
- output_size, temparray_size, output_indices, temparray_indices, data_indices = resolve_indices (a, i, NoBatch (allow_steprange (a), 1.0 ))
229
+ indices = resolve_indices (a, i, NoBatch (allow_steprange (a), 1.0 ))
198
230
# @debug output_size, temparray_size, output_indices, temparray_indices, data_indices
199
- outputarray = create_outputarray (out, a, output_size)
200
- temparray = Array {eltype(a)} (undef, temparray_size... )
201
- readblock! (a, temparray, data_indices... )
202
- transfer_results! (outputarray, temparray, output_indices, temparray_indices)
231
+ outputarray = create_outputarray (out, a, indices. output_size)
232
+ outalias = output_aliasing (indices)
233
+ if outalias === :identical
234
+ readblock! (a, outputarray, indices. data_indices... )
235
+ elseif outalias === :reshapeoutput
236
+ temparray = reshape (outputarray,indices. temparray_size)
237
+ readblock! (a, temparray, indices. data_indices... )
238
+ else
239
+ temparray = Array {eltype(a)} (undef, indices. temparray_size... )
240
+ readblock! (a, temparray, indices. data_indices... )
241
+ transfer_results! (outputarray, temparray, indices. output_indices, indices. temparray_indices)
242
+ end
203
243
outputarray
204
244
end
205
245
@@ -243,11 +283,11 @@ end
243
283
244
284
function setindex_disk_batch! (a,v,i)
245
285
batch_strategy = batchstrategy (a)
246
- output_size, temparray_size, output_indices, temparray_indices, data_indices = resolve_indices (a, i, batch_strategy)
247
- moutput_indices = MRArray (output_indices)
248
- mtemparray_indices = MRArray (temparray_indices)
249
- mdata_indicess = MRArray (data_indices)
250
- temparray = Array {eltype(a)} (undef, temparray_size... )
286
+ indices = resolve_indices (a, i, batch_strategy)
287
+ moutput_indices = MRArray (indices . output_indices)
288
+ mtemparray_indices = MRArray (indices . temparray_indices)
289
+ mdata_indicess = MRArray (indices . data_indices)
290
+ temparray = Array {eltype(a)} (undef, indices . temparray_size... )
251
291
for (output_indices, temparray_indices, data_indices) in zip (moutput_indices, mtemparray_indices, mdata_indicess)
252
292
transfer_results_write! (v, temparray, output_indices, temparray_indices)
253
293
vtemparray = maybeshrink (temparray, a, data_indices)
@@ -256,10 +296,18 @@ function setindex_disk_batch!(a,v,i)
256
296
end
257
297
258
298
function setindex_disk_nobatch! (a,v,i)
259
- output_size, temparray_size, output_indices, temparray_indices, data_indices = resolve_indices (a, i, NoBatch ())
260
- temparray = Array {eltype(a)} (undef, temparray_size... )
261
- transfer_results_write! (v, temparray, output_indices, temparray_indices)
262
- writeblock! (a, temparray, data_indices... )
299
+ indices = resolve_indices (a, i, NoBatch ())
300
+ outalias = output_aliasing (indices)
301
+ if outalias === :identical
302
+ writeblock! (a, v, indices. data_indices... )
303
+ elseif outalias === :reshapeoutput
304
+ temparray = reshape (v,indices. temparray_size)
305
+ writeblock! (a, temparray, indices. data_indices... )
306
+ else
307
+ temparray = Array {eltype(a)} (undef, indices. temparray_size... )
308
+ transfer_results_write! (v, temparray, indices. output_indices, indices. temparray_indices)
309
+ writeblock! (a, temparray, indices. data_indices... )
310
+ end
263
311
end
264
312
265
313
function setindex_disk! (a:: AbstractArray , v:: AbstractArray , i... )
@@ -268,6 +316,7 @@ function setindex_disk!(a::AbstractArray, v::AbstractArray, i...)
268
316
else
269
317
setindex_disk_nobatch! (a,v,i)
270
318
end
319
+ v
271
320
end
272
321
273
322
" Find the indices of elements containing integers in a Tuple"
0 commit comments