691
691
_cartesian_index (i:: Tuple{Vararg{Int}} ) = CartesianIndex (i)
692
692
_cartesian_index (:: Any ) = nothing
693
693
694
- """
695
- known_first(::Type{T}) -> Union{Int,Nothing}
696
-
697
- If `first` of an instance of type `T` is known at compile time, return it.
698
- Otherwise, return `nothing`.
699
-
700
- ```julia
701
- julia> ArrayInterface.known_first(typeof(1:4))
702
- nothing
703
-
704
- julia> ArrayInterface.known_first(typeof(Base.OneTo(4)))
705
- 1
706
- ```
707
- """
708
- known_first (x) = known_first (typeof (x))
709
- known_first (T:: Type ) = is_forwarding_wrapper (T) ? known_first (parent_type (T)) : nothing
710
- known_first (:: Type{<:Base.OneTo} ) = 1
711
- known_first (@nospecialize T:: Type{<:LinearIndices} ) = 1
712
- known_first (@nospecialize T:: Type{<:Base.IdentityUnitRange} ) = known_first (parent_type (T))
713
- function known_first (:: Type{<:CartesianIndices{N, R}} ) where {N, R}
714
- _cartesian_index (ntuple (i -> known_first (R. parameters[i]), Val (N)))
715
- end
716
-
717
- """
718
- known_last(::Type{T}) -> Union{Int,Nothing}
719
-
720
- If `last` of an instance of type `T` is known at compile time, return it.
721
- Otherwise, return `nothing`.
722
-
723
- ```julia
724
- julia> ArrayInterface.known_last(typeof(1:4))
725
- nothing
726
-
727
- julia> ArrayInterface.known_first(typeof(static(1):static(4)))
728
- 4
729
-
730
- ```
731
- """
732
- known_last (x) = known_last (typeof (x))
733
- known_last (T:: Type ) = is_forwarding_wrapper (T) ? known_last (parent_type (T)) : nothing
734
- function known_last (:: Type{<:CartesianIndices{N, R}} ) where {N, R}
735
- _cartesian_index (ntuple (i -> known_last (R. parameters[i]), Val (N)))
736
- end
737
-
738
- """
739
- known_step(::Type{T}) -> Union{Int,Nothing}
740
-
741
- If `step` of an instance of type `T` is known at compile time, return it.
742
- Otherwise, return `nothing`.
743
-
744
- ```julia
745
- julia> ArrayInterface.known_step(typeof(1:2:8))
746
- nothing
747
-
748
- julia> ArrayInterface.known_step(typeof(1:4))
749
- 1
750
-
751
- ```
752
- """
753
- known_step (x) = known_step (typeof (x))
754
- known_step (T:: Type ) = is_forwarding_wrapper (T) ? known_step (parent_type (T)) : nothing
755
- known_step (@nospecialize T:: Type{<:AbstractUnitRange} ) = 1
756
-
757
- """
758
- is_splat_index(::Type{T}) -> Bool
759
-
760
- Returns `static(true)` if `T` is a type that splats across multiple dimensions.
761
- """
762
- is_splat_index (T:: Type ) = false
763
- is_splat_index (@nospecialize (x)) = is_splat_index (typeof (x))
764
-
765
694
"""
766
695
ndims_index(::Type{I}) -> Int
767
696
@@ -826,162 +755,6 @@ ndims_shape(x) = ndims_shape(typeof(x))
826
755
return nothing
827
756
end
828
757
829
- """
830
- IndicesInfo{N}(inds::Tuple) -> IndicesInfo{N}(typeof(inds))
831
- IndicesInfo{N}(T::Type{<:Tuple}) -> IndicesInfo{N,pdims,cdims}()
832
- IndicesInfo(inds::Tuple) -> IndicesInfo(typeof(inds))
833
- IndicesInfo(T::Type{<:Tuple}) -> IndicesInfo{maximum(pdims),pdims,cdims}()
834
-
835
-
836
- Maps a tuple of indices to `N` dimensions. The resulting `pdims` is a tuple where each
837
- field in `inds` (or field type in `T`) corresponds to the parent dimensions accessed.
838
- `cdims` similarly maps indices to the resulting child array produced after indexing with
839
- `inds`. If `N` is not provided then it is assumed that all indices are represented by parent
840
- dimensions and there are no trailing dimensions accessed. These may be accessed by through
841
- `parentdims(info::IndicesInfo)` and `childdims(info::IndicesInfo)`. If `N` is not provided,
842
- it is assumed that no indices are accessing trailing dimensions (which are represented as
843
- `0` in `parentdims(info)[index_position]`).
844
-
845
- The the fields and types of `IndicesInfo` should not be accessed directly.
846
- Instead [`parentdims`](@ref), [`childdims`](@ref), [`ndims_index`](@ref), and
847
- [`ndims_shape`](@ref) should be used to extract relevant information.
848
-
849
- # Examples
850
-
851
- ```julia
852
- julia> using ArrayInterface: IndicesInfo, parentdims, childdims, ndims_index, ndims_shape
853
-
854
- julia> info = IndicesInfo{5}(typeof((:,[CartesianIndex(1,1),CartesianIndex(1,1)], 1, ones(Int, 2, 2), :, 1)));
855
-
856
- julia> parentdims(info) # the last two indices access trailing dimensions
857
- (1, (2, 3), 4, 5, 0, 0)
858
-
859
- julia> childdims(info)
860
- (1, 2, 0, (3, 4), 5, 0)
861
-
862
- julia> childdims(info)[3] # index 3 accesses a parent dimension but is dropped in the child array
863
- 0
864
-
865
- julia> ndims_index(info)
866
- 5
867
-
868
- julia> ndims_shape(info)
869
- 5
870
-
871
- julia> info = IndicesInfo(typeof((:,[CartesianIndex(1,1),CartesianIndex(1,1)], 1, ones(Int, 2, 2), :, 1)));
872
-
873
- julia> parentdims(info) # assumed no trailing dimensions
874
- (1, (2, 3), 4, 5, 6, 7)
875
-
876
- julia> ndims_index(info) # assumed no trailing dimensions
877
- 7
878
-
879
- ```
880
- """
881
- struct IndicesInfo{Np, pdims, cdims, Nc}
882
- function IndicesInfo {N} (@nospecialize (T:: Type{<:Tuple} )) where {N}
883
- SI = _find_first_true (map_tuple_type (is_splat_index, T))
884
- NI = map_tuple_type (ndims_index, T)
885
- NS = map_tuple_type (ndims_shape, T)
886
- if SI === nothing
887
- ndi = NI
888
- nds = NS
889
- else
890
- nsplat = N - sum (NI)
891
- if nsplat === 0
892
- ndi = NI
893
- nds = NS
894
- else
895
- splatmul = max (0 , nsplat + 1 )
896
- ndi = _map_splats (splatmul, SI, NI)
897
- nds = _map_splats (splatmul, SI, NS)
898
- end
899
- end
900
- if ndi === (1 ,) && N != = 1
901
- ns1 = getfield (nds, 1 )
902
- new {N, (:,), (ns1 > 1 ? ntuple(identity, ns1) : ns1,), ns1} ()
903
- else
904
- nds_cumsum = cumsum (nds)
905
- if sum (ndi) > N
906
- init_pdims = _accum_dims (cumsum (ndi), ndi)
907
- pdims = ntuple (nfields (init_pdims)) do i
908
- dim_i = getfield (init_pdims, i)
909
- if dim_i isa Tuple
910
- ntuple (length (dim_i)) do j
911
- dim_i_j = getfield (dim_i, j)
912
- dim_i_j > N ? 0 : dim_i_j
913
- end
914
- else
915
- dim_i > N ? 0 : dim_i
916
- end
917
- end
918
- new {N, pdims, _accum_dims(nds_cumsum, nds), last(nds_cumsum)} ()
919
- else
920
- new{N, _accum_dims (cumsum (ndi), ndi), _accum_dims (nds_cumsum, nds),
921
- last (nds_cumsum)}()
922
- end
923
- end
924
- end
925
- IndicesInfo {N} (@nospecialize (t:: Tuple )) where {N} = IndicesInfo {N} (typeof (t))
926
- function IndicesInfo (@nospecialize (T:: Type{<:Tuple} ))
927
- ndi = map_tuple_type (ndims_index, T)
928
- nds = map_tuple_type (ndims_shape, T)
929
- ndi_sum = cumsum (ndi)
930
- nds_sum = cumsum (nds)
931
- nf = nfields (ndi_sum)
932
- pdims = _accum_dims (ndi_sum, ndi)
933
- cdims = _accum_dims (nds_sum, nds)
934
- new {getfield(ndi_sum, nf), pdims, cdims, getfield(nds_sum, nf)} ()
935
- end
936
- IndicesInfo (@nospecialize t:: Tuple ) = IndicesInfo (typeof (t))
937
- @inline function IndicesInfo (@nospecialize T:: Type{<:SubArray} )
938
- IndicesInfo {ndims(parent_type(T))} (fieldtype (T, :indices ))
939
- end
940
- IndicesInfo (x:: SubArray ) = IndicesInfo {ndims(parent(x))} (typeof (x. indices))
941
- end
942
- @inline function _map_splats (nsplat:: Int , splat_index:: Int , dims:: Tuple{Vararg{Int}} )
943
- ntuple (length (dims)) do i
944
- i === splat_index ? (nsplat * getfield (dims, i)) : getfield (dims, i)
945
- end
946
- end
947
- @inline function _accum_dims (csdims:: NTuple{N, Int} , nd:: NTuple{N, Int} ) where {N}
948
- ntuple (N) do i
949
- nd_i = getfield (nd, i)
950
- if nd_i === 0
951
- 0
952
- elseif nd_i === 1
953
- getfield (csdims, i)
954
- else
955
- ntuple (Base. Fix1 (+ , getfield (csdims, i) - nd_i), nd_i)
956
- end
957
- end
958
- end
959
-
960
- function _lower_info (:: IndicesInfo{Np, pdims, cdims, Nc} ) where {Np, pdims, cdims, Nc}
961
- Np, pdims, cdims, Nc
962
- end
963
-
964
- ndims_index (@nospecialize (info:: IndicesInfo )) = getfield (_lower_info (info), 1 )
965
- ndims_shape (@nospecialize (info:: IndicesInfo )) = getfield (_lower_info (info), 4 )
966
-
967
- """
968
- parentdims(::IndicesInfo) -> Tuple
969
-
970
- Returns the parent dimension mapping from `IndicesInfo`.
971
-
972
- See also: [`IndicesInfo`](@ref), [`childdims`](@ref)
973
- """
974
- parentdims (@nospecialize info:: IndicesInfo ) = getfield (_lower_info (info), 2 )
975
-
976
- """
977
- childdims(::IndicesInfo) -> Tuple
978
-
979
- Returns the child dimension mapping from `IndicesInfo`.
980
-
981
- See also: [`IndicesInfo`](@ref), [`parentdims`](@ref)
982
- """
983
- childdims (@nospecialize info:: IndicesInfo ) = getfield (_lower_info (info), 3 )
984
-
985
758
"""
986
759
instances_do_not_alias(::Type{T}) -> Bool
987
760
@@ -1061,20 +834,6 @@ struct BandedMatrixIndex <: ArrayInterface.MatrixIndex
1061
834
isrow:: Bool
1062
835
end
1063
836
1064
- # # Precompilation
1065
-
1066
- using SnoopPrecompile
1067
- @precompile_setup begin
1068
- # Putting some things in `setup` can reduce the size of the
1069
- # precompile file and potentially make loading faster.
1070
- arrays = [rand (4 ), Base. oneto (5 )]
1071
- @precompile_all_calls begin for x in arrays
1072
- known_first (x)
1073
- known_step (x)
1074
- known_last (x)
1075
- end end
1076
- end
1077
-
1078
837
# # Extensions
1079
838
1080
839
import Requires
@@ -1086,11 +845,6 @@ import Requires
1086
845
Requires. @require StaticArraysCore = " 1e83bf80-4336-4d27-bf5d-d5a4f845583c" begin include (" ../ext/ArrayInterfaceStaticArraysCoreExt.jl" ) end
1087
846
Requires. @require CUDA = " 052768ef-5323-5732-b1bb-66c8b64840ba" begin include (" ../ext/ArrayInterfaceCUDAExt.jl" ) end
1088
847
Requires. @require Tracker= " 9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" begin include (" ../ext/ArrayInterfaceTrackerExt.jl" ) end
1089
- Requires. @require Static = " aedffcd0-7271-4cad-89d0-dc628f76c6d3" begin
1090
- include (" ../ext/ArrayInterfaceStaticExt.jl" )
1091
- Requires. @require StaticArrays = " 90137ffa-7385-5640-81b9-e52037218182" begin include (" ../ext/ArrayInterfaceStaticArraysExt.jl" ) end
1092
- Requires. @require OffsetArrays = " 6fe1bfb0-de20-5000-8ca7-80f57d26f881" begin include (" ../ext/ArrayInterfaceOffsetArraysExt.jl" ) end
1093
- end
1094
848
end
1095
849
end
1096
850
0 commit comments