@@ -15,12 +15,13 @@ Returned from `cat` on disk arrays.
15
15
16
16
It is also useful on its own as it can easily concatenate an array of disk arrays.
17
17
"""
18
- struct ConcatDiskArray{T,N,P,C,HC} <: AbstractDiskArray{T,N}
18
+ struct ConcatDiskArray{T,N,P,C,HC,ID } <: AbstractDiskArray{T,N}
19
19
parents:: P
20
20
startinds:: NTuple{N,Vector{Int}}
21
21
size:: NTuple{N,Int}
22
22
chunks:: C
23
23
haschunks:: HC
24
+ innerdims:: Val{ID}
24
25
end
25
26
26
27
function ConcatDiskArray (arrays:: AbstractArray{Union{<:AbstractArray,Missing}} )
@@ -30,47 +31,57 @@ function ConcatDiskArray(arrays::AbstractArray{Union{<:AbstractArray,Missing}})
30
31
M = ndims (et)
31
32
_ConcatDiskArray (arrays, T, Val (N), Val (M))
32
33
end
33
- function ConcatDiskArray (arrays:: AbstractArray{<:AbstractArray} )
34
- T = eltype (eltype (arrays))
35
- N = ndims (arrays)
36
- M = ndims (eltype (arrays))
37
- _ConcatDiskArray (arrays, T, Val (N), Val (M))
38
- end
39
- function ConcatDiskArray (arrays:: AbstractArray )
40
- N = ndims (arrays)
41
- M, T = foldl (arrays, init= (- 1 , Union{})) do (M, T), a
34
+ function infer_eltypes (arrays)
35
+ foldl (arrays, init= (- 1 , Union{})) do (M, T), a
42
36
if ismissing (a)
43
37
(M, promote_type (Missing, T))
44
38
else
45
39
M == - 1 || ndims (a) == M || throw (ArgumentError (" All arrays to concatenate must have equal ndims" ))
46
40
(ndims (a), promote_type (eltype (a), T))
47
41
end
48
42
end
43
+ end
44
+ function ConcatDiskArray (arrays:: AbstractArray{<:AbstractArray} )
45
+ N = ndims (arrays)
46
+ T = eltype (eltype (arrays))
47
+ if ! isconcretetype (T)
48
+ M,T = infer_eltypes (arrays)
49
+ else
50
+ M = ndims (eltype (arrays))
51
+ end
52
+ _ConcatDiskArray (arrays, T, Val (N), Val (M))
53
+ end
54
+ function ConcatDiskArray (arrays:: AbstractArray )
55
+ N = ndims (arrays)
56
+ M,T = infer_eltypes (arrays)
49
57
_ConcatDiskArray (arrays, T, Val (N), Val (M))
50
58
end
51
59
52
60
53
61
function _ConcatDiskArray (arrays, T, :: Val{N} , :: Val{M} ) where {N,M}
54
- if N > M
55
- newshape = extenddims (size (arrays), ntuple (_ -> 1 , N ), 1 )
62
+ if N < M
63
+ newshape = extenddims (size (arrays), ntuple (_ -> 1 , M ), 1 )
56
64
arrays1 = reshape (arrays, newshape)
57
- D = N
65
+ D = M
58
66
else
59
67
arrays1 = arrays
60
- D = M
68
+ D = N
61
69
end
62
- _ConcatDiskArray (arrays1:: AbstractArray , T, Val (D))
70
+ ConcatDiskArray (arrays1:: AbstractArray , T, Val (D), Val (M ))
63
71
end
64
- function _ConcatDiskArray (arrays1:: AbstractArray , T, :: Val{D} ) where {D}
72
+ function ConcatDiskArray (arrays1:: AbstractArray , T, :: Val{D} , :: Val{ID} ) where {D,ID }
65
73
startinds, sizes = arraysize_and_startinds (arrays1)
66
74
67
75
chunks = concat_chunksize (arrays1)
68
76
hc = Chunked (batchstrategy (chunks))
69
77
70
- return ConcatDiskArray {T,D,typeof(arrays1),typeof(chunks),typeof(hc)} (arrays1, startinds, sizes, chunks, hc)
78
+ return ConcatDiskArray {T,D,typeof(arrays1),typeof(chunks),typeof(hc),ID } (arrays1, startinds, sizes, chunks, hc, Val (ID) )
71
79
end
72
80
73
- extenddims (a:: Tuple{Vararg{Any,N}} , b:: Tuple{Vararg{Any,M}} , fillval) where {N,M} = extenddims ((a... , fillval), b, fillval)
81
+ function extenddims (a:: Tuple{Vararg{Any,N}} , b:: Tuple{Vararg{Any,M}} , fillval) where {N,M}
82
+ length (a) > length (b) && error (" Wrong" )
83
+ extenddims ((a... , fillval), b, fillval)
84
+ end
74
85
extenddims (a:: Tuple{Vararg{Any,N}} , _:: Tuple{Vararg{Any,N}} , _) where {N} = a
75
86
76
87
Base. size (a:: ConcatDiskArray ) = a. size
@@ -134,9 +145,12 @@ function writeblock!(a::ConcatDiskArray, aout, inds::AbstractUnitRange...)
134
145
end
135
146
136
147
# Utils
148
+ ninnerdims (a:: ConcatDiskArray ) = ninnerdims (a. innerdims)
149
+ ninnerdims (:: Val{ID} ) where ID = ID
137
150
138
151
function _concat_diskarray_block_io (f, a:: ConcatDiskArray , inds... )
139
152
# Find affected blocks and indices in blocks
153
+ ID = ninnerdims (a)
140
154
blockinds = map (inds, a. startinds, size (a. parents)) do i, si, s
141
155
bi1 = max (searchsortedlast (si, first (i)), 1 )
142
156
bi2 = min (searchsortedfirst (si, last (i) + 1 ) - 1 , s)
@@ -147,15 +161,14 @@ function _concat_diskarray_block_io(f, a::ConcatDiskArray, inds...)
147
161
size_inferred = map (a. startinds, size (a), cI. I) do si, sa, ii
148
162
ii == length (si) ? sa - si[ii] + 1 : si[ii+ 1 ] - si[ii]
149
163
end
150
- mysize = extenddims (size_inferred, cI. I, 1 )
151
- array_range = map (cI. I, a. startinds, mysize, inds) do ii, si, ms, indstoread
164
+ array_range = map (cI. I, a. startinds, size_inferred, inds) do ii, si, ms, indstoread
152
165
max (first (indstoread) - si[ii] + 1 , 1 ): min (last (indstoread) - si[ii] + 1 , ms)
153
166
end
154
167
outer_range = map (cI. I, a. startinds, array_range, inds) do ii, si, ar, indstoread
155
168
(first (ar)+ si[ii]- first (indstoread)): (last (ar)+ si[ii]- first (indstoread))
156
169
end
157
170
# Shorten array range to shape of actual array
158
- array_range = map ((i, j) -> j, size_inferred, array_range )
171
+ array_range = ntuple (j -> array_range[j], ID )
159
172
outer_range = fix_outerrangeshape (outer_range, array_range)
160
173
if ismissing (myar)
161
174
f (outer_range, array_range, missing )
0 commit comments