# Base.Cartesian's @nloops with @simd

**URL:** <https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153>\
**Category:** General Usage\
**Created:** [December 26, 2016, 1:04pm UTC](https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153 "2016-12-26T13:04:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![robertdj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertdj/32/103_2.png) [@robertdj](https://discourse.julialang.org/u/robertdj)\
**Post date:** [December 26, 2016, 1:04pm UTC](https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153/1 "2016-12-26T13:04:30Z")

</div>

The first example on how to use `@nloops` in the [Base.Cartesian documentation](http://docs.julialang.org/en/release-0.5/devdocs/cartesian/) is the following:

```julia
using Base.Cartesian

A = rand(3,3)
s = 0.0
@nloops 2 i A begin
	s += @nref 2 A i
end

```

The loop is expanded to

```julia
for i_2 = 1:size(A,2)
	for i_1 = 1:size(A,1)
		s += A[i_1, i_2]
	end
end

```

I would like to add a `@simd` macro to the inner loop as explained in [performance section](http://docs.julialang.org/en/release-0.5/manual/performance-tips/#performance-annotations) of the manual, such that the above `@nloops` is expanded to:

```julia
for i_2 = 1:size(A,2)
	@inbounds @simd for i_1 = 1:size(A,1)
		s += A[i_1, i_2]
	end
end

```

Is there a way to achieve this? Simply adding `@inbounds @simd` in front of the `@nloops` does not work.

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [December 27, 2016, 2:01am UTC](https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153/2 "2016-12-27T02:01:39Z")

</div>

I don’t think there is a direct way of doing this, but you can take a look at implementation of `@nloops` in  
[https://github.com/JuliaLang/julia/blob/d8a57182f49787055b3a864cc86401988be4bcdf/base/cartesian.jl#L47-L70](https://github.com/JuliaLang/julia/blob/d8a57182f49787055b3a864cc86401988be4bcdf/base/cartesian.jl#L47-L70)  
and add `@simd` for `dim == 1`.

---

<div class="post-metadata">

**Author:** ![robertdj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertdj/32/103_2.png) [@robertdj](https://discourse.julialang.org/u/robertdj)\
**Post date:** [December 27, 2016, 10:00pm UTC](https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153/3 "2016-12-27T22:00:07Z")

</div>

It would be nice to just use the Cartesian macros, but this is probably the way to go. Thanks!

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [December 27, 2016, 10:13pm UTC](https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153/4 "2016-12-27T22:13:07Z")

</div>

You could write a `@simd_inner_loop` macro expands nested macros and then walks through many nested `for` loops and simply annotates the innermost one. Then you could write `@simd_inner_loop @nloops 2 i A …`.

---

<div class="post-metadata">

**Author:** ![robertdj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertdj/32/103_2.png) [@robertdj](https://discourse.julialang.org/u/robertdj)\
**Post date:** [December 28, 2016, 11:33am UTC](https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153/5 "2016-12-28T11:33:32Z")

</div>

Very interesting idea! My macro skills would have to evolve first, I think…

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [December 29, 2016, 2:37am UTC](https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153/6 "2016-12-29T02:37:00Z")

</div>

I wanted something similar a while back.  
The following is somewhat convoluted but it did work for me.  
Idea was to use `@nloops` for the first N-1 loops, then explicitly code the innermost loop.

```julia
@nloops 2 (d->i_{d+1}) (d->1:size(A,d+1)) begin
    @simd for i_1 = 1:size(A,1)
        @inbounds s += @nref 3 A i
    end
end

```

This also required loosening the type constraint on the internal function `Base.Cartesian._nloops` to allow anonymous functions for the loop variable names (rather than limit to just `Symbol`).

`- function Base.Cartesian._nloops(N::Int, itersym::Symbol, rangeexpr::Expr, args::Expr...)`  
`+ function Base.Cartesian._nloops(N::Int, itersym::Expr, rangeexpr::Expr, args::Expr...)`

Allowing anonymous functions for the loop variable might be useful in its own right.

---

<div class="post-metadata">

**Author:** ![robertdj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertdj/32/103_2.png) [@robertdj](https://discourse.julialang.org/u/robertdj)\
**Post date:** [December 29, 2016, 9:25pm UTC](https://discourse.julialang.org/t/base-cartesians-nloops-with-simd/1153/7 "2016-12-29T21:25:52Z")

</div>

This looks like a quick way to solve the OP – thanks!
