Repository navigation
[JIT] Refactor attributes to support buffers and parameters as first class citizens, add support for iterating over named_buffers() - #37905
Conversation
named_buffers()named_buffers()
💊 CI failures summary and remediationsAs of commit 436f389 (more details on the Dr. CI page):
ci.pytorch.org: 1 failedThis comment was automatically generated by Dr. CI (expand for details).Follow this link to opt-out of these comments for your Pull Requests.Please report bugs/suggestions on the GitHub issue tracker. This comment has been revised 126 times. |
suo
left a comment
There was a problem hiding this comment.
Some high level thoughts, haven't had a chance to look deeply:
- We should probably first tackle the change where we add buffers as a first-class concept on ClassType, separately from adding a
named_buffers()iterator. is_parameterandwas_registered_as_bufferare mutually exclusive. Conceivably there should be an enum that expresses the three types of tensor of attributes directly (parameters, buffers, regular attributes).
|
@suo - Good suggestion. Making it a first class citizen + adding an enum would let us have a single collection to manage what we have in each slot on ClassType. I'll go back to the drawing board and look at how we can cleanly manage all 3. Looking at it, perhaps we can remove attributeNames_, attributeTypes_ parameterSlots_, and instead have a single
Thoughts? |
|
Yeah I think that's a good overall direction. Some minor bits of context that may help guide the data structure decision:
|
…/refactor_class_type_attr
…pytorch into voznesenskym/named_buffers
named_buffers()named_buffers()
suo
left a comment
There was a problem hiding this comment.
Nice! This is definitely on the right track. I left a somewhat unusual number of bikeshedding comments—this is a core API so we want to get the naming/concepts consistent.
|
|
||
| size_t slot = attributes_.size(); | ||
|
|
||
| ATTRIBUTE_KIND_ENUM kind = ATTRIBUTE_KIND_ENUM::REGULAR_ATTRIBUTE; |
There was a problem hiding this comment.
Should we consider just making ATTRIBUTE_KIND_ENUM something that the user sets? Hiding allows some weird behavior. For example: right now you can call addAttribute and have something be both a parameter and buffer—this code would silently mark the attribute as a parameter.
There was a problem hiding this comment.
I'd rather keep it as a detail of our system, and then provide safeguards. Users already signal if something is a buffer or parameter by how they register it with our module.
There was a problem hiding this comment.
curious what happens in eager if someone registers the same name/value pair as a parameter and buffer…
There was a problem hiding this comment.
I'll add a test for this!
| torch.jit.script(f) | ||
|
|
||
|
|
||
| def named_buffers_are_iterable(self): |
There was a problem hiding this comment.
I think unittest expects test methods to start with test_?
| const SourceRange& loc, | ||
| Function& m); | ||
|
|
||
| std::shared_ptr<SugaredModuleDict> getSugaredNamedBufferDict( |
There was a problem hiding this comment.
Probably we should rename SugaredModuleDict something more general, to reflact that it is not just being used as for named_modules() anymore.
There was a problem hiding this comment.
Agreed. Any suggestions?
| return attributeType_; | ||
| } | ||
|
|
||
| const std::string getName() const { |
| type()->addOrCheckAttribute(name, TensorType::get()); | ||
| bool is_param = false; | ||
| bool is_buffer = true; | ||
| type()->addOrCheckAttribute(name, TensorType::get(), is_param, is_buffer); |
There was a problem hiding this comment.
Hmm…having a lot of boolean defaults in a row is getting a little scary. For example, there is a bug here, because you are actually setting is_param = false, allow_any = true, is_buffer=false, which is not what you want. I think either we should undefault them or change it to something more declarative than several flags
There was a problem hiding this comment.
Agreed. I know you said it earlier and I pushed back, but I find myself coming around to the idea of replacing it with our enum.
There was a problem hiding this comment.
I like your earlier suggestion of utilizing our enum. Since this would be a large (but relatively simple) change, are you fine with me moving the attribute adding APIs to the new enum in a subsequent diff?
There was a problem hiding this comment.
Yea, I thought I pushed a fix. will update.
| // attributes and parameters. | ||
| if (is_module) { | ||
| std::vector<std::string> params; | ||
| std::vector<std::string> buffers; |
There was a problem hiding this comment.
Nice! Before committing this, we'll have to test for forward compatibility. Basically, can you save() with buffers, then load() using a version of pytorch that does not understand buffer serialization.
Based on skimming the import code, I think there will be an FC issue. Let's chat directly about the steps to take here.
There was a problem hiding this comment.
Agreed, let me figure out the best way to do so.
| at::Tensor v, | ||
| bool is_buffer) { | ||
| type()->addOrCheckAttribute(name, TensorType::get(), !is_buffer); | ||
| type()->addOrCheckAttribute(name, TensorType::get(), !is_buffer, is_buffer); |
There was a problem hiding this comment.
Same here (is_buffer is being passed to allow_any)
There was a problem hiding this comment.
Yeah, will fix. Good catch.
suo
left a comment
There was a problem hiding this comment.
looks good! I recommend sanity-checking the FC changes manually if you haven't already.
|
FC tests completed via:
|
facebook-github-bot
left a comment
There was a problem hiding this comment.
@voznesenskym has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
|
@voznesenskym merged this pull request in f6f1384. |
First part of #36211 - still a WIP, but asking for commentary to ensure this is the direction we want to go in.