-
Notifications
You must be signed in to change notification settings - Fork 5
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
Caching for attributes that allow it #123
Conversation
@cbourjau does this look legit? How can I ensure correctness (up for a pair-testing session!)? I'm seeing ~2x speedup in an end-to-end test that constructs, builds, and serializes a graph. |
That sounds very promising and looks like a great start! Assuming that the user never mutates these private objects, which correctness issues do you anticipate? I am certainly happy to have a pair-programming session! |
If you are worried about correctness, it would be sufficient to check if the cached AttributeProto has the same attribute name as requested, and otherwise it can be copied and a new name can be set on the copy. You shouldn't see any copies, and if they are necessary in some corner cases, they will be observable as a slight performance regression (perhaps a warning can be added if wanted). Maybe something like this would work: if self._last_onnx is None:
self._last_onnx = self._to_onnx_deref(key)
if self._last_onnx != key:
proto = onnx.AttributeProto()
proto.CopyFrom(self._last_onnx)
proto.name = key
self._last_onnx = proto
return self._last_onnx Why are the changes in |
Right now we are creating new |
The name/key is different when type checking: Line 53 in d59a999
As you can see, I'm completely ignoring it for now: Lines 61 to 67 in 0f109a1
Do you see any concrete problems with this, and can we add a test? |
Good point about the "dummy" keys used during the validation. The only worry I have about mutating the attribute is if its reference is hanging around elsewhere after a build call. Attributes will become part of Nodes when building. Thus, a test that reflects the real world would be if the attribute's name is updated in a import spox
from onnx import AttributeProto
from onnx.helper import make_node
attr = spox._attributes.AttrFloat32s([1., 2.])
attr_onnx = attr._to_onnx("foo")
node = make_node("FooNode", inputs=["bar"], outputs=["baz"])
node.attribute.append(attr_onnx)
assert node.attribute[0].name == "foo"
attr_onnx.name = "ZZZ"
assert node.attribute[0].name == "foo" The result is that |
For future reference: Simeon and I just discussed this issue. It is a bit scary to mutate the cached value with a user-provided name and it would be great to avoid doing that. To that end, we realized that the name is usually known from the start when creating the |
* At least tests pass, and that's something * Remove assert
7e4f6d7
to
e4388b3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Thanks for seeing this through! I think a performance boost like this warrants a mention in the changelog :) Can you add that please and then we are ready to merge!
Memory benchmarksI tried to memory benchmark with With caching:
Without caching
|
Each block in the benchmark shows results from re-running the same test? Either way, doesn't look as if things are out of control (which I didn't expect anyhow). I think this is good to go! Thanks! |
Checklist
CHANGELOG.rst
entry