Approach: we have matcher, voters, and candidates
- matchers map:
- functors to voters (by functor's opname)
- leaves to ScalarCand (if it is immutable and scalar)
- anything that is not matched to a voter or candidate has no candidate and marked as ANY
- voters are created by the parser, and only accept functor arguments voters generate a list of candidates based on the arguments, the list of candidates can be empty and marked as ANY
- candidates can be a scalar, an intermediate candidate, or a convertible candidate. when built:
- scalar candidates take a constant scalar node
- convertible candidates take on it's converted subgraph
- intermediate candidates do nothing Using the matcher, the optimizer makes a best attempt at mapping tensor to zero to many candidates. The optimizer is responsible for selecting the best candidates