@@ -1047,25 +1047,34 @@ end
1047
1047
1048
1048
# ## from abstractarray.jl
1049
1049
1050
- # In the common case where we have two views into the same parent, aliasing checks
1051
- # are _much_ easier and more important to get right
1052
- function mightalias (A:: SubArray{T,<:Any,P} , B:: SubArray{T,<:Any,P} ) where {T,P}
1053
- if ! _parentsmatch (A. parent, B. parent)
1054
- # We cannot do any better than the usual dataids check
1055
- return ! _isdisjoint (dataids (A), dataids (B))
1056
- end
1057
- # Now we know that A.parent === B.parent. This means that the indices of A
1058
- # and B are the same length and indexing into the same dimensions. We can
1059
- # just walk through them and check for overlaps: O(ndims(A)). We must finally
1060
- # ensure that the indices don't alias with either parent
1061
- return _indicesmightoverlap (A. indices, B. indices) ||
1062
- ! _isdisjoint (dataids (A. parent), _splatmap (dataids, B. indices)) ||
1063
- ! _isdisjoint (dataids (B. parent), _splatmap (dataids, A. indices))
1050
+ function mightalias (A:: SubArray , B:: SubArray )
1051
+ # There are three ways that SubArrays might _problematically_ alias one another:
1052
+ # 1. The parents are the same we can conservatively check if the indices might overlap OR
1053
+ # 2. The parents alias eachother in a more complicated manner (and we can't trace indices) OR
1054
+ # 3. One's parent is used in the other's indices
1055
+ # Note that it's ok for just the indices to alias each other as those should not be mutated,
1056
+ # so we can always do better than the default !_isdisjoint(dataids(A), dataids(B))
1057
+ if isbits (A. parent) || isbits (B. parent)
1058
+ return false # Quick out for immutables
1059
+ elseif _parentsmatch (A. parent, B. parent)
1060
+ # Each SubArray unaliases its own parent from its own indices upon construction, so if
1061
+ # the two parents are the same, then by construction one cannot alias the other's indices
1062
+ # and therefore this is the only test we need to perform:
1063
+ return _indicesmightoverlap (A. indices, B. indices)
1064
+ else
1065
+ A_parent_ids = dataids (A. parent)
1066
+ B_parent_ids = dataids (B. parent)
1067
+ return ! _isdisjoint (A_parent_ids, B_parent_ids) ||
1068
+ ! _isdisjoint (A_parent_ids, _splatmap (dataids, B. indices)) ||
1069
+ ! _isdisjoint (B_parent_ids, _splatmap (dataids, A. indices))
1070
+ end
1064
1071
end
1072
+ # Test if two arrays are backed by exactly the same memory in exactly the same order
1065
1073
_parentsmatch (A:: AbstractArray , B:: AbstractArray ) = A === B
1066
- # Two reshape(::Array)s of the same size aren't `===` because they have different headers
1067
- _parentsmatch (A:: Array , B:: Array ) = pointer (A) == pointer (B) && size (A) == size (B)
1074
+ _parentsmatch (A :: DenseArray , B :: DenseArray ) = elsize (A) == elsize (B) && pointer (A) == pointer (B) && size (A) == size (B)
1075
+ _parentsmatch (A:: StridedArray , B:: StridedArray ) = elsize (A) == elsize (B) && pointer (A) == pointer (B) && strides (A) == strides (B)
1068
1076
1077
+ # Given two SubArrays with the same parent, check if the indices might overlap (returning true if unsure)
1069
1078
_indicesmightoverlap (A:: Tuple{} , B:: Tuple{} ) = true
1070
1079
_indicesmightoverlap (A:: Tuple{} , B:: Tuple ) = error (" malformed subarray" )
1071
1080
_indicesmightoverlap (A:: Tuple , B:: Tuple{} ) = error (" malformed subarray" )
0 commit comments