diff --git a/README.md b/README.md index df125c7..9c3f6e8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 史莱姆区块搜索与 CUDA 基准 -当前可直接使用的入口是 **[bench/slime-bench](bench/README.md)**:指定中心区块、曼哈顿半径和实心 `n×n` 图案,测量全部有效种子的普通候选分支搜索时间,支持单张或多张 NVIDIA GPU。 +当前可直接使用的入口是 **[bench/slime-bench](bench/README.md)**:指定中心区块、曼哈顿半径和自定义图案(或实心 `n×n`),测量全部有效种子的普通候选分支搜索时间,支持单张或多张 NVIDIA GPU。 ```sh make bench @@ -8,6 +8,8 @@ make bench --position-batch 128 --devices all --repeat 3 ``` +自定义图案用 `--pattern` 或 `--pattern-file`,支持史莱姆、非史莱姆和忽略格;见 [6×6 苦力怕示例](bench/README.md#自定义图案6x6-苦力怕)。 + H100 编译:`make -C bench -B CUDA_ARCH=90`。需要 CUDA Toolkit 和 C++17 编译器。普通分支不包含拒绝重抽补扫,不能将它的结果声明为严格完整目录;参数和计时口径见 [CLI 使用说明](bench/README.md)。 ## 目录导航 diff --git a/bench/README.md b/bench/README.md index 50867cd..12d4f34 100644 --- a/bench/README.md +++ b/bench/README.md @@ -1,6 +1,6 @@ # slime-bench:普通分支全种子搜索基准 -指定中心区块、曼哈顿半径和实心 `n×n` 图案,搜索范围内每个锚点的全部有效种子,输出 JSON 结果及计时。支持 NVIDIA CUDA 单卡、多卡。 +指定中心区块、曼哈顿半径和自定义图案(或实心 `n×n`),搜索范围内每个锚点的全部有效种子,输出 JSON 结果及计时。支持 NVIDIA CUDA 单卡、多卡。 ## 本地编译与运行 @@ -16,6 +16,37 @@ mkdir -p artifacts 默认编译 `sm_86` 并附带 PTX,适合本机 RTX 3060 Laptop。换架构时用 `-B` 强制重建;仅改变 Make 变量不会使已有文件自动过期。 +## 自定义图案:6×6 苦力怕 + +`--pattern` 接受 `/` 分隔的行,或用 `--pattern-file` 读取每行一排的文本文件。`#` 必须是史莱姆区块,`.` 必须不是,`?` 不限制。支持非正方形,宽、高分别为 1~64,至少含一个 `#`;不能与 `--size` 同时指定。不自动旋转或镜像。 + +内置示例 [patterns/creeper-6x6.txt](patterns/creeper-6x6.txt) 将脸部像素设为史莱姆: + +```text +##..## +##..## +..##.. +.####. +.####. +.#..#. +``` + +```sh +./bench/bin/slime-bench --radius 512 \ + --pattern-file bench/patterns/creeper-6x6.txt \ + --position-batch 128 --max-results 100 --output artifacts/creeper.json + +# 也可直接输入;必须使用引号保护 #、? 等字符 +./bench/bin/slime-bench --radius 512 \ + --pattern '##..##/##..##/..##../.####./.####./.#..#.' --max-results 100 +``` + +目标是上面的正色模板:眼睛、鼻子和嘴巴为史莱姆区块,背景必须不是。已检查原点半径 2048、中心 `(51069,419124)` 半径 1024、32 个分散区域各半径 256、另外 128 个分散区域各半径 512;还筛选了 65,536 个坐标,选出低位候选最多的 64 个坐标类,检查这些类在世界边界内的全部 104,538 个实际位置。累计 82,047,228 次锚点检查仍未命中(不同路线可能重叠,见[搜索记录](results/creeper-6x6-search.json))。这不证明正色不存在;不能用反色图案作为该目标的搜索结果。 + +每行从左到右沿 `+X`,从上到下沿 `+Z`。返回坐标仍是矩形左上角,即使该格是 `.` 或 `?`。将 `.` 改为 `?` 可只要求轮廓、允许背景出现额外史莱姆区块。JSON 包含原始 `pattern` 行、宽高及两类约束数;自定义输入的 `square_size` 为 `null`。 + +筛选和区间求解只使用 `#` 格,随后精确核对所有 `.` 格;`?` 不参与计算。稀疏图案的候选可能很多,搜索时间不能直接套用实心方阵的基准。搜索口径仍为普通分支,不包含拒绝重抽补扫。 + ## H100 服务器 将仓库内的 `bench/` 和 `include/` 一起复制到服务器,保持相对路径;CLI 依赖 `include/slime/` 中的共用头文件。 @@ -53,7 +84,7 @@ abs(anchor_x - x) + abs(anchor_z - z) <= radius ``` - `x,z,radius` 的单位都是区块,不是方块。 -- 锚点是图案最小 X、最小 Z 的角;图案沿 `+X,+Z` 延伸。 +- 锚点是图案最小 X、最小 Z 的角;图案沿 `+X,+Z` 延伸。自定义图案的锚点是外接矩形的角。 - 半径限制锚点,图案允许超出菱形范围。 - 不自动按世界边界裁剪;锚点和整块图案须在 int32 坐标范围内,否则报错。 - `--size` 支持 1~6,默认 5。小尺寸匹配种子极多,全种子计数也可能耗时很久,不能用 1×1 推断 5×5 性能。 @@ -108,7 +139,7 @@ make -C bench test # 无需 GPU:范围、输入、可变尺寸数学对 make -C bench test-gpu # 需要 GPU:实际搜索与文件输出验证 ``` -验证内容包括:半径 0~64 的完整菱形枚举,较大半径抽样,1~6 中多个尺寸的组 mask 对照,已知 24 个命中,小根批分拆一致性,4×4 的全部 422 个示例经独立 Java 算法验证,6×6 的已知种子子集对照,以及半径 2 批量结果与全部 13 个位置分别搜索的完整列表一致。 +验证内容包括:自定义图案解析和边界、稀疏图案高位枚举对照、带忽略格及非史莱姆格的 GPU 结果与独立 Java 算法筛选对照,以及半径 0~64 的完整菱形枚举,较大半径抽样,1~6 中多个尺寸的组 mask 对照,已知 24 个命中,小根批分拆一致性,4×4 的全部 422 个示例经独立 Java 算法验证,6×6 的已知种子子集对照,以及半径 2 批量结果与全部 13 个位置分别搜索的完整列表一致。 本机实测:RTX 3060 Laptop,中心 `(0,0)`,半径 512,5×5,`--position-batch 128 --repeat 3`。525,313 个锚点,三轮均有 368,935 个低位根任务、0 个命中,扫描墙钟中位数约 **3.990 秒**。原始 JSON 在 [results/local-r512-n5.json](results/local-r512-n5.json)。另有半径 64 的快速环境验证记录;其批大小为默认 32,与上述正式样例不同。 diff --git a/bench/patterns/creeper-6x6.txt b/bench/patterns/creeper-6x6.txt new file mode 100644 index 0000000..cbf7dd5 --- /dev/null +++ b/bench/patterns/creeper-6x6.txt @@ -0,0 +1,6 @@ +##..## +##..## +..##.. +.####. +.####. +.#..#. diff --git a/bench/results/creeper-6x6-search.json b/bench/results/creeper-6x6-search.json new file mode 100644 index 0000000..8444928 --- /dev/null +++ b/bench/results/creeper-6x6-search.json @@ -0,0 +1,2076 @@ +{ + "pattern": [ + "##..##", + "##..##", + "..##..", + ".####.", + ".####.", + ".#..#." + ], + "rejection_tail_included": false, + "regions": [ + { + "center": [ + 0, + 0 + ], + "radius_chunks": 2048, + "anchors": 8392705, + "matches": 0 + }, + { + "center": [ + 51069, + 419124 + ], + "radius_chunks": 1024, + "anchors": 2099201, + "matches": 0 + }, + { + "center": [ + -1240486, + 1254452 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 551706, + 359225 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -1102646, + 1248433 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 1399253, + 1604177 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 832393, + 1323341 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 1411111, + 856325 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 897669, + 951809 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -1542224, + 1080841 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -1786464, + 1321780 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 723546, + 180115 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -298705, + 563030 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -81029, + 986500 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 984760, + 1056670 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 890629, + 857321 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -291130, + 682650 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -145770, + 156013 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -1294555, + 8076 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 870442, + -35702 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -343570, + -1546774 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 300743, + 733117 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -829122, + 971945 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 1158337, + -1681435 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 192011, + -863578 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -79456, + 497460 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 531906, + 337188 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -484327, + 1383813 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -556561, + 62465 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -1069393, + -1386708 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 1167509, + 659994 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + 1760287, + 407729 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -832640, + 423668 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "center": [ + -671167, + -1577407 + ], + "radius_chunks": 256, + "anchors": 131585, + "matches": 0 + }, + { + "batch": "more-20261016", + "center": [ + -236713, + -85186 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 4890.250875 + }, + { + "batch": "more-20261016", + "center": [ + 666436, + 669647 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5046.38283 + }, + { + "batch": "more-20261016", + "center": [ + -1154443, + -893314 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5484.632263 + }, + { + "batch": "more-20261016", + "center": [ + -121875, + 1425708 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5644.884253 + }, + { + "batch": "more-20261016", + "center": [ + 304417, + -1378369 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5703.729083 + }, + { + "batch": "more-20261016", + "center": [ + 439560, + 403506 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5837.06019 + }, + { + "batch": "more-20261016", + "center": [ + 485017, + 683707 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5878.556241 + }, + { + "batch": "more-20261016", + "center": [ + -1575885, + -1654010 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5856.308147 + }, + { + "batch": "more-20261016", + "center": [ + -1692338, + 489480 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 9991.218642 + }, + { + "batch": "more-20261016", + "center": [ + 94460, + -514270 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5323.475905 + }, + { + "batch": "more-20261016", + "center": [ + 298113, + -1251515 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5305.209153 + }, + { + "batch": "more-20261016", + "center": [ + 1005871, + -1746711 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5307.834305 + }, + { + "batch": "more-20261016", + "center": [ + 78033, + 221310 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5334.133523 + }, + { + "batch": "more-20261016", + "center": [ + 680685, + -873939 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5386.786021 + }, + { + "batch": "more-20261016", + "center": [ + -222404, + -1657566 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5482.521388 + }, + { + "batch": "more-20261016", + "center": [ + 462032, + -693479 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5394.795862 + }, + { + "batch": "more-20261016", + "center": [ + -1329079, + 1797529 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5427.682615 + }, + { + "batch": "more-20261016", + "center": [ + 1469462, + 61775 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5560.569536 + }, + { + "batch": "more-20261016", + "center": [ + 1547543, + 1409686 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5483.684237 + }, + { + "batch": "more-20261016", + "center": [ + 68743, + -349911 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5448.201818 + }, + { + "batch": "more-20261016", + "center": [ + -124724, + 762711 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5513.491708 + }, + { + "batch": "more-20261016", + "center": [ + 764697, + 580209 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5547.899899 + }, + { + "batch": "more-20261016", + "center": [ + 153626, + -525004 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5549.427627 + }, + { + "batch": "more-20261016", + "center": [ + -581865, + 690532 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5584.69107 + }, + { + "batch": "more-20261016", + "center": [ + -605455, + -1518523 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5537.561954 + }, + { + "batch": "more-20261016", + "center": [ + -708447, + -1004201 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5510.155056 + }, + { + "batch": "more-20261016", + "center": [ + 770933, + 687626 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5532.061398 + }, + { + "batch": "more-20261016", + "center": [ + -1466907, + -262914 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5532.535083 + }, + { + "batch": "more-20261016", + "center": [ + -605689, + -1028914 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5546.369918 + }, + { + "batch": "more-20261016", + "center": [ + -338833, + 502714 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5722.566882 + }, + { + "batch": "more-20261016", + "center": [ + 1671668, + 15748 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5621.389509 + }, + { + "batch": "more-20261016", + "center": [ + -835149, + 642531 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5660.798313 + }, + { + "batch": "more-20261016", + "center": [ + 412783, + -614172 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5599.440923 + }, + { + "batch": "more-20261016", + "center": [ + 1431505, + -992931 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5624.067308 + }, + { + "batch": "more-20261016", + "center": [ + 20301, + 1361819 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5774.92359 + }, + { + "batch": "more-20261016", + "center": [ + 549623, + -1658912 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5719.29063 + }, + { + "batch": "more-20261016", + "center": [ + 1286242, + -1213605 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5693.840848 + }, + { + "batch": "more-20261016", + "center": [ + -975073, + -1649260 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5643.426952 + }, + { + "batch": "more-20261016", + "center": [ + -903850, + -414908 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5888.164523 + }, + { + "batch": "more-20261016", + "center": [ + -92303, + 1185186 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5861.192233 + }, + { + "batch": "more-20261016", + "center": [ + 961017, + 966536 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5729.582619 + }, + { + "batch": "more-20261016", + "center": [ + -994830, + -1609008 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5682.793989 + }, + { + "batch": "more-20261016", + "center": [ + 759544, + 896608 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5752.019669 + }, + { + "batch": "more-20261016", + "center": [ + -424645, + -1217173 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5702.752783 + }, + { + "batch": "more-20261016", + "center": [ + 72550, + -33152 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5693.705212 + }, + { + "batch": "more-20261016", + "center": [ + -457098, + -1007181 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5891.04197 + }, + { + "batch": "more-20261016", + "center": [ + -1128502, + 951050 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5707.536614 + }, + { + "batch": "more-20261016", + "center": [ + 1321063, + -1005497 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5778.482448 + }, + { + "batch": "more-20261016", + "center": [ + -215719, + 1217321 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5745.67554 + }, + { + "batch": "more-20261016", + "center": [ + -517661, + 1377326 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5760.367596 + }, + { + "batch": "more-20261016", + "center": [ + 281670, + 1077429 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5725.672166 + }, + { + "batch": "more-20261016", + "center": [ + 98943, + -1652520 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5717.926213 + }, + { + "batch": "more-20261016", + "center": [ + 439081, + -742396 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5803.765284 + }, + { + "batch": "more-20261016", + "center": [ + -1775847, + -351124 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5780.94188 + }, + { + "batch": "more-20261016", + "center": [ + 277121, + 1193566 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6303.767806 + }, + { + "batch": "more-20261016", + "center": [ + -745342, + 798546 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6012.573935 + }, + { + "batch": "more-20261016", + "center": [ + -547803, + -1121148 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5810.14406 + }, + { + "batch": "more-20261016", + "center": [ + 1508147, + -250828 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6038.477476 + }, + { + "batch": "more-20261016", + "center": [ + -1180322, + 886630 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5784.962388 + }, + { + "batch": "more-20261016", + "center": [ + -736191, + -200158 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5924.676128 + }, + { + "batch": "more-20261016", + "center": [ + 1639782, + 909163 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5786.473076 + }, + { + "batch": "more-20261016", + "center": [ + -1435579, + -713677 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5816.160135 + }, + { + "batch": "more-20261016", + "center": [ + -512492, + -1072444 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5781.735265 + }, + { + "batch": "more-20261016", + "center": [ + -134753, + 911081 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5850.373539 + }, + { + "batch": "more-20261016", + "center": [ + 315236, + -87577 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6068.400784 + }, + { + "batch": "more-20261016", + "center": [ + 952106, + -1549527 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5887.02283 + }, + { + "batch": "more-20261016", + "center": [ + -706311, + 869544 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6056.725375 + }, + { + "batch": "more-20261016", + "center": [ + 1437402, + -1239236 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5941.416555 + }, + { + "batch": "more-20261016", + "center": [ + -1079512, + 275826 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5958.189698 + }, + { + "batch": "more-20261016", + "center": [ + 1238517, + 1633240 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5845.50298 + }, + { + "batch": "more-20261016", + "center": [ + 615146, + 796864 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5937.342679 + }, + { + "batch": "more-20261016", + "center": [ + 1133469, + 112212 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5750.517063 + }, + { + "batch": "more-20261016", + "center": [ + -1322379, + 285846 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5863.350573 + }, + { + "batch": "more-20261016", + "center": [ + -1081001, + 765410 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5896.376751 + }, + { + "batch": "more-20261016", + "center": [ + -216553, + -532570 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5912.930085 + }, + { + "batch": "more-20261016", + "center": [ + 1529113, + 184637 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6020.087535 + }, + { + "batch": "more-20261016", + "center": [ + 1023806, + -1129220 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6059.275974 + }, + { + "batch": "more-20261016", + "center": [ + -1189082, + 726981 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5884.683684 + }, + { + "batch": "more-20261016", + "center": [ + -557116, + 204666 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5773.645473 + }, + { + "batch": "more-20261016", + "center": [ + -356461, + -860056 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5829.22232 + }, + { + "batch": "more-20261016", + "center": [ + 574919, + -1214098 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5881.862683 + }, + { + "batch": "more-20261016", + "center": [ + -465839, + 949666 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6307.441773 + }, + { + "batch": "more-20261016", + "center": [ + -402235, + -217216 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5927.307004 + }, + { + "batch": "more-20261016", + "center": [ + 110214, + -1202648 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5944.605131 + }, + { + "batch": "more-20261016", + "center": [ + 183707, + 345565 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6190.251746 + }, + { + "batch": "more-20261016", + "center": [ + 686801, + 1188943 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6078.29411 + }, + { + "batch": "more-20261016", + "center": [ + -986377, + 709690 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6056.334508 + }, + { + "batch": "more-20261016", + "center": [ + 99022, + -730323 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6138.854723 + }, + { + "batch": "more-20261016", + "center": [ + -552492, + -1602503 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6284.121071 + }, + { + "batch": "more-20261016", + "center": [ + -1703034, + 883652 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6427.928492 + }, + { + "batch": "more-20261016", + "center": [ + -1496881, + -193388 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6290.027404 + }, + { + "batch": "more-20261016", + "center": [ + -1159147, + -1312455 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 7668.257741 + }, + { + "batch": "more-20261016", + "center": [ + 1539848, + 1770238 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6113.318496 + }, + { + "batch": "more-20261016", + "center": [ + 59713, + 1735029 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6131.876648 + }, + { + "batch": "more-20261016", + "center": [ + -1491426, + 107884 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6040.032722 + }, + { + "batch": "more-20261016", + "center": [ + -31919, + 1786179 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5826.740836 + }, + { + "batch": "more-20261016", + "center": [ + 1373508, + 522664 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5780.439599 + }, + { + "batch": "more-20261016", + "center": [ + 1579514, + -192616 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5813.619285 + }, + { + "batch": "more-20261016", + "center": [ + 1791480, + 1246406 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6119.797372 + }, + { + "batch": "more-20261016", + "center": [ + 309398, + 957706 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6167.665651 + }, + { + "batch": "more-20261016", + "center": [ + -1251280, + -1240255 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6129.020006 + }, + { + "batch": "more-20261016", + "center": [ + -448944, + -1754529 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5972.765624 + }, + { + "batch": "more-20261016", + "center": [ + -1478663, + -1693923 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5770.533706 + }, + { + "batch": "more-20261016", + "center": [ + -1362387, + -1446030 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5827.661886 + }, + { + "batch": "more-20261016", + "center": [ + 490293, + -1485976 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5955.496314 + }, + { + "batch": "more-20261016", + "center": [ + 1325938, + -1102480 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6153.768758 + }, + { + "batch": "more-20261016", + "center": [ + 1083851, + -1559535 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 7215.411041 + }, + { + "batch": "more-20261016", + "center": [ + -1564896, + -297372 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 14595.540764 + }, + { + "batch": "more-20261016", + "center": [ + -188667, + -682845 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 15070.174167 + }, + { + "batch": "more-20261016", + "center": [ + -477498, + 1625359 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 15001.46266 + }, + { + "batch": "more-20261016", + "center": [ + -1494399, + -716616 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 13269.603474 + }, + { + "batch": "more-20261016", + "center": [ + -222855, + -469044 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5866.164965 + }, + { + "batch": "more-20261016", + "center": [ + 524238, + 58888 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5762.909747 + }, + { + "batch": "more-20261016", + "center": [ + 392428, + 683333 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5931.013304 + }, + { + "batch": "more-20261016", + "center": [ + -1397625, + 325316 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5829.381895 + }, + { + "batch": "more-20261016", + "center": [ + 1279320, + -771466 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5896.99046 + }, + { + "batch": "more-20261016", + "center": [ + -449649, + 933565 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5906.303661 + }, + { + "batch": "more-20261016", + "center": [ + -96791, + 369332 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5864.11389 + }, + { + "batch": "more-20261016", + "center": [ + -1624700, + 637783 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5871.760816 + }, + { + "batch": "more-20261016", + "center": [ + 481939, + 1170836 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5862.56754 + }, + { + "batch": "more-20261016", + "center": [ + 616940, + -1642380 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5925.925537 + }, + { + "batch": "more-20261016", + "center": [ + 1728471, + 510588 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5952.515631 + }, + { + "batch": "more-20261016", + "center": [ + -504261, + -825765 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5943.699789 + }, + { + "batch": "more-20261016", + "center": [ + 1428870, + 1469285 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6042.665873 + }, + { + "batch": "more-20261016", + "center": [ + -12716, + -201958 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6275.041978 + }, + { + "batch": "more-20261016", + "center": [ + -1519970, + 1565668 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 6239.067291 + }, + { + "batch": "more-20261016", + "center": [ + 35767, + 1574126 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5975.647292 + }, + { + "batch": "more-20261016", + "center": [ + -378519, + 585138 + ], + "radius_chunks": 512, + "anchors": 525313, + "matches": 0, + "scan_wall_ms": 5836.052954 + } + ], + "total_anchors": 82047228, + "total_matches": 0, + "targeted_search": { + "sampled_coordinates_for_ranking": 65536, + "selected_classes": [ + [ + 1450, + -309427, + 383378 + ], + [ + 1344, + -60272, + -1079339 + ], + [ + 1147, + 851079, + -1401833 + ], + [ + 1147, + -804267, + -1730433 + ], + [ + 1065, + 622802, + 897497 + ], + [ + 1062, + -112067, + -1085729 + ], + [ + 1029, + 570745, + -905547 + ], + [ + 999, + 1015951, + -577814 + ], + [ + 895, + -768179, + 847316 + ], + [ + 883, + -1795128, + 1517010 + ], + [ + 811, + -1381790, + -1499102 + ], + [ + 785, + -1566882, + 739009 + ], + [ + 753, + -348264, + -1451629 + ], + [ + 697, + -940737, + 957948 + ], + [ + 674, + 1776404, + 1352035 + ], + [ + 658, + -828774, + -946913 + ], + [ + 646, + -735624, + -1791272 + ], + [ + 642, + 1147613, + 1507226 + ], + [ + 632, + -983469, + -1523707 + ], + [ + 622, + -1426190, + 1524573 + ], + [ + 614, + 315702, + -667321 + ], + [ + 601, + -38972, + 228469 + ], + [ + 597, + -328043, + 1050949 + ], + [ + 594, + 220587, + -547692 + ], + [ + 590, + 92592, + -933730 + ], + [ + 581, + 1507521, + 577709 + ], + [ + 575, + 337067, + 1484562 + ], + [ + 570, + 1701249, + -996509 + ], + [ + 563, + -708041, + -455276 + ], + [ + 550, + 335595, + -1203922 + ], + [ + 543, + 341418, + 1052887 + ], + [ + 539, + -1792477, + -1026347 + ], + [ + 533, + -31054, + -430081 + ], + [ + 525, + -394366, + -1192193 + ], + [ + 522, + -1628751, + -306760 + ], + [ + 516, + 556545, + -62443 + ], + [ + 506, + 859096, + 313627 + ], + [ + 501, + -114783, + -1011326 + ], + [ + 483, + -1370600, + 730293 + ], + [ + 481, + -216146, + 1015872 + ], + [ + 476, + -1062421, + 1085623 + ], + [ + 464, + -1249671, + 1307087 + ], + [ + 464, + -195106, + -1132815 + ], + [ + 463, + 287072, + 1446775 + ], + [ + 461, + 860112, + -672273 + ], + [ + 458, + -1440521, + -820874 + ], + [ + 444, + 196637, + -748413 + ], + [ + 441, + 962979, + 921037 + ], + [ + 439, + 1756020, + -1102101 + ], + [ + 435, + -1421150, + -409545 + ], + [ + 435, + -1086501, + -1610599 + ], + [ + 418, + -793339, + -597672 + ], + [ + 417, + 790354, + 1309798 + ], + [ + 407, + -482053, + 1753776 + ], + [ + 407, + 838322, + -1223775 + ], + [ + 396, + -543106, + 1724906 + ], + [ + 396, + -842320, + -895468 + ], + [ + 391, + 380877, + 228569 + ], + [ + 391, + 1550806, + -1719783 + ], + [ + 391, + -108500, + 393362 + ], + [ + 382, + -689228, + -990985 + ], + [ + 378, + 1759717, + -743277 + ], + [ + 372, + 1435571, + 370397 + ], + [ + 370, + -7563, + -732238 + ] + ], + "class_period": [ + 65536, + 131072 + ], + "anchor_min": [ + -1875000, + -1875000 + ], + "anchor_max": [ + 1874994, + 1874994 + ], + "anchors": 104538, + "root_jobs": 63786606, + "matches": 0, + "scan_ms": 62660.21000000001 + }, + "count_kind": "anchor visits; different search routes may overlap", + "source_sha256": { + "bench/slime_bench.cu": "3c70cbe2e5babc3e737199fb5e62b78ea9c5daadc0020af77292c2d59516259e", + "include/slime/solver_core.hpp": "feb1200518716b4d796fb60f60a83b6b798155bbd4e795531793181a5c7f9eba", + "include/slime/upper_interval.hpp": "af3fddf7705295d91ffd6e2190f542004a3ecff847fce9d4c9b13125bdbdc2d5" + } +} diff --git a/bench/slime_bench.cu b/bench/slime_bench.cu index 4ec676a..b559625 100644 --- a/bench/slime_bench.cu +++ b/bench/slime_bench.cu @@ -25,7 +25,25 @@ using Clock=std::chrono::steady_clock; struct Coord{int32_t x,z;}; struct Job{uint32_t position,root;}; struct Match{uint64_t seed;int32_t x,z;}; -struct Config{int32_t x=0,z=0;uint64_t radius=0;int size=5,positionBatch=32,jobBatch=2048,repeats=1;uint64_t maxResults=0;size_t cacheClasses=4096;std::string devices="0",output;bool dry=false,list=false;}; +struct PatternCell{int x,z;uint8_t requirement;}; +struct Pattern{int width=0,height=0,positive=0;std::vector rows;std::vector cells;}; +Pattern parsePattern(std::string text){ + std::replace(text.begin(),text.end(),'/','\n'); + Pattern p;std::stringstream input(text);std::string row; + while(std::getline(input,row)){if(!row.empty()&&row.back()=='\r')row.pop_back();if(row.empty())throw std::runtime_error("empty pattern row");p.rows.push_back(row);} + if(p.rows.empty())throw std::runtime_error("empty pattern"); + p.width=p.rows[0].size();p.height=p.rows.size(); + if(p.width>64||p.height>64)throw std::runtime_error("pattern dimensions must be 1..64"); + for(auto& r:p.rows)if(r.size()!=size_t(p.width))throw std::runtime_error("pattern rows must have equal width"); + for(char wanted:{'#','.'})for(int z=0;zINT32_MAX)throw std::runtime_error("invalid int32 coordinate");return int32_t(n);} uint64_t anchors(uint64_t r){return 1+2*r*(r+1);} @@ -38,15 +56,20 @@ Coord coordinate(const Config& c,uint64_t index){ } uint64_t classKey(Coord p){return (uint64_t(uint32_t(p.x)&65535)<<17)|(uint32_t(p.z)&131071);} void terms(Coord p,int n,sr::CellTerm* out){uint64_t anchor=sr::coordinateTerm(p.x,p.z);for(int z=0;z=(uint64_t(positions)<<18))return; uint32_t pos=t>>18,root=t&262143;const auto* p=cells+uint64_t(pos)*count; - for(int i=0;i=n)return;const auto job=jobs[k]; - for(int i=0;i>18; prepared[(uint64_t(k)*count+i)*2+1]=((((a^sr::kCombinedXor)&262143)*sr::kJavaMultiplier+11)>>17); } @@ -61,22 +84,22 @@ __host__ __device__ uint32_t groupMask(const uint32_t*p,uint32_t base,int count) return mask; } struct Emit{ - Coord p;Match* out;uint64_t capacity;unsigned long long* total; - __device__ void operator()(uint64_t seed){uint64_t slot=atomicAdd(total,1ULL);if(slot=(uint64_t(n)<<13))return; uint32_t g=index&8191,k=index>>13,base=((g>>4)<<8)+(g&15);const uint32_t* p=prepared+uint64_t(k)*count*2; - uint32_t mask=groupMask(p,base,count); - Job job=jobs[k];Emit emit{coords[job.position],out,capacity,total}; - while(mask){uint32_t j=__ffs(mask)-1;mask&=mask-1;fs::solveIntervals(job.root+(uint64_t(base+16*j)<<18),cells+uint64_t(job.position)*count,count,emit);} + uint32_t mask=groupMask(p,base,positive); + Job job=jobs[k];Coord origin=coords[job.position];Emit emit{origin,sr::coordinateTerm(origin.x+originX,origin.z+originZ),cells+uint64_t(job.position)*count+positive,count-positive,out,capacity,total}; + while(mask){uint32_t j=__ffs(mask)-1;mask&=mask-1;fs::solveIntervals(job.root+(uint64_t(base+16*j)<<18),cells+uint64_t(job.position)*count,positive,emit);} } templatestruct Buffer{T* p=nullptr;explicit Buffer(size_t n){if(n)CUDA(cudaMalloc(&p,n*sizeof(T)));}~Buffer(){if(p)cudaFree(p);}Buffer(const Buffer&)=delete;}; struct Metrics{int device;std::string name;uint64_t positions=0,classes=0,cacheHits=0,jobs=0,matches=0;double setupMs=0,scanMs=0,rootMs=0,searchMs=0;Clock::time_point start,end;std::vector sample;}; struct Shared{std::atomic next{0},done{0};std::atomic finished{0};int ready=0,workerCount=0;std::condition_variable cv;std::atomic cancel{false};std::mutex mutex;std::string error;}; void worker(const Config& c,int device,Shared& shared,Metrics& result){try{ auto setup=Clock::now();CUDA(cudaSetDevice(device));cudaDeviceProp prop{};CUDA(cudaGetDeviceProperties(&prop,device));result.device=device;result.name=prop.name; - int count=c.size*c.size;size_t rootsCapacity=size_t(c.positionBatch)*(1U<<17); + int count=c.pattern.cells.size(),positive=c.pattern.positive;size_t rootsCapacity=size_t(c.positionBatch)*(1U<<17); Buffer dcells(size_t(c.positionBatch)*count);Bufferdcoords(c.positionBatch);Bufferdroots(rootsCapacity),djobs(c.jobBatch); Bufferprep(size_t(c.jobBatch)*count*2);Buffertotal(1);Buffermatches(c.maxResults); std::map> cache;std::deque fifo;size_t cachedRoots=0; @@ -95,9 +118,9 @@ void worker(const Config& c,int device,Shared& shared,Metrics& result){try{ if(it!=cache.end()){lists[key]=it->second;++result.cacheHits;}else{lists[key]={};missing.push_back(p);missingKeys.push_back(key);} } if(!missing.empty()){ - auto start=Clock::now();std::vector cells(missing.size()*count);for(size_t i=0;i cells(missing.size()*count);for(size_t i=0;i>>(dcells.p,missing.size(),count,droots.p,total.p);CUDA(cudaGetLastError()); + rootsKernel<<>>(dcells.p,missing.size(),count,positive,droots.p,total.p);CUDA(cudaGetLastError()); unsigned long long found;CUDA(cudaMemcpy(&found,total.p,sizeof(found),cudaMemcpyDeviceToHost));if(found>rootsCapacity)throw std::runtime_error("root capacity invariant failed"); std::vector roots(found);if(found)CUDA(cudaMemcpy(roots.data(),droots.p,found*sizeof(Job),cudaMemcpyDeviceToHost)); for(auto job:roots)lists[missingKeys[job.position]].push_back(job.root); @@ -112,12 +135,12 @@ void worker(const Config& c,int device,Shared& shared,Metrics& result){try{ std::vector active;std::vector cells;std::vector jobs;jobs.reserve(c.jobBatch); for(uint32_t i=0;i>>(dcells.p,djobs.p,jobs.size(),count,prep.p); - searchKernel<<>>(dcells.p,dcoords.p,djobs.p,jobs.size(),count,prep.p,matches.p,c.maxResults,total.p);CUDA(cudaGetLastError()); + prepareKernel<<>>(dcells.p,djobs.p,jobs.size(),count,positive,prep.p); + searchKernel<<>>(dcells.p,dcoords.p,djobs.p,jobs.size(),count,positive,c.pattern.cells.front().x,c.pattern.cells.front().z,prep.p,matches.p,c.maxResults,total.p);CUDA(cudaGetLastError()); unsigned long long found;CUDA(cudaMemcpy(&found,total.p,sizeof(found),cudaMemcpyDeviceToHost));if(found>UINT64_MAX-result.matches)throw std::runtime_error("match count exceeds uint64");result.matches+=found;result.jobs+=jobs.size(); size_t take=std::min(found,c.maxResults-result.sample.size());if(take){size_t old=result.sample.size();result.sample.resize(old+take);CUDA(cudaMemcpy(result.sample.data()+old,matches.p,take*sizeof(Match),cudaMemcpyDeviceToHost));} result.searchMs+=std::chrono::duration(Clock::now()-start).count();jobs.clear();}; @@ -130,12 +153,15 @@ void worker(const Config& c,int device,Shared& shared,Metrics& result){try{ }catch(const std::exception& e){shared.cancel=true;std::lock_guard lock(shared.mutex);shared.error="GPU "+std::to_string(device)+": "+e.what();shared.cv.notify_all();}} std::string escape(const std::string&s){std::ostringstream o;for(unsigned char ch:s){if(ch=='"'||ch=='\\')o<<'\\'<=0) - --size N Square side, 1..6 (default 5) + --size N Solid square side, 1..6 (default 5) + --pattern TEXT Rows separated by /; # slime, . non-slime, ? ignored + --pattern-file FILE Same pattern, one row per line (dimensions 1..64) + Requires at least one #; exclusive with --size --devices 0,1,... CUDA device indices, or all (default 0) --repeat N Complete passes; fresh root cache each pass (default 1) --position-batch N Anchors per scheduled batch, 1..256 (default 32) @@ -153,20 +179,28 @@ this diamond. Coordinates are not clipped to Minecraft's world border. Small squares can have enormous numbers of matching seeds and take very long. )";} int main(int argc,char**argv){try{ - Config c;bool radiusSet=false;for(int i=1;i=argc)throw std::runtime_error("missing value for "+a);std::string v=argv[++i]; auto bounded=[&](uint64_t lo,uint64_t hi){auto n=number(v);if(nhi)throw std::runtime_error("out of range: "+a);return n;}; if(a=="--x")c.x=signed32(v);else if(a=="--z")c.z=signed32(v);else if(a=="--radius"){c.radius=bounded(0,INT32_MAX);radiusSet=true;} - else if(a=="--size")c.size=bounded(1,6);else if(a=="--devices")c.devices=v;else if(a=="--repeat")c.repeats=bounded(1,1000); + else if(a=="--size"){c.size=bounded(1,6);sizeSet=true;} + else if(a=="--pattern"||a=="--pattern-file"){if(patternSet)throw std::runtime_error("specify only one pattern");patternSet=true; + if(a=="--pattern")patternText=v;else{std::ifstream file(v);if(!file)throw std::runtime_error("cannot read pattern: "+v);std::ostringstream text;text<INT32_MAX)throw std::runtime_error("coordinates including square must fit int32"); + if(patternSet&&sizeSet)throw std::runtime_error("--size and pattern options are mutually exclusive"); + if(!patternSet){for(int z=0;zINT32_MAX)throw std::runtime_error("coordinates including pattern must fit int32"); if(!c.output.empty()&&std::ifstream(c.output).good())throw std::runtime_error("output already exists: "+c.output); - std::ostringstream report;report< devices;if(c.devices=="all"){for(int i=0;i +struct HostEmit{ + const sr::CellTerm* cells;int count;std::set* result; + __host__ __device__ void operator()(uint64_t seed){ +#ifndef __CUDA_ARCH__ + if(sr::verifyPattern(seed,cells,count))result->insert(seed); +#endif + } +}; void check(bool ok,const char*msg){if(!ok)throw std::runtime_error(msg);} int main(){ - uint64_t points=0,groups=0;std::mt19937_64 rng(123456); + uint64_t points=0,groups=0,mixed=0;std::mt19937_64 rng(123456); for(int r=0;r<=64;++r){Config c;c.x=-123;c.z=98;c.radius=r;std::set> actual; for(uint64_t i=0;i cells(count);terms(coord,pattern,cells.data()); + uint64_t normalized=(world+sr::coordinateTerm(coord.x+pattern.cells.front().x,coord.z+pattern.cells.front().z))&sr::kMask48; + check(sr::verifyPattern(normalized,cells.data(),count),"normalized pattern mismatch"); + uint64_t low=normalized&((1ULL<<35)-1);std::set actual,expected; + HostEmit emit{cells.data()+pattern.positive,count-pattern.positive,&actual}; + fs::solveIntervals(low,cells.data(),pattern.positive,emit); + for(uint64_t high=0;high<8192;++high){uint64_t seed=low+(high<<35); + // Ordinary branch requires a successful first draw at positive cells. + bool ordinary=true;for(int i=0;i>17)%10!=0)ordinary=false; + if(ordinary&&sr::verifyPattern(seed,cells.data(),count))expected.insert(seed); + } + check(actual==expected,"mixed pattern high-bit solver mismatch");++mixed; + uint32_t root=low&262143,base=uint32_t(low>>18)&~240U; + std::vector prepared(count*2); + for(int i=0;i>18;prepared[2*i+1]=((((a^sr::kCombinedXor)&262143)*sr::kJavaMultiplier+11)>>17);} + uint32_t wanted=0;for(int j=0;j<16;++j)if(fs::differenceFilter(root+(uint64_t(base+16*j)<<18),cells.data(),pattern.positive))wanted|=1U< FS_HD FS_INLINE void solveIntervals(uint64_t low, const sr::CellTerm* cells, int count, Emit& emit) {