# Type instabilities when introducing a Channel as a parameter in a ODE problem

**URL:** https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737
**Category:** Performance
**Tags:** type-stability, differentialequation
**Created:** [November 2, 2023, 11:16pm UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737 "2023-11-02T23:16:31Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![albertomercurio](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albertomercurio/32/27051_2.png) [@albertomercurio](https://discourse.julialang.org/u/albertomercurio)
#### Post date: [November 2, 2023, 11:16pm UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/1 "2023-11-02T23:16:31Z")

</div>

Hello.

Hello, in the following I show a minimal working example of the problem. I want to implement a type stable function that solves an ODE that implements a Channel as a parameter. But I figured out that the `solve` function returns `Any` type.

This is the minimal code:

```julia
function prova(A, b, tspan; alg=Tsit5())
    progr_channel = Channel{Bool}()
    p = (L=A,progr_channel=progr_channel)
    prob = ODEProblem{true}(prova_func, b, tspan, p)
    sol = solve(prob, alg)
    return prova(sol)
end

function prova(sol)
    return sol
end

prova_func(du, u, p, t) = mul!(du, p.L, u)

A = rand(5,5)
b = rand(5)
tspan = (0.0, 1.0)
res = prova(A, b, tspan)

```

This channel will be helpful in the future for implementing a ProgressMeter in an ensemble problem or even a simple ode (if I want more customizations)

```julia
@async while take!(progr_channel)
    next!(myProgressMeter)
end

# and in a function
pop!(prob.p.progr_channel)

```

but when I use Cthulhu to discover type instabilities, I see that the function `solve` returns `Any`. After that, it is impossible for julia to identify the type of the outcome of the solution.

How to solve it?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [November 3, 2023, 9:12am UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/2 "2023-11-03T09:12:30Z")

</div>

This is worth an issue.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [November 3, 2023, 9:52am UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/3 "2023-11-03T09:52:44Z")

</div>

> [@albertomercurio](#):
>
> This channel will be helpful in the future for implementing a ProgressMeter in an ensemble problem

A bit of a tangent but there is series of PRs being actively work on right now for this feature, which you might be interest in.

> <https://github.com/SciML/SciMLBase.jl/pull/514/>
>
> This is the first part of a series of PRs that adds progress support to Ensemble…Poblem.
> 
> What this part does is if progress is enabled, initialize progress bars for every trajectory, and give every solve an unique ID.
> 
> For very large ensembles the expectation is that the logger shows this in a sensible way, for example, show the overall progress:
> 
> \`\`\`
> sum\_logger = let progress = Dict{Symbol, Float64}()
> TransformerLogger(TerminalLogger()) do log
> if log.level == LogLevel(-1) && haskey(log.kwargs, :progress)
> @show log
> pr = log.kwargs\[:progress\]
> if pr isa Number
> progress\[log.id\] = pr
> elseif pr == "done"
> progress\[log.id\] = 1.0
> end
> tot = sum(values(progress))/length(progress)
> if tot\>=1.0
> tot="done"
> empty!(progress)
> end
> log = merge(log, (;id=:total, message="Total", kwargs=Dict(:progress=\>tot)))
> else
> log
> end
> end
> end
> global\_logger(sum\_logger)
> \`\`\`

I think they are getting close to done.

---

<div class="post-metadata">

### Author: ![albertomercurio](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albertomercurio/32/27051_2.png) [@albertomercurio](https://discourse.julialang.org/u/albertomercurio)
#### Post date: [November 3, 2023, 5:39pm UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/4 "2023-11-03T17:39:32Z")

</div>

Thanks for telling me this the existence of this PR. However, the use of an external Progress Meter might be useful in a multitude of situations.

For example, we can redirect the stderr output to a file and print the progress bar on that file, which is very useful when using remote machines with very long tasks, and I don’t think it is supported by the native progress bar.

Moreover, the current progress meter inside the ODE is not much supported in jupyter notebook. I tested it once and it printed line by line the progress bar, which is very confusing.

And last but not least, it can be easily implemented to show progress bars of ensemble problems.

By the way, this topic goes beyond the use of a progress meter, since the Channel (or even a Remote Channel) might be used in a multitude of ways.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [November 6, 2023, 3:08am UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/5 "2023-11-06T03:08:31Z")

</div>

But you can always just use a function barrier on the solve so if your ODE solve is \>100ns it’s a non-issue in practice.

But as a way to handle this, try overloading `DiffEqBase.anytypedual(x::Channel, counter = 0) = Any`.

---

<div class="post-metadata">

### Author: ![albertomercurio](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albertomercurio/32/27051_2.png) [@albertomercurio](https://discourse.julialang.org/u/albertomercurio)
#### Post date: [September 29, 2024, 11:01am UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/6 "2024-09-29T11:01:07Z")

</div>

Hi,

sorry for this very late response.

The code in my example is now type-stable, I don’t know if this is due to some update in either in the packages or in Julia itself.

However, now, I would like to put a `RemoteChannel`. This would be very useful in `EnsembleDistributed` simulations, where the workers need to communicate somehow. (In my case they have to communicate to update the progress bar).

I saw that the code in my example becomes type-unstable if I replace the `progr_channel` with `RemoteChannel(() -> Channel{Bool}(), 1)`.

It returns `Any`, which is a bad story.

BTW, what is the exact function barrier that you where thinking about? I tried to define a function that first defines the problem, and then another one to solve it, but nothing.

Also,

> [@ChrisRackauckas](#):
>
> But as a way to handle this, try overloading `DiffEqBase.anytypedual(x::Channel, counter = 0) = Any`.

what do you mean exactly here?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [September 29, 2024, 11:44pm UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/7 "2024-09-29T23:44:12Z")

</div>

> [@albertomercurio](#):
>
> what do you mean exactly here?

That’s for a different thing? Do you have that error? Since you’re reviving a year old issue and that part changed a lot, I would presume that’s automatically handled.

> [@albertomercurio](#):
>
> I saw that the code in my example becomes type-unstable if I replace the `progr_channel` with `RemoteChannel(() -> Channel{Bool}(), 1)`.

Just type assert the return.

---

<div class="post-metadata">

### Author: ![albertomercurio](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albertomercurio/32/27051_2.png) [@albertomercurio](https://discourse.julialang.org/u/albertomercurio)
#### Post date: [September 30, 2024, 8:41pm UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/8 "2024-09-30T20:41:53Z")

</div>

> [@ChrisRackauckas](#):
>
> Just type assert the return.

How exactly?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [October 1, 2024, 11:21am UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/9 "2024-10-01T11:21:12Z")

</div>

`::T` on the return of the channel

---

<div class="post-metadata">

### Author: ![albertomercurio](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albertomercurio/32/27051_2.png) [@albertomercurio](https://discourse.julialang.org/u/albertomercurio)
#### Post date: [October 3, 2024, 4:14pm UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/10 "2024-10-03T16:14:15Z")

</div>

Oh great! That was easy! Thanks!

BTW, why is Julia not able to automatically infer it?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [October 4, 2024, 11:31am UTC](https://discourse.julialang.org/t/type-instabilities-when-introducing-a-channel-as-a-parameter-in-a-ode-problem/105737/11 "2024-10-04T11:31:40Z")

</div>

Channels act over IO so their results cannot be inferred. You could send practically anything if you are reading some stream of 01011010011. The only way to know what type it will be is to either read the message for what type it is, which is inherently dynamic, or to assert what type you are expecting.
