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

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:

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)

@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?

1 Like

This is worth an issue.

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.

I think they are getting close to done.

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.

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.

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,

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.

Just type assert the return.

How exactly?

::T on the return of the channel

Oh great! That was easy! Thanks!

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

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.

1 Like