Skip to content

Commit

Permalink
Add docs page and more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisYatunin committed Apr 2, 2024
1 parent b48fde8 commit 8ec14f6
Show file tree
Hide file tree
Showing 10 changed files with 394 additions and 148 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/DocCleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Doc Preview Cleanup

on:
pull_request:
types: [closed]

jobs:
doc-preview-cleanup:
runs-on: ubuntu-latest
steps:
- name: Checkout gh-pages branch
uses: actions/checkout@v4
with:
ref: gh-pages

- name: Delete preview and history
run: |
git config user.name "Documenter.jl"
git config user.email "[email protected]"
git rm -rf "previews/PR$PRNUM"
git commit -m "delete preview"
git branch gh-pages-new $(echo "delete history" | git commit-tree HEAD^{tree})
env:
PRNUM: ${{ github.event.number }}

- name: Push changes
run: |
git push --force origin gh-pages-new:gh-pages
28 changes: 28 additions & 0 deletions .github/workflows/Documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Documentation

on:
push:
branches:
- main
tags: '*'
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
docbuild:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v1
with:
version: '1.10'
- name: Install dependencies
run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key
run: julia --project=docs/ docs/make.jl
5 changes: 4 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ uuid = "0fe1646c-419e-43be-ac14-22321958931b"
authors = ["CliMA Contributors <[email protected]>"]
version = "0.1.0"

[deps]

[compat]
julia = "1.10"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Aqua", "JET", "OrderedCollections", "PrettyTables", "SafeTestsets", "Test"]
test = ["Aqua", "JET", "InteractiveUtils", "OrderedCollections", "PrettyTables", "SafeTestsets", "Test"]
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,22 @@
# UnrolledUtilities.jl
A Julia package that provides unrolled analogues to functions from `Base` and `Base.Iterators`

|||
|---------------------:|:----------------------------------------------|
| **Documentation** | [![dev][docs-dev-img]][docs-dev-url] |
| **Docs Build** | [![docs build][docs-bld-img]][docs-bld-url] |
| **GHA CI** | [![gha ci][gha-ci-img]][gha-ci-url] |
| **Code Coverage** | [![codecov][codecov-img]][codecov-url] |

[docs-dev-img]: https://img.shields.io/badge/docs-dev-blue.svg
[docs-dev-url]: https://CliMA.github.io/UnrolledUtilities.jl/dev/

[docs-bld-img]: https://github.com/CliMA/UnrolledUtilities.jl/actions/workflows/docs.yml/badge.svg
[docs-bld-url]: https://github.com/CliMA/UnrolledUtilities.jl/actions/workflows/docs.yml

[gha-ci-img]: https://github.com/CliMA/UnrolledUtilities.jl/actions/workflows/ci.yml/badge.svg
[gha-ci-url]: https://github.com/CliMA/UnrolledUtilities.jl/actions/workflows/ci.yml

[codecov-img]: https://codecov.io/gh/CliMA/UnrolledUtilities.jl/branch/main/graph/badge.svg
[codecov-url]: https://codecov.io/gh/CliMA/UnrolledUtilities.jl

8 changes: 8 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
34 changes: 34 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Documenter

include(joinpath("..", "test", "test_and_analyze.jl"))

comparison_table_file = joinpath("docs", "src", "comparison_table.md")

open(comparison_table_file, "w") do io
println(io, "# Comparison Table\n```@raw html")
println(io, "<div style=\"width: max(80vw, 100%)\">") # use 80% of viewport
print_comparison_table(io, true)
println(io, "</div>")
println(io, "```")
end

makedocs(;
sitename = "UnrolledUtilities.jl",
modules = [UnrolledUtilities],
pages = ["Home" => "index.md", "Comparison Table" => "comparison_table.md"],
format = Documenter.HTML(
prettyurls = get(ENV, "CI", nothing) == "true",
size_threshold_ignore = ["comparison_table.md"],
),
clean = true,
)

rm(comparison_table_file)

deploydocs(
repo = "github.com/CliMA/UnrolledUtilities.jl.git",
target = "build",
devbranch = "main",
push_preview = true,
forcepush = true,
)
40 changes: 40 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# UnrolledUtilities.jl

A collection of generated functions in which all loops are unrolled and inlined.

The functions exported by this module are
- `unrolled_any(f, itr)`: similar to `any`
- `unrolled_all(f, itr)`: similar to `all`
- `unrolled_foreach(f, itrs...)`: similar to `foreach`
- `unrolled_map(f, itrs...)`: similar to `map`
- `unrolled_reduce(op, itr; [init])`: similar to `reduce`
- `unrolled_mapreduce(f, op, itrs...; [init])`: similar to `mapreduce`
- `unrolled_zip(itrs...)`: similar to `zip`
- `unrolled_in(item, itr)`: similar to `in`
- `unrolled_unique(itr)`: similar to `unique`
- `unrolled_filter(f, itr)`: similar to `filter`
- `unrolled_split(f, itr)`: similar to `(filter(f, itr), filter(!f, itr))`, but
without duplicate calls to `f`
- `unrolled_flatten(itr)`: similar to `Iterators.flatten`
- `unrolled_flatmap(f, itrs...)`: similar to `Iterators.flatmap`
- `unrolled_product(itrs...)`: similar to `Iterators.product`
- `unrolled_take(itr, ::Val{N})`: similar to `Iterators.take`, but with the
second argument wrapped in a `Val`
- `unrolled_drop(itr, ::Val{N})`: similar to `Iterators.drop`, but with the
second argument wrapped in a `Val`

These functions are guaranteed to be type-stable whenever they are given
iterators with inferrable lengths and element types, including when
- the iterators have nonuniform element types (with the exception of `map`, all
of the corresponding functions from `Base` encounter type-instabilities and
allocations when this is the case)
- the iterators have many elements (e.g., more than 32, which is the threshold
at which `map` becomes type-unstable for `Tuple`s)
- `f` and/or `op` recursively call the function to which they is passed, with an
arbitrarily large recursion depth (e.g., if `f` calls `map(f, itrs)`, it will
be type-unstable when the recursion depth exceeds 3, but this will not be the
case with `unrolled_map`)

Moreover, these functions are very likely to be optimized out through constant
propagation when the iterators have singleton element types (and when the result
of calling `f` and/or `op` on these elements is inferrable).
48 changes: 3 additions & 45 deletions src/UnrolledUtilities.jl
Original file line number Diff line number Diff line change
@@ -1,45 +1,3 @@
"""
UnrolledUtilities
A collection of generated functions in which all loops are unrolled and inlined.
The functions exported by this module are
- `unrolled_any(f, itr)`: similar to `any`
- `unrolled_all(f, itr)`: similar to `all`
- `unrolled_foreach(f, itrs...)`: similar to `foreach`
- `unrolled_map(f, itrs...)`: similar to `map`
- `unrolled_reduce(op, itr; [init])`: similar to `reduce`
- `unrolled_mapreduce(f, op, itrs...; [init])`: similar to `mapreduce`
- `unrolled_zip(itrs...)`: similar to `zip`
- `unrolled_in(item, itr)`: similar to `in`
- `unrolled_unique(itr)`: similar to `unique`
- `unrolled_filter(f, itr)`: similar to `filter`
- `unrolled_split(f, itr)`: similar to `(filter(f, itr), filter(!f, itr))`, but
without duplicate calls to `f`
- `unrolled_flatten(itr)`: similar to `Iterators.flatten`
- `unrolled_flatmap(f, itrs...)`: similar to `Iterators.flatmap`
- `unrolled_product(itrs...)`: similar to `Iterators.product`
- `unrolled_take(itr, ::Val{N})`: similar to `Iterators.take`, but with the
second argument wrapped in a `Val`
- `unrolled_drop(itr, ::Val{N})`: similar to `Iterators.drop`, but with the
second argument wrapped in a `Val`
These functions are guaranteed to be type-stable whenever they are given
iterators with inferrable lengths and element types, including when
- the iterators have nonuniform element types (with the exception of `map`, all
of the corresponding functions from `Base` encounter type-instabilities and
allocations when this is the case)
- the iterators have many elements (e.g., more than 32, which is the threshold
at which `map` becomes type-unstable for `Tuple`s)
- `f` and/or `op` recursively call the function to which they is passed, with an
arbitrarily large recursion depth (e.g., if `f` calls `map(f, itrs)`, it will
be type-unstable when the recursion depth exceeds 3, but this will not be the
case with `unrolled_map`)
Moreover, these functions are very likely to be optimized out through constant
propagation when the iterators have singleton element types (and when the result
of calling `f` and/or `op` on these elements is inferrable).
"""
module UnrolledUtilities

export unrolled_any,
Expand Down Expand Up @@ -73,7 +31,7 @@ function zipped_f_exprs(itr_types)
return (:(f($((:(itrs[$l][$n]) for l in 1:L)...))) for n in 1:N)
end
@inline @generated unrolled_foreach(f, itrs...) =
Expr(:block, zipped_f_exprs(itrs)...)
Expr(:block, zipped_f_exprs(itrs)..., nothing)
@inline @generated unrolled_map(f, itrs...) =
Expr(:tuple, zipped_f_exprs(itrs)...)

Expand All @@ -89,8 +47,8 @@ struct NoInit end
@inline unrolled_reduce(op, itr; init = NoInit()) =
unrolled_reduce_without_init(op, init isa NoInit ? itr : (init, itr...))

@inline unrolled_mapreduce(f, op, itrs...; init_kwarg...) =
unrolled_reduce(op, unrolled_map(f, itrs...); init_kwarg...)
@inline unrolled_mapreduce(f, op, itrs...; init = NoInit()) =
unrolled_reduce(op, unrolled_map(f, itrs...); init)

@inline unrolled_zip(itrs...) = unrolled_map(tuple, itrs...)

Expand Down
11 changes: 7 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using SafeTestsets

#! format: off
@safetestset "Test and Analyze" begin @time include("test_and_analyze.jl") end
@safetestset "Aqua" begin @time include("aqua.jl") end
#! format: on
@safetestset "Test and Analyze" begin
@time include("test_and_analyze.jl")
print_comparison_table()
end
@safetestset "Aqua" begin
@time include("aqua.jl")
end
Loading

0 comments on commit 8ec14f6

Please sign in to comment.