@@ -127,7 +127,7 @@ const senseRaycast = (pos: d.v2f, angle: number, offset: number) => {
127127 return hitT ;
128128} ;
129129
130- const evalNetwork = ( genome : d . Infer < typeof Genome > , a : d . v4f , b : d . v4f , c : d . v4f ) => {
130+ const evalNetwork = ( genome : d . InferGPU < typeof Genome > , a : d . v4f , b : d . v4f , c : d . v4f ) => {
131131 'use gpu' ;
132132 const h1 = std . tanh (
133133 std . transpose ( genome . h1 . wA ) * a +
@@ -257,23 +257,22 @@ const simulatePipeline = root.createGuardedComputePipeline((i) => {
257257
258258// upper 16 bits = quantized fitness [0,65535], lower 16 bits = car index
259259const reductionPackedBuffer = root . createBuffer ( d . atomic ( d . u32 ) , 0 ) . $usage ( 'storage' ) ;
260- const championGenomeBuffer = root . createBuffer ( Genome ) . $usage ( 'storage' ) ;
261260const bestFitnessBuffer = root . createBuffer ( d . f32 ) . $usage ( 'storage' ) ;
262261
263262const reductionLayout = tgpu . bindGroupLayout ( {
264263 fitness : { storage : FitnessArray } ,
265264 genome : { storage : GenomeArray } ,
266265 packed : { storage : d . atomic ( d . u32 ) , access : 'mutable' } ,
267- championGenome : { storage : Genome , access : 'mutable' } ,
266+ bestIdx : { storage : d . u32 , access : 'mutable' } ,
268267 bestFitness : { storage : d . f32 , access : 'mutable' } ,
269268} ) ;
270269
271270const reductionBindGroups = [ 0 , 1 ] . map ( ( i ) =>
272271 root . createBindGroup ( reductionLayout , {
273272 fitness : ga . fitnessBuffer ,
274273 genome : ga . genomeBuffers [ i ] ,
274+ bestIdx : ga . bestIdxBuffer ,
275275 packed : reductionPackedBuffer ,
276- championGenome : championGenomeBuffer ,
277276 bestFitness : bestFitnessBuffer ,
278277 } ) ,
279278) ;
@@ -289,11 +288,10 @@ const reductionPipeline = root.createGuardedComputePipeline((i) => {
289288 std . atomicMax ( reductionLayout . $ . packed , packed ) ;
290289} ) ;
291290
292- const finalizeReductionPipeline = root . createGuardedComputePipeline ( ( _x ) => {
291+ const finalizeReductionPipeline = root . createGuardedComputePipeline ( ( ) => {
293292 'use gpu' ;
294293 const packed = std . atomicLoad ( reductionLayout . $ . packed ) ;
295- const bestIdx = packed & 0xffff ;
296- reductionLayout . $ . championGenome = Genome ( reductionLayout . $ . genome [ bestIdx ] ) ;
294+ reductionLayout . $ . bestIdx = packed & 0xffff ;
297295 reductionLayout . $ . bestFitness = ( d . f32 ( packed >> 16 ) / 65535 ) * 64 ;
298296} ) ;
299297
@@ -396,7 +394,6 @@ let population = DEFAULT_POP;
396394let rafHandle = 0 ;
397395let pendingEvolve = false ;
398396let showBestOnly = false ;
399- let hasChampion = false ;
400397let displayedBestFitness = 0 ;
401398
402399const statsDiv = document . querySelector ( '.stats' ) as HTMLDivElement ;
@@ -429,12 +426,6 @@ function frame() {
429426 if ( ! paused ) {
430427 if ( pendingEvolve ) {
431428 ga . evolve ( population ) ;
432- if ( hasChampion ) {
433- const src = root . unwrap ( championGenomeBuffer ) ;
434- const encoder = root . device . createCommandEncoder ( ) ;
435- encoder . copyBufferToBuffer ( src , 0 , root . unwrap ( ga . genomeBuffers [ ga . current ] ) , 0 , src . size ) ;
436- root . device . queue . submit ( [ encoder . finish ( ) ] ) ;
437- }
438429 steps = 0 ;
439430 params . writePartial ( { generation : ga . generation } ) ;
440431 pendingEvolve = false ;
@@ -449,11 +440,9 @@ function frame() {
449440 const dispatchCount = Math . ceil ( stepsToRun / innerSteps ) ;
450441
451442 const simEncoder = root . device . createCommandEncoder ( ) ;
443+ const encoderPipeline = simulatePipeline . with ( simBindGroups [ ga . current ] ) . with ( simEncoder ) ;
452444 for ( let dispatch = 0 ; dispatch < dispatchCount ; dispatch ++ ) {
453- simulatePipeline
454- . with ( simBindGroups [ ga . current ] )
455- . with ( simEncoder )
456- . dispatchThreads ( population ) ;
445+ encoderPipeline . dispatchThreads ( population ) ;
457446 }
458447 root . device . queue . submit ( [ simEncoder . finish ( ) ] ) ;
459448
@@ -468,10 +457,9 @@ function frame() {
468457 const reductionEncoder = root . device . createCommandEncoder ( ) ;
469458 reductionEncoder . clearBuffer ( root . unwrap ( reductionPackedBuffer ) ) ;
470459 reductionPipeline . with ( bg ) . with ( reductionEncoder ) . dispatchThreads ( population ) ;
471- finalizeReductionPipeline . with ( bg ) . with ( reductionEncoder ) . dispatchThreads ( 1 ) ;
460+ finalizeReductionPipeline . with ( bg ) . with ( reductionEncoder ) . dispatchThreads ( ) ;
472461 root . device . queue . submit ( [ reductionEncoder . finish ( ) ] ) ;
473462
474- hasChampion = true ;
475463 void bestFitnessBuffer . read ( ) . then ( ( fitness ) => {
476464 displayedBestFitness = fitness ;
477465 } ) ;
@@ -488,7 +476,7 @@ function frame() {
488476 carPipeline
489477 . withColorAttachment ( { view : context , loadOp : 'load' , storeOp : 'store' } )
490478 . with ( instanceLayout , ga . currentStateBuffer )
491- . draw ( 4 , showBestOnly && hasChampion ? 1 : population ) ;
479+ . draw ( 4 , showBestOnly ? 1 : population ) ;
492480
493481 rafHandle = requestAnimationFrame ( frame ) ;
494482}
@@ -527,7 +515,6 @@ let gridSizeKey = 'S';
527515function startSimulation ( ) {
528516 steps = 0 ;
529517 pendingEvolve = false ;
530- hasChampion = false ;
531518 displayedBestFitness = 0 ;
532519 params . writePartial ( { generation : 0 } ) ;
533520 ga . init ( ) ;
0 commit comments