Skip to content

Commit 301771d

Browse files
committed
Merge branch 'tile_rand' into 'main'
Support generating tiles of random numbers (GH-1010) See merge request omniverse/warp!1818
2 parents fd60557 + 437bb64 commit 301771d

File tree

7 files changed

+897
-0
lines changed

7 files changed

+897
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
compilation time. Lower levels may improve compile times but reduce run-time performance. It can be configured
3232
globally, or per-module using `wp.set_module_options({"optimization_level": #})`. Currently it only has an effect
3333
on GPU modules and only when using CUDA Toolkit 12.9 or newer ([GH-1084](https://github.com/NVIDIA/warp/issues/1084)).
34+
- Add `wp.tile_randi()` and `wp.tile_randf()` to support generating tiles of random numbers ([GH-1010](https://github.com/NVIDIA/warp/issues/1010))
3435
- Add `wp.mesh_query_ray_anyhit` for ray any-hit queries ([GH-1097](https://github.com/NVIDIA/warp/issues/1097)).
3536
- Add support for group-aware construction and queries for `wp.Mesh` ([GH-1097](https://github.com/NVIDIA/warp/issues/1097)):
3637
- New constructor argument: `groups` for per-face group IDs.

docs/modules/functions.rst

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,187 @@ Tile Primitives
19171917
:returns: A tile filled with the specified value
19181918

19191919

1920+
.. py:function:: tile_randi(shape: tuple[int, ...], rng: uint32, storage: str) -> Tile[Any,tuple[int, ...]]
1921+
1922+
.. hlist::
1923+
:columns: 8
1924+
1925+
* Kernel
1926+
1927+
Generate a tile of random integers.
1928+
1929+
:param shape: Shape of the output tile
1930+
:param rng: Random number generator state, typically from :func:`warp.rand_init`
1931+
:param storage: The storage location for the tile: ``"register"`` for registers
1932+
(default) or ``"shared"`` for shared memory.
1933+
:returns: A tile of random integers with the specified shape
1934+
1935+
Example:
1936+
1937+
.. testcode::
1938+
1939+
TILE_M, TILE_N = 2, 2
1940+
M, N = 2, 2
1941+
seed = 42
1942+
1943+
@wp.kernel
1944+
def rand_kernel(seed: int, x: wp.array2d(dtype=int)):
1945+
i, j = wp.tid()
1946+
rng = wp.rand_init(seed, i * TILE_M + j)
1947+
t = wp.tile_randi(shape=(TILE_M, TILE_N), rng=rng)
1948+
wp.tile_store(x, t, offset=(i * TILE_M, j * TILE_N))
1949+
1950+
x = wp.zeros(shape=(M * TILE_M, N * TILE_N), dtype=int)
1951+
wp.launch_tiled(rand_kernel, dim=[M, N], inputs=[seed, x], block_dim=32)
1952+
print(x.numpy())
1953+
1954+
.. testoutput::
1955+
1956+
[[ 798497746 1803297529 -955788638 17806966]
1957+
[ 1788185933 1320194893 2073257406 -2009156320]
1958+
[ -257534450 -1138585923 1145322783 -321794125]
1959+
[-2096177388 -1835610841 1159339128 -652221052]]
1960+
1961+
1962+
1963+
.. py:function:: tile_randi(shape: tuple[int, ...], rng: uint32, min: int32, max: int32, storage: str) -> Tile[Any,tuple[int, ...]]
1964+
:noindex:
1965+
:nocontentsentry:
1966+
1967+
.. hlist::
1968+
:columns: 8
1969+
1970+
* Kernel
1971+
1972+
Generate a tile of random integers within a specified range.
1973+
1974+
:param shape: Shape of the output tile
1975+
:param rng: Random number generator state, typically from :func:`warp.rand_init`
1976+
:param min: Minimum value (inclusive) for random integers
1977+
:param max: Maximum value (exclusive) for random integers
1978+
:param storage: The storage location for the tile: ``"register"`` for registers
1979+
(default) or ``"shared"`` for shared memory.
1980+
:returns: A tile of random integers in the range [min, max) with the specified shape
1981+
1982+
Example:
1983+
1984+
.. testcode::
1985+
1986+
TILE_M, TILE_N = 2, 2
1987+
M, N = 2, 2
1988+
seed = 42
1989+
1990+
@wp.kernel
1991+
def rand_range_kernel(seed: int, x: wp.array2d(dtype=int)):
1992+
i, j = wp.tid()
1993+
rng = wp.rand_init(seed, i * TILE_M + j)
1994+
t = wp.tile_randi(shape=(TILE_M, TILE_N), rng=rng, min=-5, max=5)
1995+
wp.tile_store(x, t, offset=(i * TILE_M, j * TILE_N))
1996+
1997+
x = wp.zeros(shape=(M * TILE_M, N * TILE_N), dtype=int)
1998+
wp.launch_tiled(rand_range_kernel, dim=[M, N], inputs=[seed, x], block_dim=32)
1999+
print(x.numpy())
2000+
2001+
.. testoutput::
2002+
2003+
[[ 1 4 3 1]
2004+
[-2 -2 1 1]
2005+
[ 1 -2 -2 -4]
2006+
[ 3 0 3 -1]]
2007+
2008+
2009+
2010+
.. py:function:: tile_randf(shape: tuple[int, ...], rng: uint32, storage: str) -> Tile[Any,tuple[int, ...]]
2011+
2012+
.. hlist::
2013+
:columns: 8
2014+
2015+
* Kernel
2016+
2017+
Generate a tile of random floats.
2018+
2019+
:param shape: Shape of the output tile
2020+
:param rng: Random number generator state, typically from :func:`warp.rand_init`
2021+
:param storage: The storage location for the tile: ``"register"`` for registers
2022+
(default) or ``"shared"`` for shared memory.
2023+
:returns: A tile of random floats in the range [0, 1) with the specified shape
2024+
2025+
Example:
2026+
2027+
.. testcode::
2028+
2029+
TILE_M, TILE_N = 2, 2
2030+
M, N = 2, 2
2031+
seed = 42
2032+
2033+
@wp.kernel
2034+
def rand_kernel(seed: int, x: wp.array2d(dtype=float)):
2035+
i, j = wp.tid()
2036+
rng = wp.rand_init(seed, i * TILE_M + j)
2037+
t = wp.tile_randf(shape=(TILE_M, TILE_N), rng=rng)
2038+
wp.tile_store(x, t, offset=(i * TILE_M, j * TILE_N))
2039+
2040+
x = wp.zeros(shape=(M * TILE_M, N * TILE_N), dtype=float)
2041+
wp.launch_tiled(rand_kernel, dim=[M, N], inputs=[seed, x], block_dim=32)
2042+
print(x.numpy())
2043+
2044+
.. testoutput::
2045+
2046+
[[0.1859147 0.41986287 0.7774631 0.00414598]
2047+
[0.41634446 0.3073818 0.4827178 0.53220683]
2048+
[0.9400381 0.73490226 0.26666623 0.9250764 ]
2049+
[0.51194566 0.57261354 0.26992965 0.8481429 ]]
2050+
2051+
2052+
2053+
.. py:function:: tile_randf(shape: tuple[int, ...], rng: uint32, min: float32, max: float32, storage: str) -> Tile[Any,tuple[int, ...]]
2054+
:noindex:
2055+
:nocontentsentry:
2056+
2057+
.. hlist::
2058+
:columns: 8
2059+
2060+
* Kernel
2061+
2062+
Generate a tile of random floats within a specified range.
2063+
2064+
:param shape: Shape of the output tile
2065+
:param rng: Random number generator state, typically from :func:`warp.rand_init`
2066+
:param min: Minimum value (inclusive) for random floats
2067+
:param max: Maximum value (exclusive) for random floats
2068+
:param storage: The storage location for the tile: ``"register"`` for registers
2069+
(default) or ``"shared"`` for shared memory.
2070+
:returns: A tile of random floats in the range [min, max) with the specified shape
2071+
2072+
Example:
2073+
2074+
.. testcode::
2075+
2076+
TILE_M, TILE_N = 2, 2
2077+
M, N = 2, 2
2078+
seed = 42
2079+
2080+
@wp.kernel
2081+
def rand_range_kernel(seed: int, x: wp.array2d(dtype=float)):
2082+
i, j = wp.tid()
2083+
rng = wp.rand_init(seed, i * TILE_M + j)
2084+
t = wp.tile_randf(shape=(TILE_M, TILE_N), rng=rng, min=-5.0, max=5.0)
2085+
wp.tile_store(x, t, offset=(i * TILE_M, j * TILE_N))
2086+
2087+
x = wp.zeros(shape=(M * TILE_M, N * TILE_N), dtype=float)
2088+
wp.launch_tiled(rand_range_kernel, dim=[M, N], inputs=[seed, x], block_dim=32)
2089+
print(x.numpy())
2090+
2091+
.. testoutput::
2092+
2093+
[[-3.140853 -0.80137134 2.7746308 -4.95854 ]
2094+
[-0.83655536 -1.9261819 -0.17282188 0.32206833]
2095+
[ 4.400381 2.3490226 -2.3333378 4.2507644 ]
2096+
[ 0.11945665 0.7261354 -2.3007035 3.481429 ]]
2097+
2098+
2099+
2100+
19202101
.. py:function:: tile_arange(*args: Scalar, dtype: Scalar, storage: str) -> Tile[Scalar,tuple[int]]
19212102
19222103
.. hlist::

docs/modules/tiles.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ Construction
204204
* :func:`tile_zeros`
205205
* :func:`tile_ones`
206206
* :func:`tile_full`
207+
* :func:`tile_randi`
208+
* :func:`tile_randf`
207209
* :func:`tile_arange`
208210
* :func:`tile`
209211
* :func:`untile`

warp/__init__.pyi

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2624,6 +2624,169 @@ def tile_full(shape: tuple[int, ...], value: Any, dtype: Any, storage: str) -> T
26242624
"""
26252625
...
26262626

2627+
@over
2628+
def tile_randi(shape: tuple[int, ...], rng: uint32, storage: str) -> Tile[Any, tuple[int, ...]]:
2629+
"""Generate a tile of random integers.
2630+
2631+
:param shape: Shape of the output tile
2632+
:param rng: Random number generator state, typically from :func:`warp.rand_init`
2633+
:param storage: The storage location for the tile: ``"register"`` for registers
2634+
(default) or ``"shared"`` for shared memory.
2635+
:returns: A tile of random integers with the specified shape
2636+
2637+
Example:
2638+
2639+
.. testcode::
2640+
2641+
TILE_M, TILE_N = 2, 2
2642+
M, N = 2, 2
2643+
seed = 42
2644+
2645+
@wp.kernel
2646+
def rand_kernel(seed: int, x: wp.array2d(dtype=int)):
2647+
i, j = wp.tid()
2648+
rng = wp.rand_init(seed, i * TILE_M + j)
2649+
t = wp.tile_randi(shape=(TILE_M, TILE_N), rng=rng)
2650+
wp.tile_store(x, t, offset=(i * TILE_M, j * TILE_N))
2651+
2652+
x = wp.zeros(shape=(M * TILE_M, N * TILE_N), dtype=int)
2653+
wp.launch_tiled(rand_kernel, dim=[M, N], inputs=[seed, x], block_dim=32)
2654+
print(x.numpy())
2655+
2656+
.. testoutput::
2657+
2658+
[[ 798497746 1803297529 -955788638 17806966]
2659+
[ 1788185933 1320194893 2073257406 -2009156320]
2660+
[ -257534450 -1138585923 1145322783 -321794125]
2661+
[-2096177388 -1835610841 1159339128 -652221052]]
2662+
2663+
"""
2664+
...
2665+
2666+
@over
2667+
def tile_randi(shape: tuple[int, ...], rng: uint32, min: int32, max: int32, storage: str) -> Tile[Any, tuple[int, ...]]:
2668+
"""Generate a tile of random integers within a specified range.
2669+
2670+
:param shape: Shape of the output tile
2671+
:param rng: Random number generator state, typically from :func:`warp.rand_init`
2672+
:param min: Minimum value (inclusive) for random integers
2673+
:param max: Maximum value (exclusive) for random integers
2674+
:param storage: The storage location for the tile: ``"register"`` for registers
2675+
(default) or ``"shared"`` for shared memory.
2676+
:returns: A tile of random integers in the range [min, max) with the specified shape
2677+
2678+
Example:
2679+
2680+
.. testcode::
2681+
2682+
TILE_M, TILE_N = 2, 2
2683+
M, N = 2, 2
2684+
seed = 42
2685+
2686+
@wp.kernel
2687+
def rand_range_kernel(seed: int, x: wp.array2d(dtype=int)):
2688+
i, j = wp.tid()
2689+
rng = wp.rand_init(seed, i * TILE_M + j)
2690+
t = wp.tile_randi(shape=(TILE_M, TILE_N), rng=rng, min=-5, max=5)
2691+
wp.tile_store(x, t, offset=(i * TILE_M, j * TILE_N))
2692+
2693+
x = wp.zeros(shape=(M * TILE_M, N * TILE_N), dtype=int)
2694+
wp.launch_tiled(rand_range_kernel, dim=[M, N], inputs=[seed, x], block_dim=32)
2695+
print(x.numpy())
2696+
2697+
.. testoutput::
2698+
2699+
[[ 1 4 3 1]
2700+
[-2 -2 1 1]
2701+
[ 1 -2 -2 -4]
2702+
[ 3 0 3 -1]]
2703+
2704+
"""
2705+
...
2706+
2707+
@over
2708+
def tile_randf(shape: tuple[int, ...], rng: uint32, storage: str) -> Tile[Any, tuple[int, ...]]:
2709+
"""Generate a tile of random floats.
2710+
2711+
:param shape: Shape of the output tile
2712+
:param rng: Random number generator state, typically from :func:`warp.rand_init`
2713+
:param storage: The storage location for the tile: ``"register"`` for registers
2714+
(default) or ``"shared"`` for shared memory.
2715+
:returns: A tile of random floats in the range [0, 1) with the specified shape
2716+
2717+
Example:
2718+
2719+
.. testcode::
2720+
2721+
TILE_M, TILE_N = 2, 2
2722+
M, N = 2, 2
2723+
seed = 42
2724+
2725+
@wp.kernel
2726+
def rand_kernel(seed: int, x: wp.array2d(dtype=float)):
2727+
i, j = wp.tid()
2728+
rng = wp.rand_init(seed, i * TILE_M + j)
2729+
t = wp.tile_randf(shape=(TILE_M, TILE_N), rng=rng)
2730+
wp.tile_store(x, t, offset=(i * TILE_M, j * TILE_N))
2731+
2732+
x = wp.zeros(shape=(M * TILE_M, N * TILE_N), dtype=float)
2733+
wp.launch_tiled(rand_kernel, dim=[M, N], inputs=[seed, x], block_dim=32)
2734+
print(x.numpy())
2735+
2736+
.. testoutput::
2737+
2738+
[[0.1859147 0.41986287 0.7774631 0.00414598]
2739+
[0.41634446 0.3073818 0.4827178 0.53220683]
2740+
[0.9400381 0.73490226 0.26666623 0.9250764 ]
2741+
[0.51194566 0.57261354 0.26992965 0.8481429 ]]
2742+
2743+
"""
2744+
...
2745+
2746+
@over
2747+
def tile_randf(
2748+
shape: tuple[int, ...], rng: uint32, min: float32, max: float32, storage: str
2749+
) -> Tile[Any, tuple[int, ...]]:
2750+
"""Generate a tile of random floats within a specified range.
2751+
2752+
:param shape: Shape of the output tile
2753+
:param rng: Random number generator state, typically from :func:`warp.rand_init`
2754+
:param min: Minimum value (inclusive) for random floats
2755+
:param max: Maximum value (exclusive) for random floats
2756+
:param storage: The storage location for the tile: ``"register"`` for registers
2757+
(default) or ``"shared"`` for shared memory.
2758+
:returns: A tile of random floats in the range [min, max) with the specified shape
2759+
2760+
Example:
2761+
2762+
.. testcode::
2763+
2764+
TILE_M, TILE_N = 2, 2
2765+
M, N = 2, 2
2766+
seed = 42
2767+
2768+
@wp.kernel
2769+
def rand_range_kernel(seed: int, x: wp.array2d(dtype=float)):
2770+
i, j = wp.tid()
2771+
rng = wp.rand_init(seed, i * TILE_M + j)
2772+
t = wp.tile_randf(shape=(TILE_M, TILE_N), rng=rng, min=-5.0, max=5.0)
2773+
wp.tile_store(x, t, offset=(i * TILE_M, j * TILE_N))
2774+
2775+
x = wp.zeros(shape=(M * TILE_M, N * TILE_N), dtype=float)
2776+
wp.launch_tiled(rand_range_kernel, dim=[M, N], inputs=[seed, x], block_dim=32)
2777+
print(x.numpy())
2778+
2779+
.. testoutput::
2780+
2781+
[[-3.140853 -0.80137134 2.7746308 -4.95854 ]
2782+
[-0.83655536 -1.9261819 -0.17282188 0.32206833]
2783+
[ 4.400381 2.3490226 -2.3333378 4.2507644 ]
2784+
[ 0.11945665 0.7261354 -2.3007035 3.481429 ]]
2785+
2786+
2787+
"""
2788+
...
2789+
26272790
@over
26282791
def tile_arange(*args: Scalar, dtype: Scalar, storage: str) -> Tile[Scalar, tuple[int]]:
26292792
"""Generate a tile of linearly spaced elements.

0 commit comments

Comments
 (0)