mx.transpose arbitrary axis?
jingpengw opened this issue · comments
mx.transpose seems only be able to transpose all the axis, how can I swap arbitrary axis of a symbolic NDArray?
methods( mx.transpose )
transpose(in1::MXNet.mx.NDArray)
transpose(in1::MXNet.mx.NDArray, out1::MXNet.mx.NDArray) at ~.julia/v0.4/MXNet/src/ndarray.jl:1046
the python frontend seems have this functionality.
We currently don't create docs for this function because it collides with the Julia base function. But it takes the same kwargs as the Python version. See http://mxnet.io/packages/python/ndarray.html#mxnet.ndarray.transpose
thanks for the explanation. I tried but still not work. Anything wrong here?
julia> a = rand(mx.MX_float, 2,3,4,5,6);
julia> mxa = mx.NDArray(a)
mx.NDArray{Float32}(2,3,4,5,6)
julia> mx.transpose(mxa, axes=(2,1,3,4,5))
ERROR: MethodError: `_compose!` has no method matching _compose!(::MXNet.mx.SymbolicNode, ::Symbol, ::MXNet.mx.NDArray)
Closest candidates are:
_compose!(::MXNet.mx.SymbolicNode, ::Union{Ptr{UInt8},Symbol}, ::MXNet.mx.SymbolicNode...)
_compose!(::MXNet.mx.SymbolicNode)
_compose!(::MXNet.mx.SymbolicNode, ::MXNet.mx.SymbolicNode...)
in __transpose#65__ at /usr/people/jingpeng/.julia/v0.4/MXNet/src/symbolic-node.jl:673
julia> mx.transpose(mxa, (2,1,3,4,5))
ERROR: MethodError: `_compose!` has no method matching _compose!(::MXNet.mx.SymbolicNode, ::Symbol, ::MXNet.mx.NDArray, ::Tuple{Int64,Int64,Int64,Int64,Int64})
Closest candidates are:
_compose!(::MXNet.mx.SymbolicNode, ::Union{Ptr{UInt8},Symbol}, ::MXNet.mx.SymbolicNode...)
_compose!(::MXNet.mx.SymbolicNode)
_compose!(::MXNet.mx.SymbolicNode, ::MXNet.mx.SymbolicNode...)
in __transpose#65__ at /usr/people/jingpeng/.julia/v0.4/MXNet/src/symbolic-node.jl:673
@pluskid Any input? It seems that we don't generate the transpose
function for the axes
version. Looking at the output of MXFuncDescribe
n_scalars
= 0
julia> mx._get_function_expressions(mx._get_function(:transpose), :transpose)
2-element Array{Expr,1}:
:(function transpose(in1::MXNet.mx.NDArray,out1::MXNet.mx.NDArray)
begin # /home/wallnuss/.julia/v0.6/MXNet/src/ndarray.jl, line 1044:
local handle = _get_function(:transpose) # /home/wallnuss/.julia/v0.6/MXNet/src/ndarray.jl, line 1045:
_invoke_mxfunction(handle,MX_handle[in1],MX_float[],MX_handle[out1])
end
return out1
end)
:(function transpose(in1::MXNet.mx.NDArray)
transpose(in1::MXNet.mx.NDArray,NDArray(_ndarray_alloc()))
end)
julia> mx._get_function_description(mx._get_function(:transpose))
(:transpose," transpose(src, axes)\n\nTranspose the input matrix and return a new one\n\n# Arguments\n* `src::NDArray`: Source input to the function\n\n* `axes::Shape(tuple), optional, default=()`: Target axis order. By default the axes will be inverted.\n")
It seems to me that we need to use MXFuncInvokeEx
to be able to pass kwargs to mxnet and combine that with information from MXFuncGetInfo
to discover the kwargs.
@jingpengwu This is a real problem on our side, so thank you for bringing this to our attention.
An update of this issue.
In the master branch, the transpose
function was replaced with SwapAxis
and the axis number is following python style again. It might be more efficient to follow the internal indexing of mxnet, but is potentially confusing for Julia users.
julia> using MXNet
julia> a = rand(2,2)
2×2 Array{Float64,2}:
0.82092 0.842056
0.653796 0.842246
julia> nda = mx.NDArray(a)
mx.NDArray{Float64}(2,2)
julia> copy( mx.SwapAxis(nda; dim1 = 1, dim2=0) )
2×2 Array{Float64,2}:
0.82092 0.653796
0.842056 0.842246
Yes, this is a long standing issue. Currently I don't have very good solution except it clearly document it (which is still need to be done...)
One way might be to take a look at the design of https://github.com/JuliaArrays/AxisArrays.jl and PermutedDimensionArrays. Julia's toolbox to work with arbitrary arrays should allow us to use Python's convention while keeping performance.