@@ -539,4 +539,30 @@ ndims_index(@nospecialize T::Type{<:Base.LogicalIndex}) = ndims(fieldtype(T, :ma
539
539
ndims_index (T:: DataType ) = 1
540
540
ndims_index (@nospecialize (i)) = ndims_index (typeof (i))
541
541
542
+ """
543
+ instances_do_not_alias(::Type{T}) -> Bool
544
+
545
+ Is it safe to `ivdep` arrays containing elements of type `T`?
546
+ That is, would it be safe to write to an array full of `T` in parallel?
547
+ This is not true for `mutable struct`s in general, where editing one index
548
+ could edit other indices.
549
+ That is, it is not safe when different instances may alias the same memory.
550
+ """
551
+ instances_do_not_alias (:: Type{T} ) where {T} = Base. isbitstype (T)
552
+
553
+ """
554
+ indices_do_not_alias(::Type{T<:AbstractArray}) -> Bool
555
+
556
+ Is it safe to `ivdep` arrays of type `T`?
557
+ That is, would it be safe to write to an array of type `T` in parallel?
558
+ Examples where this is not true are `BitArray`s or `view(rand(6), [1,2,3,1,2,3])`.
559
+ That is, it is not safe whenever different indices may alias the same memory.
560
+ """
561
+ indices_do_not_alias (:: Type ) = false
562
+ indices_do_not_alias (:: Type{A} ) where {T, A<: Base.StridedArray{T} } = instances_do_not_alias (T)
563
+ indices_do_not_alias (:: Type{Adjoint{T,A}} ) where {T, A <: AbstractArray{T} } = indices_do_not_alias (A)
564
+ indices_do_not_alias (:: Type{Transpose{T,A}} ) where {T, A <: AbstractArray{T} } = indices_do_not_alias (A)
565
+ indices_do_not_alias (:: Type{<:SubArray{<:Any,<:Any,A,I}} ) where {
566
+ A,I<: Tuple{Vararg{Union{Base.RangeIndex, Base.ReshapedUnitRange, Base.AbstractCartesianIndex}}} } = indices_do_not_alias (A)
567
+
542
568
end # module
0 commit comments