LightGraphs.jl Transition

I guess I would have expected

  • Rename LightGraphs → Graphs
  • Merge in some OldGraphs functionality
  • Keep the LightGraphs UUID

If it’s the LightGraphs API, what’s the point of taking the Graphs UUID? I don’t see how that helps anyone.

Thanks, good to know I wasn’t entirely misunderstanding it.

Agreed, but that’s generally discouraged. Generally there’s a migration path, or at least some notes about updating, or it’s just released with a new name (and UUID).

2 Likes

Yeah, you’re right, that won’t work, since a manifest for an environment can only have one version of a particular package/UUID. Sorry. :sweat_smile:

I think the reason they had to do that is because the General Registry only allows one package of a given name, and Graphs was already in the registry. So, although UUIDs can allow you to have a local DataFrames.jl (for example) package that is totally different from the real DataFrames.jl package, there can be only one DataFrames.jl package in the registry, if I understand correctly.

1 Like

That’s not the case, as @StefanKarpinski pointed out to me when I wanted to use Measures.jl. And since Graphs was renamed OldGraphs, I’d expect it would have worked out just fine that way.

2 Likes

Anyway, there’s probably no backing out of it at this point. I just hope there’s some support for migration.

Oh, that’s interesting, and good to know. I see that you can do something like this in the package manager:

pkg> add Example=7876af07-990d-54b4-ab0e-23690620f79a

I wonder what happens if you do

pkg> add Example

when there are two different Example packages in the registry. Hopefully it returns an ambiguity error. Although if that were the case, it would be massively disruptive to users if I registered my own DataFrames.jl package. :joy:

IIRC there are some options for disambiguation. Maybe the REPL prompts you asking which one you mean?

1 Like

In that case, I guess the argument for taking over Graphs.jl is so that users don’t have to type the following to install the new LightGraphs.jl:

pkg> add Graphs=093fc24a-ae57-5d10-9952-331d41423f4d

Of course they could have changed the name to something new like HeavyGraphs.jl, but given that LightGraphs.jl is the de facto standard for graphs in Julia, it makes some sense to take over the Graphs.jl name.

Hi @cscherrer, It looks like you are using Graphs.jl@v0.10, LightGraphs, MetaGraphs, and SimpleGraphs.jl all in the same package. I’m not clear on the internals of Soss, but it seems like we might be able to upstream some code to avoid the dependence on Graphs.jl@v0.10. From the Github search and reading the code, it looks like you are just using Graphs.jl@v0.10 to topologically sort instances of SimpleGraphs.AbstractSimpleGraphs. It might be easiest to upstream the topological_sort_by_dfs code from Graphs.jlv1.4.0 into SimpleGraphs.jl so that you don’t need Graphs.jl@v0.10.

Are there any other uses of Graphs@v0.10 that I’m not seeing?

6 Likes

Thanks @jpfairbanks . I think that might be it, but I haven’t worked on the graph stuff in a long time.

This might be a small part of the confusion. The (old) Graphs package was not renamed to OldGraphs. The only thing that changed name was the repository which originally hosted the Graphs package. You can see here that it still refers to the package as Graphs.

4 Likes

I had an old topo_sort function laying around, so I converted it to use SimpleGraphs.jl:

using SimpleGraphs

function topo_sort(g::SimpleDigraph{T}) where {T}
    g = deepcopy(g)
    order = T[]
    s = collect(filter(v -> in_deg(g, v) == 0, vlist(g)))

    while !isempty(s)
        u = pop!(s)
        push!(order, u)

        for v in out_neighbors(g, u)
            delete!(g, u, v)
            if in_deg(g, v) == 0
                push!(s, v)
            end
        end
    end

    if NE(g) > 0
        error("Graph contains cycles.")
    end

    order
end

Example 1

g = SimpleDigraph{String}()
add_edges!(g, [("a", "b"), ("a", "c"), ("b", "d"), ("c", "d")])
julia> topo_sort(g)
4-element Vector{String}:
 "a"
 "c"
 "b"
 "d"

Example 2

g2 = SimpleDigraph{String}()
add_edges!(g2, [("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")])
julia> topo_sort(g2)
ERROR: Graph contains cycles.
4 Likes

Tests are passing with this! Thanks @CameronBieganek

6 Likes

Just to try to clarify:

  • people using the old Graphs package don’t need to do anything as long as they have appropriate compat bounds on their dependencies; if you don’t, at a compat entry bounding Graphs < 1 (or just don’t update your dependencies)

  • people using LightGraphs also don’t have to do anything, you can just keep using LG <= 1.3.5 with no changes

  • only people who are using LightGraphs and want new features developed after 1.3.5 need to do anything: just remove LightGraphs as a dependency and add Graphs@1; then change “LightGraphs” in your code to “Graphs”; that’s it: Graphs 1.4.0 works exactly like LightGraphs 1.3.5 except for the name

6 Likes

Is that entirely true though?
It seems to me thatl LightGraphs have managed to change their name by coopting the previous Graphs package. This will not be a problem to users of the old Graphs, but it seems to be a problem to package authors who depend on the old Graphs, but who still want to allow their package users to use the new version of Graphs (really LightGraphs) in their projects with that package, right? Importantly, these people have been able to do that up until now.

3 Likes

This is exactly it. Luckily with @CameronBieganek 's help I was able to drop the Graphs dependency altogether, but without that it would have required some changes to migrate.

@jpfairbanks was kindly helping me with that, and fortunately seemed not too painful. But I think it’s important to be aware this use case could lead to some issues.

2 Likes

With any luck, @cscherrer is the only package author who depended on the old Graphs.jl. :wink:

However, I can’t verify that on JuliaHub now, since JuliaHub now shows the dependents of the new Graphs.jl, rather than the dependents of the old Graphs.jl.

1 Like

Chad had this problem only because he was using both Graphs and LightGraphs in the same codebase. We resolved the issue by eliminating an unnecessary complication in his code. If anyone else has a package that uses both Graphs and LightGraphs, I would be interested in learning why. We can probably add some features to help you avoid that complexity.

1 Like

Actually, that’s not correct. Chad was using the old Graphs.jl and Ed Scheinerman’s SimpleGraphs.jl, which is unrelated to LightGraphs.jl. The problem is what @mkborregaard said:

2 Likes

That’s correct. Because the new Graphs.jl uses the UUID of the old Graphs.jl, depending on one prevents downstream users from using the other. So for Soss (and I’d guess other packages) constraining to the old version was just not an option.

By moving entirely to SimpleGraphs internally, users are free to build Soss models with the new version of Graphs.

1 Like

@StefanKarpinski could you update this? Using a compat bound to the old Graphs.jl prevents downstream users from using the new Graphs.jl. Personally, I wouldn’t use any package that does this, it’s way too restrictive.

Sorry to put you on the spot, but it seems likely some people might see your summary and skip details of the discussion.