Skip to content
Merged
Show file tree
Hide file tree
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
23 changes: 17 additions & 6 deletions docs/src/datadeps.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,20 @@ Dagger.spawn_datadeps() do
end
```

You can pass any number of aliasing modifiers to `Deps`. This is particularly
useful for declaring aliasing with `Diagonal`, `Bidiagonal`, `Tridiagonal`, and
`SymTridiagonal` access, as these "wrappers" make a copy of their parent array
and thus can't be used to "mask" access to the parent like `UpperTriangular`
and `UnitLowerTriangular` can (which is valuable for writing memory-efficient,
generic algorithms in Julia).
We call `InOut(Diagonal)` an "aliasing modifier". The purpose of `Deps` is to
pass an argument (here, `A`) as-is, while specifying to Datadeps what portions
of the argument will be accessed (in this case, the diagonal elements) and how
(read/write/both). You can pass any number of aliasing modifiers to `Deps`.

`Deps` is particularly useful for declaring aliasing with `Diagonal`,
`Bidiagonal`, `Tridiagonal`, and `SymTridiagonal` access, as these "wrappers"
make a copy of their parent array and thus can't be used to "mask" access to the
parent like `UpperTriangular` and `UnitLowerTriangular` can (which is valuable
for writing memory-efficient, generic algorithms in Julia).

### Supported Aliasing Modifiers

- Any function that returns the original object or a view of the original object
- `UpperTriangular`/`LowerTriangular`/`UnitUpperTriangular`/`UnitLowerTriangular`
- `Diagonal`/`Bidiagonal`/`Tridiagonal`/`SymTridiagonal` (via `Deps`, e.g. to read from the diagonal of `X`: `Dagger.@spawn sum(Deps(X, In(Diagonal)))`)
- `Symbol` for field access (via `Deps`, e.g. to write to `X.value`: `Dagger.@spawn setindex!(Deps(X, InOut(:value)), :value, 42)`
7 changes: 6 additions & 1 deletion src/memory-spaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,12 @@ function memory_spans(oa::ObjectAliasing)
return [span]
end

aliasing(x, T) = aliasing(T(x))
function aliasing(x, dep_mod)
if dep_mod isa Symbol
return aliasing(getfield(x, dep_mod))
end
return aliasing(dep_mod(x))
end
function aliasing(x::T) where T
if isbits(x)
return NoAliasing()
Expand Down
10 changes: 9 additions & 1 deletion test/datadeps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ function test_task_dominators(logs::Dict, tid::Int, doms::Vector; all_tids::Vect
end

@everywhere do_nothing(Xs...) = nothing
@everywhere mut_ref!(R) = (R[] .= 0;)
function test_datadeps(;args_chunks::Bool,
args_thunks::Bool,
args_loc::Int,
Expand Down Expand Up @@ -425,10 +426,17 @@ function test_datadeps(;args_chunks::Bool,
end

# Inner Scope
@test_throws Dagger.Sch.SchedulingException Dagger.spawn_datadeps() do
@test_throws Dagger.Sch.SchedulingException Dagger.spawn_datadeps() do
Dagger.@spawn scope=Dagger.ExactScope(Dagger.ThreadProc(1, 5000)) 1+1
end

# Field aliasing
X = Ref(rand(1000))
@test all(x->x==0, fetch(Dagger.spawn_datadeps() do
Dagger.@spawn mut_ref!(Deps(X, InOut(:x)))
Dagger.@spawn getfield(Deps(X, In(:x)), :x)
end))

# Add-to-copy
A = rand(1000)
B = rand(1000)
Expand Down