https://github.com/clima/multibroadcastfusion.jl

A Julia package for fusing multiple broadcast expressions together

https://github.com/clima/multibroadcastfusion.jl

Science Score: 13.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (7.1%) to scientific vocabulary
Last synced: 9 months ago · JSON representation

Repository

A Julia package for fusing multiple broadcast expressions together

Basic Info
  • Host: GitHub
  • Owner: CliMA
  • License: mit
  • Language: Julia
  • Default Branch: main
  • Size: 94.7 KB
Statistics
  • Stars: 11
  • Watchers: 2
  • Forks: 1
  • Open Issues: 13
  • Releases: 4
Created over 2 years ago · Last pushed over 1 year ago
Metadata Files
Readme License

README.md

MultiBroadcastFusion.jl

A Julia package for fusing multiple broadcast expressions together.

A motivating example of this package is the following:

```julia x1 = rand(3,3) x2 = rand(3,3) x3 = rand(3,3) x4 = rand(3,3) y1 = rand(3,3) y2 = rand(3,3)

2 writes, 4 unique reads, but 8 reads including redundant ones

@. y1 = x1 * x2 + x3 * x4 @. y2 = x1 * x3 + x2 * x4 ```

In this example, there are 4 unique reads, and 2 writes. However, because the reads are in two separate broadcast expressions, there are 8 reads total, including redundant ones. Another important note is that y1 and y2 are stored separately in memory. Fusing these operations can be achieved by changing the memory layout, and adjusting the implementation. For example:

```julia X = map(x->Tuple(rand(4)),zeros(3,3)); Y = map(x->Tuple(rand(2)),zeros(3,3));

foo(x) = (x[1] * x[2] + x[3] * x[4], x[1] * x[3] + x[2] * x[4])

4 reads, 2 writes

@. Y = foo(X) ```

However, this is not an objectively better solution:

  • The memory layout, and code implementation, had to be changed in order to make this work, and this can be very difficult for a complex codebase.
  • Memory acces of X and Y is now strided, which could result in less performant code than a single fused loop with more contiguous memory.

Ideally, we would like for the loops to be fused with the more contiguous data layouts:

```julia x1 = rand(3,3) x2 = rand(3,3) x3 = rand(3,3) x4 = rand(3,3) y1 = rand(3,3) y2 = rand(3,3)

2 writes, 4 unique reads. The compiler can hoist the redundant memory reads here.

for i in eachindex(x1,x2,x3,x4,y1,y2) y1[i] = x1[i] * x2[i] + x3[i] * x4[i] y2[i] = x1[i] * x3[i] + x2[i] * x4[i] end ```

With this package, we can apply @fused_direct to reduce the number of reads and preserve the memory layout:

```julia import MultiBroadcastFusion as MBF x1 = rand(3,3) x2 = rand(3,3) x3 = rand(3,3) x4 = rand(3,3) y1 = rand(3,3) y2 = rand(3,3)

4 reads, 2 writes

MBF.@fused_direct begin @. y1 = x1 * x2 + x3 * x4 @. y2 = x1 * x3 + x2 * x4 end ```

This is achieved by fusing the loops and inlining with the given data, resulting in the compiler being able to perform Common-SubExpression Elimination (CSE) on the memory loads.

Custom implementations

Users can write custom implementations, using the @make_type and @make_fused macros, and then defining Base.copyto! on the type you've defined

```julia import MultiBroadcastFusion as MBF import MultiBroadcastFusion: fused_direct

MBF.@maketype MyFusedMultiBroadcast MBF.@makefused fuseddirect MyFusedMultiBroadcast myfused

Now, @fused_direct will call Base.copyto!(::MyFusedMultiBroadcast). Let's define it:

function Base.copyto!(fmb::MyFusedMultiBroadcast) pairs = fmb.pairs destinations = map(x->x.first, pairs) @inbounds for i in eachindex(destinations) # does @inline pair.first[i] = pair.second[i] for all pairs MBF.rcopyto_at!(pairs, i) end return nothing end

x1 = rand(3,3) x2 = rand(3,3) x3 = rand(3,3) x4 = rand(3,3) y1 = rand(3,3) y2 = rand(3,3)

4 reads, 2 writes

@my_fused begin @. y1 = x1 * x2 + x3 * x4 @. y2 = x1 * x3 + x2 * x4 end ```

Writing custom macros

Users can also write custom macros with, for example,

```julia import MultiBroadcastFusion as MBF

struct FusedMultiBroadcast{T} pairs::T end macro getfusedmultibroadcast(expr) _pairs = gensym() quote $pairs = $(esc(MBF.fuseddirect(expr))) FusedMultiBroadcast($pairs) end end ```

This can be helpful for inspecting multibroadcast objects.

Owner

  • Name: Climate Modeling Alliance
  • Login: CliMA
  • Kind: organization
  • Email: clima@caltech.edu

An alliance of scientists, engineers and applied mathematicians, dedicated to pioneering a new, data-informed approach to climate modeling

GitHub Events

Total
  • Create event: 4
  • Commit comment event: 2
  • Issues event: 7
  • Watch event: 3
  • Issue comment event: 7
  • Push event: 11
  • Pull request event: 4
  • Fork event: 1
Last Year
  • Create event: 4
  • Commit comment event: 2
  • Issues event: 7
  • Watch event: 3
  • Issue comment event: 7
  • Push event: 11
  • Pull request event: 4
  • Fork event: 1

Packages

  • Total packages: 1
  • Total downloads:
    • julia 94 total
  • Total dependent packages: 1
  • Total dependent repositories: 0
  • Total versions: 7
juliahub.com: MultiBroadcastFusion

A Julia package for fusing multiple broadcast expressions together

  • Versions: 7
  • Dependent Packages: 1
  • Dependent Repositories: 0
  • Downloads: 94 Total
Rankings
Dependent repos count: 9.7%
Average: 24.4%
Dependent packages count: 39.0%
Last synced: 10 months ago

Dependencies

.github/workflows/CodeCov.yml actions
  • actions/checkout v4 composite
  • codecov/codecov-action v3 composite
  • julia-actions/setup-julia latest composite
.github/workflows/CompatHelper.yml actions
.github/workflows/JuliaFormatter.yml actions
  • actions/checkout v4 composite
  • dorny/paths-filter v2 composite
  • julia-actions/setup-julia latest composite
  • styfle/cancel-workflow-action 0.4.0 composite
.github/workflows/TagBot.yml actions
  • JuliaRegistries/TagBot v1 composite
.github/workflows/ci.yml actions
  • actions/cache v1 composite
  • actions/checkout v4 composite
  • codecov/codecov-action v1 composite
  • julia-actions/julia-buildpkg v1 composite
  • julia-actions/julia-processcoverage v1 composite
  • julia-actions/julia-runtest v1 composite
  • julia-actions/setup-julia v1 composite
.github/workflows/invalidations.yml actions
  • actions/checkout v4 composite
  • julia-actions/julia-buildpkg v1 composite
  • julia-actions/julia-invalidations v1 composite
  • julia-actions/setup-julia v1 composite