Skip to content

Commit d87bc9c

Browse files
committed
ci: add testing
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
1 parent 601fa07 commit d87bc9c

File tree

7 files changed

+67
-26
lines changed

7 files changed

+67
-26
lines changed

.github/workflows/ci.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ jobs:
3838
- uses: wntrblm/nox@2024.04.15
3939
- run: nox -s ${{ matrix.session }}
4040

41+
free-threading:
42+
runs-on: ${{ matrix.runs-on }}
43+
strategy:
44+
fail-fast: false
45+
matrix:
46+
runs-on: [ubuntu-latest, windows-latest]
47+
name: cibw on ${{ matrix.runs-on }}
48+
steps:
49+
- uses: actions/checkout@v4
50+
- uses: pypa/cibuildwheel@v2.18
51+
working-directory: projects/hello-free-threading
52+
env:
53+
CIBW_PRERELEASE_PYTHONS: True
54+
4155
pass:
4256
if: always()
4357
needs: [checks]

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ docs/_build
5656
# build output (testing)
5757
skbuild/cmake_test_compile/*
5858
*.env
59+
wheelhouse
60+
dist/*
5961

6062
# Generated manifests
6163
MANIFEST

noxfile.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"core-pybind11-hello",
1616
"hatchling-pybind11-hello",
1717
]
18+
if sys.version_info >= (3, 13):
19+
hello_list.append("hello-free-threading")
1820

1921

2022
@nox.session

projects/hello-free-threading/pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ build-backend = "scikit_build_core.build"
55
[project]
66
name = "freecomputepi"
77
version = "0.0.1"
8+
9+
[tool.cibuildwheel]
10+
build = "cp313*"
11+
free-threaded-support = true
12+
test-command = "pytest {project} --durations=0"
13+
test-requires = ["pytest"]

projects/hello-free-threading/src/freecomputepi/comp.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,25 @@
55

66
from ._core import pi
77

8-
num_trials = 10_000_000
8+
9+
def pi_in_threads(threads: int, trials: int) -> float:
10+
if threads == 0:
11+
return pi(trials)
12+
with ThreadPoolExecutor(max_workers=threads) as executor:
13+
return statistics.mean(executor.map(pi, [trials // threads] * threads))
914

1015

11-
def main():
16+
def main() -> None:
1217
parser = argparse.ArgumentParser()
1318
parser.add_argument("--threads", type=int, default=0)
19+
parser.add_argument("--trials", type=int, default=100_000_000)
1420
args = parser.parse_args()
15-
threads = args.threads
16-
start = time.monotonic()
17-
18-
if threads == 0:
19-
π = pi(num_trials)
20-
else:
21-
with ThreadPoolExecutor(max_workers=threads) as executor:
22-
π = statistics.mean(executor.map(pi, [num_trials // threads] * threads))
2321

22+
start = time.monotonic()
23+
π = pi_in_threads(args.threads, args.trials)
2424
stop = time.monotonic()
25-
print(f"{num_trials} trials, {π = }, {stop - start:.4} s")
25+
26+
print(f"{args.trials} trials, {π = }, {stop - start:.4} s")
2627

2728

2829
if __name__ == "__main__":

projects/hello-free-threading/src/freecomputepi/pure.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,40 @@
44
import time
55
from concurrent.futures import ThreadPoolExecutor
66

7-
num_trials = 10_000_000
87

9-
10-
def π(num_trials: int) -> float:
8+
def pi(trials: int) -> float:
119
Ncirc = 0
1210
ran = random.Random()
1311

14-
for _ in range(num_trials):
12+
for _ in range(trials):
1513
x = ran.uniform(-1, 1)
1614
y = ran.uniform(-1, 1)
1715

1816
test = x * x + y * y
1917
if test <= 1:
2018
Ncirc += 1
2119

22-
return 4.0 * (Ncirc / num_trials)
20+
return 4.0 * (Ncirc / trials)
21+
2322

23+
def pi_in_threads(threads: int, trials: int) -> float:
24+
if threads == 0:
25+
return pi(trials)
26+
with ThreadPoolExecutor(max_workers=threads) as executor:
27+
return statistics.mean(executor.map(pi, [trials // threads] * threads))
2428

25-
def main():
29+
30+
def main() -> None:
2631
parser = argparse.ArgumentParser()
2732
parser.add_argument("--threads", type=int, default=0)
33+
parser.add_argument("--trials", type=int, default=10_000_000)
2834
args = parser.parse_args()
29-
threads = args.threads
30-
start = time.monotonic()
31-
32-
if threads == 0:
33-
pi = π(num_trials)
34-
else:
35-
with ThreadPoolExecutor(max_workers=threads) as executor:
36-
pi = statistics.mean(executor.map(π, [num_trials // threads] * threads))
3735

36+
start = time.monotonic()
37+
π = pi_in_threads(args.threads, args.trials)
3838
stop = time.monotonic()
39-
print(f"{num_trials} trials, pi is {pi}, {stop - start:.4} s")
39+
40+
print(f"{args.trials} trials, {π = }, {stop - start:.4} s")
4041

4142

4243
if __name__ == "__main__":
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import freecomputepi.comp
2+
import freecomputepi.pure
3+
import pytest
4+
5+
6+
@pytest.mark.parametrize("threads", [0, 1, 2, 4])
7+
def test_pure(threads):
8+
π = freecomputepi.pure.pi_in_threads(threads, 10_000_000)
9+
assert π == pytest.approx(3.1415926535, rel=0.01)
10+
11+
12+
@pytest.mark.parametrize("threads", [0, 1, 2, 4])
13+
def test_comp(threads):
14+
π = freecomputepi.comp.pi_in_threads(threads, 100_000_000)
15+
assert π == pytest.approx(3.1415926535, rel=0.01)

0 commit comments

Comments
 (0)