Skip to content

Instantly share code, notes, and snippets.

@timholy
Last active August 29, 2015 13:56
Show Gist options
  • Save timholy/9296859 to your computer and use it in GitHub Desktop.
Save timholy/9296859 to your computer and use it in GitHub Desktop.
Test for cartesian iteration using tuples
function sumtuple{T}(A::AbstractArray{T,3}, iter)
s = zero(typeof(one(T)+one(T)))
for k = 1:iter
I = (1,1,1)
while I[3] <= size(A,3)
s += A[I...]
if I[1] < size(A,1)
I = (I[1]+1,I[2],I[3])
elseif I[2] < size(A,2)
I = (1,I[2]+1,I[3])
else
I = (1,1,I[3]+1)
end
end
end
s
end
function sumloop{T}(A::AbstractArray{T,3}, iter)
s = zero(typeof(one(T)+one(T)))
for k = 1:iter
for i3 = 1:size(A,3)
for i2 = 1:size(A,2)
for i1 = 1:size(A,1)
s += A[i1,i2,i3]
end
end
end
end
s
end
import Base: getindex, start, done, next
import Base.Cartesian: @nexprs, @ntuple, @ngenerate
immutable TupleIter{N}
I::NTuple{N,Int}
end
getindex(I::TupleIter, n) = I.I[n]
TupleIter(A::Array) = TupleIter(size(A))
# start{N}(lim::TupleIter{N}) = ntuple(N, d->1)
@ngenerate N NTuple{N,Int} start{N}(lim::TupleIter{N}) = @ntuple N d->1
done{N}(lim::TupleIter{N}, I::NTuple{N,Int}) = I[N] > lim[N]
@ngenerate N (NTuple{N,Int},NTuple{N,Int}) function next{N}(lim::TupleIter{N}, I::NTuple{N,Int})
@nexprs N i->begin
if I[i] < lim[i]
newI = @ntuple N d->((d < i) ? 1 :
(d == i) ? I[d]+1 : I[d])
return I, newI
end
end
newI = @ntuple N d->((d<N) ? 1 : lim[N]+1)
I, newI
end
# function next{N}(lim::TupleIter{N}, I::NTuple{N,Int})
# for i = 1:N
# if I[i] < lim[i]
# newI = ntuple(N, d->(d < i) ? 1 :
# (d == i) ? I[d]+1 : I[d])
# return I, newI
# end
# end
# newI = ntuple(N, d->(d<N) ? 1 : lim[N]+1)
# I, newI
# end
function sumtuple_gen{T}(A::AbstractArray{T}, iter)
s = zero(typeof(one(T)+one(T)))
for k = 1:iter
for I = TupleIter(A)
s += A[I...]
end
end
s
end
function sumtuple_inlined_cartesian{T}(A::AbstractArray{T,3}, iter)
s = zero(typeof(one(T)+one(T)))
for k = 1:iter
I = (1,1,1)
while I[3] <= size(A,3)
s += A[I...]
isdone = false
@nexprs 3 i->begin
if !isdone && I[i] < size(A, i)
I = @ntuple 3 d->((d < i) ? 1 :
(d == i) ? I[d]+1 : I[d])
isdone = true
end
end
if !isdone
I = @ntuple 3 d->((d<3) ? 1 : size(A,3)+1)
end
end
end
s
end
function sumtuple_inlined_anon{T}(A::AbstractArray{T,3}, iter)
s = zero(typeof(one(T)+one(T)))
for k = 1:iter
I = (1,1,1)
while I[3] <= size(A,3)
s += A[I...]
isdone = false
for i = 1:3
if !isdone && I[i] < size(A, i)
I = ntuple(3, d->(d < i) ? 1 :
(d == i) ? I[d]+1 : I[d])
isdone = true
end
end
if !isdone
I = ntuple(3, d->(d<3) ? 1 : size(A,3)+1)
end
end
end
s
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment