Skip to content

gh-1145: Default to wrapping rng if backend is not known - #1169

Merged
paddyroddy merged 12 commits into
mainfrom
connor/1145-validate-rng
Jul 29, 2026
Merged

gh-1145: Default to wrapping rng if backend is not known#1169
paddyroddy merged 12 commits into
mainfrom
connor/1145-validate-rng

Conversation

@connoraird

@connoraird connoraird commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Description

  • Alters the existing glass.rng.Generator to allow it to wrap more than just NumPy RNGs.
  • Adds a new RNG protocol to ensure the wrapped rng in glass.rng.Generator defines the required methods.
  • Updates how rngs are handles within functions to ensure they always return the required array backend.

Closes: #1145

Changelog entry

Changed: glass.rng.Generator class now wraps returned values ensuring all methods return the correct array backend.

Checks

  • Is your code passing linting?
  • Is your code passing tests?
  • Have you added additional tests (if required)?
  • Have you modified/extended the documentation (if required)?
  • Have you added a one-liner changelog entry above (if required)?

@connoraird connoraird self-assigned this Jul 21, 2026
@connoraird connoraird added the array-api Work is related to the Array API label Jul 21, 2026
@connoraird
connoraird requested a review from paddyroddy July 21, 2026 09:23
@connoraird
connoraird force-pushed the connor/1145-validate-rng branch from 7b789f3 to e430a79 Compare July 21, 2026 09:23
@connoraird connoraird changed the title gh-1145: Default to wrapping rng if not backend not known gh-1145: Default to wrapping rng if backend is not known Jul 21, 2026
Comment thread tests/core/test_array_api_utils.py Outdated
Comment thread glass/galaxies.py
Comment thread glass/galaxies.py Outdated
Comment thread glass/rng.py Outdated
import glass.jax # noqa: PLC0415

return glass.jax.Generator(seed=seed)
return glass.jax.Generator(seed=seed) # ty: ignore[invalid-return-type]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be changing the output type above from UnifiedGenerator?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change it to what? An alternative is to keep UnifiedGenerator as it was and give this new protocol class a different name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the name of the protocol

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will have a look, but yes the alternative was some long-winded UnifiedGenerator | glass.jax.Generator | ... etc.

Comment thread glass/rng.py Outdated
Comment thread glass/rng.py
Comment thread glass/rng.py Outdated
Comment thread glass/rng.py Outdated
Comment thread glass/rng.py
Comment thread glass/points.py
@connoraird
connoraird requested a review from paddyroddy July 21, 2026 13:57
@connoraird

Copy link
Copy Markdown
Contributor Author

@paddyroddy I've made some significant changes after discovering a bug when adding the new tests with JAX.

@paddyroddy

Copy link
Copy Markdown
Member

@paddyroddy I've made some significant changes after discovering a bug when adding the new tests with JAX.

Okay, will have a look

Comment thread glass/rng.py
Comment thread glass/rng.py Outdated
assert isinstance(rng, glass.rng.Generator)


@pytest.mark.skipif(not HAVE_ARRAY_API_STRICT, reason="test requires array_api_strict")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are much better

Comment thread glass/jax.py
"""Draw samples from a multinomial distribution."""
# Ensure arrays are jax arrays
n = jnp.asarray(n)
pvals = jnp.asarray(pvals)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting that it's only these two methods that needed it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, it's needed because of the way we index pvals below pvals[..., 0]. I suppose n may not be necessary but it's a bit more complete.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although, maybe I'm misremembering as both instances are passing into _shape so that might be it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remind me why this change is needed now? Is it because we are now actually testing with JAX?

@connoraird

Copy link
Copy Markdown
Contributor Author

I've removed the Protocol class as I don't think it was actually doing anything. It definitely wasn't doing what I wanted which was restricting what RNGs could be passed to Generator

@connoraird
connoraird requested a review from paddyroddy July 28, 2026 09:15
@paddyroddy

Copy link
Copy Markdown
Member

I've removed the Protocol class as I don't think it was actually doing anything. It definitely wasn't doing what I wanted which was restricting what RNGs could be passed to Generator

Okay makes sense. Would be good if @ntessore could explain them to us a bit more 😅

@paddyroddy

Copy link
Copy Markdown
Member

Could have been a fluke, but the examples took more than 20 mins and failed. Looks like they usually take about 15 mins. Have re-run, otherwise we might have had a regression.

@paddyroddy paddyroddy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, see one comment on examples timing

Comment thread glass/rng.py
Comment on lines +94 to +104
if rng is None:
if xp.__name__ == "jax.numpy":
import glass.jax # noqa: PLC0415

self.rng = glass.jax.Generator(seed=seed)
else:
import numpy as np # noqa: PLC0415

self.rng = np.random.default_rng(seed=seed)
else:
self.rng = rng

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this logic is nice and clear now

@paddyroddy
paddyroddy merged commit 898c45a into main Jul 29, 2026
13 of 15 checks passed
@paddyroddy
paddyroddy deleted the connor/1145-validate-rng branch July 29, 2026 11:49
@paddyroddy

Copy link
Copy Markdown
Member

Examples took 21:00

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

array-api Work is related to the Array API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rng backend isn't validated

2 participants