Skip to content

Instantly share code, notes, and snippets.

@nalimilan
Last active September 18, 2016 10:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nalimilan/f84d0c8880904cde586a to your computer and use it in GitHub Desktop.
Save nalimilan/f84d0c8880904cde586a to your computer and use it in GitHub Desktop.
immutable Zip2Same{I1, I2} # <: AbstractZipIterator
same::Bool
a::I1
b::I2
end
zipsame(a, b) = Zip2Same(typeof(a)==typeof(b) && a==b, a, b)
Base.length(z::Zip2Same) = z.same ? length(z.a) : min(length(z.a), length(z.b))
Base.eltype{I1,I2}(::Type{Zip2Same{I1,I2}}) = Tuple{eltype(I1), eltype(I2)}
@inline Base.start(z::Zip2Same) = z.same ? (s = start(z.a); (s,s::typeof(start(z.b)))) : (start(z.a), start(z.b))
@inline function Base.next(z::Zip2Same, st)
n1 = next(z.a,st[1])
n2 = next(z.b,st[2])
if z.same
n11, n12 = n1
n21, n22 = n2
return ((n11, n11::typeof(n21)), (n12, n12::typeof(n22)))
end
return ((n1[1], n2[1]), (n1[2], n2[2]))
end
@inline Base.done(z::Zip2Same, st) = done(z.a,st[1]) | (!z.same & done(z.b,st[2]))
function mydot1{T}(A::AbstractArray{T}, B::AbstractArray{T})
s = zero(T)*zero(T)+zero(T)*zero(T)
for I in eachindex(A, B)
@inbounds s += A[I]*B[I]
end
s
end
Base.done(z::Base.Zip2, st) = done(z.a,st[1])
function mydot2{T}(A::AbstractArray{T}, B::AbstractArray{T})
s = zero(T)*zero(T)+zero(T)*zero(T)
for (IA, IB) in zip(eachindex(A), eachindex(B))
@inbounds s += A[IA]*B[IB]
end
s
end
function mydotshared{T}(A::AbstractArray{T}, B::AbstractArray{T})
s = zero(T)*zero(T)+zero(T)*zero(T)
for (IA, IB) in zipsame(eachindex(A), eachindex(B))
@inbounds s += A[IA]*B[IB]
end
s
end
A = rand(5000,5001);
B = rand(5000,5001);
# Do not use the entirety of parent arrays, as unit-stride sub arrays can give more efficient code than the general case
AS = view(rand(6000,5001), 1:5000, :);
BS = view(rand(6000,5001), 1:5000, :);
mydot1(A, B); mydot1(AS, BS); mydot1(AS, B);
mydot2(A, B); mydot2(AS, BS); mydot2(AS, B);
mydotshared(A, B); mydotshared(AS, BS); mydotshared(AS, B);
println("Two Arrays:")
@time mydot1(A, B);
@time mydot2(A, B);
@time mydotshared(A, B);
println("Two LinearSlow SubArrays")
@time mydot1(AS, BS);
@time mydot2(AS, BS);
@time mydotshared(AS, BS);
println("Mixed case")
@time mydot1(AS, B);
@time mydot2(AS, B);
@time mydotshared(AS, B);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment