# Fixing red bars at top of flame profile

**URL:** <https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316>\
**Category:** Performance\
**Created:** [August 28, 2023, 11:57pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316 "2023-08-28T23:57:21Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![ilanggear](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ilanggear/32/862_2.png) [@ilanggear](https://discourse.julialang.org/u/ilanggear)\
**Post date:** [August 28, 2023, 11:57pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/1 "2023-08-28T23:57:22Z")

</div>

I’ve attached a screenshot of my flame profile. I’ve read that red bars near the top signal a problem with type instability. But I have specified the type of every struct member and the vast majority of my code relies on side effects, not return values.

Here’s one function that is causing multiple red bars, It gets called a lot, so it makes sense that it shows a wide bar in the flame profile. But I don’t know what’s causing the redness. Anyone have any insights?

```julia
function augmentCount!(base, cd, fvi, fv, fromTmp; w = 1, inc=1, numIndicesCutoff = 10_000) #w is width, inc is count to increment
    cdtw = cd.taskDat
    c = 0
    if fromTmp
        while length(cdtw.countsLow[w]) < fvi
            push!(cdtw.countsLow[w], 0)
        end
        if cdtw.countsLow[w][fvi] + inc < typemax(UInt8)
            c = cdtw.countsLow[w][fvi] += inc
        elseif cdtw.countsLow[w][fvi] < typemax(UInt8)
            cdtw.countsLow[w][fvi] = typemax(UInt8)
            base.countsMed[w][fv] = inc + cdtw.countsLow[w][fvi]
            c = base.countsMed[w][fv]
        elseif haskey(base.countsMed[w], fv) 
            if base.countsMed[w][fv] + inc <= typemax(UInt16)
                c = base.countsMed[w][fv] += inc
            else 
                c = base.countsHi[w][fv] = inc + base.countsMed[w][fv]
                delete!(base.countsMed[w], fv)
            end
        else c = base.countsHi[w][fv] += inc
        end
    else
        if base.countsLow[w][fvi] + inc < typemax(UInt8)
            c = base.countsLow[w][fvi] += inc
        elseif base.countsLow[w][fvi] < typemax(UInt8)
            base.countsLow[w][fvi] = typemax(UInt8)
            c = base.countsMed[w][fvi] = d.countsLow[fvi] + inc
        elseif haskey(base.countsMed[w], fvi) 
            if base.countsMed[w][fvi] + inc <= typemax(UInt16)
                c = base.countsMed[w][fvi] += inc
            else delete!(base.countsMed[w], fvi)
                base.countsHi[w][fvi] += inc
            end
        else base.countsHi[w][fvi] += inc
        end
    end
    return c
end

```

One sample call: c = augmentCount!(base, cd, fvi, fv, true; w=1)  
Another: c2 = augmentCount!(base, cd, binFvi, binFv, fromTmp; w=2)

The types of the args are as follows: base is an immutable struct, cd is a mutable struct, fvi and binfvi are Ints, fv and binFV are small tuples, fromTmp is a Bool, and w is an Int. Would it help if I posted the contents of the structs?

 ![Screen Shot 2023-08-28 at 5.25.50 PM](https://global.discourse-cdn.com/julialang/original/3X/1/0/1066d3f45893b07edea6efaa8df934d66803c3a8.png)

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [August 29, 2023, 4:24am UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/2 "2023-08-29T04:24:46Z")

</div>

> [@ilanggear](#):
>
> But I have specified the type of every struct member

Would help to show all the struct definitions. It’s easy enough to make a mistake in typing such that a parametric type is underspecified or so.

And ideally, we would be able to run your code for testing, but that might not be feasible.

---

<div class="post-metadata">

**Author:** ![ilanggear](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ilanggear/32/862_2.png) [@ilanggear](https://discourse.julialang.org/u/ilanggear)\
**Post date:** [August 29, 2023, 5:14pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/3 "2023-08-29T17:14:04Z")

</div>

I tried restructuring my code to move some variables out of a mutable struct and into an immutable structure, but it didn’t change much. The modified first three lines of the function are

```julia
function augmentCount!(base, td, fvi, fv, fromTmp; w = 1, inc=1, numIndicesCutoff = 10_000) #w is width, inc is count to increment
    c = 0
    if fromTmp
...

```

The td var is typed as

```julia
struct TaskDat_Pass1 <: AbstractTaskDat

    attIdToFeatValList::Tuple{
        Vector{Tuple{UInt32, UInt16, UInt16}},
        Vector{Tuple{UInt32, UInt32}} } 

    featValToAttIdDict::Tuple{
        Dict{Tuple{UInt32, UInt16, UInt16}, UInt32},
        Dict{Tuple{UInt32, UInt32}, UInt64} }    
        
    countsLow::Tuple{Vector{UInt8}, Vector{UInt8}}
end

```

and the base var is

```julia
struct GlobalBase
    featSpecList::Vector{FeatSpec}
    featSpecDict::Dict{String, UInt16}

    relationSet::Set{UInt8} # relations
    coreFeatSet::Set{UInt8} # upos, entity, caps, tense, number, headoffset, etc.
    basicFeatSet::Set{UInt8} # relations plus core feats
    miscFeatSet::Set{UInt8} # same-sen lemmas, same-doc lemmas
    formSet::Set{String} # set of form strings from Wiktionary

    featValListSorted::Tuple{
        Vector{Tuple{UInt32, UInt8, UInt8}}, #, UInt8, UInt8}}
        Vector{NTuple{2,UInt32}},  
        Vector{NTuple{3,UInt32}}, 
        Vector{NTuple{4,UInt32}},  
        Vector{NTuple{5,UInt32}} }

    countsLow::Tuple{
        Vector{UInt8}, 
        Vector{UInt8}, 
        Vector{UInt8}, 
        Vector{UInt8}, 
        Vector{UInt8}} 
    countsMed::Tuple{
        Dict{Tuple{UInt32, UInt16, UInt16}, UInt16},
        Dict{NTuple{2, UInt32}, UInt16},
        Dict{NTuple{3, UInt32}, UInt16},
        Dict{NTuple{4, UInt32}, UInt16},
        Dict{NTuple{5, UInt32}, UInt16} }
    countsHi::Tuple{
        Dict{Tuple{UInt32, UInt16, UInt16}, UInt32},
        Dict{NTuple{2, UInt32}, UInt32},
        Dict{NTuple{3, UInt32}, UInt32},
        Dict{NTuple{4, UInt32}, UInt32},
        Dict{NTuple{5, UInt32}, UInt32} }
    
    #indices::Vector{Vector{Vector{UInt8}}} # N-ary x FvId x Indices
    odds::Tuple{
        Vector{Float16},
        Vector{Float16},
        Vector{Float16},
        Vector{Float16},
        Vector{Float16} } 
end

```

The other parameters are scalars. It would be difficult to post some standalone runnable code, but perhaps I could set up a repo on Github or something? Would that help?

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [August 29, 2023, 5:33pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/4 "2023-08-29T17:33:35Z")

</div>

I’m not entirely sure if this is it, but one potential type-stability problem is that `countsMed` and a couple of other members are heterogeneous tuples. These are then accessed as `countsMed[w]`, but since `w` is not known at compile time there is no way to know what type you are accessing, leading to type instability.

Although I’ve never actually used it myself, [GitHub - JuliaDebug/Cthulhu.jl: The slow descent into madness](https://github.com/JuliaDebug/Cthulhu.jl) seems like it might be a good tool for nailing down where the inference fails.

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [August 29, 2023, 5:36pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/5 "2023-08-29T17:36:34Z")

</div>

I think tuples are not the issue, because

```julia
julia> isconcretetype(Tuple{
        Dict{Tuple{UInt32, UInt16, UInt16}, UInt16},
        Dict{NTuple{2, UInt32}, UInt16},
        Dict{NTuple{3, UInt32}, UInt16},
        Dict{NTuple{4, UInt32}, UInt16},
        Dict{NTuple{5, UInt32}, UInt16} })
true

```

But I second the suggestion to give `Cthulhu` a try and use it to step through the offending call.  
With the right toggles set it basically shows you the `@code_warntype` output on every level of the call stack.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [August 29, 2023, 6:25pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/6 "2023-08-29T18:25:26Z")

</div>

> [@JonasWickman](#):
>
> `countsMed` and a couple of other members are heterogeneous tuples. These are then accessed as `countsMed[w]`, but since `w` is not known at compile time there is no way to know what type you are accessing

That could be it. If you can’t get `w` to constprop, you could think about pulling that integer into the type domain by making it a `Val(1)` etc. argument. Then you’d be sure that it can be type stable for each `w`.

---

<div class="post-metadata">

**Author:** ![ilanggear](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ilanggear/32/862_2.png) [@ilanggear](https://discourse.julialang.org/u/ilanggear)\
**Post date:** [August 29, 2023, 6:38pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/7 "2023-08-29T18:38:40Z")

</div>

Thank you, thank you for the suggestions. I will try them out!

---

<div class="post-metadata">

**Author:** ![ilanggear](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ilanggear/32/862_2.png) [@ilanggear](https://discourse.julialang.org/u/ilanggear)\
**Post date:** [September 1, 2023, 3:28am UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/8 "2023-09-01T03:28:11Z")

</div>

Sometimes when I try to descend when using Cthulhu, I get the following error: ERROR: AssertionError: kind(sig) == K"call". What does it mean and how do I deal with it?

 ![Screen Shot 2023-08-31 at 9.25.02 PM](https://global.discourse-cdn.com/julialang/original/3X/3/b/3bd66c0959fe763e451b5bb0137b3e98514fad55.png)

---

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [September 1, 2023, 9:47am UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/9 "2023-09-01T09:47:46Z")

</div>

Try updating Cthulhu, the latest version is 2.9.2. If the doesn’t fix it, if you could share the code necessary to reproduce the error that would help in fixing it.

---

<div class="post-metadata">

**Author:** ![ilanggear](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ilanggear/32/862_2.png) [@ilanggear](https://discourse.julialang.org/u/ilanggear)\
**Post date:** [September 5, 2023, 10:43pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/10 "2023-09-05T22:43:41Z")

</div>

I have narrowed down my problem with Cthulhu to the following code snippet. The f.coreF function is held as a field of a struct and it returns a limited range of diverse values. I can’t avoid not knowing ahead of time what the return type will be (although it gets standardized to a string right away). My question is why does Cthulhu return an error: “ERROR: type Union has no field parameters” or a similar error message about the type of the TopOfBottom? Is there a better way to do what I’m doing?

```julia
struct FeatSpec
    name::String # string version of name
    tuple::Tuple#{Vararg{UInt8}} # tuple version of name
    id::UInt32 # id in main featSpecList
    coreF::Function # function that returns feature from specified granular segment
...<snipped>
end

const FeatValTypes::Type = Union{UInt8, Int8, String, Vector{UInt8}, Vector{Int8},Vector{String}}
 .... <snipped>

 vals0::FeatValTypes = f.coreF(docSens, s, t)
    

```

---

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [September 6, 2023, 3:13pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/11 "2023-09-06T15:13:00Z")

</div>

Unfortunately, that error is a bug with Cthulhu. A new version should be released soon.

The reason you have type stability is not just because the return type is unknown but also because each function has their own type so the type of `coreF` is unknown (`Function` is not a concrete type).  
There are two main solutions for this, either make `FeatSpec` a parametric type such that its type depends on which function `coreF` is or use a function wrapper from [yuyichao/FunctionWrappers.jl (github.com)](https://github.com/yuyichao/FunctionWrappers.jl).

I would recommend the first method if the type of `coreF` can be inferred, i.e. if you have a `Vector[FeatSpec}` the `coreF` should be the same for all of them. If you only have a few different `coreF`s I would create seperate lists for each of them. Otherwise FunctionWrappers.jl will probably be better.

---

<div class="post-metadata">

**Author:** ![ilanggear](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ilanggear/32/862_2.png) [@ilanggear](https://discourse.julialang.org/u/ilanggear)\
**Post date:** [September 6, 2023, 3:57pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/12 "2023-09-06T15:57:40Z")

</div>

Thanks so much Zentrik for the response. It helps.  
I have a couple further questions about your suggestions. I do have a main Vector[FeatSpec], but every entry in the vector (about 20) has its own unique function. All the functions take the same three variables as input, eg (docSens, s, t). I could group the featSpecs and parameterize them by the type of output variable, but I’m not sure that helps anything because there is generally more than one function per output type. I tried making the name of the feature as a parameter via Val{f.name}, as in coreF(Val(f.name), docSens, s, t) but that didn’t seem to make much difference in performance.  
Thanks for the pointer to the function wrappers. I’ll take a look…

---

<div class="post-metadata">

**Author:** ![Zentrik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zentrik/32/35409_2.png) [@Zentrik](https://discourse.julialang.org/u/Zentrik)\
**Post date:** [September 6, 2023, 4:14pm UTC](https://discourse.julialang.org/t/fixing-red-bars-at-top-of-flame-profile/103316/13 "2023-09-06T16:14:41Z")

</div>

> [@ilanggear](#):
>
> ```julia
> struct FeatSpec
> name::String # string version of name
> tuple::Tuple#{Vararg{UInt8}} # tuple version of name
> id::UInt32 # id in main featSpecList
> coreF::Function # function that returns feature from specified granular segment
> ...<snipped>
> end
> 
> const FeatValTypes::Type = Union{UInt8, Int8, String, Vector{UInt8}, Vector{Int8},Vector{String}}
> .... <snipped>
> 
> vals0::FeatValTypes = f.coreF(docSens, s, t)
> 
> ```

Sorry just to clarify for the first suggestion I meant something like

```julia
struct FeatSpec{T}
    name::String # string version of name
    tuple::Tuple#{Vararg{UInt8}} # tuple version of name
    id::UInt32 # id in main featSpecList
    coreF::T # function that returns feature from specified granular segment
...<snipped>
end

const FeatValTypes::Type = Union{UInt8, Int8, String, Vector{UInt8}, Vector{Int8},Vector{String}}
 .... <snipped>

 vals0::FeatValTypes = f.coreF(docSens, s, t)

```

But it does sound like FunctionWrappers.jl would be the right choice here.
