Skip to content

Commit 597324e

Browse files
authored
RNG Functionality Support (#145)
* rng library being generated and model almost done * rng interface integrated into sim * adding support to check for JOB_shotnum * integrated into build files to build pecos_rng_pcg * modified makefile to build pecos rng library across different envs * modified workflow to build rng lib * missed including nanobind explictly in Install build dependencies step * added docstrings and types to parameters and return type * pre-commit changes * more pre-commit changes * pre-commit green * fixed up github action * cleaned up makefile and how to pecos_rng library and modified github action to take account python version for cmake * pre-commit changes * added test case for rng * pre-commit changes for test * changed from unittest to pytest * modified ruff to ignore specific ruff check to assure appropriate building of png library * modified workflow to pick appropriate repo * github action chanegs * lib change didnt go through? fixing * moving stuff around for ci * forgot to fix sdist action * removed uv usage in release * removed uv for build_sdist_quantum_pecos * made changes to python-test to see if pecos rng is built proper * success with python-release action. Adding prefix path to cmake to see if can build with python-test * uv not finding paths properly running new cmmd * changes * moved things around for test * pre-commit changes * Workspace Makefile fix? ---------
1 parent a37facd commit 597324e

17 files changed

Lines changed: 461 additions & 15 deletions

File tree

.github/workflows/python-release.yml

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,16 @@ jobs:
198198
- name: Install pecos-rslib
199199
run: pip install ./pecos-rslib-wheel/*.whl
200200

201-
- name: Install build dependencies
201+
- name: Install pecos RNG build dependencies
202202
run: |
203-
python -m pip install --upgrade pip
204-
pip install build
203+
pip install build nanobind
204+
205+
- name: Build PECOS RNG
206+
run: |
207+
cd clibs/pecos-rng && mkdir build && cd build/ && cmake ..
208+
make && cd .. && pip install .
209+
env:
210+
NANOBIND_DIR: python -m nanobind --include_dir
205211

206212
- name: Build quantum-pecos SDist
207213
run: |
@@ -249,10 +255,16 @@ jobs:
249255
- name: Install pecos-rslib
250256
run: pip install ./pecos-rslib-wheel/*.whl
251257

252-
- name: Install build dependencies
258+
- name: Install pecos rng build dependencies
259+
run: |
260+
pip install build nanobind
261+
262+
- name: Build PECOS RNG
253263
run: |
254-
python -m pip install --upgrade pip
255-
pip install build
264+
cd clibs/pecos-rng && mkdir build && cd build/ && cmake ..
265+
make && cd .. && pip install .
266+
env:
267+
NANOBIND_DIR: python -m nanobind --include_dir
256268

257269
- name: Build quantum-pecos wheel
258270
run: |

.github/workflows/python-test.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,18 @@ jobs:
6969
uv lock --project .
7070
uv sync --project .
7171
72+
- name: Install pecos rng build dependencies
73+
run: |
74+
uv pip install build nanobind scikit-build-core cmake ninja
75+
76+
- name: Build PECOS RNG
77+
run: |
78+
export NANOBIND_CMAKE_DIR=$(uv run -- python -m nanobind --cmake_dir)
79+
export NANOBIND_DIR=$(uv run -- python -m nanobind --include_dir)
80+
cd clibs/pecos-rng && mkdir build && cd build/ && cmake .. -DCMAKE_PREFIX_PATH=$NANOBIND_CMAKE_DIR
81+
cmake --build . && cd ..
82+
uv pip install .
83+
7284
- name: Install pecos-rslib with maturin
7385
run: |
7486
cd python/pecos-rslib

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ dist/
3232
downloads/
3333
eggs/
3434
.eggs/
35-
lib/
3635
lib64/
3736
parts/
3837
sdist/
@@ -177,3 +176,7 @@ cython_debug/
177176
# and can be added to the global gitignore or merged into this file. For a more nuclear
178177
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
179178
.idea/
179+
180+
# Prevent subdirectory virtual environments
181+
clibs/*/.venv/
182+
clibs/*/uv.lock

Makefile

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
# Try to autodetect if python3 or python is the python executable used.
44
PYTHONPATH := $(shell which python 2>/dev/null || which python3 2>/dev/null)
5-
65
SHELL=bash
76

87
# Requirements
@@ -20,27 +19,37 @@ installreqs: ## Install Python project requirements to root .venv
2019
@echo "Installing requirements..."
2120
uv sync
2221

22+
.PHONY: buildrng
23+
buildrng:
24+
@echo "Building and installing RNG library..."
25+
uv pip install nanobind
26+
cd clibs/pecos-rng && CC=gcc CXX=g++ uv pip install --python $(shell uv run which python) -e .
27+
2328
# Building development environments
2429
# ---------------------------------
2530
.PHONY: build
2631
build: installreqs ## Compile and install for development
2732
@unset CONDA_PREFIX && cd python/pecos-rslib/ && uv run maturin develop --uv
33+
$(MAKE) buildrng
2834
@unset CONDA_PREFIX && cd python/quantum-pecos && uv pip install -e .[all]
2935

3036
.PHONY: build-basic
3137
build-basic: installreqs ## Compile and install for development but do not include install extras
3238
@unset CONDA_PREFIX && cd python/pecos-rslib/ && uv run maturin develop --uv
39+
$(MAKE) buildrng
3340
@unset CONDA_PREFIX && cd python/quantum-pecos && uv pip install -e .
3441

3542
.PHONY: build-release
3643
build-release: installreqs ## Build a faster version of binaries
3744
@unset CONDA_PREFIX && cd python/pecos-rslib/ && uv run maturin develop --uv --release
45+
$(MAKE) buildrng
3846
@unset CONDA_PREFIX && cd python/quantum-pecos && uv pip install -e .[all]
3947

4048
.PHONY: build-native
4149
build-native: installreqs ## Build a faster version of binaries with native CPU optimization
4250
@unset CONDA_PREFIX && cd python/pecos-rslib/ && RUSTFLAGS='-C target-cpu=native' \
4351
&& uv run maturin develop --uv --release
52+
$(MAKE) buildrng
4453
@unset CONDA_PREFIX && cd python/quantum-pecos && uv pip install -e .[all]
4554

4655
# Documentation
@@ -146,6 +155,12 @@ clean-unix:
146155
@find . -type d -name "junit" -exec rm -rf {} +
147156
@find python -name "*.so" -delete
148157
@find python -name "*.pyd" -delete
158+
@# Clean clibs build artifacts
159+
@find clibs -type d -name "build" -exec rm -rf {} +
160+
@find clibs -type d -name "dist" -exec rm -rf {} +
161+
@find clibs -type d -name "*.egg-info" -exec rm -rf {} +
162+
@find clibs -type d -name ".venv" -exec rm -rf {} +
163+
@find clibs -name "uv.lock" -delete
149164
@# Clean all target directories in crates (in case they were built independently)
150165
@find crates -type d -name "target" -exec rm -rf {} +
151166
@find python -type d -name "target" -exec rm -rf {} +
@@ -167,6 +182,12 @@ clean-windows-ps:
167182
@powershell -Command "Get-ChildItem -Path . -Recurse -Directory -Filter '.hypothesis' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue"
168183
@powershell -Command "Get-ChildItem -Path . -Recurse -Directory -Filter 'junit' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue"
169184
@powershell -Command "Get-ChildItem -Path python -Recurse -File -Include '*.so','*.pyd' | Remove-Item -Force -ErrorAction SilentlyContinue"
185+
@# Clean clibs build artifacts
186+
@powershell -Command "Get-ChildItem -Path clibs -Recurse -Directory -Filter 'build' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue"
187+
@powershell -Command "Get-ChildItem -Path clibs -Recurse -Directory -Filter 'dist' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue"
188+
@powershell -Command "Get-ChildItem -Path clibs -Recurse -Directory -Filter '*.egg-info' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue"
189+
@powershell -Command "Get-ChildItem -Path clibs -Recurse -Directory -Filter '.venv' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue"
190+
@powershell -Command "Get-ChildItem -Path clibs -Recurse -File -Filter 'uv.lock' | Remove-Item -Force -ErrorAction SilentlyContinue"
170191
@# Clean all target directories in crates
171192
@powershell -Command "Get-ChildItem -Path crates -Recurse -Directory -Filter 'target' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue"
172193
@powershell -Command "Get-ChildItem -Path python -Recurse -Directory -Filter 'target' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue"
@@ -187,6 +208,12 @@ clean-windows-cmd:
187208
-@for /f "delims=" %%d in ('dir /s /b /ad .hypothesis 2^>nul') do @rd /s /q "%%d" 2>nul
188209
-@for /f "delims=" %%d in ('dir /s /b /ad junit 2^>nul') do @rd /s /q "%%d" 2>nul
189210
-@for /f "delims=" %%f in ('dir /s /b python\*.so python\*.pyd 2^>nul') do @del "%%f" 2>nul
211+
-@REM Clean clibs build artifacts
212+
-@for /f "delims=" %%d in ('dir /s /b /ad clibs\build 2^>nul') do @rd /s /q "%%d" 2>nul
213+
-@for /f "delims=" %%d in ('dir /s /b /ad clibs\dist 2^>nul') do @rd /s /q "%%d" 2>nul
214+
-@for /f "delims=" %%d in ('dir /s /b /ad clibs\*.egg-info 2^>nul') do @rd /s /q "%%d" 2>nul
215+
-@for /f "delims=" %%d in ('dir /s /b /ad clibs\.venv 2^>nul') do @rd /s /q "%%d" 2>nul
216+
-@for /f "delims=" %%f in ('dir /s /b clibs\uv.lock 2^>nul') do @del "%%f" 2>nul
190217
-@REM Clean all target directories in crates
191218
-@for /f "delims=" %%d in ('dir /s /b /ad crates\target 2^>nul') do @rd /s /q "%%d" 2>nul
192219
-@for /f "delims=" %%d in ('dir /s /b /ad python\target 2^>nul') do @rd /s /q "%%d" 2>nul
@@ -201,10 +228,10 @@ pip-install-uv: ## Install uv using pip and create a venv. (Recommended to inst
201228
@echo "Creating venv and installing dependencies..."
202229
uv sync
203230

204-
.PONY: dev
231+
.PHONY: dev
205232
dev: clean build test ## Run the typical sequence of commands to check everything is running correctly
206233

207-
.PONY: devl ## Run the commands to make sure everything runs + lint
234+
.PHONY: devl ## Run the commands to make sure everything runs + lint
208235
devl: dev lint
209236

210237
# Help

clibs/pecos-rng/CMakeLists.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# CMakeLists.txt
2+
cmake_minimum_required(VERSION 3.15...3.27)
3+
project(pecos_rng LANGUAGES C CXX)
4+
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
5+
6+
7+
if (CMAKE_VERSION VERSION_LESS 3.18)
8+
set(DEV_MODULE Development)
9+
else()
10+
set(DEV_MODULE Development.Module)
11+
endif()
12+
13+
# Find Python (for Python 3.13)
14+
find_package(Python REQUIRED COMPONENTS Interpreter ${DEV_MODULE})
15+
16+
# Detect the installed nanobind package and import it into CMake
17+
# This executes a Python command to get the nanobind CMake directory
18+
execute_process(
19+
COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
20+
OUTPUT_STRIP_TRAILING_WHITESPACE
21+
OUTPUT_VARIABLE nanobind_ROOT
22+
)
23+
24+
set(CMAKE_PREFIX_PATH "${nanobind_ROOT}" ${CMAKE_PREFIX_PATH})
25+
26+
# This sets up nanobind
27+
find_package(nanobind CONFIG REQUIRED)
28+
29+
# Add your C source file as a library
30+
add_library(rng_pcg STATIC src/rng_pcg.c) # Compile test.c as a static library
31+
nanobind_add_module(pecos_rng src/wrapper.cpp)
32+
target_link_libraries(pecos_rng PRIVATE rng_pcg)
33+
# Install the module so it can be found by pip install
34+
install(TARGETS pecos_rng DESTINATION "pecos_pcg")

clibs/pecos-rng/README.md

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"""Python Package responsible for generating random numbers using pcg_rng."""
2+
3+
from .pecos_rng import (
4+
pcg32_boundedrand,
5+
pcg32_frandom,
6+
pcg32_random,
7+
pcg32_srandom,
8+
)
9+
10+
__all__ = ["pcg32_boundedrand", "pcg32_frandom", "pcg32_random", "pcg32_srandom"]

clibs/pecos-rng/pyproject.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[build-system]
2+
requires = ["scikit-build-core[pyproject]", "nanobind"]
3+
build-backend = "scikit_build_core.build"
4+
5+
[project]
6+
name = "pecos-pcg"
7+
version = "0.1.0"
8+
description = "A Python package with a nanobind-based C++ extension"
9+
license = { text = "MIT" }
10+
readme = "README.md"
11+
requires-python = ">=3.8"
12+
classifiers = [
13+
"Programming Language :: Python :: 3",
14+
"Programming Language :: C++",
15+
"License :: OSI Approved :: MIT License"
16+
]
17+
18+
[tool.scikit-build]
19+
wheel.packages = ["pecos_pcg"]
20+
# Optional: set cmake minimum version or other CMake arguments
21+
cmake.minimum-version = "3.18"
22+
cmake.verbose = true

clibs/pecos-rng/src/rng_pcg.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* PCG Random Number Generation for C.
3+
*
4+
* Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* For additional information about the PCG random number generation scheme,
19+
* including its license and other licensing options, visit
20+
*
21+
* http://www.pcg-random.org
22+
*/
23+
24+
#include <math.h>
25+
#include "rng_pcg.h"
26+
27+
// RNG state structure
28+
typedef struct pcg_state_setseq_64 {
29+
uint64_t state;
30+
uint64_t inc;
31+
} pcg32_random_t;
32+
33+
// global RNG state
34+
static pcg32_random_t pcg32_global = {
35+
0x853c49e6748fea9bULL,
36+
0xda3e39cb94b95bdbULL
37+
};
38+
39+
// default multi[plier]
40+
#define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL
41+
42+
// helper functions
43+
static inline uint32_t pcg_rotr_32(uint32_t value, unsigned int urot) {
44+
int rot = (int)urot;
45+
return (value >> rot) | (value << ((-rot) & 31));
46+
}
47+
48+
static inline void pcg_setseq_64_step_r(pcg32_random_t* rng) {
49+
rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc;
50+
}
51+
52+
static inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state) {
53+
return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u);
54+
}
55+
56+
static inline uint32_t pcg32_random_r(pcg32_random_t* rng) {
57+
const uint64_t oldstate = rng->state;
58+
pcg_setseq_64_step_r(rng);
59+
return pcg_output_xsh_rr_64_32(oldstate);
60+
}
61+
62+
static inline uint32_t pcg32_boundedrand_r(pcg32_random_t* rng, uint32_t ubound) {
63+
int32_t bound = (int32_t)ubound;
64+
uint32_t threshold = -bound % bound;
65+
for (;;) {
66+
const uint32_t r = pcg32_random_r(rng);
67+
if (r >= threshold)
68+
return r % bound;
69+
}
70+
}
71+
72+
static inline void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq) {
73+
rng->state = 0U;
74+
rng->inc = (initseq << 1u) | 1u;
75+
pcg_setseq_64_step_r(rng);
76+
rng->state += initstate;
77+
pcg_setseq_64_step_r(rng);
78+
}
79+
80+
// public interface to RNG
81+
82+
uint32_t pcg32_random() {
83+
return pcg32_random_r(&pcg32_global);
84+
}
85+
86+
uint32_t pcg32_boundedrand(uint32_t bound) {
87+
return pcg32_boundedrand_r(&pcg32_global, bound);
88+
}
89+
90+
double pcg32_frandom() {
91+
return ldexp(pcg32_random(), -32);
92+
}
93+
94+
void pcg32_srandom(uint64_t seq) {
95+
pcg32_srandom_r(&pcg32_global, 42u, seq);
96+
}

clibs/pecos-rng/src/rng_pcg.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* PCG Random Number Generation for C.
3+
*
4+
* Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* For additional information about the PCG random number generation scheme,
19+
* including its license and other licensing options, visit
20+
*
21+
* http://www.pcg-random.org
22+
*/
23+
24+
#pragma once
25+
26+
#include <stdint.h>
27+
28+
#if __cplusplus
29+
extern "C" {
30+
#endif
31+
32+
uint32_t pcg32_random();
33+
34+
uint32_t pcg32_boundedrand(uint32_t bound);
35+
36+
double pcg32_frandom();
37+
38+
void pcg32_srandom(uint64_t seq);
39+
40+
#if __cplusplus
41+
}
42+
#endif

0 commit comments

Comments
 (0)