Skip to content

willow-ahrens/Swizzles.jl

Repository files navigation

Swizzles

Swizzles are Julia operators that allow the user to fuse reduction and transposition operations into broadcast expressions. Swizzles are lazily evaluated, creating a language of Julia objects to represent tensor contractions and related operations. Swizzles were created as a good-faith attempt to implement tensor algebra using the abstractions and programming patterns of base Julia (broadcasting in particular). We hope that the results of our exploration may help inform future implementation decisions and redesigns of the Julia standard library. This project is no longer actively developed; Willow is working on Finch.jl now. Swizzles.jl has been tested on Julia 1.5.

What Is?

Swizzle(op, mask...)(init, arg) creates an operator which initializes dst using init, then reduces arg into dst such that dimension d of dst corresponds to dimension mask[d] of arg. This operator is represented lazily using the array type SwizzledArray. Thus,

julia> using Swizzles

julia> A = [1 2 3; 4 5 6; 7 8 9]
3×3 Array{Int64,2}:
 1  2  3
 4  5  6
 7  8  9

julia> Swizzle(+, 2).(A)
3-element Array{Int64,1}:
 12
 15
 18

julia> Swizzle(+).(A)
45

We can use an instance of the singleton type Nil to insert a size 1 dimension into dst.

julia> Swizzle(+, nil, 2).(A)
1×3 Array{Int64,2}:
 12  15  18

It is convenient to represent transpositions (Swizzles which do not initialize or reduce) using the operator Beam(imask...). Beam(imask...)(arg) produces an output array dst such that dimension imask[d] of dst corresponds to dimension d of arg.

julia> B = [12; 15; 18]
3-element Array{Int64,1}:
 12
 15
 18

julia> Beam(2).(B)
1×3 Array{Int64,2}:
 12  15  18

Notice the similarity between index notation

A[i,j] = ∑ B[i,k,l] * D[l,j] * C[k,j]

and the Swizzles.jl representation

A .= Swizzle(+, 2, 1).(Beam(+, 2, 3, 4).(B) .* Beam(4, 1).(D) .* Beam(3, 1).(C))

Why?

Swizzles.jl was created to provide a trait-based dispatch mechanism for tensor kernel selection and array implementation. Swizzles uses BroadcastStyles and eachindex to help select implementations, and provides an alternative abstract array supertype, StylishArray, for new array types to target. The language of Swizzle and Broadcast provides a high-level intermediate representation for tensor operations.

More Examples!

julia> using Swizzles, LinearAlgebra

julia> x = rand(7); y = rand(7);

julia> Swizzle(+).(x .* y) ≈ dot(x, y)
true

julia> Swizzle(+).(abs.(x)) ≈ norm(x, 1)
true

julia> A = rand(5, 7); B = rand(7, 8);

julia> Swizzle(+, nil, 2).(A) ≈ sum(A, dims=1)
true

julia> Swizzle(+, 2).(A) ≈ sum(A, dims=1)[1,:]
true

julia> Beam(2, 1).(A) ≈ transpose(A)
true

julia> Beam(1, 4).(A) ≈ reshape(A, 5, 1, 1, 7)
true

julia> Swizzle(+, 1, 3).(A.*Beam(2, 3).(B)) ≈ A * B
true

About

AbstracterArrays

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages