Repository: pytorch
Issue: DOT/SVG Generation of Quantization Annotated FX Graphs Broken on 2.5.0.dev20240901
Labels: triaged,module: fx,oncall: pt2,oncall: fx,oncall: export

### 🐛 Describe the bug

During our FX based workflows, we generate DOT/SVG outputs of FX graphs during every stage of the process. On the latest PyTorch releases, the DOT generation of quantization annotated graphs seem to be broken. Here's a simple example code to reproduce this issue:

```python
import torch
import torch.nn as nn
from torch.ao.quantization.quantize_pt2e import prepare_pt2e
from torch.ao.quantization.quantizer.xnnpack_quantizer import (
    XNNPACKQuantizer, get_symmetric_quantization_config
    )
from torch.fx.passes.graph_drawer import FxGraphDrawer

# author a model.
class MLPNet(nn.Module):
    def __init__(self):
        super(MLPNet, self).__init__()
        self.conv1 = nn.Conv1d(2,4,3,padding=(1,1))
        self.relu1 = nn.ReLU()
        self.fc1 = nn.Linear(64, 64)
        self.relu1 = nn.ReLU()
        self.fc2 = nn.Linear(64, 32)
        self.relu2 = nn.ReLU()
        
    def forward(self, x, y):
        layer10 = self.relu1(self.fc1(x))
        layer11 = self.relu1(self.fc1(y))
        out = self.relu2(self.fc2(layer10 + layer11))
        return out
    
    def name(self):
        return "MLP"

model = MLPNet().eval()

# generate a uniform distribution of data.
n_batches = 100
# generate some example input.
x_in = torch.distributions.uniform.Uniform(-1, 1).sample([n_batches, 64, 64])

# export the model.
m_pre = torch.export.export(model, (x_in[0,:], x_in[0,:])).module()

# prepare annotated graph.
quantizer = XNNPACKQuantizer()
quantizer.set_global(get_symmetric_quantization_config())
m_annot = prepare_pt2e(m_pre, quantizer)

# generate DOT/SVG graphs.
g_dot = FxGraphDrawer(m_annot, "Model")
g_dot.get_dot_graph().write_raw("annotated_graph{}.dot".format(torch.__version__))
g_dot.get_dot_graph().write_svg("annotated_graph{}.svg".format(torch.__version__))

```
This  produces the following error:

```
$ python3 tests/repro/etorch_example.py

"dot" with args ['-Tsvg', '/tmp/tmphnnemdsx'] returned code: 1

stdout, stderr:
 b''
b"Error: /tmp/tmphnnemdsx: syntax error in line 5 near '.'\n"

Traceback (most recent call last):
  File "/<...>/tests/repro/etorch_example.py", line 49, in <module>
    g_dot.get_dot_graph().write_svg("annotated_graph{}.svg".format(torch.__version__))
  File "/opt/conda/envs/executorch/lib/python3.10/site-packages/pydot/core.py", line 177, in __write_method
    self.write(path, format=f, prog=prog, encoding=encoding)
  File "/opt/conda/envs/executorch/lib/python3.10/site-packages/pydot/core.py", line 1708, in write
    s = self.create(prog, format, encoding=encoding)
  File "/opt/conda/envs/executorch/lib/python3.10/site-packages/pydot/core.py", line 1825, in create
    assert process.returncode == 0, (
AssertionError: "dot" with args ['-Tsvg', '/tmp/tmphnnemdsx'] returned code: 1
```

When I compare the version of `.dot` files produced between the working (`2.5.0.dev20240618+cpu`) and not-working (`2.5.0.dev20240901`) versions, I see that the not-working version is missing quotes which the dot program doesn't seem to like.

Working:
```dot
"activation_post_process_1.eps" -> activation_post_process_1;
"activation_post_process_1.min_val" [fillcolor=Salmon, fontcolor="#000000", label="{buffer\ltorch.float32[]\n}", shape=record, style="filled,rounded"];
```

Not-Working:
```dot
activation_post_process_1.eps -> activation_post_process_1;
activation_post_process_1.min_val [label="{buffer\ltorch.float32[]\n}", fillcolor=Salmon, style="filled,rounded", fontcolor="#000000", shape=record];
```

My dot version is `12.0.0 (20240803.0821)`.

Please let me know if I can provide more information.


### Versions

PyTorch version: 2.5.0.dev20240901+cpu
Is debug build: False
CUDA used to build PyTorch: None
ROCM used to build PyTorch: N/A

OS: Debian GNU/Linux 11 (bullseye) (x86_64)
GCC version: (Debian 10.2.1-6) 10.2.1 20210110
Clang version: 11.0.1-2
CMake version: version 3.30.3
Libc version: glibc-2.31

Python version: 3.10.0 | packaged by conda-forge | (default, Nov 20 2021, 02:24:10) [GCC 9.4.0] (64-bit runtime)
Python platform: Linux-4.12.14-122.183-default-x86_64-with-glibc2.31
Is CUDA available: False
CUDA runtime version: No CUDA
CUDA_MODULE_LOADING set to: N/A
GPU models and configuration: No CUDA
Nvidia driver version: No CUDA
cuDNN version: No CUDA
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True

Versions of relevant libraries:
[pip3] executorch==0.4.0a0+6328d41
[pip3] numpy==1.26.4
[pip3] onnx==1.16.2
[pip3] torch==2.5.0.dev20240901+cpu
[pip3] torchaudio==2.5.0.dev20240901+cpu
[pip3] torchsr==1.0.4
[pip3] torchvision==0.20.0.dev20240901+cpu
[conda] executorch                0.4.0a0+6328d41          pypi_0    pypi
[conda] numpy                     1.26.4                   pypi_0    pypi
[conda] torch                     2.5.0.dev20240901+cpu          pypi_0    pypi
[conda] torchaudio                2.5.0.dev20240901+cpu          pypi_0    pypi
[conda] torchsr                   1.0.4                    pypi_0    pypi
[conda] torchvision               0.20.0.dev20240901+cpu          pypi_0    pypi


cc @ezyang @SherlockNoMad @EikanWang @jgong5 @wenzhe-nrv @avikchaudhuri @gmagogsfm @zhxchen17 @tugsbayasgalan @angelayi @suo @ydwu4 @penguinwu @chauhang