* Initial changes with comments on potential unit test changes.
* Update tests to disable TransposeOptimizer as that's simpler.
Add some extra comments.
Cleanup.
* Update comments in TransformGraph
* Add regression test.
Add limitation that transpose optimizer will ignore assigned nodes that do not match the context EP if that is set.
* Fix test. I removed a trailing Transpose after initial validation to simplify but that changed things so that the transpose optimizer didn't kick in, and the DQ -> Transpose -> Q was actually converted to a single Transpose by the CPU EP QDQ handling. Same end result in most builds so the subtle difference wasn't noticed, but in a build without contrib ops the CPU EP QDQ handling is disabled so the end result was different.
Update the test to re-instate the trailing Transpose so transpose optimizer alters the graph as desired.
* Don't run level 1 optimizers after partitioning as they don't guarantee to handle EP assignment for new nodes they create.
Add an optimizer that can remove leftover Q->DQ pairs. Depending on the model this may help with performance and/or improve accuracy. Optional as it could make things worse so user needs to be aware of this and test what works best for their scenario. Enable with SessionOptions config param `session.enable_quant_qdq_cleanup`
Update QDQ propagation transformer to insert new QDQ nodes instead of moving the existing one. This creates a more consistent `DQ -> op -> Q` pattern for other components to recognize.
Upgrade this transformer to a basic level optimization as it yields a valid ONNX graph.