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