@@ -1494,4 +1494,48 @@ mod tests {
14941494 }
14951495 assert_eq ! ( pipeline. scratch_pool. len( ) , after_burst) ;
14961496 }
1497+
1498+ // ScratchGuard::drop moves the scratch to the pool with mem::take, which leaves the
1499+ // default None variant behind in the guard. The pool must end up holding the scratch
1500+ // the model used: if the None leftover were pushed instead, the pool would still
1501+ // count one scratch, and the next encode would take it and panic in
1502+ // PipelineModel::tokenize_pipeline.
1503+ #[ test]
1504+ fn the_pool_gets_back_the_used_scratch_not_the_none_leftover ( ) {
1505+ let pipeline = hello_pipeline ( ) ;
1506+ pipeline. encode ( "hello" , false ) . unwrap ( ) ;
1507+ assert_eq ! ( pipeline. scratch_pool. len( ) , 1 ) ;
1508+ let scratch = pipeline. scratch_pool . get ( & pipeline. model ) ;
1509+ assert ! (
1510+ matches!( * scratch, PipelineModelScratch :: BPE ( _) ) ,
1511+ "the pooled scratch is not the BPE scratch the model used"
1512+ ) ;
1513+ }
1514+
1515+ // Pooling is only worth it if a scratch keeps the state it built up across calls.
1516+ // A fresh BpeScratch has room for 64 symbols; encoding a longer sequence grows it.
1517+ // After a second, short encode the pooled scratch must still be the grown one,
1518+ // not a fresh replacement built somewhere along the way.
1519+ #[ test]
1520+ fn a_reused_scratch_keeps_its_grown_buffers ( ) {
1521+ let pipeline = hello_pipeline ( ) ;
1522+ let long_input = "hello" . repeat ( 50 ) ;
1523+ pipeline. encode ( & long_input, false ) . unwrap ( ) ;
1524+ assert_eq ! ( pipeline. scratch_pool. len( ) , 1 ) ;
1525+
1526+ pipeline. encode ( "hello" , false ) . unwrap ( ) ;
1527+ assert_eq ! ( pipeline. scratch_pool. len( ) , 1 ) ;
1528+
1529+ let scratch = pipeline. scratch_pool . get ( & pipeline. model ) ;
1530+ let PipelineModelScratch :: BPE ( bpe_scratch) = & * scratch else {
1531+ panic ! ( "the pooled scratch is not a BPE scratch" ) ;
1532+ } ;
1533+ assert ! (
1534+ bpe_scratch. word. capacity( ) >= long_input. len( ) ,
1535+ "the pooled scratch is not the one grown by the long input: \
1536+ room for {} symbols after a {}-byte input",
1537+ bpe_scratch. word. capacity( ) ,
1538+ long_input. len( )
1539+ ) ;
1540+ }
14971541}
0 commit comments