-
Notifications
You must be signed in to change notification settings - Fork 4
Add opt-in scale-test tier #104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| name: Scale Tests | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| schedule: | ||
| - cron: "37 8 * * 0" | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| scale: | ||
| name: Julia 1 - ubuntu-latest - x64 - scale | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 75 | ||
| env: | ||
| QUBOTOOLS_SCALE_TESTS: true | ||
| QUBOTOOLS_SCALE_MAX_N: 100000 | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| - uses: julia-actions/setup-julia@v3 | ||
| with: | ||
| version: "1" | ||
| arch: x64 | ||
| - uses: julia-actions/cache@v3 | ||
| - uses: julia-actions/julia-buildpkg@v1 | ||
| - name: Run scale tests | ||
| run: julia --project=. -e 'using Pkg; Pkg.test(; test_args = ["scale-only"])' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| # Scalability | ||
|
|
||
| QUBOTools keeps the default test suite focused on small fixtures so that | ||
| `Pkg.test("QUBOTools")` remains suitable for pull requests and local | ||
| development. Large generated instances are covered by an opt-in scale-test tier. | ||
|
|
||
| Run the full scale tier from the repository root with: | ||
|
|
||
| ```bash | ||
| QUBOTOOLS_SCALE_TESTS=true julia --project=. -e 'using Pkg; Pkg.test(; test_args = ["scale-only"])' | ||
| ``` | ||
|
|
||
| To run a smaller local smoke pass, cap the maximum generated dimension: | ||
|
|
||
| ```bash | ||
| QUBOTOOLS_SCALE_TESTS=true QUBOTOOLS_SCALE_MAX_N=5000 julia --project=. -e 'using Pkg; Pkg.test(; test_args = ["scale-only"])' | ||
| ``` | ||
|
|
||
| The scheduled GitHub Actions scale job runs generated sparse cases at | ||
| `n = 1000`, `5000`, `20000`, and `100000` with average degree 4. These cases | ||
| exercise: | ||
|
|
||
| - sparse model construction from generated linear and quadratic dictionaries; | ||
| - dense Sherrington-Kirkpatrick and Wishart synthesis smoke cases at `n = 1000`; | ||
| - energy evaluation on random states; | ||
| - sparse, dictionary, and dense form agreement at `n = 1000`; | ||
| - sparse and dictionary form agreement at larger sizes; | ||
| - QUBin round-trips at every scale-test size; | ||
| - QUBO text round-trips at `n = 20000` and `n = 100000`; | ||
| - exact Float64 preservation for a portfolio-like numerical range from | ||
| `1e-3` through `2e10`; | ||
| - `SampleSet` construction and duplicate-state merging with large states. | ||
|
|
||
| ## Practical Envelope | ||
|
|
||
| Sparse forms are the intended representation for large generated and archived | ||
| instances. A sparse quadratic form is backed by Julia's `SparseMatrixCSC`, which | ||
| stores one row index and one value per nonzero term plus one column pointer per | ||
| variable. With 64-bit indices and `Float64` coefficients, the dominant storage | ||
| is about 16 bytes per quadratic nonzero plus about 8 bytes per variable for | ||
| column pointers. Sparse linear terms add about 16 bytes per nonzero. Temporary | ||
| construction dictionaries and I/O buffers require additional memory, so peak | ||
| memory is higher than the final sparse form. | ||
|
|
||
| Dense forms use an `n x n` `Float64` matrix for quadratic terms. That is about | ||
| `8n^2` bytes before Julia array overhead, so dense forms are practical only for | ||
| small cross-checks. The scale tier limits dense correctness checks to | ||
| `n = 1000`. | ||
|
|
||
| The current scheduled envelope is sparse instances with 100000 variables and | ||
| about 200000 quadratic terms. Denser QOBLib-style archives with millions of | ||
| terms should be tested with a dedicated benchmark or data-validation workflow so | ||
| their time and memory budgets can be reviewed separately from regular package | ||
| tests. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,14 +28,26 @@ const QUBOModel = QUBOTools_MOI.QUBOModel | |
| const NumberOfReads = QUBOTools_MOI.NumberOfReads | ||
|
|
||
| const __TEST_PATH__ = @__DIR__ | ||
| const __SCALE_ONLY__ = "scale-only" in ARGS | ||
|
|
||
| function _scale_tests_requested() | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate of
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in 3088bf8. |
||
| return lowercase(get(ENV, "QUBOTOOLS_SCALE_TESTS", "false")) in | ||
| Set(["1", "true", "yes", "on"]) | ||
| end | ||
|
|
||
| # Include assets | ||
| include("assets/comparison.jl") | ||
| include("assets/foreign_tests.jl") | ||
|
|
||
| # Include test functions | ||
| include("unit/unit.jl") | ||
| include("integration/integration.jl") | ||
| if __SCALE_ONLY__ || _scale_tests_requested() | ||
| include("scale/scale.jl") | ||
| end | ||
|
|
||
| if !__SCALE_ONLY__ | ||
| include("unit/unit.jl") | ||
| include("integration/integration.jl") | ||
| end | ||
|
|
||
| function test_main() | ||
| @testset "◈ ◈ ◈ QUBOTools.jl Test Suite ◈ ◈ ◈" verbose = true begin | ||
|
|
@@ -46,4 +58,12 @@ function test_main() | |
| return nothing | ||
| end | ||
|
|
||
| test_main() # Here we go! | ||
| if __SCALE_ONLY__ | ||
| test_scale() | ||
| else | ||
| test_main() # Here we go! | ||
|
|
||
| if _scale_tests_requested() | ||
| test_scale() | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| using Test | ||
| using Random | ||
| using QUBOTools | ||
|
|
||
| include("scale.jl") | ||
|
|
||
| if _scale_tests_enabled() | ||
| test_scale() | ||
| else | ||
| @info "Set QUBOTOOLS_SCALE_TESTS=true to run the scale-test tier" | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocking: the new writer emits default
Float64strings, so values such as1.0e-5or2.0e10are valid output here but fail on immediate re-read because the Rudy parser only accepts fixed decimal literals. I reproduced this with a temporary spin model written throughFormat{:rudy};read_modelfails on0 0 1.0e-5withSyntax Error. Please either teach the Rudy parser the same scientific-notation numeric grammar accepted by QUBO, including constant comments, and add an exponent round-trip test, or format Rudy output with a representation the existing parser accepts.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in b34b8f5. The Rudy parser now accepts exponent-form numbers for coefficient lines and constant-term comments, and
test/unit/library/formats.jladds a write/read round-trip with exponent-form linear, quadratic, and offset values.