-
Notifications
You must be signed in to change notification settings - Fork 0
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
Tester prototype #83
Tester prototype #83
Conversation
Nice! I like the direction you've taken. Thanks for all of the effort you're putting into this. Sorry about the long wait on #30. |
…1 of cleaning up the pin specs. Instead of one giant test script, actually broke most of them up into independent test cases. The ones that aren't (list-like test and meta), I'm planning to make interfaces and test drivers for, so left them alone for now. That'll be part 2
Hi @coreyeng, sorry it took a while to look at this properly, awesome PR as always! Some random comments as a I read through it: No issue with Interesting point re The arch with a common frontend API with different backend generator targets is perfect. Awesome that you have allowed both Rust and Python-based generators. I don't really like the idea of AST mutation beyond appending new nodes, but on the other hand being able to modify the recent past was sometimes useful when creating drivers in O1. Great to see the OrigenSim target already stubbed out! On tester-specific stuff, the ability to add arbitrary meta data is powerful and a great feature, however for some ATE-specific features it would be good to see proper AST support too. I find the last comments about generator order a little confusing. If we have multiple targets then once one is done then the next one would start working on the master AST which should have been unmodified by the previous generator, then going on to do its own transformations. One comment on the API/AST is that I see you have a vector node, probably because we had it in O1. We should not have the concept of a vector in the top-level AST, only pin changes, cycles and timing information. Finally I have never seen PyTest crash when running with -s, which I do quite a lot. I am running on Linux though (well, WSL2 on Win10). |
Hi @ginty, thanks for the feedback!
It was really only an issue with users pretty new to programming overall or, in some smaller cases, an english-second-language thing of not fully grasping how the term I think most of the change requests are AST related, but just to point out again real quick that for all the AST stuff, this was only meant to be a stub so I could show some real examples of the tester and generators working. I fully expected this to be replaced when we knew more AST details, and actually thought this would be ripped out as a whole. Though, if the direction here is salvageable, I can definitely develop the AST some, it just wasn't my intention and I put very little effort it, outside of what I wanted to show with the generators.
Those were my thoughts as well, though I wasn't really sure what a user API might look like and what would be useful. Going with the above point though, I decided just to give them the entire AST to 'prove the point' rather than as a real feature. I think we can open a ticket to discuss what a manipulations a user should be able to do to the AST and I can build those in. The fact that I can give them the AST at all should mean that we can easily provide them functions instead and not run into borrower or conversion (between Python & Rust) issues.
Not currently in the way described, though that could be added. Currently, we could add whatever ATE-specifics we wanted and the generator could just choose to ignore it if its unsure what to do with the node type (for example, the OrigenSim stub ignores everything!), going along with your note of:
I was avoiding ATE specifics in the AST because I think it might over-complicate the AST. It seemed more straightforward for the ATE to instead shift in a generalized
Actually, there was no way in O1 to deal with this easily. It was actually due to the interceptors and callbacks iterating through the plugins which As for the context, my thought was if we wanted some sort of 'pre-processing' of the AST from the user's perspective, or other 'utility-like' generators, those could be loaded first, do their thing, then the actual generators would start up. I'm not sure how useful this would be (sounds like 'not very') and it was easier to add it now and remove later than vice-versa. Again, not being sure of how the AST will look in the end, I just wanted to be sure we could do these things, if the need arose. Regarding all the other AST/vector node comments, I agree, and I actually left off pin states for that reason and just focused on something simple, but would do something (even if just comment generation). I know you want to go with a more protocol-aware AST and only jump into actually driving pins if the generator necessitates it. Again, not sure how that would look and didn't put much thought into just a stubbed AST for prototyping but can definitely pick this up.
It originates in Anyway, what would be the next steps for this PR you'd like to see? Do you want to reuse the AST stuff in place here as kickstarter? Instead of a wholesale replacement, like I was expecting? |
If there are more pattern AST node types that you know could be used right away, I'd be happy to add those (can do fairly easily) to #48 while I'm working on making the connection between Python and Rust. |
…s out the original pin group/collection list indexing wasn't actually aligned with Python. Should be now that its moved to list-like API
@pderouen I'm not sure of what's all needed yet. I think in general adding new nodes as needed shouldn't be too bad. They'll probably a few times which we'll need to add new stuff. |
Hi @coreyeng, thanks for the quick and full reply. I've open up this ticket to discuss the environment thing, so we can take any further discussion on that over there - #88
OK, sounds good. In my view, I think its really just a negative offset argument that's required to a few key APIs, something like I do think we should have tester-specific AST nodes, just stuffing things in meta is just an informal way of doing the same thing - i.e. if the backend can generate something from it then it should be a formal API. Probably we need @pderouen's branch to be finished before we decide how we want to lay out the node definitions, so we don't need to decide it right now.
Yeah, I could definitely see that being useful and good you have added it.
As a reviewer it is pretty hard to envisage here exactly what is final intent and what is just placeholder/throwaway. I think we should discuss with @pderouen at this week's core team what the status and expectations for his branch are. What do you think? |
Hi @ginty, thanks for the additional feedback!
Not knowing exactly what's needed is why I'm always inclined to just provide everything. It may be I need a mentality switch since a compiled backend allows us immutably in anything not exposed, whereas all Ruby (or even all Python) allows full mutability via monkeypatching and metaprogramming, provided you know where to look, which is something I do quite a bit when I'm in a time crunch or someone is twiddling their thumbs waiting on an update from me. That said, I can take the current 'full-mutability' and start an API with the 'tester.capture' as a use case. Once that's in place, it should be pretty easy to additional things as it comes up and we can decide from there where to draw the line. I honestly don't know the answer, IMO there's arguments for both sides.
That's okay by me. I didn't go much into tester-specifics, but I also like
I thought the final intent was clear, so my mistake if it wasn't, but with this PR I wanted to show the Most of this wasn't meant to be ripped out, just a rudimentary base for us to build off of. For example, with this, I could start working on the entire source -> output process, where the StubAST in there now is transparent, allowing me to further develop while #30 is in development (or maybe I switch to trying to help out with that?).
I would normally agree with this, but I also think this project is early enough to where churn will be expected. Since its also a small dev team right now I'm not too concerned with conflicts, but if we let this stew for a while it'l become more and more of a "tester prototype + ..." (as it already has) as I'm building other stuff based on this. The TL;DR; I'm okay with all the above feedback and I really just wanted to PR the |
That sounds good, just saying that Origen should not do it that way for official APIs. Metadata should be for, well, metadata and maybe doubling as a get-out-of-jail system, but real data should be backed by real data structures.
Ha, yes I think you should if that's the case! So I am still a bit confused as to what you want to do here, as when I give feedback on the AST not being right you indicate that it is just a throwaway placeholder...
And then when I say, OK then, let's wait until we have the platform in place and do it properly you then say...
I do think it is good that we have two voices arguing for a different approach to this and probably the right way is somewhere down the middle. For me though, I still think we should align with @pderouen this week and then decide where we go from here. I don't think he is really that far away from having the AST platform being available. Then we decide the next level of foundation like where the common AST nodes and APIs are defined and where the ATE-specific nodes and APIs are defined. Add in a few examples and then hook that up to your generation infrastructure. |
Hi @ginty , thanks for the additional feedback!
The only thing I foresee as being ripped out and reworked completely is the actual StubAST structure. The available nodes here will need updating, but the structure and usage by generators should be similar. Or at least, that's what I'm proposing. On the PyAPI side, everything here and here would need to be updated with whatever the true nodes are, but I foresee the structure being the same. The pyclass was providing a fully-mutable representation and from previous discussions we'll move away for that and provide an API. I can begin working on that now though. But, everything save for the actual Hope that helps clear it up some!
That's fine, and normally I'd agree, but its still early stages and I don't think the stubbed stuff is ingrained. I purposefully tried to make that easily replaceable. My concern is that in order to continue to build up the generation portion I need the contents here and I wanted to have the tester API, generators, etc. etc. peer-reviewed, while glossing over the AST. This'll become and larger and larger PR (as it kinda has with the pin updates) if I keep going. If you're okay with this being a tester prototype + some other stuff PR, then I'm okay with leaving this open. I think the project is still small enough to where keeping this in sync with master shouldn't be a hassle. |
Hi @ginty, I think I've got this integrated with the proper AST from #92. I used the I changed the specs slightly to account for immutable ASTs, so the interceptors that were changing the nodes are no longer supported. The interceptors are still there though. I currently have them keying off of tester methods, but I wonder if they should be going off of the I also followed suite in using traits to implement the generators, replacing the On a different note, what would you think of renaming what I'm currently calling 'generators' to 'renderers' instead? |
Hi @coreyeng, this looks good and no issue with introducing the term See external comment needing clarification. |
Thanks! I'll update I updated the The only place I saw a problem with this was in the bit collection tests since they are run in multiple threads. I added a I changed the |
So, now that we think about it more deeply, I'm not sure that erroring on a lock is the right thing. |
Okay. I wasn't sure where we would try to parallelism, but if we do the AST transmutations in parallel or a divide-and-conquer certain processors, this will definitely get in the way. I think telling the difference between a transient lock and deadlock might actually be impossible. The best we could do is use the So, do you think we just go back to |
Hi @coreyeng, I think we should pretty much go back to
Areas to be careful:
|
Okay. We'll just have to watch during PRs that those are followed. The pyapi locking something then calling an underlying method is what I'm afraid of. In general you'd have to know both sides to know where the lock is occurring. In any case, I reverted the functions and bit collection tests. Should be the same as before now. |
Hi, There was bug in this PR regarding the targets: the default (no matter what it is) won't be found. I fixed this and while I was at it, I went ahead and just piled on most of what was asked for in #88. This updates the The standard I hope the help dialog is self-explanatory. One thing not mentioned there though is setting targets in other commands. I updated all the existing commands that accepted a target to instead accept a list of comma-separated targets: For example, The A bit more verbose, but also takes care of any resolution, though any failures to resolve should've gotten caught before this. I added each command calling In order to do this while reusing the I also tossed in some macros to print errors saying 'something went wrong in the backend'. I think later we can expand these to actually give a link to where to open a bug report or something along those lines, which I think would be nice since panics will often be development issues. Such as here, I think I hit everything asked for except for two spots:
|
Hi @coreyeng, nah let's just go ahead and merge this if you're ready - I've kinda lost track of what's in it tbh, but your target command update looks nice!
No big deal though. |
Thanks! Yeah, this definitely grew a bit out of control. I'll try to do better next time. I'll update the target command as well. The full paths ended up being a side effect of where I chose to do the name-cleansing. I'll switch it back and maybe add a |
Hello,
I've got a prototyped tester interface that I think is in good enough shape to start looking at. A few quick notes first in case anyone wants to pull it down:
StubAST
!) but these are just a proof of concept and are by no means complete. Eventually, all this stubbed stuff should be replaced with Pattern internals #30I went in a different direction than what we have for O1 (and as a result, xfailed this compiler test for the time being). All of this is open for discussion and I just kinda went with a gut feeling to start. Firstly,
origen.tester
is now 'always' available, with always in quotes because certain things may raise errors if, for example, a timeset hasn't been set. But, point is, it won't beNone
.The main reason for this is that inheritance is a bit trickier in Rust, then throwing frontend support on top of that lends itself better to an adaptor pattern than just straight inheritance (via
mixins
) that we usually work with in Ruby. Instead of having abase
which the O1 testers would inherit from, we have a topmost interface, which O2generators
will plug into. Now,origen.tester
provides a constant API to build up an AST and set and register generators. It’s thegenerators
responsibility now to produce some output, given the AST.The pattern source will more or less be a straight translation from O1. Given just the basic API, a simple pattern would still look like this.
Secondly, I've always had a heck of time trying to convince new users, especially those not very familiar with programming in general or with non-native English speakers, that setting Origen's
environment
is separate from the OS's environment itself (the platform they're running on, environment variables, etc.). Since we're going from the ground up, I instead dual-purposed thetarget
nomenclature, which I'm 50/50 on myself. When it comes time to actually generate the output, the frontend will iterate through all the targeted generators and produce an output for each one. I don't currently have anything using file IO, but I threw together a dummy V93K one that prints would-be comments and vectors to the console:I've got some test generators still floating around, but as we flush out the real ones we can remove the test ones.
So, that's the big thing. We now have a
tester
with some of the elementary O1 API working and are able to use the frontend to build up a dummy AST, and use a Rust-powered backend to generate some output.This use case is what I think will be the most prominent. Ideally, we'd keep all the generators in the backend and use the AST directly to produce an output. However, I think that'd be a little too naïve to only support that, so I added some extra features to make sure the structure is flexible for what I'm guessing would be feature requests that'd come up pretty quickly.
Frontend Generators
If needed, you can write a generator in the frontend, register it, and then use it like one in the backend. This'll allow generators to be prototyped or written completely without needing to know Rust and requiring new backend builds. This'll have some performance impact compared to generators that operate entirely in the backend, but that's to be expected. Anyway, here is an example of creating a frontend generator, and here's an example of registering and using it. Shown below as well:
As we move forward, these will need more context, like the filename to write, which would also come from the backend. Things like that can be easily added though with the given structure. We'd just be passing additional arguments, so it won't be structural problem.
Interceptors/Callbacks
An aspect that I also wanted to make sure we had was
callbacks/interceptors
from O1. OrigenSim just overrode thecycle
andcc
methods in O1, but that's easily doable in Rust. Instead, I added the callback/interceptor structure and used that. A test generator with some interceptors is available here, and would have this output when generated:Interceptors can be used similarly in the frontend as well:
One point of discussion is whether or not we want the interceptors to be able to mutate the AST. Currently, they can, both from the frontend and the backend. I did this 99% to make sure it was possible and that both the borrower checker and PyO3 would even allow such this to occur, and 1% because I think users should be able to. I actually think we shouldn't allow mutable AST access and should instead require them to throw in
meta
objects (covered next for the frontend), but I don't have "backend meta" working yet. Only on the frontend.For a practical example of the interceptors which doesn't mutate the AST, there's the dummy OrigenSim generator which would work in much the way it does now… hijack the calls to
cc
orcycle
, do its thing, but ultimately leave the AST untouched.Frontend Meta
I added
meta
support to the AST nodes, like I had for pins. I think this gives pretty much unlimited flexibility in that someone should be able to write a generator to do anything, no Rust experience required or even waiting for us to add additional features. Here's a generator which disregards the AST for the most part and instead uses only the node type and the meta objects attached to the node to generate an output. This isn't an overly practical approach, but its possible, which is all I was going for here. The output of this will look like:Targeted Generator Ordering
One thing to observe, and I did this on purpose, is that the generators will be run in the order in which they were targeted, allowing for
utility
generators to take effect first.For example, targeting the
PyTestGeneratorWithInterceptor
then theDummyGeneratorWithInterceptors
produce this output, while targeting them in reverse order produces this output. Notice the reversed order ofIntercepted By PyTestGeneratorWithInterceptor
andComment intercepted by DummyGeneratorWithInterceptors!
.Again, whether we allow the AST to be mutated like this in the long term is a discussion point, but this order dependency would apply to
meta
regardless.Other Notes
Just some additional things in this PR:
I've been using this in 0.8.5 and I've not noticed it causing any problems. I'm assuming this means the subclassing is fine in 9+, which I'm pretty sure they'll hit a non-alpha 0.9 before we're ready to release O2.
dut lock
, that's been fixed.config.field
that was seen before.-s
switch… but I'm not 100% sure. I've only noticed the crashes when running regressions and only during one of the generators. It seems too that when CPU usage is high, like when our IT decides to push new virus definitions every other hour or so and Symantec hijacks 50% of my CPU bandwidth for whatever TF its doing () its more likely to happen. I can't get anything consistent though, and I've never seen it happen when I don't use the-s
switch, so I'm assuming that's the cause (and, if so, its probably a windows-only thing). I also have never seen just the generaltester
usage fail, so I don't think its tied to the first bullet at all (the stack trace doesn’t show any pyo3 stuff also). But, if anyone notices it popping up, let me know, because I really want to know what's causing it if its not that.