[dynamo] fix reconstruct of ConvertSymintSource.
Labels: ciflow/trunk, release notes: fx, module: dynamo, ciflow/inductor, release notes: dynamo

Stack from [ghstack](https://github.com/ezyang/ghstack) (oldest at bottom):
* #109734
* __->__ #109916

**Motivation:**
dynamo produces optimized python byte code that calls the optimized graphs. Previously, the reconstruct method of ConvertIntSource uses the wrapped sym bool's reconstruct method, which is essentially accessing the symbool from inputs directly. However, the optimized graph that dynamo extracted expects input to be SymInt. This creates a inconsistency between what optimized byte code passes into optimized graph and what the optimized graph expects.

**Implementation:**
This PR fixes the reconstruct method of ConvertSymintSource by inserting the cast_symbool_to_symint_guardless call into the optimized python byte code so that before optimized graph is invoked, the SymBool has already been converted to SymInt. The implication is that when optimized python byte code is executed, a cast_symbool_to_symint_guardless call will be inserted right before calling the graph that dynamo traced. 

After this PR, for the following code :
```python
def true_fn(x):
    return x - x.cos()

def false_fn(x):
    return x + x.sin()

def foo(x):
    return cond(x.shape[0] == 4, true_fn, false_fn, [x])
gm = make_fx(foo, tracing_mode='symbolic')(torch.ones(3, 4))
```
In cond, we call torch.compile and dynamo extracts the following graph for cond:
```python
===== __compiled_fn_0 =====
<eval_with_key>.2 class GraphModule(torch.nn.Module):
   def forward(self, L_args_0_ : torch.SymInt, s1 : torch.SymInt, s2 : torch.SymInt, L_args_3_0_ : torch._subclasses.fake_tensor.FakeTensor):
       l_args_0_ = L_args_0_
       l_args_3_0_ = L_args_3_0_

       # File: /home/yidi/local/pytorch/torch/_dynamo/external_utils.py:17, code: return fn(*args, **kwargs)
       cond_true_0 = self.cond_true_0
       cond_false_0 = self.cond_false_0
       cond = torch.ops.higher_order.cond(l_args_0_, cond_true_0, cond_false_0, [l_args_3_0_]);  l_args_0_ = cond_true_0 = cond_false_0 = l_args_3_0_ = None
       return (cond,)

   class GraphModule(torch.nn.Module):
       def forward(self, l_args_3_0_):
           # File: /home/yidi/local/pytorch/test/functorch/test_control_flow.py:1538, code: return x - x.cos()
           cos = l_args_3_0_.cos()
           sub = l_args_3_0_ - cos;  l_args_3_0_ = cos = None
           return sub

   class GraphModule(torch.nn.Module):
       def forward(self, l_args_3_0_):
           # File: /home/yidi/local/pytorch/test/functorch/test_control_flow.py:1541, code: return x + x.sin()
           sin = l_args_3_0_.sin()
           add = l_args_3_0_ + sin;  l_args_3_0_ = sin = None
           return add
```

make_fx then runs the optimized code and produce a graph module like below:
```python
class foo(torch.nn.Module):
    def forward(self, x_1: f32[s0, s1]):
        # No stacktrace found for following nodes
        sym_size: Sym(s0) = torch.ops.aten.sym_size(x_1, 0)
        eq: Sym(Eq(s0, 4)) = sym_size == 4;  sym_size = None
        cast_symbool_to_symint_guardless: Sym(Piecewise((1, Eq(s0, 4)), (0, True))) = torch.ops.higher_order.cast_symbool_to_symint_guardless(eq);  eq = None
        true_graph_0 = self.true_graph_0
        false_graph_0 = self.false_graph_0
        conditional: f32[s0, s1] = torch.ops.higher_order.cond(cast_symbool_to_symint_guardless, true_graph_0, false_graph_0, [x_1]);  cast_symbool_to_symint_guardless = true_graph_0 = false_graph_0 = x_1 = None
        return conditional
        
    class <lambda>(torch.nn.Module):
        def forward(self, arg0_1: f32[s0, s1]):
            # No stacktrace found for following nodes
            cos: f32[s0, s1] = torch.ops.aten.cos.default(arg0_1)
            sub: f32[s0, s1] = torch.ops.aten.sub.Tensor(arg0_1, cos);  arg0_1 = cos = None
            return sub
            
    class <lambda>(torch.nn.Module):
        def forward(self, arg0_1: f32[s0, s1]):
            # No stacktrace found for following nodes
            sin: f32[s0, s1] = torch.ops.aten.sin.default(arg0_1)
            add: f32[s0, s1] = torch.ops.aten.add.Tensor(arg0_1, sin);  arg0_1 = sin = None
            return add
```

Before this PR, the optimized python byte code directly feed Eq into __compiled_fn_0. With this PR, we'll additionally call cast_symbool_to_symint_guardless to convert the SymBool to SymInt and feed the SymInt to __compiled_fn_0.


Additionally, we need to track this newly created SymInt in current ProxyTensorDispatchMode.sym_mode during make_fx so that this conversion is recorded in the graph. Otherwise, we won't be able to find the proxy of the SymInt in the tracer and throws an error when creating args in cond's ProxyTorchMode handling logic. We implemented a higher order op for this purpose.

**Test plan:**
See modified tests

cc @voznesenskym @penguinwu @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @Xia-Weiwen @wenzhe-nrv @jiayisunx @chenyang78 @aakhundov @kadeng