fusesoc
fusesoc copied to clipboard
Improve error message for missing dependencies
When FuseSoC fails to satisfy the dependencies of a core it prints a confusing error message, coming directly from the internal solver e.g.
raise RuntimeError(msg.format(e.unsat.to_string(pool)))
RuntimeError: UNSATISFIABLE: Conflicting requirements:
Requirements: 'de0_nano == 0-0' <- 'non_existing_core >= 0-0'
+de0_nano-0-0 was ignored because it depends on missing packages
Requirements: 'de0_nano == 0-0'
Install command rule (+de0_nano-0-0)
This error should be made more user friendly to clearly indicate the problem
Recently this message seems to have got much worse. I'm not sure whether I'm doing something differently, or if something in fusesoc changed with the latest version.
Now the message doesn't even tell me which dependency is missing.
simplesat.errors.SatisfiabilityError: Conflicting requirements:
[-60]
[-43, 60]
[43]
This sounds like a step in the wrong direction :/
I can't reproduce it myself here. Maybe it's something that has changed upstream. Could you check the versions of simplesat and okonomiyaki. I'm using 0.8.0 and 0.16.9 here
Actually, I can reproduce it if I run transaction = solver.solve(request)
in coremanager.py
without catching the exception. I wonder if something goes wrong so that it doesn't catch it in your case. Do you get a full backtrace?
Sorry for my low quality bug report! The change that's causing me problems, and that I didn't describe well earlier, is that previously if a dependency was missing, the error message would tell me which dependency was missing. Now the error message just tells me which core has a missing dependency.
This means if a core has 10 dependencies I have to go through all 10, one by one to work out which might be causing problems. Usually it's because I've made a typo in a core name.
I think the message I used to take advantage of was in the SatisfiabilityError message, so when I got a Dependency error I could just scroll up to view that message. It seems likely that I was depending on SimpleSat error messages that have changed.
I've made an example commit showing a relevant situation: https://github.com/benreynwar/fusesoc/commit/131e1de29a8e98c798e80d01080ae6e9bc1a7932
Nowhere in the resultant error message is the missing core named.
Ah ok. I see what you mean now. I think you just need to catch the DependencyError in your code.
Something like this
def test_missing_deps():
flags = {
'flow': 'sim',
'tool': 'ghdl',
}
try:
cores = cm.get_depends(Vlnv('missing_deps'), flags=flags)
except DependencyError as e:
print(e.msg + "\nFailed to resolve dependencies for {}".format('missing_deps'))
Is that what you're looking for?
With from fusesoc.coremanager import CoreManager, DependencyError
Yes. But I still won't know which of the dependencies are missing. Previously I was able to see exactly which dependency was not satisfied. This error message will only tell me which core has a missing dependency.
On Tue, Aug 22, 2017 at 1:21 AM, Olof Kindgren [email protected] wrote:
With from fusesoc.coremanager import CoreManager, DependencyError
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/olofk/fusesoc/issues/153#issuecomment-323954597, or mute the thread https://github.com/notifications/unsubscribe-auth/AAX_BEqzAZ84JG7KMTu2G8CNCQCs7FBFks5sao9tgaJpZM4NWcYY .
Basically the problem is that e.msg which was taken from the SatisfiabilityError is no longer as informative as it used to be, because of changes in simplesat. I think that's what's going on.
On Tue, Aug 22, 2017 at 8:50 AM, Ben Reynwar [email protected] wrote:
Yes. But I still won't know which of the dependencies are missing. Previously I was able to see exactly which dependency was not satisfied. This error message will only tell me which core has a missing dependency.
On Tue, Aug 22, 2017 at 1:21 AM, Olof Kindgren [email protected] wrote:
With from fusesoc.coremanager import CoreManager, DependencyError
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/olofk/fusesoc/issues/153#issuecomment-323954597, or mute the thread https://github.com/notifications/unsubscribe-auth/AAX_BEqzAZ84JG7KMTu2G8CNCQCs7FBFks5sao9tgaJpZM4NWcYY .
I'm still a bit confused. Running the test here with my additions gives me
tests/test_missing_deps.py Conflicting requirements:
Requirements: 'missing_deps >= 0-0' <- 'doesnt_exist >= 0-0'
+missing_deps-0-0 was ignored because it depends on missing packages
Requirements: 'missing_deps >= 0-0'
Install command rule (+missing_deps-0-0)
Failed to resolve dependencies for missing_deps
Do you get something else (if so, which simplesat version do you have), or do I misunderstand something?
Sorry to bump a dormant issue, but I thought I might add my experience of these error messages in case it's helpful to anyone who comes across a similar issue. If I get time I might try looking into this myself as the following has just caused some unexpectedly long debug sessions!
The above discussion seems to focus on cores that don't exist in the FuseSoC libraries available to any given invocation of fusesoc
. I can easily recreate this with a simple core file and get the style of error @olofk mentions in the post above. For example:
CAPI=2:
name: ::missingdep:0.0.0
filesets:
rtl:
depend:
- ::notactuallyhere
targets:
default:
filesets: [rtl]
sim:
default_tool: modelsim
filesets: [rtl]
toplevel:
- nota.realcore
Which gives an error message indicating the problem, complete with a mention of "notactuallyhere":
Requirements: 'missingdep == 0.0.0-0' <- 'notactuallyhere >= 0-0'
+missingdep-0.0.0-0 was ignored because it depends on missing packages
Requirements: 'missingdep == 0.0.0-0'
Install command rule (+missingdep-0.0.0-0)
If I make the core more complex and have a single core file depend on another core that does exist, but at two different versions, there is also a good error message that indicates the version collision. For example:
CAPI=2:
name: ::conflictdep:0.0.0
filesets:
rtl:
depend:
- ::osvvm:2018.04
- ::osvvm:2020.01
targets:
default:
filesets: [rtl]
sim:
default_tool: modelsim
filesets: [rtl]
toplevel:
- nota.realcore
This direct conflict on two versions of OSVVM gives the error:
ERROR: Conflicting requirements:
Requirements: 'conflictdep == 0.0.0-0' <- 'osvvm == 2018.04-0, == 2020.01-0'
+conflictdep-0.0.0-0 was ignored because it depends on missing packages
Requirements: 'conflictdep == 0.0.0-0'
Install command rule (+conflictdep-0.0.0-0)
Failed to resolve dependencies for ::conflictdep
The problem seems to come when the conflicting dependencies do not belong in the same core. For example, imagine I have a top level core "diamonddep" that depends on two other cores "B" and "C". Each of these dependencies depends on a fourth core "D". In Core B, we need "D" at exactly version 1.0.0, whilst in core "C" we need "D" at exactly version 2.0.0. This is very similar to the conflict above, but when running FuseSoC the error message fails to convey that D == 1.0.0, 2.0.0
:
ERROR: Conflicting requirements:
Requirements: 'diamonddep == 0.0.0-0'
Install command rule (+diamonddep-0.0.0-0)
Failed to resolve dependencies for ::diamonddep:0.0.0
As the tree of dependencies grows increasingly complex, this message is not of any use in tracking down the problem core. I believe this is caused by simplesat
not providing a good error message in this case, but I don't know why. I did try a branch that used the SatisfiabilityErrorWithHint
approach instead of just SatisfiabilityError
but this did not improve anything.
Hopefully this might be useful in documenting a possible issue. If I get some time I will try to look into it.