Support custom slime chunk patterns in CUDA finder

This commit is contained in:
Yaossg 2026-10-16 23:51:12 +08:00
parent dd5fab9540
commit 7952207735
10 changed files with 2302 additions and 34 deletions

View file

@ -26,8 +26,31 @@ def main():
assert r['anchors']==1+2*radius*(radius+1)
assert r['first_anchor']==[-123,456-radius] and r['last_anchor']==[-123,456+radius]
for bad in [[],['--radius','-1'],['--radius','1','--size','0'],['--radius','1','--size','7'],['--radius','abc'],['--radius','0','--x','2147483647'],['--radius','1','--repeat','0'],['--radius','1','--position-batch','0']]:run(*bad,'--dry-run',ok=False)
summary={'cli_scope_and_errors':True}
pattern='?##./#..?/..#?'
r=run('--radius',0,'--pattern',pattern,'--dry-run')
assert r['pattern']==pattern.split('/') and r['square_size'] is None
assert (r['pattern_width'],r['pattern_height'],r['slime_cells'],r['non_slime_cells'])==(4,3,4,5)
for bad_pattern in ['', '.', '??', '#/##', '#x', '#//.', '#/'+'#'*65]:
run('--radius',0,'--pattern',bad_pattern,'--dry-run',ok=False)
run('--radius',0,'--size',5,'--pattern','#','--dry-run',ok=False)
run('--radius',0,'--pattern','#','--pattern','#','--dry-run',ok=False)
run('--radius',0,'--pattern-file','/nonexistent-pattern','--dry-run',ok=False)
run('--radius',0,'--x',2147483647,'--pattern','?#','--dry-run',ok=False)
r=run('--radius',0,'--x',2147483647,'--pattern','#/#','--dry-run')
with tempfile.TemporaryDirectory() as tmp:
path=Path(tmp)/'pattern.txt';path.write_bytes(b'?##.\r\n#..?\r\n..#?\r\n')
assert run('--radius',0,'--pattern-file',path,'--dry-run')['pattern']==pattern.split('/')
summary={'cli_scope_and_errors':True,'pattern_inputs':True}
if args.gpu:
# A mixed-mask regression fixture; this is not the target creeper pattern.
fixture=json.loads((HERE/'testdata/mixed-mask-regression.json').read_text())
face=run('--x',fixture['chunk_x'],'--z',fixture['chunk_z'],'--radius',0,
'--pattern','/'.join(fixture['pattern']),'--max-results',1000)
hits=face['rounds'][0]
assert not hits['sample_truncated'] and any(s==fixture['seed48'] for s,x,z in hits['sample'])
for seed,x,z in hits['sample']:
assert all(slime(seed,x+dx,z+dz)==(ch=='#') for dz,row in enumerate(fixture['pattern']) for dx,ch in enumerate(row))
summary['mixed_mask_verified_matches']=hits['matches']
common=['--x',51069,'--z',419124]
reference=run(*common,'--radius',0,'--size',5,'--repeat',2,'--max-results',100)
expected={61692151016558,15959335054446}
@ -45,6 +68,36 @@ def main():
wanted={t for t in samples[0] if all(slime(t[0],t[1]+dx,t[2]+dz) for dx in range(n) for dz in range(n))}
assert set(map(tuple,r['rounds'][0]['sample']))==wanted
summary[f'size_{n}']=r['rounds'][0]['matches']
# The same 5x5 positive constraints, shifted inside a non-square mask.
# Empty anchor exercises normalization independently of the first #.
rows=['?'*7]+['?'+'#'*5+'.' for _ in range(5)]+['?.?????']
pattern='/'.join(rows)
masked=run('--x',51068,'--z',419123,'--radius',0,'--pattern',pattern,'--max-results',100)
wanted={(seed,51068,419123) for seed,x,z in samples[0]
if all(ch=='?' or slime(seed,51068+dx,419123+dz)==(ch=='#')
for dz,row in enumerate(rows) for dx,ch in enumerate(row))}
assert wanted and set(map(tuple,masked['rounds'][0]['sample']))==wanted
assert masked['rounds'][0]['matches']==len(wanted)
# Identical positive subset, but ignored rather than forbidden background.
ignored=pattern.replace('.', '?')
loose=run('--x',51068,'--z',419123,'--radius',0,'--pattern',ignored,'--max-results',100)
assert {s for s,x,z in loose['rounds'][0]['sample']}=={s for s,x,z in samples[0]}
# Force a forbidden cell to reject at least one known positive candidate.
seed=next(iter(samples[0]))[0]
dx,dz=next((dx,dz) for dz in range(16) for dx in range(16)
if not (1<=dx<=5 and 1<=dz<=5) and slime(seed,51068+dx,419123+dz))
rejection=[list('?'*16) for _ in range(16)]
for z in range(1,6):
for x in range(1,6):rejection[z][x]='#'
rejection[dz][dx]='.'
rejected=run('--x',51068,'--z',419123,'--radius',0,'--pattern',
'/'.join(''.join(row) for row in rejection),'--max-results',100)
expected_seeds={s for s,x,z in samples[0] if not slime(s,51068+dx,419123+dz)}
assert len(expected_seeds)<24
assert {s for s,x,z in rejected['rounds'][0]['sample']}==expected_seeds
assert rejected['rounds'][0]['matches']==len(expected_seeds)
summary['mixed_pattern_vs_independent_filter']=len(wanted)
summary['forbidden_cell_excludes_candidates']=True
diamond=run(*common,'--radius',2,'--size',5,'--max-results',1000,'--position-batch',3)
split=[]
for dz in range(-2,3):