Open
Description
If I wrap a numeric type, I can't use BLAS or LAPACK calls anymore. This hurts performance considerably:
module Elements
export MyEl
immutable MyEl{T}
el::T
end
Base.zero{T}(::Type{MyEl{T}}) = MyEl{T}(zero(T))
Base.conj!{T<:Real}(A::Array{MyEl{T}}) = A
Base.promote_rule{T,S}(::Type{MyEl{T}}, ::Type{MyEl{S}}) = MyEl{promote_type{T,S}}
+{S,T}(a::MyEl{S}, b::MyEl{T}) = MyEl{promote_type(S,T)}(a.el+b.el)
*{S,T}(a::MyEl{S}, b::MyEl{T}) = MyEl{promote_type(S,T)}(a.el*b.el)
end
julia> using Elements
julia> A = rand(200,199);
julia> B = reinterpret(MyEl{Float64}, A);
# After warmup
julia> @time A'*A;
elapsed time: 0.002651306 seconds (316976 bytes allocated)
julia> @time B'*B;
elapsed time: 0.020106977 seconds (317216 bytes allocated)
It's using the generic_matmatmul!
fallback, since a MyEl{Float64}
is not recognized as a type that one can pass to BLAS/LAPACK.
It would seem that the best approach would be to define a set of numeric traits and have the BLAS/LAPACK routines use them. I'm submitting this issue to open discussion about how best to do this. Here's one proposal:
blastype{T}(::Type{T}) = T
blastype{T}(::Type{MyEl{T}}) = T # defined by package author
some_blas_call(A::StridedArray) = some_blas_call(blastype(eltype(A)), A)
function some_blas_call{T<:BlasComplex}(::Type{T}, A)
# the version that calls blas goes here
end
function some_blas_call{T}(::Type{T}, A)
# the generic fallback goes here
end
[cjh: colorized]
Metadata
Metadata
Assignees
Labels
No labels