# \[ANN\] Ghost.jl - the code tracer

**URL:** <https://discourse.julialang.org/t/ann-ghost-jl-the-code-tracer/63403>\
**Category:** Package Announcements\
**Tags:** announcement\
**Created:** [June 22, 2021, 10:37pm UTC](https://discourse.julialang.org/t/ann-ghost-jl-the-code-tracer/63403 "2021-06-22T22:37:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [June 22, 2021, 10:37pm UTC](https://discourse.julialang.org/t/ann-ghost-jl-the-code-tracer/63403/1 "2021-06-22T22:37:58Z")

</div>

[**Ghost.jl**](https://github.com/dfdx/Ghost.jl) lets you recursively trace a function execution and record all primitive operations onto a linearized tape.

```julia
using Ghost

inc(x) = x + 1
mul(x, y) = x * y
inc_double(x) = mul(inc(x), inc(x))

val, tape = trace(inc_double, 2.0)

```

result:

```julia
(9.0, Tape{Dict{Any, Any}}
  inp %1::typeof(Main. __atexample__ 257.inc_double)
  inp %2::Float64
  %3 = +(%2, 1)::Float64
  %4 = +(%2, 1)::Float64
  %5 = *(%3, %4)::Float64
)

```

Previously Ghost has been part of the autodiff package [Yota](https://github.com/dfdx/Yota.jl) and was used to break down complex functions into the list of primitives amenable to differentiation. Other use cases include function serialization, analysis or modification, as well as providing a general [graph representation](https://dfdx.github.io/Ghost.jl/dev/tape/).

As an experimental feature, Ghost also supports [loop operation](https://dfdx.github.io/Ghost.jl/dev/loops/), making it suitable for many dynamic graph problems.

Ghost has some intersecting functionality with IR-level packages such as [Cassette](https://github.com/JuliaLabs/Cassette.jl), [IRTools](https://github.com/FluxML/IRTools.jl), [CodeInfoTools](https://github.com/JuliaCompilerPlugins/CodeInfoTools.jl), etc., but works on a higher level (i.e. no segfaults due to incorrectly inserted operation) and makes emphasis on linearized graph representation.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 22, 2021, 11:18pm UTC](https://discourse.julialang.org/t/ann-ghost-jl-the-code-tracer/63403/2 "2021-06-22T23:18:25Z")

</div>

This looks cool. I’ve also seen [GitHub - MasonProtter/SymbolicTracing.jl: (experimental) tracing and abstract interpretation with SymbolicUtils.jl](https://github.com/MasonProtter/SymbolicTracing.jl). Do you or @Mason know how these relate to each other?

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [June 23, 2021, 9:29am UTC](https://discourse.julialang.org/t/ann-ghost-jl-the-code-tracer/63403/3 "2021-06-23T09:29:00Z")

</div>

SymbolicTracing looks interesting and the two packages certainly have similar approaches to tracing. A few differences I see though (based on the README):

- SymbolicTracing works only with abstract type while Ghost can as well trace through concrete types and struct fields
- SymbolicTracing doesn’t seem to handle control flow; Ghost can follow branches, including conditions and loops
- Loops in Ghost can also be traced as a separate operation
- I’m not sure it’s possible to include operations out of the dependency graph in SymbolicTracing (e.g. `println()` statement); in Ghost you can have both - a pure computational graph and a graph with side effects
- In general, Symbolic\* packages seem to be more oriented to pure symbolic graphs, while Ghost’s `Tape` is an abstraction for any kind of computation

---

<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:** [June 24, 2021, 7:00am UTC](https://discourse.julialang.org/t/ann-ghost-jl-the-code-tracer/63403/4 "2021-06-24T07:00:09Z")

</div>

~~Is there a way to get a pullback function with Yota (for vector-jacobian-products), instead of “just” a gradient?~~

Posted to the latest Yotal.jl announcement instead.

---

<div class="post-metadata">

**Author:** ![phg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phg/32/17184_2.png) [@phg](https://discourse.julialang.org/u/phg)\
**Post date:** [July 1, 2021, 2:59pm UTC](https://discourse.julialang.org/t/ann-ghost-jl-the-code-tracer/63403/5 "2021-07-01T14:59:40Z")

</div>

Having written an IRTools-based tracker myself, I must say that the internals look really nice and clean!
