[WIP] Improved error handling for template instantiation#12449
[WIP] Improved error handling for template instantiation#12449bendavid wants to merge 15 commits into
Conversation
|
Starting build on |
b8e1515 to
1e89113
Compare
|
The failure to unload broken declarations (@jalopezg-git FYI), does that still happen after this PR, or is this addressed by the PR? I'm not sure I understand how much of the PR description describes this PR vs what's left to be done? |
Axel-Naumann
left a comment
There was a problem hiding this comment.
Thanks a lot for your work on this. Can you remind me what typical new failures would look like if instead we were to repeat the lookup without diagnostic suppression, in those cases where cppyy cannot find a suitable function to call?
|
All of the code example/output in the PR description corresponds to with this PR included. Repeating the lookup without diagnostic suppression doesn't give the correct error message again ie with superfluous debug output snipped out: So the relevant error message |
|
Failure for ubuntu20 build looks possibly unrelated to this PR. |
|
So in fact there is already a problem with rolling back the transaction even when just using test.h template <typename T>
class Helper {
public:
Helper() {}
std::size_t operator() () const {
const std::size_t res = 0;
res = T{0, 0}.size();
return res;
}
};
template <typename H>
std::size_t call_helper(const H &helper) {
return helper();
}testdeclare.py import ROOT
ret = ROOT.gInterpreter.Declare('#include "test.h"')
print("header include ret", ret)
print("creating helper")
helper = ROOT.Helper[ROOT.std.vector["double"]]()
bad_template = "template std::size_t call_helper<Helper<std::vector<double>>>(const Helper<std::vector<double>>&);"
for i in range(2):
print(f"declare attempt {i}")
ret = ROOT.gInterpreter.Declare(bad_template)
print("ret", ret)output: So again the error message is different/more obscure on the second attempt at explicit template instantiation. |
I don't know how this PR relates to the unloading issues in cling. What I saw in the past is that |
|
After modifying the logic to catch the error and fail the transaction rather than unloading the decl directly, repeated attempts at template instantiation from pyroot now behaves similarly to with TInterpreter::Declare. The remaining problems with incomplete rollback are almost certainly related to the issue which @jalopezg-git referred to, and can be fixed by his forthcoming PR. Still TODO for this PR: |
Test Results 22 files 22 suites 3d 19h 19m 38s ⏱️ For more details on these failures, see this check. Results for commit dee2fb7. ♻️ This comment has been updated with latest results. |
ac63baf to
59c2de3
Compare
2aa7e7a to
4e29a95
Compare
|
The failure in |
|
PR and description updated addressing also the diagnostic capture and printing. I'm still not totally sure about how the catching of errors and rollback of the transaction is handled in LookupHelper as said in the description. |
|
Any ideas on the remaining windows failure would also be welcome (it doesn't happen on linux and I don't have a windows setup to test with at the moment) |
jalopezg-git
left a comment
There was a problem hiding this comment.
Thanks for the contribution (and sorry for the delay in the review), @bendavid! 🙂 I have attached some comments to further improve the PR.
Regarding the unloading errors that I mentioned in one of my previous comments, I'll open a pull request soon.
|
Build failed on windows10/cxx14. Failing tests: |
|
I think this PR stalled for a while; perhaps we can give it a push and finally merge in the coming weeks? |
|
Yes ok I can come back to this next week. |
FYI, #13565 should fix the issues with unloading that I mentioned before in this PR! I still need to look at two test failures, but it's mostly there 🙂! |
@bendavid #13565 was recently merged into master. Provided that you have the time, you could rebase this PR and see how it works now. |
|
(Updated to fix code formatting) |
|
@wlav What do you think of the cppyy related changes? |
|
From a quick look: indentation is all over the place (4 -> 3; tabs; missing indentation) and some of the new error messages are very verbose, which will look bad on a simple Python command prompt. The addition of a do-nothing Of the new functionality, the diagnostics are probably fine, but some of the newly added error setting (e.g in Instantiate) may break tests (would have to see). The one thing that can't happen is |
|
@guitargeek I'm on vacation until Aug. 27. I can look at this again when I'm back, but you're also welcome to take this over. In case it helps I had rebased this on top of 6.34.04 a little while ago, so some of the conflicts may already be solved in https://github.com/bendavid/root/tree/v6-34-04-patches |
…ler errors and warnings during template instantiation
…available on all build platforms
…ed with jitted version of Book
8b22039 to
d9e2515
Compare
|
@bendavid I've taken the liberty of rebasing the branch on latest master, make some little adaptations to address review comments, and add a test. |
| R__WRITE_LOCKGUARD(ROOT::gCoreMutex); | ||
|
|
||
| const std::string diagnosticsold = diagnostics.str(); | ||
| TInterpreter::RedirectDiagnostics redirectRAII(gInterpreter, diagnostics, /*enableColors*/ true, /*indent*/ 4); |
There was a problem hiding this comment.
I wonder how this interacts with the future rebase of clingwrapper on top of CppInterop @aaronj0 @Vipul-Cariappa . Do we have similar infrastructure for retrieving interpreter diagnostics without leaking implementation details here?
There was a problem hiding this comment.
We currently do not have a way of doing this. But it should be relatively easy to implement. The question of "without leaking implementation details", not sure about that. If the question is: Can we propagate why a template instantiation fails? Yes, we propagate the reason.
There was a problem hiding this comment.
Maybe a clearer rephrasing of my question would be "can we obtain the same interpreter diagnostics in clingwrapper.cxx, without using any ROOT facility (i.e. R__WRITE_LOCKGUARD, ROOT::gCoreMutex, TInterpreter in this case), so that this diagnostic can become something generic and still give us the chance one day of outsourcing clingwrapper.cxx?"
There was a problem hiding this comment.
"can we obtain the same interpreter diagnostics in clingwrapper.cxx, without using any ROOT facility (i.e. R__WRITE_LOCKGUARD, ROOT::gCoreMutex, TInterpreter in this case)
The way I see it, we will still need the gCore mutex for the clingwrapper API to continue supporting ROOT threading model. Which is not a problem since we still link against Core in the design that migrates to InterOp.
so that this diagnostic can become something generic and still give us the chance one day of outsourcing clingwrapper.cxx
As Vipul mentioned, obtaining the diagnostic itself is not yet supported, but it can indeed be done generically, i.e., based on Clang's diagnostics engine (like this PR does). Based on that, I would comment that the right place for the very nice TClingDiagnosticsRAII implemented by this PR is probably CppInterOp, which solves the concern on whether this can be generalized and outsourced. In my view, clingwrapper is the one part that will/should contain ROOT-specific extensions on top of CppInterOp. @vgvassilev can comment on the changes in Cling's LookupHelper, but on first glance, that looks good to me.
One way to proceed is to keep the current approach and, as part of the migration, upstream the diagnostics from TCling to CppInterOp, and revert the changes in TInterpreter, since we can then interact with the Cpp::Interpreter directly. If the need for this PR is not immediate, the easier option is to revisit it on top of the migration PR. Ideally, we shouldn't grow further the interactions between Core and the interpreter via metacling for cppyy use cases. Apart from that, this PR heads in the right direction and proposes some quite nice additions.
|
Just to keep track of my advancements, here is my plan regarding this PR to address the problem properly while ensuring a sustainable transition:
This will require some more time 🚧 |
This is the first part of root-project#12449 Co-authored-by: Josh Bendavid <Josh.Bendavid@cern.ch>
This is the first part of root-project#12449 Co-authored-by: Josh Bendavid <Josh.Bendavid@cern.ch>
Two substantive changes:
This PR fixes #11854
There are still some remaining problems with the transaction rollback, however template instantiation from cppyy now behaves the same as calling
TInterpreter::Declarein this respect. This is likely related to the issues described by @jalopezg-git in #12449 (comment) and can be fixed in a future PR.Consider the following test case:
test.h:
test.py
The output below is now close to optimal for the first instantiation attempt. On the second instantiation attempt the error message is different/less useful because of the imperfect transaction rollback already noted. (but the same happens instantiating the template through
TInterpreter::Declareas said)(on the console the output also has the nice highlighting and colors one would normally get from clang diagnostic printing, see screenshot below)
Needless to say, taken together this constitutes a major improvement when trying to use complex templated code with pyroot/cppyy