-
-
Notifications
You must be signed in to change notification settings - Fork 316
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
optimize the graph shape to not create sub-graphs when possible #724
base: master
Are you sure you want to change the base?
Conversation
Here is a corner case.
Every second, Is it worth to add the |
I do not know, but let's please definitely add this as a test =D If for weird examples like this we have a dynamic graph, it is okay. What's the |
Another corner case:
No higher-order functions this time. In order for
The hard step is (3), because the type
is not what we need. We need
is it worth implementing |
This case (or something that looks like it) seems more plausible, but still in the 20%. I think our goal for Let's add this as a test btw =D |
in the
it maps |
Yet another corner case. Lambdas are always constant, but in
the nested Actually, this might not be a corner case at all... The
would |
It thus looks like |
Hmmm... Is it still possible to do a The advantage of doing this in two steps are:
The down side is we have extra commits in master, but that just means more points! \o/ It will also give us a chance to briefly verify if the signature of SetScope:
Still makes sense or if this should be a single combined arg or something different. Actually a good question is: Are you currently happy/okay with the design of SetScope or is it broken in your mind as a stage? |
right, right, you want me to make these kinds of decisions on my own... I say we keep a single Except we make this speculative call from |
You're in charge, I'm meant to be here to complain if my spider sense goes off, or if I feel you're writing pure/functional code instead of elegant, imperative, faster golang code ;) |
Yes, if we give up on optimizing inside lambdas. |
So currently we use Value() here for printf... Does this mean that this is currently incorrect? Would we have to plumb through the sctx parameter? (This call happens during unification to inspect the format string.) mgmt/lang/funcs/core/fmt/printf_func.go Line 280 in 6a6546d
|
I'd try this:
I suspect that since Value doesn't have an sctx parameter, when printf calls |
Indeed there's an issue! Actually I found a sort-of related bug. Hmmm... Well here's the interesting point: plumbing through sctx would be very complicated... Which leads me to think that the more appropriate solution is one in which sctx is "captured" within the Expr AST node, so that we don't need to plumb it through the API... |
That would not work because the same Expr is used for several lambda calls. You can only store one sctx in the Expr itself, but you can pass a different sctx each time Graph() or Value() is called. |
Yes, but if we have to have an sctx inside of Unify, that means we need to plumb this into the unification engine... I feel like the right approach might involve an Initial Expr* whatever ast node, with it's own sctx, but then when it's used we copy it and have a new sctx contained within for each different Expr? Or something else? |
Remember, we used to do that, but we had to change course in order to support We can't do that with But we only create more Funcs, we don't create more Exprs! And we don't need to: lambdas are monomorphic, so the |
(I will add a patch to add that test in and add errors on those two nils.) |
More importantly for this MR, since
There is no need to add |
Here's the patch (just testing) Sort of related:
So btw for this test, with the dynamic printf enabled ( Why do I mention any of this? Because speculatively, I would expect this func to be run at compile time... |
(Merged in master.) |
Wait, do you want to evaluate statically-known expressions at compile-time or to generate a graph with no sub-graphs when possible? It's not the same thing! |
Huh, the code on this branch doesn't even compile? 7b5466e fails with
Instead of starting from a broken #716, I'll start from master. I'll cherry-pick from #716 later if that turns out to be useful for this MR. |
a83a075
to
c333cb5
Compare
I'm confused, why does this say that I have closed the PR?? Oh! I have reverted |
Oh, hm weird. Maybe I forgot to include something in my commit? if you need it LMK and I'll make sure it's working. |
I have created tests based on the counter-examples in this thread, let's see if GitHub will allow me to reopen the PR... |
caa6870
to
87c0967
Compare
Sorry I've been a bit AFK, I'm mid conferencing and gave my first presentation today. One more on Monday, and then a workshop on Wednesday =D Thanks for all your great work. Ping me for anything you're stuck on or busy work that you need me to refactor/golangify/etc. |
Me too, I was in NYC for work! I have also been elected as one of the administrators of my building, and it's taking a lot of time. I was actually working on mgmt to relax a bit from all that 😅
Woohoo! I hope everybody is as excited about mgmt as you were hoping!
Not a chance, focus on your conference! |
165 / 206 tests pass, not too bad but there is still a lot of work to do! |
up to 183 / 206! |
Sweet! Remember TestAstFunc1 doesn't matter since that's just shapes which
will change.
…On Sun, Feb 4, 2024, 05:02 Samuel Gélineau ***@***.***> wrote:
up to 183 / 206!
—
Reply to this email directly, view it on GitHub
<#724 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABA7M2S363NZG6VI4B52EDYR4B4PAVCNFSM6AAAAABAX2TBGKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMRVGU3TENBXGY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Oh, I didn't even look at TestAstFunc1, those are all TestAstFunc2 failures. Here's the next failure:
Since the problem only occurs when the function is called twice, I suspect that we're trying to Revert () the nodes added by the first call, so they're no longer available for the second call. |
up to 195 / 206! |
The next failure is
The test always generates the wrong Func graph, but it is non-deterministic, different runs generate different incorrect Func graphs: I am thus guessing that when we generate the static graph and capture it via the Txn which isn't connected to the engine, the code which generates the static graph spawns some threads and not all the nodes have been added by those threads when the graph is extracted from the Txn. |
I'm trying to think what would race there, that feels a bit unusual unless
there was something concurrent added in this branch. I'll look at the diff
tonight. Could there be a bug or an API mismatch somewhere in the TXN code?
I'll be back in a few days and on a regular hacking schedule again.
Thanks for your work here!
…On Sat, Feb 10, 2024, 22:37 Samuel Gélineau ***@***.***> wrote:
The next failure is chained-vars.txtar, slightly tweaked to make the
labels unique:
import "fmt"
$zero = 0
$one = $zero + 1
$two = $one * 2 # needs a chain to panic
test fmt.printf("%d%d%d", $zero, $one, $two) {}
The test always generates the wrong Func graph, but it is
non-deterministic, different runs generate different incorrect Func graphs:
failure1.png (view on web)
<https://github.com/purpleidea/mgmt/assets/49000/a0b0c147-0188-4b5f-9211-ec17025a4ea2>
failure2.png (view on web)
<https://github.com/purpleidea/mgmt/assets/49000/e9553b4e-865f-42f1-84c9-6cc233a0e3ef>
failure3.png (view on web)
<https://github.com/purpleidea/mgmt/assets/49000/fe4968df-62de-48d7-89ae-75a3b0af723c>
failure4.png (view on web)
<https://github.com/purpleidea/mgmt/assets/49000/96734ece-78b9-44af-9d12-ac7d4befed98>
failure5.png (view on web)
<https://github.com/purpleidea/mgmt/assets/49000/654e1b02-1041-495a-80c9-ec4631f58587>
failure6.png (view on web)
<https://github.com/purpleidea/mgmt/assets/49000/54f4c86e-6670-4184-aa05-72eed9bd7e8e>
I am thus guessing that when we generate the static graph and capture it
via the Txn which isn't connected to the engine, the code which generates
the static graph spawns some threads and not all the nodes have been added
by those threads when the graph is extracted from the Txn.
—
Reply to this email directly, view it on GitHub
<#724 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABA7M2A4YOILXARWGNZNNTYS7R73AVCNFSM6AAAAABAX2TBGKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZXGE4DSMZSGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I think the problem is as follows. For dynamic graphs, it is normal for a Func to hold onto the Txn and to use it to add more nodes asynchronously over time. For the optimization, I need the opposite: I need the |
I tested my hypothesis by sleeping for three seconds before extracting the graph for the Txn, but that did not fix the problem. Thus, it is not the case that the graph quickly reaches an equilibrium. Maybe it's not threads, but the random order in which the elements of a map are traversed? |
Let's see, so Then, Timeless or timefull, the optimization fires regardless, so the Everything so far seems to work as intended, since that Next, The What are the differences between the Another difference is that |
This jumped out at me... Is the pointer of _operator unique or is there a chance you forgot to copy it or something and it's actually the same operator pointer as previously used? If that's not it, then don't worry about this, we'll debug together after I look at the code more. I'm back in two days and I'll be focusing more on coding and not demoing/etc. Cheers |
I did forget initially, and one of the tests caught it, and that mistake has since been fixed. But who knows, maybe I fixed it incorrectly, just enough to fix that other test but not well enough to fix this one as well? Nah, there are clearly two |
Nope, same behaviour if I use |
Printing the graphs extracted from each Txn, I see some unexpected results. I expected the first Txn to contain 0, 1, There are thus two bugs and one source of non-determinism. The first bug is that each Txn contains the dependencies of the inputs, when they should only contain one node per input. The source of non-determinism is that only a subset of the spurious dependencies are added. Finally, the second bug is that the last Txn's graph seems to be the final graph, when instead the final graph should be the union of the graphs from all the Txn's. |
b8072b2
to
380004b
Compare
Working on #717