research: preserve solver experiments and reproducible benchmarks
This commit is contained in:
parent
12e4266950
commit
e93bc20b0a
85 changed files with 518443 additions and 0 deletions
202
research/README.md
Normal file
202
research/README.md
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
# Slime pattern reverse-search prototype
|
||||
|
||||
当前范围测速 CLI 见 [bench/README.md](../bench/README.md),共用算法实现见 [include/](../include/README.md)。本目录保留研究入口与历史路径;近期实验见 [实验导航](experiments/README.md)。
|
||||
|
||||
This directory retains fixed-coordinate seed solvers and fixed-seed coordinate scanners.
|
||||
It is not a complete all-seed world-border catalog generator.
|
||||
|
||||
- `slime_pattern_prototype.py`: readable reference/oracle.
|
||||
- `slime_pattern_cpp.cpp`, `slime_pattern_cuda.cu`: fixed-coordinate seed search.
|
||||
- `slime_position_cuda.cu`: direct vs tiled outer-sum coordinate scans.
|
||||
- `slime_position_residue_cuda.cu`: fixed-seed coordinate-residue filtering.
|
||||
- `slime_bruteforce_cpp_bench.cpp`, `slime_bruteforce_cuda_bench.cu`: baseline benchmarks.
|
||||
- `slime_solver_core.hpp`: shared arithmetic and upper13 solver.
|
||||
|
||||
See [优化摘要](OPTIMIZATION_SUMMARY.md) and [BENCHMARK.md](BENCHMARK.md).
|
||||
The independent X/Z filter/join route and its middle-bit experiments have been removed;
|
||||
method, historical results and stopping reasons are consolidated in
|
||||
[X/Z 筛轴试错报告](XZ_FILTER_TRIAL_REPORT.md).
|
||||
|
||||
## What is implemented
|
||||
|
||||
- Minecraft/Java-compatible coordinate overflow and `Random.nextInt(10)`
|
||||
verification.
|
||||
- Arbitrary patterns using `#` (slime), `.` (non-slime), and `?` (ignored).
|
||||
- Lower-seed 2-adic lifting from 18 bits toward the 35-bit boundary.
|
||||
- The analytic `35 + 13` split. For `seed = lower35 + m * 2^35`, all pattern
|
||||
cells share the same upper-state displacement. Substituting
|
||||
`n = 1645*m mod 8192` turns each required-slime cell into a piecewise
|
||||
`n mod 5` constraint with one threshold. Sorting those thresholds solves all
|
||||
upper 13 bits without scanning 8192 values.
|
||||
- The position outer-sum identity modulo `2^32`, used to reuse coordinate
|
||||
arithmetic in fixed-seed scans.
|
||||
- A full-world fixed-seed position search: filter the `2^36` pairs
|
||||
`(x mod 2^18, z mod 2^18)` on CUDA, expand only surviving residue classes,
|
||||
then perform exact Java verification.
|
||||
|
||||
## Run it
|
||||
|
||||
The known public 5x5 sample is:
|
||||
|
||||
```bash
|
||||
python3 research/slime_pattern_prototype.py verify \
|
||||
--seed 61692151016558 --x 51069 --z 419124 -n 5
|
||||
```
|
||||
|
||||
Recover the 12 upper-bit solutions belonging to one known lower-35-bit value:
|
||||
|
||||
```bash
|
||||
python3 research/slime_pattern_prototype.py upper \
|
||||
--lower35 16420645998 --x 51069 --z 419124 -n 5
|
||||
```
|
||||
|
||||
Show the 18-to-24-bit lifting counts:
|
||||
|
||||
```bash
|
||||
python3 research/slime_pattern_prototype.py roots \
|
||||
--x 51069 --z 419124 -n 5 --bits 24
|
||||
```
|
||||
|
||||
Use a custom pattern (rows are separated by `/`):
|
||||
|
||||
```bash
|
||||
python3 research/slime_pattern_prototype.py verify \
|
||||
--seed 61692151016558 --x 51069 --z 419124 \
|
||||
--pattern '##?/..#/#?#'
|
||||
```
|
||||
|
||||
Check and print the outer-sum position signature:
|
||||
|
||||
```bash
|
||||
python3 research/slime_pattern_prototype.py signature \
|
||||
--x 51069 --z 419124 -n 5
|
||||
```
|
||||
|
||||
Run the tests:
|
||||
|
||||
```bash
|
||||
python3 -m unittest discover -s research -p 'test_*.py'
|
||||
```
|
||||
|
||||
## C++ and CUDA
|
||||
|
||||
Build both native implementations:
|
||||
|
||||
```bash
|
||||
make -C research
|
||||
```
|
||||
|
||||
The CPU CLI exposes the same important stages as the Python oracle:
|
||||
|
||||
```bash
|
||||
research/slime_pattern_cpp verify \
|
||||
--seed 61692151016558 --x 51069 --z 419124 -n 5
|
||||
|
||||
research/slime_pattern_cpp roots \
|
||||
--x 51069 --z 419124 -n 5 --bits 24
|
||||
|
||||
research/slime_pattern_cpp upper \
|
||||
--lower35 16420645998 --x 51069 --z 419124 -n 5
|
||||
```
|
||||
|
||||
`search` performs the complete fixed-position pipeline. For the public 5x5
|
||||
sample it expands 84 lower-18 roots into 11,010,048 lower-35-bit values and
|
||||
recovers all 24 known seeds:
|
||||
|
||||
```bash
|
||||
research/slime_pattern_cpp search \
|
||||
--x 51069 --z 419124 -n 5 -p 16 --max-results 32
|
||||
```
|
||||
|
||||
On the development machine this CPU run took about 0.68 seconds with 16 worker
|
||||
threads. Treat that as a local sanity benchmark, not a portable performance
|
||||
claim.
|
||||
|
||||
The CUDA program performs the same complete fixed-position search and accepts
|
||||
the same compact arbitrary-pattern syntax:
|
||||
|
||||
```bash
|
||||
research/slime_pattern_cuda \
|
||||
--x 51069 --z 419124 -n 5 --threads 128 --max-results 32
|
||||
|
||||
research/slime_pattern_cuda \
|
||||
--x 0 --z 0 --pattern '##?/..#/#?#' --threads 128
|
||||
```
|
||||
|
||||
CUDA 12 compilation was verified, and the solver was subsequently benchmarked
|
||||
on an RTX 3060 Laptop GPU. See [BENCHMARK.md](BENCHMARK.md) for the old/new CPU
|
||||
and CUDA comparison, methodology, commands, and limitations. GPU execution
|
||||
from a sandboxed session may still require host GPU permission.
|
||||
|
||||
## Coordinate-side outer-sum experiment
|
||||
|
||||
For a fixed world seed, compare a direct position scan against a tiled
|
||||
outer-sum scan over an inclusive rectangle:
|
||||
|
||||
```bash
|
||||
research/slime_position_cuda \
|
||||
--seed 61692151016558 \
|
||||
--x0 46973 --x1 55165 --z0 415028 --z1 423220 \
|
||||
-n 5 --repeats 5
|
||||
```
|
||||
|
||||
Both kernels run on every invocation. Their sorted hit lists must be exactly
|
||||
equal or the program fails. The direct kernel recomputes the full coordinate
|
||||
term at each tested cell. The outer kernel assigns a 16x16 position tile to a
|
||||
CUDA block and shares the expanded `F(x+i)` and `G(z+j)` axis arrays across the
|
||||
block. On the development RTX 3060 Laptop GPU, the 67,125,249-position command
|
||||
above took 1.608 ms direct versus 1.332 ms outer-sum (median of five), a 1.21x
|
||||
kernel speedup, and found only `(51069, 419124)`.
|
||||
|
||||
This result is intentionally modest. A solid pattern rejects almost every
|
||||
position on its first one or two chunks, so the direct kernel seldom evaluates
|
||||
all 25 coordinate polynomials. Outer-sum removes duplicated coordinate work,
|
||||
but does not change the asymptotic rectangle area. It remains a fixed-seed arithmetic-reuse baseline; full seed/coordinate catalog generation is unresolved.
|
||||
|
||||
## Full-world fixed-seed residue search
|
||||
|
||||
The low output parity used by the seed lifting depends on coordinates only
|
||||
modulo `2^18`. The residue solver checks that fixed `2^36` space once, then
|
||||
expands the surviving residue pairs into the requested world rectangle:
|
||||
|
||||
```bash
|
||||
research/slime_position_residue_cuda --seed 61692151016558 -n 5
|
||||
```
|
||||
|
||||
The default bounds are `[-1875000, 1874999]` on both axes. For the public seed
|
||||
on the development RTX 3060 Laptop GPU, the residue kernel took 1.93 seconds,
|
||||
retained 180,476 of 68,719,476,736 residue pairs, and expanded them into
|
||||
36,937,048 exact candidates out of 14,062,500,000,000 world positions. Exact
|
||||
CPU verification took another 284 ms and found only `(51069, 419124)`.
|
||||
|
||||
Across four tested seeds, the kernel stayed between 1.92 and 1.94 seconds and
|
||||
retained 175,992--195,672 residue pairs. Including axis-table preparation and
|
||||
exact verification, a full run took about 2.5 seconds. A measured `2^34`
|
||||
direct-position CUDA run projects to about 429 seconds over the same world, so
|
||||
the residue method is about 170x faster end-to-end for this fixed-seed 5x5
|
||||
workload.
|
||||
|
||||
## Removed experiments
|
||||
|
||||
Failed and inferior approaches are not part of the active build. Their data,
|
||||
failure reasons, and key implementation snippets are preserved in
|
||||
[`REJECTED_EXPERIMENTS.md`](REJECTED_EXPERIMENTS.md).
|
||||
|
||||
## Prototype limitations
|
||||
|
||||
1. The upper-bit candidate generator describes the first `next(31)` draw.
|
||||
Java rejects only the final eight of the `2^31` possible values before
|
||||
drawing again. Every emitted seed is checked with the exact rejection loop,
|
||||
so there are no false positives, but a solution whose first draw is rejected
|
||||
and whose later draw succeeds can be missed. An exhaustive catalog builder
|
||||
must add a tiny exceptional-state branch.
|
||||
2. Ordinary lifting is weak after the output parity becomes known: modulo 5 can
|
||||
still be repaired by unknown binary bits. A solid 5x5 sample has 84 roots at
|
||||
18 bits and 5,376 at 24 bits, then grows to roughly 11 million lower-35
|
||||
low-bit values. The CLI therefore has a candidate safety limit.
|
||||
3. Full-world position enumeration is implemented only for a fixed seed and a
|
||||
solid square of size 1--8. Joint unknown `(seed, x, z)` catalog generation
|
||||
is still unresolved; the X/Z independent-filter route was retired; see the trial report.
|
||||
4. The residue parity filter shares the first-draw rejection-tail caveat from
|
||||
item 1. Exact verification prevents false positives, but the rare solution
|
||||
whose first draw is rejected can be filtered out before verification.
|
||||
Loading…
Add table
Add a link
Reference in a new issue