# \[ANN\] Announcing PAPI.jl

**URL:** <https://discourse.julialang.org/t/ann-announcing-papi-jl/69357>\
**Category:** Package Announcements\
**Tags:** performance, hardware\
**Created:** [October 7, 2021, 9:50am UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357 "2021-10-07T09:50:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomhaber](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@tomhaber](https://discourse.julialang.org/u/tomhaber)\
**Post date:** [October 7, 2021, 9:50am UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357/1 "2021-10-07T09:50:12Z")

</div>

I would like to introduce [PAPI.jl](https://github.com/tomhaber/PAPI.jl), Julia bindings for the [PAPI](http://icl.cs.utk.edu/papi/index.html) hardware performance counters library.

Performance Application Programming Interface (PAPI) is a portable and efficient API to access  
the performance counters available on modern processors. It attempts to provide a unified set of performance metrics across vendors and platforms. Besides performance counters, it includes components to measure power consumption, software-defined events, task granularity, etc  
PAPI includes a component for the linux performance counters, so all those counters are also accessible from PAPI.jl

PAPI.jl adds high-level functions on top providing useful primitives that developers can easily understand and use. As well as, allowing access to some of the low-level primitives from Julia.  
The basic interface is provided by two macros ‘profile’ and ‘sample’: both taking a set of events and a function call. ‘profile’ gives a one-shot profile whereas ‘sample’ offers a more detailed insight with multiple samples (useful for statistical testing).

Example usage:

```julia
using PAPI

function mysum(X::AbstractArray)
    s = zero(eltype(X))
    for x in X
        s += x
    end
    s
end

X = rand(10_000)
stats = @profile mysum(X)

```

which by default outputs a profile about number of total and branching instructions

```julia
  BR_INS = 4875055 # 22.0% of all instructions # 588.0 M/sec 
  BR_MSP = 188115 # 4.0% of all branches
  TOT_INS = 22197305 # 0.839 insn per cycle
  TOT_CYC = 26453432 # 3.191 Ghz # 1.192 cycles per insn
  runtime = 8289881 nsecs

```

A set of events can also be provided, for example giving insight into vectorization

```julia
julia> stats = @profile [PAPI.VEC_DP, PAPI.DP_OPS] mysum(X)
EventValues:
  VEC_DP = 1000000
  DP_OPS = 1000000 # 1.0x vectorized
  runtime = 1424735 nsecs

```

I use it extensively in my high-performance work and hope others might find it useful as well.  
This kind of profiling however does not give a complete picture and care needs to be taken when interpreting performance counters.

URL: [GitHub - JuliaPerf/PAPI.jl: PAPI bindings for Julia](https://github.com/tomhaber/PAPI.jl)

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [October 8, 2021, 7:11am UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357/2 "2021-10-08T07:11:03Z")

</div>

Awesome!

Is this the same `@profile` as `Profiling.@profile` (hooked in to it somehow)?

---

<div class="post-metadata">

**Author:** ![tomhaber](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@tomhaber](https://discourse.julialang.org/u/tomhaber)\
**Post date:** [October 8, 2021, 8:41am UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357/3 "2021-10-08T08:41:54Z")

</div>

Sadly no. I was looking at the (profile) sampling code in Julia, in an attempt to hijack it. But at that point it was not extendable. The idea back then was to trigger a sampling event in Julia on a counter overflow, but it didn’t like me doing that without calling `Profile.init` and installing the timer.

`PAPI.@profile` counts the events during a single invocation of the function as opposed to `PAPI.@sample` which calls it many times. I pretty much using it to see if the optimizations I’m applying are actually able to make a difference (e.g. in the number of cache misses)

I regards to combining it with `Profiling.@profile`: I’m more inclined to actually using the `perf` tool outside of Julia. For that you would probably have to build Julia from source as the jitevents for perf aren’t enabled in the binary release ☹

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 8, 2021, 9:19am UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357/4 "2021-10-08T09:19:05Z")

</div>

How does `@profile mysum(X)` handle precompilation? Should we do `mysum(X)` first (so it precompiles) and then `@profile mysum(X)`, or it is fine to do just the later?

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [October 8, 2021, 9:23am UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357/5 "2021-10-08T09:23:21Z")

</div>

> [@tomhaber](#):
>
> `PAPI.@profile` counts

Just a suggestion - maybe name it `PAPI.@perfcounters` or so then? A naming conflict with a very established function in a standard library may confuse people.

---

<div class="post-metadata">

**Author:** ![tomhaber](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@tomhaber](https://discourse.julialang.org/u/tomhaber)\
**Post date:** [October 8, 2021, 9:34am UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357/6 "2021-10-08T09:34:16Z")

</div>

`PAPI.@profile` has a `warmup` parameter (default=0) and does that many warmup rounds prior to measuring.

It also includes a `gcfirst` parameter to do a few rounds of garbage collection first.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 8, 2021, 12:42pm UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357/7 "2021-10-08T12:42:51Z")

</div>

I just found this: [https://github.com/jakebolewski/PAPI.jl](https://github.com/jakebolewski/PAPI.jl). Any connection?

---

<div class="post-metadata">

**Author:** ![tomhaber](https://avatars.discourse-cdn.com/v4/letter/t/41988e/32.png) [@tomhaber](https://discourse.julialang.org/u/tomhaber)\
**Post date:** [October 9, 2021, 7:12am UTC](https://discourse.julialang.org/t/ann-announcing-papi-jl/69357/8 "2021-10-09T07:12:01Z")

</div>

Very outdated package that does something related
