Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update README to clarify multi-line blocks #142

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,106 @@ Some warnings are in order:
</details>
<details><summary><b>Larger expressions</b></summary>

The syntax within the `begin ... end``` is essentially identical to a single-line `@tullio ...`
statement with some care.

Let's consider the following example:

```julia
using Tullio

A = rand(3, 4, 5, 6)
B = rand(5, 6, 7, 8)
C = rand(7, 8)

@tullio D[i, j] := begin
TMP[i, j, m, n] = A[i, j, k, l] * B[k, l, m, n]
TMP[i, j, m, n] * C[m, n]
end
Comment on lines +282 to +285
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this one is safe, but I'm not keen to encourage such use. Tullio will often multi-thread over indices it deems safe, but it is not smart enough to notice that this is writing into an array. If it had TMP[j, m, n] = , this would introduce data races.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I think I should had a comment to that effect. It is another difference with single liners.

```

On the first line of the `@tullio` block, the `:=` assignment follows the syntax of one-liners.
`:=` creates a new array. `=` would overwrite an existing one.

However, _within_ the block, the normal Julia syntax applies. `:=` is undefined and cannot be used.
Within the block and simplifying a lot, Tulio will copy that line verbatim and wrap it within as many
loops as required and add the necessary code for vectorization, restarts,... The Julia scope syntax is
therefore applied. Within the scope of loops, TMP will be created without needing the `:=` syntax
(which is invalid).

Another consequence of this is the use of the `<|` leftward pipe symbol. It is not defined in the Julia
`Base` package.

This block is valid.

```julia
@tullio C[k, l] := begin
A[i, j, k, l] * B[i, j] |> sqrt
end
```

This block will yield an error.

```julia
@tullio C[k, l] := begin
sqrt <| A[i, j, k, l] * B[i, j]
end
```

WARNING: A succession of one-liners can refer to the same array multiple times

This is safe:

```julia
using Tullio

A = rand(3, 4, 5, 6)
B = rand(5, 6, 7, 8)
C = rand(7, 8)

@tullio TMP[i, j, m, n] := A[i, j, k, l] * B[k, l, m, n]
@tullio TMP[i, j] = TMP[i, j, m, n] * C[m, n]
@tullio D[i, j] := TMP[i, j]
```

But, within a block, the entire block will be within a series of loops which can be
spawned to several threads. Reusing the same symbols can bring data races.

This is asking for trouble:

```julia
using Tullio

A = rand(3, 4, 5, 6)
B = rand(5, 6, 7, 8)
C = rand(7, 8)

@tullio D[i, j] := begin
TMP[i, j, m, n] = A[i, j, k, l] * B[k, l, m, n]
TMP[i, j] = TMP[i, j, m, n] * C[m, n]
TMP[i, j]
end
```

This is the better code:

```julia
using Tullio

A = rand(3, 4, 5, 6)
B = rand(5, 6, 7, 8)
C = rand(7, 8)

@tullio D[i, j] := begin
TMP[i, j, m, n] = A[i, j, k, l] * B[k, l, m, n]
ANOTHER_TMP[i, j] = TMP[i, j, m, n] * C[m, n]
ANOTHER_TMP[i, j]
end
```


Keeping this in mind, here are a few multi-line examples.

```julia
using Tullio, OffsetArrays

Expand Down