Conversation
| nodes = {} | ||
| edges = [] | ||
| ignored_nodes = set() | ||
| skipped_nodes = set() |
There was a problem hiding this comment.
Does skipped_nodes means nodes we still need to process?
There was a problem hiding this comment.
It means that we can rewire around them. That is, if we want to skip B in A -> B -> C we can avoid B and go straight from A -> C. This is useful when encountering + because in that case, we simply want circumvent + since, in NIR, two edges into the same node is exactly addition.
There was a problem hiding this comment.
Right, so the only thing on this one is that the variable name is kind-a confusing but this is stricktly personal preference. To me skipped hints to the ignore these nodes path, even if you already have the ignored_nodes set there.
There was a problem hiding this comment.
That's actually a good point. What would be a better name? "bypassed_nodes"? :)
There was a problem hiding this comment.
I was thinking more on something in the lines of "rewiring_nodes" or "postprocessed_nodes"
|
I've added a method to translate NIR graphs to Torch graphs using torch.fx. There are a few questions I would be curious to hear your opinion on:
|
chanokin
left a comment
There was a problem hiding this comment.
just a tiny observation in the _is_stateful and _construct_fx_graph functions.
| return tuple(node_outputs[a] for a, _ in input_nodes) | ||
|
|
||
|
|
||
| def _is_stateful(module: torch.nn.Module) -> bool: |
There was a problem hiding this comment.
Given that you have an "or" at the end, does this really ensure you have a "state" argument in the function? Just becaues _construct_fx_graph depends on this when you have a stateful function.
Also, how would you enforce this in customizations to the frameworks, for example, if John Doe creates a brand new AwesomeNeuron type for Norse, can you raise an exception if the forward method lacks the "state" argument?
I remember we talked about dictionaries making things easier to grab lists of available Nodes and to add custom nodes without needing to modify codebases for the packages (be it NIR, Norse or SNNTorch). I'm not entirely sure what the problem with the pointer to a function is? As long as you have somewhat fixed arguments, it's no biggie in my mind. All that being said, I think this is ready to fly! Minor adjustments could be dealt with later. |
pabogdan
left a comment
There was a problem hiding this comment.
It's difficult for me to say at the moment with confidence, but this looks good to me (superficially). Mapping such as these should enable more complex extensions / transforms as well if someone needs to implement those
| # Loop through all the nodes in the queue | ||
| while module_queue: | ||
| module_name, module = module_queue.popleft() | ||
| if recursion_counter[module_name] > 3: |
There was a problem hiding this comment.
Why is the counter set to 3 here? I would expect a single visit to a note is sufficient to disqualify it from looking at it any more
There was a problem hiding this comment.
3 is the third time around (note that the collections.Counter starts counting with 1). Technically, the worst case for the revisit is N - 1 if you have N modules: they could be listed in the opposite order, interchangeably. Here's an example in a simple graph 1 -> 2 -> 3. If the modules are listed in the order 3, 1, 2, the module 3 would re-queue to wait for module 2. Module 1 would be defined, but module 2 would have to wait again. The queue is now 3, 2, in which case module 3 would re-queue to wait for module 2.
The main problem is that we cannot see whether a module is defined without running the code. Having a set of traceable nodes is necessary to mark them as leaf nodes when processing them with torch.fx. We could let the user specify a set of modules in a separate datastructure, but that seems cumbersome... Thank you to @pabogdan and @chanokin for the comments! If you're ok with it, I'll merge it for now. We can always improve the code later if something needs changing |
This PR ports the graph tracing to torch.fx instead of using the homebrewed graph tracer.
TBC...