Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ProblemGraph creation #3

Merged

Conversation

AntoinePrv
Copy link

@AntoinePrv AntoinePrv commented Sep 15, 2022

Hi @syslaila,

Here are some suggestions for mamba-org#1891. In the first commit, you'll find a proposal for a simplification of the ProblemGraph. I also included all utility classes inside the class to avoid saturating the mamba namespace.

In the last commit, I added a templated constructor (from_problems) that could be used in tests with generic data. I added another constructor (from_solver) that use it with the MSolver and MPool.
This is still a work in progress (everything is actually), but I think it provides good separation of concerns and encapsulation.
It does split the logic off adding problems and their dependencies in two separate functions in order to avoid a big template mess.
I don't yet have full visibility on whether it will work for all the logic we have (maybe some checks will be duplicated, hopefully not too many), but I wanted to share the idea. What do you think? I'll keep working on it tomorrow.

@AntoinePrv
Copy link
Author

@syslaila, here it was it would look like. What do you think?
I've abandoned the idea of having a constructor that would take a get generic list of problems, it was not worth the complexity. Instead there is a simple constructor that can take an already built graph and conflict map.

For testing the constructor, we'll have to build a local repo with some packages, the way we did it for PubGrub.
Then we can use the other constructor for testing the compression etc.

This is currently compiling. I'm happy to write some tests if we agree on this.

@crogoz
Copy link
Owner

crogoz commented Sep 19, 2022

For testing the constructor, we'll have to build a local repo with some packages, the way we did it for PubGrub.
Then we can use the other constructor for testing the compression etc.

This sounds good! 👍

// These functions do not return a reference so we make sure to
// compute the value only once.
// TODO change name of these functions to make explicit it is not a ref.
auto source = problem.source();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed in cases of a conflict for a "mamba install" command that these would sometimes segfault if the id is something invalid - we might need to test this again

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! problem.source() is an std::optional so if we can pinpoint a bug we should fix it in SolverProblem.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@syslaila if you have a reproducible example, I'm willing to investigate. Best would be if you can reproduce using libmamba/libmambapy from main and open a separate issue for it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll get an example today. However, I think we shouldn't block the merging of this PR on this since we don't support yet an "UPDATE" solver rule (and I think we would also need to filter out the ids from https://github.com/syslaila/mamba-fork/pull/3/files#diff-e214b9fbd2b0497c09f4b5738a8aec7bdb8f107f5c7e3415be65d12898fc91f3R267)

@AntoinePrv
Copy link
Author

TODO: Actually the problem_type is never filled, I need to add that

libmamba/src/core/satisfiability_error.cpp Outdated Show resolved Hide resolved
libmamba/src/core/satisfiability_error.cpp Outdated Show resolved Hide resolved
Comment on lines 245 to 337
auto src_id
= ensure_solvable(problem.source_id, std::move(source).value(), type);
auto tgt_id
= ensure_solvable(problem.target_id, std::move(target).value(), type);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though the type would be optional in this case - from https://github.com/syslaila/mamba-fork/pull/3/files#diff-e214b9fbd2b0497c09f4b5738a8aec7bdb8f107f5c7e3415be65d12898fc91f3R234. I wouldn't pass it here.
I would expect the problem_type to be different for the source package & the target package. Same in the other cases as well.

// These functions do not return a reference so we make sure to
// compute the value only once.
// TODO change name of these functions to make explicit it is not a ref.
auto source = problem.source();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll get an example today. However, I think we shouldn't block the merging of this PR on this since we don't support yet an "UPDATE" solver rule (and I think we would also need to filter out the ids from https://github.com/syslaila/mamba-fork/pull/3/files#diff-e214b9fbd2b0497c09f4b5738a8aec7bdb8f107f5c7e3415be65d12898fc91f3R267)

@AntoinePrv
Copy link
Author

@syslaila This is in a pretty good state structure-wise for you to look at. We have some tests running, but we are however printing warnings for unexpected optionals.

I am not so convinced with the approach consisting of having a large switch on SolverRuleinfo. I believe it will take time to get right and will be hard to maintain.
I suggest we try to infer what to do with nodes as much as possible (it does not cover 100% so we still need to check for some problem types) based on which optionals are empty.

https://github.com/AntoinePrv/mamba-error-reporting/blob/00ef5ce3b438df0bb508ff4f7f5d8504f39efc6d/src/mamba_error_reporting/algorithm.py#L86

https://github.com/AntoinePrv/mamba-error-reporting/blob/00ef5ce3b438df0bb508ff4f7f5d8504f39efc6d/src/mamba_error_reporting/algorithm.py#L135

I'm yet to add the conda-forge tests.

return std::nullopt;
}

class ProblemsGraphCreator
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we need to declare it in the header file in order to use it ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because we do not use it outside satisfiability_error.cpp. It's an implementation detail only used inside ProblemsGraph::from_solver but nowhere else.

auto ProblemsGraphCreator::add_conflict(node_id n1, node_id n2) -> void
{
m_conflicts[n1].insert(n2);
m_conflicts[n2].insert(n2);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
m_conflicts[n2].insert(n2);
m_conflicts[n2].insert(n1);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

auto parse_problems() -> void;
};

auto ProblemsGraphCreator::ensure_solvable(SolvId solv_id, node_t&& node) -> node_id
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the naming is confusing to me, I would use something like get_or_create_solvable but up to you

@crogoz
Copy link
Owner

crogoz commented Sep 29, 2022

This looks great, thanks Antoine!

We have some tests running, but we are however printing warnings for unexpected optionals.

I think we can switch this to a debug messages ?

I am not so convinced with the approach consisting of having a large switch on SolverRuleinfo. I believe it will take time to get right and will be hard to maintain.
I suggest we try to infer what to do with nodes as much as possible (it does not cover 100% so we still need to check for some problem types) based on which optionals are empty.

We can try it since you've done the proof of concept using the generalised approach. But yes, I think we need to do some filtering (we might also get extra packages from the solverRuleInfo eg. for solver_rule_pkg & solver_rule_job).
Should the filtering out of deps be part of this PR or another one ?

@AntoinePrv
Copy link
Author

I think we can switch this to a debug messages ?

I think we should get rid of all messages by fixing the code, otherwise it means our checks are not sync with what we get in practice. I haven't looked in details into the graph but perhaps it is missing some nodes.

We can try it since you've done the proof of concept using the generalised approach. But yes, I think we need to do some filtering (we might also get extra packages from the solverRuleInfo eg. for solver_rule_pkg & solver_rule_job).

I'll give it a go, see if does a better job.

Should the filtering out of deps be part of this PR or another one ?

Although I expect we'll find more issues down the road, we should fix all possible errors. I'll look into the graph see if there are missing nodes (not super convenient to do in C++ :( )

@crogoz crogoz merged commit ddea299 into crogoz:cr/problems-graph-creator Oct 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants