[ANN] InplacePermutations.jl

Hello,

This started as a fun exploration, I don’t have a specific usecase for it but maybe somebody else will.

This is a very small package that introduces a permutedims!(array, perm) variant that permutes an array reusing the same underlaying memory buffer without needing auxiliary buffers/allocations.
It needs to known array sizes and permutation tuple at compile time for best performance.

using InplacePermutations

A = rand(8, 6, 2, 2)
Aorig = copy(A)                                  # keep a pristine reference for comparison

B = InplacePermutations.permutedims!(A, (2, 4, 1, 3))   # mutates A in place

B == permutedims(Aorig, (2, 4, 1, 3))        # true
size(B)                                      # (6, 2, 8, 2)

Baseline Base.permutedims! with a (36,24) array

BenchmarkTools.Trial: 10000 samples with 259 evaluations per sample.
 Range (min … max):  297.297 ns … 692.085 ns  β”Š GC (min … max): 0.00% … 0.00%
 Time  (median):     297.938 ns               β”Š GC (median):    0.00%
 Time  (mean Β± Οƒ):   302.942 ns Β±  15.778 ns  β”Š GC (mean Β± Οƒ):  0.00% Β± 0.00%

  β–ˆβ–ƒβ– ▁ ▁▂▃▁                                                    ▁
  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‡β–‡β–ˆβ–ˆβ–‡β–†β–‡β–‡β–†β–…β–†β–†β–…β–…β–…β–…β–…β–…β–†β–…β–…β–…β–…β–…β–…β–…β–„β–†β–…β–…β–†β–†β–„β–†β–†β–†β–…β–…β–†β–…β–„β–…β–…β–…β–…β–…β–„β–…β–„β–ƒ β–ˆ
  297 ns        Histogram: log(frequency) by time        377 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

Same array with array size and permutation known at compile time

BenchmarkTools.Trial: 10000 samples with 671 evaluations per sample.
 Range (min … max):  187.841 ns … 325.633 ns  β”Š GC (min … max): 0.00% … 0.00%
 Time  (median):     188.462 ns               β”Š GC (median):    0.00%
 Time  (mean Β± Οƒ):   191.987 ns Β±   8.242 ns  β”Š GC (mean Β± Οƒ):  0.00% Β± 0.00%

  β–ˆβ–†β–‚β–β–β–β–‚β–„β–‚β–β– ▁   ▁                                             ▁
  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‡β–‡β–ˆβ–ˆβ–‡β–‡β–‡β–‡β–†β–†β–†β–†β–‡β–†β–‡β–†β–‡β–‡β–ˆβ–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–‡β–†β–…β–…β–†β–…β–…β–†β–…β–†β–…β–…β–…β–…β–…β–† β–ˆ
  188 ns        Histogram: log(frequency) by time        226 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

There are some caveats:

  • Works best on small ish arrays
  • Can be compilation heavy with big arrays (tunable trade-off between compilation time and speed)
  • New sizes/perm combinations will generate a new function everytime.

More details in the repo.

PS.: currently being registered. Not married to the name, if you have opinions let me know!

1 Like