Using RNG Generator in torch.compile

crizz: <p>Hi, I was trying to find some info on how random number generation works in torch compile. I have some code that generates quite often random numbers (an RL environment), and I am trying to speed everything up using compile, but I noticed calls to torch.rand  and similar introduce graph breaks when using the generator argument. Is there a way to avoid this? What is actually happening under the hood here?</p>
<p>Here is an example:</p>
<pre><code class="lang-auto">import torch as th

th._logging.set_logs(recompiles=True, graph_breaks=True)

rng = th.Generator(device="cuda")

@th.compile(mode="max-autotune")
def sum_random( a, b):
    br = th.randn((1,), device= "cuda")*b
    return a+br

@th.compile(mode="max-autotune")
def sum_random_rng( a, b):
    br = th.randn((1,), device= "cuda", generator = rng)*b
    return a+br


a = th.as_tensor([10.,20,30], device = "cuda")
b = th.as_tensor([1.,2,3], device= "cuda")
print("Without generator:")
print(sum_random(a,b))
print("With generator:")
print(sum_random_rng(a,b))

</code></pre>
<p>And the output (on torch 2.8.0) is:</p>
<pre><code class="lang-auto">Without generator:
tensor([ 8.9647, 17.9294, 26.8942], device='cuda:0')
With generator:
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks] Graph break in user code at /home/host/lr_ws/src/torch_rng_compile.py:19
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks] Graph Break Reason: Failed to convert args/kwargs to proxy
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks]   Explanation: Missing `as_proxy()` implementation for some arg/kwarg.
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks] 
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks] 
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks]   Developer debug context: call_function args: TupleVariable(length=1) ConstantVariable(str: 'cuda') UserDefinedObjectVariable(Generator)
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks] 
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks] User code traceback:
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks]   File "/home/host/lr_ws/src/torch_rng_compile.py", line 28, in &lt;module&gt;
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks]     print(sum_random_rng(a,b))
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks]   File "/home/host/lr_ws/src/torch_rng_compile.py", line 19, in sum_random_rng
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks]     br = th.randn((1,), device= "cuda", generator = rng)*b
V0819 16:18:25.308000 694852 torch/_dynamo/symbolic_convert.py:560] [1/0] [__graph_breaks] 
tensor([ 8.8488, 17.6975, 26.5463], device='cuda:0')
</code></pre>

ptrblck: <p>I believe this issue is tracked <a href="https://github.com/pytorch/pytorch/issues/88576">here</a> so feel free to share your use case in this GitHub issue.</p>

crizz: <p>Thanks, I dug a bit in the code starting from <a href="https://github.com/pytorch/pytorch/issues/88576" rel="noopener nofollow ugc">issue 88576</a> you linked, and it looks to me that things have been rearranged and support for Generators removed. This <a href="https://github.com/pytorch/pytorch/pull/109410" rel="noopener nofollow ugc">PR</a> removed the lines mentioned in issue 88576. From what I understand the current handling of random functions in dynamo is at <a href="https://github.com/pytorch/pytorch/blob/main/torch/_inductor/fx_passes/replace_random.py" rel="noopener nofollow ugc">replace_random.py</a> (see <a href="https://github.com/pytorch/pytorch/pull/100064" rel="noopener nofollow ugc">PR 100064</a>). And from what I understand Generators are not handled and only the global seed can be used, I’m not sure if there’s some alternative, or if there are further discussions somewhere, it would be nice to have some mechanism to manage an RNG or have some equivalent method.</p>