py2sess 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. py2sess-0.4.2/.github/workflows/cd.yml +113 -0
  2. py2sess-0.4.2/.github/workflows/ci.yml +98 -0
  3. py2sess-0.4.2/.github/workflows/release.yml +179 -0
  4. py2sess-0.4.2/.gitignore +23 -0
  5. py2sess-0.4.2/.pre-commit-config.yaml +15 -0
  6. py2sess-0.4.2/CMakeLists.txt +48 -0
  7. py2sess-0.4.2/LICENSE +674 -0
  8. py2sess-0.4.2/MANIFEST.in +27 -0
  9. py2sess-0.4.2/PKG-INFO +253 -0
  10. py2sess-0.4.2/README.md +210 -0
  11. py2sess-0.4.2/benchmarks/solar_jacobian_profile1/README.md +16 -0
  12. py2sess-0.4.2/benchmarks/solar_jacobian_profile1/fortran_jacobian_reference.npz +0 -0
  13. py2sess-0.4.2/benchmarks/solar_jacobian_profile1/rt_inputs.npz +0 -0
  14. py2sess-0.4.2/benchmarks/solar_jacobian_profile1/scene.yaml +4 -0
  15. py2sess-0.4.2/benchmarks/thermal_jacobian_profile1/README.md +15 -0
  16. py2sess-0.4.2/benchmarks/thermal_jacobian_profile1/fortran_jacobian_reference.npz +0 -0
  17. py2sess-0.4.2/benchmarks/thermal_jacobian_profile1/gas_xsec.nc +0 -0
  18. py2sess-0.4.2/benchmarks/thermal_jacobian_profile1/profile.csv +125 -0
  19. py2sess-0.4.2/benchmarks/thermal_jacobian_profile1/scene.yaml +19 -0
  20. py2sess-0.4.2/benchmarks/tir_profile1/README.md +17 -0
  21. py2sess-0.4.2/benchmarks/tir_profile1/aerosol_properties.nc +0 -0
  22. py2sess-0.4.2/benchmarks/tir_profile1/gas_xsec.nc +0 -0
  23. py2sess-0.4.2/benchmarks/tir_profile1/profile.csv +116 -0
  24. py2sess-0.4.2/benchmarks/tir_profile1/reference_outputs.npz +0 -0
  25. py2sess-0.4.2/benchmarks/tir_profile1/scene.yaml +24 -0
  26. py2sess-0.4.2/benchmarks/uv_profile1/README.md +17 -0
  27. py2sess-0.4.2/benchmarks/uv_profile1/aerosol_properties.nc +0 -0
  28. py2sess-0.4.2/benchmarks/uv_profile1/gas_xsec.nc +0 -0
  29. py2sess-0.4.2/benchmarks/uv_profile1/profile.csv +116 -0
  30. py2sess-0.4.2/benchmarks/uv_profile1/reference_outputs.npz +0 -0
  31. py2sess-0.4.2/benchmarks/uv_profile1/scene.yaml +25 -0
  32. py2sess-0.4.2/docs/api_arguments.md +127 -0
  33. py2sess-0.4.2/docs/full_spectrum_benchmarks.md +162 -0
  34. py2sess-0.4.2/docs/level_fluxes.md +116 -0
  35. py2sess-0.4.2/examples/_full_spectrum_benchmark_common.py +194 -0
  36. py2sess-0.4.2/examples/benchmark_scene_full_spectrum.py +386 -0
  37. py2sess-0.4.2/examples/build_thermal_source_from_temperature.py +28 -0
  38. py2sess-0.4.2/examples/compare_fortran_jacobian.py +494 -0
  39. py2sess-0.4.2/examples/level_flux_beer_lambert.py +61 -0
  40. py2sess-0.4.2/examples/retrieve_synthetic_spectra.py +261 -0
  41. py2sess-0.4.2/native/CMakeLists.txt +103 -0
  42. py2sess-0.4.2/native/csrc/loops.cuh +80 -0
  43. py2sess-0.4.2/native/csrc/native_bindings.cpp +324 -0
  44. py2sess-0.4.2/native/csrc/native_dispatch.cpp +2038 -0
  45. py2sess-0.4.2/native/csrc/native_dispatch.hpp +411 -0
  46. py2sess-0.4.2/native/csrc/native_dispatch_cuda.cu +766 -0
  47. py2sess-0.4.2/native/csrc/native_module.cpp +245 -0
  48. py2sess-0.4.2/native/csrc/native_module.hpp +44 -0
  49. py2sess-0.4.2/native/csrc/thermal_2s_impl.hpp +1859 -0
  50. py2sess-0.4.2/pyproject.toml +79 -0
  51. py2sess-0.4.2/scripts/analyze_delta_m_chain_rule.py +275 -0
  52. py2sess-0.4.2/scripts/benchmark_disotest_flux.py +2298 -0
  53. py2sess-0.4.2/scripts/benchmark_full_spectrum_rt.py +1702 -0
  54. py2sess-0.4.2/scripts/benchmark_level_flux_references.py +594 -0
  55. py2sess-0.4.2/scripts/benchmark_level_flux_speed_colab.py +515 -0
  56. py2sess-0.4.2/scripts/benchmark_paper_rt.py +2943 -0
  57. py2sess-0.4.2/scripts/build_paper_rt_timing_summary.py +287 -0
  58. py2sess-0.4.2/scripts/colab_a100_native_paper_benchmark.sh +77 -0
  59. py2sess-0.4.2/scripts/colab_build_native_cuda.py +136 -0
  60. py2sess-0.4.2/scripts/colab_native_cuda_smoke.py +412 -0
  61. py2sess-0.4.2/scripts/combine_oco3_replay_to_netcdf.py +237 -0
  62. py2sess-0.4.2/scripts/compare_pydisort_full_spectrum_flux.py +841 -0
  63. py2sess-0.4.2/scripts/create_hitran_opacity_table.py +335 -0
  64. py2sess-0.4.2/scripts/export_full_spectrum_benchmark_bundle.py +171 -0
  65. py2sess-0.4.2/scripts/export_jacobian_overhead_summary.py +271 -0
  66. py2sess-0.4.2/scripts/export_pydisort_full_spectrum_flux_nc.py +578 -0
  67. py2sess-0.4.2/scripts/generate_jacobian_validation_summary.py +457 -0
  68. py2sess-0.4.2/scripts/oco3_paper_support/rt_retrieval/.gitignore +2 -0
  69. py2sess-0.4.2/scripts/oco3_paper_support/rt_retrieval/README.md +11 -0
  70. py2sess-0.4.2/scripts/package_colab_repo.sh +32 -0
  71. py2sess-0.4.2/scripts/plot_paper_rt_benchmarks.py +860 -0
  72. py2sess-0.4.2/scripts/prepare_oco3_threeband_replay_cases.py +615 -0
  73. py2sess-0.4.2/scripts/run_full_benchmark_threads.sh +106 -0
  74. py2sess-0.4.2/scripts/run_oco3_paper_replay.py +203 -0
  75. py2sess-0.4.2/scripts/run_oco3_paper_replay_batch.py +294 -0
  76. py2sess-0.4.2/scripts/run_oco3_threeband_py2sess_replay.py +4724 -0
  77. py2sess-0.4.2/setup.py +55 -0
  78. py2sess-0.4.2/src/py2sess/__init__.py +163 -0
  79. py2sess-0.4.2/src/py2sess/api.py +5295 -0
  80. py2sess-0.4.2/src/py2sess/benchmarks/__init__.py +47 -0
  81. py2sess-0.4.2/src/py2sess/benchmarks/flux_references.py +529 -0
  82. py2sess-0.4.2/src/py2sess/benchmarks/kinetics_flux.py +142 -0
  83. py2sess-0.4.2/src/py2sess/data/__init__.py +1 -0
  84. py2sess-0.4.2/src/py2sess/data/benchmark/__init__.py +1 -0
  85. py2sess-0.4.2/src/py2sess/data/benchmark/tir_benchmark_fixture.npz +0 -0
  86. py2sess-0.4.2/src/py2sess/data/benchmark/tir_reference_outputs.npz +0 -0
  87. py2sess-0.4.2/src/py2sess/data/benchmark/uv_benchmark_fixture.npz +0 -0
  88. py2sess-0.4.2/src/py2sess/data/benchmark/uv_reference_outputs.npz +0 -0
  89. py2sess-0.4.2/src/py2sess/optical/__init__.py +95 -0
  90. py2sess-0.4.2/src/py2sess/optical/_hitran_numba.py +289 -0
  91. py2sess-0.4.2/src/py2sess/optical/brdf_solar_obs.py +515 -0
  92. py2sess-0.4.2/src/py2sess/optical/brdf_thermal.py +174 -0
  93. py2sess-0.4.2/src/py2sess/optical/delta_m.py +149 -0
  94. py2sess-0.4.2/src/py2sess/optical/delta_m_torch.py +78 -0
  95. py2sess-0.4.2/src/py2sess/optical/geocape.py +319 -0
  96. py2sess-0.4.2/src/py2sess/optical/hitran.py +663 -0
  97. py2sess-0.4.2/src/py2sess/optical/opacity_table.py +263 -0
  98. py2sess-0.4.2/src/py2sess/optical/phase.py +581 -0
  99. py2sess-0.4.2/src/py2sess/optical/phase_torch.py +302 -0
  100. py2sess-0.4.2/src/py2sess/optical/planck.py +582 -0
  101. py2sess-0.4.2/src/py2sess/optical/planck_torch.py +216 -0
  102. py2sess-0.4.2/src/py2sess/optical/properties.py +256 -0
  103. py2sess-0.4.2/src/py2sess/optical/properties_torch.py +249 -0
  104. py2sess-0.4.2/src/py2sess/optical/rayleigh.py +88 -0
  105. py2sess-0.4.2/src/py2sess/optical/scene.py +467 -0
  106. py2sess-0.4.2/src/py2sess/optical/scene_io.py +1147 -0
  107. py2sess-0.4.2/src/py2sess/optical/solar_reference.py +280 -0
  108. py2sess-0.4.2/src/py2sess/optical/surface_leaving.py +611 -0
  109. py2sess-0.4.2/src/py2sess/reference_cases.py +182 -0
  110. py2sess-0.4.2/src/py2sess/retrieval/__init__.py +23 -0
  111. py2sess-0.4.2/src/py2sess/retrieval/oe.py +355 -0
  112. py2sess-0.4.2/src/py2sess/rtsolver/__init__.py +60 -0
  113. py2sess-0.4.2/src/py2sess/rtsolver/backend.py +101 -0
  114. py2sess-0.4.2/src/py2sess/rtsolver/batch_accumulation.py +72 -0
  115. py2sess-0.4.2/src/py2sess/rtsolver/bvp_batch.py +576 -0
  116. py2sess-0.4.2/src/py2sess/rtsolver/bvp_batch_torch.py +1721 -0
  117. py2sess-0.4.2/src/py2sess/rtsolver/fo_flux.py +319 -0
  118. py2sess-0.4.2/src/py2sess/rtsolver/fo_solar_obs.py +1027 -0
  119. py2sess-0.4.2/src/py2sess/rtsolver/fo_solar_obs_batch_numpy.py +565 -0
  120. py2sess-0.4.2/src/py2sess/rtsolver/fo_solar_obs_batch_torch.py +486 -0
  121. py2sess-0.4.2/src/py2sess/rtsolver/fo_solar_obs_torch.py +598 -0
  122. py2sess-0.4.2/src/py2sess/rtsolver/fo_thermal.py +546 -0
  123. py2sess-0.4.2/src/py2sess/rtsolver/fo_thermal_torch.py +261 -0
  124. py2sess-0.4.2/src/py2sess/rtsolver/geometry.py +134 -0
  125. py2sess-0.4.2/src/py2sess/rtsolver/lattice_result.py +31 -0
  126. py2sess-0.4.2/src/py2sess/rtsolver/native_backend.py +551 -0
  127. py2sess-0.4.2/src/py2sess/rtsolver/preprocess.py +671 -0
  128. py2sess-0.4.2/src/py2sess/rtsolver/solar_obs_batch_numpy.py +870 -0
  129. py2sess-0.4.2/src/py2sess/rtsolver/solar_obs_batch_torch.py +802 -0
  130. py2sess-0.4.2/src/py2sess/rtsolver/solver.py +2156 -0
  131. py2sess-0.4.2/src/py2sess/rtsolver/solver_common.py +410 -0
  132. py2sess-0.4.2/src/py2sess/rtsolver/solver_torch.py +2213 -0
  133. py2sess-0.4.2/src/py2sess/rtsolver/taylor.py +172 -0
  134. py2sess-0.4.2/src/py2sess/rtsolver/taylor_torch.py +66 -0
  135. py2sess-0.4.2/src/py2sess/rtsolver/thermal_batch_numpy.py +985 -0
  136. py2sess-0.4.2/src/py2sess/rtsolver/thermal_batch_torch.py +886 -0
  137. py2sess-0.4.2/src/py2sess/scene.py +479 -0
  138. py2sess-0.4.2/tests/__init__.py +1 -0
  139. py2sess-0.4.2/tests/analytic_oracles.py +96 -0
  140. py2sess-0.4.2/tests/test_analytic_cases.py +656 -0
  141. py2sess-0.4.2/tests/test_api.py +2349 -0
  142. py2sess-0.4.2/tests/test_disotest_benchmark.py +208 -0
  143. py2sess-0.4.2/tests/test_flux_references.py +74 -0
  144. py2sess-0.4.2/tests/test_fortran_jacobian_validation.py +304 -0
  145. py2sess-0.4.2/tests/test_full_spectrum_benchmark.py +134 -0
  146. py2sess-0.4.2/tests/test_geocape_inputs.py +204 -0
  147. py2sess-0.4.2/tests/test_helper_parity.py +589 -0
  148. py2sess-0.4.2/tests/test_hitran_inputs.py +246 -0
  149. py2sess-0.4.2/tests/test_native_backend.py +508 -0
  150. py2sess-0.4.2/tests/test_opacity_table.py +184 -0
  151. py2sess-0.4.2/tests/test_optical_phase.py +460 -0
  152. py2sess-0.4.2/tests/test_optical_properties.py +177 -0
  153. py2sess-0.4.2/tests/test_optical_scene.py +269 -0
  154. py2sess-0.4.2/tests/test_reference_cases.py +776 -0
  155. py2sess-0.4.2/tests/test_retrieval.py +271 -0
  156. py2sess-0.4.2/tests/test_scene_io.py +725 -0
  157. py2sess-0.4.2/tests/test_solar_reference.py +223 -0
  158. py2sess-0.4.2/tests/test_thermal_source.py +200 -0
@@ -0,0 +1,113 @@
1
+ name: Auto Tag on PR Merge
2
+
3
+ on:
4
+ pull_request:
5
+ types: [closed]
6
+ branches: [main]
7
+
8
+ concurrency:
9
+ group: auto-tag-main
10
+ cancel-in-progress: false
11
+
12
+ jobs:
13
+ create-tag:
14
+ if: ${{ github.event.pull_request.merged == true }}
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: write
18
+ pull-requests: read
19
+
20
+ steps:
21
+ - name: Checkout code
22
+ uses: actions/checkout@v5
23
+ with:
24
+ fetch-depth: 0
25
+
26
+ - name: Determine next version
27
+ id: next_version
28
+ env:
29
+ LABELS_JSON: ${{ toJson(github.event.pull_request.labels) }}
30
+ run: |
31
+ EXISTING_TAG=$(git tag --points-at HEAD | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || true)
32
+ if [[ -n "$EXISTING_TAG" ]]; then
33
+ echo "skip_bump=true" >> "$GITHUB_OUTPUT"
34
+ echo "tag=$EXISTING_TAG" >> "$GITHUB_OUTPUT"
35
+ echo "version=${EXISTING_TAG#v}" >> "$GITHUB_OUTPUT"
36
+ exit 0
37
+ fi
38
+
39
+ BUMP_TYPE=$(python3 - <<'PY'
40
+ import json
41
+ import os
42
+
43
+ labels = {item["name"] for item in json.loads(os.environ["LABELS_JSON"])}
44
+ selected = [
45
+ name.split(":", 1)[1]
46
+ for name in ("release:major", "release:minor", "release:patch")
47
+ if name in labels
48
+ ]
49
+ if len(selected) > 1:
50
+ raise SystemExit(f"multiple release labels found: {', '.join(selected)}")
51
+ print(selected[0] if selected else "patch")
52
+ PY
53
+ )
54
+
55
+ LATEST=$(git describe --tags --abbrev=0 || echo "v0.0.0")
56
+ MAJOR=$(echo "$LATEST" | cut -d. -f1 | sed 's/v//')
57
+ MINOR=$(echo "$LATEST" | cut -d. -f2)
58
+ PATCH=$(echo "$LATEST" | cut -d. -f3)
59
+
60
+ case "$BUMP_TYPE" in
61
+ major)
62
+ MAJOR=$((MAJOR+1))
63
+ MINOR=0
64
+ PATCH=0
65
+ ;;
66
+ minor)
67
+ MINOR=$((MINOR+1))
68
+ PATCH=0
69
+ ;;
70
+ patch)
71
+ PATCH=$((PATCH+1))
72
+ ;;
73
+ *)
74
+ echo "Unsupported bump type: $BUMP_TYPE"
75
+ exit 1
76
+ ;;
77
+ esac
78
+
79
+ while true; do
80
+ NEXT_VERSION="${MAJOR}.${MINOR}.${PATCH}"
81
+ NEXT_TAG="v${NEXT_VERSION}"
82
+ if ! git ls-remote --tags origin "refs/tags/${NEXT_TAG}" | grep -q "refs/tags/${NEXT_TAG}$"; then
83
+ break
84
+ fi
85
+ PATCH=$((PATCH+1))
86
+ done
87
+
88
+ echo "bump_type=${BUMP_TYPE}" >> "$GITHUB_OUTPUT"
89
+ echo "tag=${NEXT_TAG}" >> "$GITHUB_OUTPUT"
90
+ echo "version=${NEXT_VERSION}" >> "$GITHUB_OUTPUT"
91
+
92
+ - name: Create and push tag
93
+ if: ${{ steps.next_version.outputs.skip_bump != 'true' }}
94
+ env:
95
+ TAG: ${{ steps.next_version.outputs.tag }}
96
+ run: |
97
+ git config user.name "github-actions[bot]"
98
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
99
+ git tag "$TAG"
100
+ git push origin "$TAG"
101
+
102
+ - name: Create GitHub Release
103
+ if: ${{ steps.next_version.outputs.skip_bump != 'true' }}
104
+ env:
105
+ GH_TOKEN: ${{ github.token }}
106
+ GH_REPO: ${{ github.repository }}
107
+ TAG: ${{ steps.next_version.outputs.tag }}
108
+ run: |
109
+ if gh release view "$TAG" >/dev/null 2>&1; then
110
+ gh release edit "$TAG" --title "Release $TAG"
111
+ else
112
+ gh release create "$TAG" --title "Release $TAG" --generate-notes
113
+ fi
@@ -0,0 +1,98 @@
1
+ name: Continuous Integration
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ types: [opened, synchronize, reopened]
7
+ push:
8
+ branches: [main]
9
+
10
+ env:
11
+ PYTHON_VERSION: "3.11"
12
+ BUILD_TYPE: Release
13
+
14
+ defaults:
15
+ run:
16
+ shell: bash
17
+
18
+ jobs:
19
+ pre-commit:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - name: Check out code
23
+ uses: actions/checkout@v4
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: ${{ env.PYTHON_VERSION }}
29
+
30
+ - name: Cache pre-commit
31
+ uses: actions/cache@v4
32
+ with:
33
+ path: ~/.cache/pre-commit
34
+ key: ${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
35
+ restore-keys: |
36
+ ${{ runner.os }}-pre-commit-
37
+
38
+ - name: Install pre-commit
39
+ run: python -m pip install pre-commit
40
+
41
+ - name: Run pre-commit
42
+ uses: pre-commit/action@v3.0.1
43
+
44
+ build-and-test:
45
+ needs: pre-commit
46
+ runs-on: ${{ matrix.os }}
47
+ strategy:
48
+ fail-fast: true
49
+ matrix:
50
+ os: [ubuntu-latest, macos-latest]
51
+ steps:
52
+ - name: Check out code
53
+ uses: actions/checkout@v4
54
+ with:
55
+ fetch-depth: 0
56
+
57
+ - name: Set up Python
58
+ uses: actions/setup-python@v5
59
+ with:
60
+ python-version: ${{ env.PYTHON_VERSION }}
61
+ cache: pip
62
+ cache-dependency-path: pyproject.toml
63
+
64
+ - name: Install Python dependencies
65
+ run: |
66
+ python -m pip install --upgrade pip
67
+ python -m pip install build ninja scikit-build-core setuptools-scm wheel
68
+ if [[ "$RUNNER_OS" == "Linux" ]]; then
69
+ python -m pip install --extra-index-url https://download.pytorch.org/whl/cpu -e ".[torch,native,speed]"
70
+ else
71
+ python -m pip install -e ".[torch,native,speed]"
72
+ fi
73
+
74
+ - name: Configure CMake
75
+ run: cmake -S . -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
76
+
77
+ - name: Build
78
+ run: cmake --build build --config ${{ env.BUILD_TYPE }} --parallel 3
79
+
80
+ - name: Build package distributions
81
+ run: python -m build
82
+
83
+ - name: Import smoke test
84
+ run: python -c "import py2sess"
85
+
86
+ - name: Run test suite
87
+ env:
88
+ PYTHONDONTWRITEBYTECODE: "1"
89
+ run: python -m unittest discover -s tests -v
90
+
91
+ - name: Run example smoke tests
92
+ env:
93
+ PYTHONDONTWRITEBYTECODE: "1"
94
+ PYTHONPATH: src
95
+ run: |
96
+ python examples/benchmark_scene_full_spectrum.py --profile benchmarks/uv_profile1/profile.csv --scene benchmarks/uv_profile1/scene.yaml --backend numpy --require-python-generated-inputs
97
+ python examples/benchmark_scene_full_spectrum.py --profile benchmarks/tir_profile1/profile.csv --scene benchmarks/tir_profile1/scene.yaml --backend numpy --require-python-generated-inputs
98
+ python examples/build_thermal_source_from_temperature.py
@@ -0,0 +1,179 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ ref:
7
+ description: "Git ref to build, for example main, a release branch, or v0.4.2"
8
+ required: true
9
+ default: "main"
10
+ tag:
11
+ description: "Tag to publish, for example v0.4.2"
12
+ required: false
13
+ version:
14
+ description: "Optional version override for dry-run builds, for example 0.4.2"
15
+ required: false
16
+ publish:
17
+ description: "Publish checked distributions to PyPI"
18
+ required: true
19
+ default: false
20
+ type: boolean
21
+
22
+ concurrency:
23
+ group: publish-pypi-${{ github.event.inputs.ref }}-${{ github.event.inputs.publish }}
24
+ cancel-in-progress: false
25
+
26
+ env:
27
+ BUILD_TYPE: Release
28
+ MACOS_ARCH: arm64
29
+ HOST_PYTHON: "3.11"
30
+
31
+ defaults:
32
+ run:
33
+ shell: bash
34
+
35
+ jobs:
36
+ build-macos:
37
+ name: Build macOS Native Wheels
38
+ runs-on: macos-latest
39
+ strategy:
40
+ fail-fast: true
41
+ matrix:
42
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
43
+ env:
44
+ MACOSX_DEPLOYMENT_TARGET: "15.0"
45
+ steps:
46
+ - name: Checkout code
47
+ uses: actions/checkout@v5
48
+ with:
49
+ fetch-depth: 0
50
+ ref: ${{ github.event.inputs.ref }}
51
+
52
+ - name: Setup Host Python
53
+ uses: actions/setup-python@v5
54
+ with:
55
+ python-version: ${{ env.HOST_PYTHON }}
56
+ cache: pip
57
+
58
+ - name: Configure macOS build env
59
+ run: |
60
+ PV=${{ matrix.python-version }}
61
+ PV=${PV//./}
62
+ echo "PY_VERSION=$PV" >> "$GITHUB_ENV"
63
+ echo "CIBW_BUILD=cp${PV}*" >> "$GITHUB_ENV"
64
+ echo "ARCHFLAGS=-arch ${{ env.MACOS_ARCH }}" >> "$GITHUB_ENV"
65
+ if [[ -n "${{ github.event.inputs.version }}" ]]; then
66
+ echo "SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PY2SESS=${{ github.event.inputs.version }}" >> "$GITHUB_ENV"
67
+ fi
68
+
69
+ - name: Build macOS wheel
70
+ env:
71
+ CIBW_PLATFORM: macos
72
+ CIBW_ARCHS: ${{ env.MACOS_ARCH }}
73
+ CIBW_BUILD_FRONTEND: "build; args: --no-isolation"
74
+ CIBW_CONFIG_SETTINGS: "cmake.define.PY2SESS_BUILD_NATIVE=ON"
75
+ CIBW_BEFORE_BUILD: |
76
+ python -m pip install 'cmake<=3.30' ninja build scikit-build-core setuptools-scm torch
77
+ CIBW_REPAIR_WHEEL_COMMAND_MACOS: |
78
+ export TORCH_LIB=$(python -c 'import torch; print(torch.__path__[0] + "/lib")')
79
+ export DYLD_FALLBACK_LIBRARY_PATH="$TORCH_LIB:$DYLD_FALLBACK_LIBRARY_PATH"
80
+ delocate-wheel -e torch -e libc10 -e libtorch -w {dest_dir} {wheel}
81
+ CIBW_TEST_REQUIRES: "torch"
82
+ CIBW_TEST_COMMAND: python -c "import py2sess; assert py2sess.native_extension_available(), py2sess.native_backend_info(); from py2sess.reference_cases import load_tir_benchmark_case; load_tir_benchmark_case()"
83
+ run: |
84
+ pip install cibuildwheel
85
+ python -m cibuildwheel --output-dir wheelhouse
86
+
87
+ - name: Upload macOS wheels
88
+ uses: actions/upload-artifact@v4
89
+ with:
90
+ name: wheels-macos-${{ matrix.python-version }}-${{ env.MACOS_ARCH }}
91
+ path: wheelhouse/*.whl
92
+
93
+ build-sdist:
94
+ name: Build Source Distribution
95
+ runs-on: ubuntu-latest
96
+ steps:
97
+ - name: Checkout code
98
+ uses: actions/checkout@v5
99
+ with:
100
+ fetch-depth: 0
101
+ ref: ${{ github.event.inputs.ref }}
102
+
103
+ - name: Setup Python
104
+ uses: actions/setup-python@v5
105
+ with:
106
+ python-version: ${{ env.HOST_PYTHON }}
107
+ cache: pip
108
+
109
+ - name: Build sdist
110
+ run: |
111
+ if [[ -n "${{ github.event.inputs.version }}" ]]; then
112
+ export SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PY2SESS="${{ github.event.inputs.version }}"
113
+ fi
114
+ python -m pip install build
115
+ python -m build --sdist
116
+
117
+ - name: Upload sdist
118
+ uses: actions/upload-artifact@v4
119
+ with:
120
+ name: sdist
121
+ path: dist/*.tar.gz
122
+
123
+ validate-distributions:
124
+ name: Validate Distributions
125
+ needs: [build-macos, build-sdist]
126
+ runs-on: ubuntu-latest
127
+ if: ${{ always() }}
128
+ steps:
129
+ - name: Download distributions
130
+ uses: actions/download-artifact@v4
131
+ with:
132
+ path: artifacts
133
+
134
+ - name: Require successful builds
135
+ run: |
136
+ test "${{ needs.build-macos.result }}" = "success"
137
+ test "${{ needs.build-sdist.result }}" = "success"
138
+
139
+ - name: Aggregate into dist
140
+ run: |
141
+ mkdir -p dist
142
+ find artifacts -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec mv {} dist/ \;
143
+
144
+ - name: Check distributions
145
+ run: |
146
+ python -m venv .twine-check
147
+ . .twine-check/bin/activate
148
+ python -m pip install --upgrade pip twine pkginfo packaging
149
+ python -m twine check dist/*
150
+
151
+ - name: Upload checked distributions
152
+ uses: actions/upload-artifact@v4
153
+ with:
154
+ name: checked-distributions
155
+ path: dist/*
156
+
157
+ publish-pypi:
158
+ name: Publish to PyPI
159
+ needs: [validate-distributions]
160
+ runs-on: ubuntu-latest
161
+ if: ${{ github.event.inputs.publish == 'true' && needs.validate-distributions.result == 'success' }}
162
+ environment: pypi
163
+ permissions:
164
+ contents: read
165
+ id-token: write
166
+ steps:
167
+ - name: Validate publish inputs
168
+ run: |
169
+ test -n "${{ github.event.inputs.tag }}"
170
+ test "${{ github.event.inputs.ref }}" = "${{ github.event.inputs.tag }}"
171
+
172
+ - name: Download checked distributions
173
+ uses: actions/download-artifact@v4
174
+ with:
175
+ name: checked-distributions
176
+ path: dist
177
+
178
+ - name: Publish to PyPI
179
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,23 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.so
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .DS_Store
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ benchmark_bundles/
11
+ outputs/
12
+ .codex/
13
+ idea.md
14
+ docs/assets/
15
+ docs/copernicus_template/
16
+ docs/fo_flux_equations.md
17
+ docs/level_flux_benchmarks.md
18
+ docs/level_flux_formula_review.md
19
+ docs/paper_rt_benchmarks.md
20
+ docs/paper_rt_release_checklist.md
21
+ docs/py2sess_rt_benchmark_paper.*
22
+ docs/retrieval.md
23
+ docs/reviewer_revision_checklist.md
@@ -0,0 +1,15 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v6.0.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-toml
9
+
10
+ - repo: https://github.com/astral-sh/ruff-pre-commit
11
+ rev: v0.15.11
12
+ hooks:
13
+ - id: ruff
14
+ args: ["--fix"]
15
+ - id: ruff-format
@@ -0,0 +1,48 @@
1
+ cmake_minimum_required(VERSION 3.18)
2
+
3
+ if(DEFINED SKBUILD_PROJECT_VERSION)
4
+ set(PY2SESS_VERSION "${SKBUILD_PROJECT_VERSION}")
5
+ else()
6
+ set(PY2SESS_VERSION "0.4.2")
7
+ endif()
8
+
9
+ project(py2sess_native
10
+ LANGUAGES CXX
11
+ DESCRIPTION "Native C++/CUDA extension scaffold for py2sess")
12
+
13
+ set(CMAKE_CXX_STANDARD 17)
14
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
15
+ set(CMAKE_CXX_EXTENSIONS OFF)
16
+
17
+ option(PY2SESS_BUILD_NATIVE "Build the optional py2sess native extension" OFF)
18
+ option(PY2SESS_NATIVE_CUDA "Build CUDA native dispatch stubs" OFF)
19
+
20
+ if(PY2SESS_BUILD_NATIVE)
21
+ find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
22
+
23
+ execute_process(
24
+ COMMAND ${Python3_EXECUTABLE} -c "import torch, pathlib; print(pathlib.Path(torch.utils.cmake_prefix_path).as_posix())"
25
+ RESULT_VARIABLE _TORCH_PREFIX_RESULT
26
+ OUTPUT_VARIABLE _TORCH_PREFIX
27
+ OUTPUT_STRIP_TRAILING_WHITESPACE
28
+ )
29
+ if(_TORCH_PREFIX_RESULT EQUAL 0 AND NOT _TORCH_PREFIX STREQUAL "")
30
+ list(APPEND CMAKE_PREFIX_PATH "${_TORCH_PREFIX}")
31
+ endif()
32
+
33
+ if(PY2SESS_NATIVE_CUDA)
34
+ enable_language(CUDA)
35
+ endif()
36
+
37
+ add_subdirectory(native)
38
+ else()
39
+ find_package(Python REQUIRED COMPONENTS Interpreter)
40
+ add_custom_target(
41
+ py2sess_python_sources
42
+ ALL
43
+ COMMAND ${CMAKE_COMMAND} -E echo
44
+ "Preparing py2sess ${PY2SESS_VERSION} for Python ${Python_VERSION}"
45
+ VERBATIM
46
+ )
47
+ install(CODE "message(STATUS \"py2sess ${PY2SESS_VERSION} has no native CMake artifacts in this build\")")
48
+ endif()