Skip to content

Commit a267340

Browse files
authored
Split distribution operator test cases (#2609)
1 parent bf52906 commit a267340

6 files changed

Lines changed: 235 additions & 178 deletions

File tree

tests/test_bernoulli.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import pytest
2+
import torch
3+
4+
import flag_gems
5+
6+
from . import accuracy_utils as utils
7+
8+
9+
@pytest.mark.bernoulli_
10+
@pytest.mark.parametrize("shape", utils.DISTRIBUTION_SHAPES)
11+
@pytest.mark.parametrize("dtype", utils.FLOAT_DTYPES)
12+
def test_bernoulli_(shape, dtype):
13+
x = torch.empty(size=shape, dtype=dtype, device=flag_gems.device)
14+
p = 0.5
15+
with flag_gems.use_gems():
16+
x.bernoulli_(p)
17+
18+
# Check that all values are 0 or 1
19+
assert ((x == 0) | (x == 1)).all()
20+
21+
# Check that the mean is approximately p (statistical test)
22+
mean = x.float().mean().item()
23+
assert abs(mean - p) < 0.1
24+
25+
26+
@pytest.mark.bernoulli_
27+
@pytest.mark.parametrize("shape", utils.DISTRIBUTION_SHAPES)
28+
@pytest.mark.parametrize("dtype", utils.FLOAT_DTYPES)
29+
@pytest.mark.parametrize("p", [0.0, 0.3, 0.7, 1.0])
30+
def test_bernoulli_various_p(shape, dtype, p):
31+
x = torch.empty(size=shape, dtype=dtype, device=flag_gems.device)
32+
with flag_gems.use_gems():
33+
x.bernoulli_(p)
34+
35+
# Check that all values are 0 or 1
36+
assert ((x == 0) | (x == 1)).all()
37+
38+
# Check boundary cases
39+
if p == 0.0:
40+
assert (x == 0).all()
41+
elif p == 1.0:
42+
assert (x == 1).all()
43+
else:
44+
# Check that the mean is approximately p
45+
mean = x.float().mean().item()
46+
assert abs(mean - p) < 0.15

tests/test_distribution_ops.py

Lines changed: 0 additions & 178 deletions
This file was deleted.

tests/test_exponential.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import pytest
2+
import torch
3+
4+
import flag_gems
5+
6+
from . import accuracy_utils as utils
7+
8+
9+
@pytest.mark.exponential_
10+
@pytest.mark.parametrize("shape", utils.DISTRIBUTION_SHAPES)
11+
@pytest.mark.parametrize("dtype", utils.FLOAT_DTYPES)
12+
def test_exponential_(shape, dtype):
13+
x = torch.empty(size=shape, dtype=dtype, device=flag_gems.device)
14+
with flag_gems.use_gems():
15+
x.exponential_()
16+
17+
assert x.min() > 0
18+
19+
20+
@pytest.mark.exponential_
21+
@pytest.mark.parametrize("shape", utils.DISTRIBUTION_SHAPES)
22+
@pytest.mark.parametrize("dtype", utils.FLOAT_DTYPES)
23+
def test_accuracy_fast_exponential_(shape, dtype):
24+
x = torch.empty(size=shape, dtype=dtype, device=flag_gems.device)
25+
lambd = 1.0
26+
mean_tol = 0.05
27+
var_tol = 0.05
28+
with flag_gems.use_gems():
29+
x.exponential_()
30+
31+
x_res = utils.to_reference(x)
32+
mean_res = torch.mean(x_res.to(torch.float32)).to(dtype)
33+
var_res = torch.var(x_res.to(torch.float32)).to(dtype)
34+
mean_ref = 1.0 / lambd
35+
var_ref = 1.0 / (lambd**2)
36+
37+
assert torch.abs(mean_res - mean_ref) < mean_tol
38+
assert torch.abs(var_res - var_ref) < var_tol

tests/test_multinomial.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import random
22
import time
33

4+
import numpy as np
45
import pytest
6+
import scipy
57
import torch
68

79
import flag_gems
@@ -43,6 +45,26 @@ def test_multinomial_with_replacement(shape, dtype, n_samples):
4345
assert torch.sum(res_dist == 0) / res_dist.numel() < 0.001
4446

4547

48+
@pytest.mark.multinomial
49+
@pytest.mark.parametrize("shape", [(1024, 10)])
50+
@pytest.mark.parametrize("dtype", [torch.float16, torch.float32])
51+
@pytest.mark.parametrize("n_samples", [2048])
52+
def test_multinomial_with_replacement_1(shape, dtype, n_samples):
53+
# First use multinomial to generate a series of indices, then
54+
# use the index counts as the input probabilities (scaled)
55+
rand_indices = torch.multinomial(torch.rand(shape), n_samples, True).to(device)
56+
inp_counts = torch.nn.functional.one_hot(rand_indices).sum(1)
57+
with flag_gems.use_gems():
58+
out_indices = torch.multinomial(inp_counts.to(dtype=dtype), n_samples, True)
59+
out_counts = torch.nn.functional.one_hot(out_indices).sum(1)
60+
61+
# Do a simple Chi-square test
62+
assert torch.equal(inp_counts.sum(-1), out_counts.sum(-1))
63+
64+
_, pvalue = scipy.stats.chisquare(out_counts.tolist(), inp_counts.tolist(), axis=-1)
65+
assert np.sum(pvalue < 0.05) / len(pvalue) < 0.1
66+
67+
4668
@pytest.mark.multinomial
4769
@pytest.mark.parametrize("pool", utils.UT_SHAPES_2D)
4870
@pytest.mark.parametrize("dtype", utils.FLOAT_DTYPES)

0 commit comments

Comments
 (0)