Implementation:AUTOMATIC1111 Stable diffusion webui Philox RNG
| Knowledge Sources | |
|---|---|
| Domains | Random_Number_Generation, Reproducibility |
| Last Updated | 2025-05-15 00:00 GMT |
Overview
Implements the Philox 4x32 counter-based random number generator with Box-Muller transform on CPU, replicating the exact output of torch.randn on CUDA devices for cross-device reproducibility.
Description
The Philox RNG module provides a pure NumPy implementation of the Philox 4x32 counter-based random number generator, matching the CUDA implementation used by PyTorch. The philox4_32 function runs 10 rounds of the Philox algorithm on a 4xN counter array and a 2xN key array (derived from the seed), producing 4xN pseudo-random 32-bit integers. The box_muller function transforms pairs of uniform random integers into standard normal random variables using the Box-Muller method, returning only the sine component. The Generator class provides a user-friendly interface: given a seed, it generates normally distributed random arrays of arbitrary shape via the randn method, maintaining an internal offset counter that increments with each call. This allows CPU-based generation that produces identical results to torch.randn(..., device='cuda'), enabling reproducible image generation regardless of the device used.
Usage
Use this module when you need to generate random noise tensors on CPU that exactly match the output of CUDA's random number generator, ensuring that the same seed produces the same image regardless of whether generation runs on CPU or GPU.
Code Reference
Source Location
- Repository: AUTOMATIC1111_Stable_diffusion_webui
- File: modules/rng_philox.py
- Lines: 1-102
Signature
def uint32(x: np.ndarray) -> np.ndarray
def philox4_round(counter: np.ndarray, key: np.ndarray) -> None
def philox4_32(counter: np.ndarray, key: np.ndarray, rounds: int = 10) -> np.ndarray
def box_muller(x: np.ndarray, y: np.ndarray) -> np.ndarray
class Generator:
def __init__(self, seed: int) -> None
def randn(self, shape: tuple) -> np.ndarray
Import
from modules.rng_philox import Generator
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| seed | int | Yes | The random seed, used as the Philox key |
| shape | tuple[int, ...] | Yes | Shape of the output random array |
| counter | np.ndarray | Yes | 4xN array of uint32 counter values (internal use) |
| key | np.ndarray | Yes | 2xN array of uint32 key values derived from the seed (internal use) |
| rounds | int | No | Number of Philox rounds (default 10) |
Outputs
| Name | Type | Description |
|---|---|---|
| result | np.ndarray | Array of standard normal random values with the requested shape (float32) |
Usage Examples
from modules.rng_philox import Generator
g = Generator(seed=42)
# Generate noise matching torch.randn output on CUDA
noise = g.randn(shape=(1, 4, 64, 64))
# Subsequent calls advance the internal offset
noise2 = g.randn(shape=(1, 4, 64, 64))