{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "e271b0e0-8e90-4e73-83a1-25c94fa8a9e6",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"@atime (macro with 1 method)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using BenchmarkTools\n",
"macro atime(expr) :(@btime $expr samples=1 evals=1) end"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "061f4513-203e-4298-915a-996fa0010281",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MethodInstance for PermutedDimsArray(::Array{Int64, 4}, ::NTuple{4, Int64})\n",
" from PermutedDimsArray(data::AbstractArray{T, N}, perm) where {T, N} in Base.PermutedDimsArrays at permuteddimsarray.jl:42\n",
"Static Parameters\n",
" T = \u001b[36mInt64\u001b[39m\n",
" N = \u001b[36m4\u001b[39m\n",
"Arguments\n",
" #self#\u001b[36m::Type{PermutedDimsArray}\u001b[39m\n",
" data\u001b[36m::Array{Int64, 4}\u001b[39m\n",
" perm\u001b[36m::NTuple{4, Int64}\u001b[39m\n",
"Locals\n",
" iperm\u001b[36m::NTuple{4, Int64}\u001b[39m\n",
"Body\u001b[91m\u001b[1m::PermutedDimsArray{Int64, 4, _A, _B, Array{Int64, 4}} where {_A, _B}\u001b[22m\u001b[39m\n",
"\u001b[90m1 ─\u001b[39m Core.NewvarNode(:(iperm))\n",
"\u001b[90m│ \u001b[39m %2 = Base.PermutedDimsArrays.length(perm)\u001b[36m::Core.Const(4)\u001b[39m\n",
"\u001b[90m│ \u001b[39m %3 = (%2 == $(Expr(:static_parameter, 2)))\u001b[36m::Core.Const(true)\u001b[39m\n",
"\u001b[90m│ \u001b[39m Core.typeassert(%3, Core.Bool)\n",
"\u001b[90m└──\u001b[39m goto #3\n",
"\u001b[90m2 ─\u001b[39m Core.Const(:(Base.PermutedDimsArrays.string(perm, \" is not a valid permutation of dimensions 1:\", $(Expr(:static_parameter, 2)))))\n",
"\u001b[90m│ \u001b[39m Core.Const(:(Base.PermutedDimsArrays.ArgumentError(%6)))\n",
"\u001b[90m└──\u001b[39m Core.Const(:(Base.PermutedDimsArrays.throw(%7)))\n",
"\u001b[90m3 ┄\u001b[39m (iperm = Base.PermutedDimsArrays.invperm(perm))\n",
"\u001b[90m│ \u001b[39m %10 = $(Expr(:static_parameter, 1))\u001b[36m::Core.Const(Int64)\u001b[39m\n",
"\u001b[90m│ \u001b[39m %11 = $(Expr(:static_parameter, 2))\u001b[36m::Core.Const(4)\u001b[39m\n",
"\u001b[90m│ \u001b[39m %12 = Core._apply_iterate(Base.iterate, Core.tuple, perm)\u001b[36m::NTuple{4, Int64}\u001b[39m\n",
"\u001b[90m│ \u001b[39m %13 = Core._apply_iterate(Base.iterate, Core.tuple, iperm)\u001b[36m::NTuple{4, Int64}\u001b[39m\n",
"\u001b[90m│ \u001b[39m %14 = Base.PermutedDimsArrays.typeof(data)\u001b[36m::Core.Const(Array{Int64, 4})\u001b[39m\n",
"\u001b[90m│ \u001b[39m %15 = Core.apply_type(Base.PermutedDimsArrays.PermutedDimsArray, %10, %11, %12, %13, %14)\u001b[91m\u001b[1m::Type{PermutedDimsArray{Int64, 4, _A, _B, Array{Int64, 4}}} where {_A, _B}\u001b[22m\u001b[39m\n",
"\u001b[90m│ \u001b[39m %16 = (%15)(data)\u001b[91m\u001b[1m::PermutedDimsArray{Int64, 4, _A, _B, Array{Int64, 4}} where {_A, _B}\u001b[22m\u001b[39m\n",
"\u001b[90m└──\u001b[39m return %16\n",
"\n"
]
}
],
"source": [
"A = rand(0:9, 2, 3, 4, 5)\n",
"perm = (4, 3, 1, 2)\n",
"@code_warntype PermutedDimsArray(A, perm)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "8aef944c-1d6d-4bd2-bae5-55457063ad00",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"PermutedDimsArray(data::AbstractArray{T, N}, perm) where {T, N} in Base.PermutedDimsArrays at permuteddimsarray.jl:42"
],
"text/plain": [
"PermutedDimsArray(data::AbstractArray{T, N}, perm) where {T, N} in Base.PermutedDimsArrays at permuteddimsarray.jl:42"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@which PermutedDimsArray(zeros(1, 2, 3, 4), (4, 2, 1, 3))"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "9477f6e5-2156-495f-9461-d251101df637",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Main.O"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"module O\n",
"\n",
"struct PermutedDimsArray{T,N,AA<:AbstractArray{T,N},NT<:Dims{N}} <: AbstractArray{T,N}\n",
" parent::AA\n",
" perm::NT\n",
" iperm::NT\n",
"end\n",
"\n",
"function PermutedDimsArray(data::AbstractArray{T,N}, perm::Dims{N}) where {T,N}\n",
" iperm = invperm(perm)\n",
" PermutedDimsArray{T,N,typeof(data),typeof(perm)}(data, perm, iperm)\n",
"end\n",
"function PermutedDimsArray(data::AbstractArray{T,N}, perm) where {T,N}\n",
" PermutedDimsArray(data, Dims{N}(perm))\n",
"end\n",
"\n",
"Base.parent(A::PermutedDimsArray) = A.parent\n",
"Base.size(A::PermutedDimsArray{T,N}) where {T,N} = genperm(size(parent(A)), A.perm)\n",
"Base.axes(A::PermutedDimsArray{T,N}) where {T,N} = genperm(axes(parent(A)), A.perm)\n",
"\n",
"Base.similar(A::PermutedDimsArray, T::Type, dims::Base.Dims) = similar(parent(A), T, dims)\n",
"\n",
"Base.unsafe_convert(::Type{Ptr{T}}, A::PermutedDimsArray{T}) where {T} = Base.unsafe_convert(Ptr{T}, parent(A))\n",
"\n",
"Base.pointer(A::PermutedDimsArray, i::Integer) = throw(ArgumentError(\"pointer(A, i) is deliberately unsupported for PermutedDimsArray\"))\n",
"\n",
"function Base.strides(A::PermutedDimsArray{T,N}) where {T,N}\n",
" s = strides(parent(A))\n",
" ntuple(d->s[A.perm[d]], Val(N))\n",
"end\n",
"Base.elsize(::Type{<:PermutedDimsArray{<:Any, <:Any, P}}) where {P} = Base.elsize(P)\n",
"\n",
"@inline function Base.getindex(A::PermutedDimsArray{T,N}, I::Vararg{Int,N}) where {T,N}\n",
" @boundscheck checkbounds(A, I...)\n",
" @inbounds val = getindex(A.parent, genperm(I, A.iperm)...)\n",
" val\n",
"end\n",
"@inline function Base.setindex!(A::PermutedDimsArray{T,N}, val, I::Vararg{Int,N}) where {T,N}\n",
" @boundscheck checkbounds(A, I...)\n",
" @inbounds setindex!(A.parent, val, genperm(I, A.iperm)...)\n",
" val\n",
"end\n",
"\n",
"@inline genperm(I::NTuple{N,Any}, perm::Dims{N}) where {N} = ntuple(d -> I[perm[d]], Val(N))\n",
"@inline genperm(I, perm::AbstractVector{Int}) = genperm(I, (perm...,))\n",
"\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "93665a6d-82d2-44fe-8de3-35cf45ce7d71",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MethodInstance for Main.O.PermutedDimsArray(::Array{Int64, 4}, ::NTuple{4, Int64})\n",
" from Main.O.PermutedDimsArray(data::AbstractArray{T, N}, perm::Tuple{Vararg{Int64, N}}) where {T, N} in Main.O at In[4]:9\n",
"Static Parameters\n",
" T = \u001b[36mInt64\u001b[39m\n",
" N = \u001b[36m4\u001b[39m\n",
"Arguments\n",
" #self#\u001b[36m::Type{Main.O.PermutedDimsArray}\u001b[39m\n",
" data\u001b[36m::Array{Int64, 4}\u001b[39m\n",
" perm\u001b[36m::NTuple{4, Int64}\u001b[39m\n",
"Locals\n",
" iperm\u001b[36m::NTuple{4, Int64}\u001b[39m\n",
"Body\u001b[36m::Main.O.PermutedDimsArray{Int64, 4, Array{Int64, 4}, NTuple{4, Int64}}\u001b[39m\n",
"\u001b[90m1 ─\u001b[39m (iperm = Main.O.invperm(perm))\n",
"\u001b[90m│ \u001b[39m %2 = $(Expr(:static_parameter, 1))\u001b[36m::Core.Const(Int64)\u001b[39m\n",
"\u001b[90m│ \u001b[39m %3 = $(Expr(:static_parameter, 2))\u001b[36m::Core.Const(4)\u001b[39m\n",
"\u001b[90m│ \u001b[39m %4 = Main.O.typeof(data)\u001b[36m::Core.Const(Array{Int64, 4})\u001b[39m\n",
"\u001b[90m│ \u001b[39m %5 = Main.O.typeof(perm)\u001b[36m::Core.Const(NTuple{4, Int64})\u001b[39m\n",
"\u001b[90m│ \u001b[39m %6 = Core.apply_type(Main.O.PermutedDimsArray, %2, %3, %4, %5)\u001b[36m::Core.Const(Main.O.PermutedDimsArray{Int64, 4, Array{Int64, 4}, NTuple{4, Int64}})\u001b[39m\n",
"\u001b[90m│ \u001b[39m %7 = (%6)(data, perm, iperm)\u001b[36m::Main.O.PermutedDimsArray{Int64, 4, Array{Int64, 4}, NTuple{4, Int64}}\u001b[39m\n",
"\u001b[90m└──\u001b[39m return %7\n",
"\n"
]
}
],
"source": [
"A = rand(0:9, 2, 3, 4, 5)\n",
"perm = (4, 3, 1, 2)\n",
"@code_warntype O.PermutedDimsArray(A, perm)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "b5f4a05d-8bb5-4d3a-a129-76041475a5eb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 5.900 μs (4 allocations: 176 bytes)\n",
" 200.000 ns (0 allocations: 0 bytes)\n"
]
},
{
"data": {
"text/plain": [
"true"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"A = rand(2, 3, 4, 5)\n",
"perm = (4, 3, 1, 2)\n",
"B = @atime PermutedDimsArray($A, $perm)\n",
"C = @atime O.PermutedDimsArray($A, $perm)\n",
"B == C"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "c4ffaeec-04a9-41dd-8d5c-87d2eff38e47",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 8.500 μs (5 allocations: 272 bytes)\n",
" 300.000 ns (0 allocations: 0 bytes)\n"
]
},
{
"data": {
"text/plain": [
"true"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"A = rand(2, 3, 4, 5)\n",
"perm = [4, 3, 1, 2]\n",
"B = @atime PermutedDimsArray($A, $perm)\n",
"C = @atime O.PermutedDimsArray($A, $perm)\n",
"B == C"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6c2b0903-b140-4a1e-832f-54d2cc8be86b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"jupytext": {
"formats": "ipynb,jl:hydrogen"
},
"kernelspec": {
"display_name": "Julia 1.8.0",
"language": "julia",
"name": "julia-1.8"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.8.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}