From c98d25c255e529a2f080becdf29e709920fdf273 Mon Sep 17 00:00:00 2001 From: monkey-w1n5t0n Date: Tue, 21 Jul 2026 12:48:50 +0200 Subject: [PATCH] refactor(wasm): delete 12 dead C-API entries and the weights-publish channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 1 group 4 (S33, S34, L54). - S33: removed 12 dead entries across the full 5-layer registration chain (bindings.cpp KEEPALIVE -> EXPORTED_FUNCTIONS -> the NispsModule declaration table -> the WasmIML wrapper -> the EngineApi facade): nisps_ml_reset, example_count, move_weights, feedback_learning_paused, feedback_drag, jolt_lr_scale, jolt_tick_lr_ramp, pipeline_state_size/save_state/load_state, feedback_placing and feedback_state. Each was grepped against manifold/src, manifold/tests, the e2e specs, manifold/tests/wasm-load.ts and tests/cpp/parity_wasm.mjs — the parity gate builds its own API via cwrap and is a real consumer, so it counts. KEPT deliberately: EXPORTED_RUNTIME's heap views + ccall/cwrap (the parity harness and wasm-load.ts depend on them), and nisps_ml_feedback_static_output, whose C export IS called directly by parity_wasm.mjs even though no TS wrapper reaches it. Also dropped parity_wasm.mjs's moveWeights cwrap, which was declared but never invoked. - S34: deleted the publishWeights_ channel — EngineSink.setWeights, Spine.setWeights/weights()/liveWeights and every call site. It ran a C->heap copy plus a fresh Float32Array allocation at up to 200 Hz into a field nothing read. getWeights survives for persistence and the debug probe. - L54: worklet loader — deleted the unused imports object, the 'c' branch, exMap and the duplicate second loop, and replaced the silent `() => 0` stub with one that throws, so a missing import fails loudly instead of returning plausible zeros into the audio path. manifold/public/nisps.{js,wasm} rebuilt with the trimmed export list (emcc 3.1.69, the CI-pinned version) and committed — the freshness gate added in Phase 0 requires it, and the webhook ships this artifact to production. Gates: run-all-tests.sh ALL GREEN, parity 1273 floats within 1e-5. --- manifold/public/nisps.js | 2 +- manifold/public/nisps.wasm | Bin 131692 -> 130000 bytes manifold/src/engine/engine-api.ts | 17 --- manifold/src/engine/sink.ts | 3 - manifold/src/engine/spine.ts | 18 +--- manifold/src/engine/types.ts | 12 --- manifold/src/engine/wasm-iml.ts | 81 +-------------- .../src/engine/worklet/nisps-processor.ts | 48 +++------ nisps/wasm/README.md | 6 +- nisps/wasm/bindings.cpp | 97 ------------------ scripts/build-wasm.sh | 15 ++- tests/cpp/parity_wasm.mjs | 1 - 12 files changed, 33 insertions(+), 267 deletions(-) diff --git a/manifold/public/nisps.js b/manifold/public/nisps.js index 0c7ad29..794bc3c 100644 --- a/manifold/public/nisps.js +++ b/manifold/public/nisps.js @@ -6,7 +6,7 @@ var createNispsModule = (() => { function(moduleArg = {}) { var moduleRtn; -var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string"&&process.type!="renderer";var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptName){scriptDirectory=_scriptName}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=url=>fetch(url,{credentials:"same-origin"}).then(response=>{if(response.ok){return response.arrayBuffer()}return Promise.reject(new Error(response.status+" : "+response.url))})}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var wasmBinary=Module["wasmBinary"];var wasmMemory;var ABORT=false;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){var preRuns=Module["preRun"];if(preRuns){if(typeof preRuns=="function")preRuns=[preRuns];preRuns.forEach(addOnPreRun)}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){var postRuns=Module["postRun"];if(postRuns){if(typeof postRuns=="function")postRuns=[postRuns];postRuns.forEach(addOnPostRun)}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);function findWasmBinary(){var f="nisps.wasm";if(!isDataURI(f)){return locateFile(f)}return f}var wasmBinaryFile;function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary){return readAsync(binaryFile).then(response=>new Uint8Array(response),()=>getBinarySync(binaryFile))}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function getWasmImports(){return{a:wasmImports}}function createWasm(){var info=getWasmImports();function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["d"];updateMemoryViews();addOnInit(wasmExports["e"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}wasmBinaryFile??=findWasmBinary();instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var callRuntimeCallbacks=callbacks=>{callbacks.forEach(f=>f(Module))};var noExitRuntime=Module["noExitRuntime"]||true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var __abort_js=()=>{abort("")};var __emscripten_memcpy_js=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead=NaN)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};var wasmImports={c:__abort_js,b:__emscripten_memcpy_js,a:_emscripten_resize_heap};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["e"])();var _nisps_ml_create=Module["_nisps_ml_create"]=(a0,a1,a2,a3,a4)=>(_nisps_ml_create=Module["_nisps_ml_create"]=wasmExports["f"])(a0,a1,a2,a3,a4);var _nisps_ml_reshape=Module["_nisps_ml_reshape"]=(a0,a1,a2,a3,a4,a5)=>(_nisps_ml_reshape=Module["_nisps_ml_reshape"]=wasmExports["g"])(a0,a1,a2,a3,a4,a5);var _nisps_ml_destroy=Module["_nisps_ml_destroy"]=a0=>(_nisps_ml_destroy=Module["_nisps_ml_destroy"]=wasmExports["h"])(a0);var _nisps_ml_set_input=Module["_nisps_ml_set_input"]=(a0,a1,a2)=>(_nisps_ml_set_input=Module["_nisps_ml_set_input"]=wasmExports["i"])(a0,a1,a2);var _nisps_ml_process=Module["_nisps_ml_process"]=a0=>(_nisps_ml_process=Module["_nisps_ml_process"]=wasmExports["j"])(a0);var _nisps_ml_outputs=Module["_nisps_ml_outputs"]=a0=>(_nisps_ml_outputs=Module["_nisps_ml_outputs"]=wasmExports["k"])(a0);var _nisps_ml_infer_batch=Module["_nisps_ml_infer_batch"]=(a0,a1,a2,a3)=>(_nisps_ml_infer_batch=Module["_nisps_ml_infer_batch"]=wasmExports["l"])(a0,a1,a2,a3);var _nisps_ml_add_example=Module["_nisps_ml_add_example"]=(a0,a1,a2)=>(_nisps_ml_add_example=Module["_nisps_ml_add_example"]=wasmExports["m"])(a0,a1,a2);var _nisps_ml_train=Module["_nisps_ml_train"]=(a0,a1,a2,a3,a4)=>(_nisps_ml_train=Module["_nisps_ml_train"]=wasmExports["n"])(a0,a1,a2,a3,a4);var _nisps_ml_eval_loss=Module["_nisps_ml_eval_loss"]=a0=>(_nisps_ml_eval_loss=Module["_nisps_ml_eval_loss"]=wasmExports["o"])(a0);var _nisps_ml_weight_count=Module["_nisps_ml_weight_count"]=a0=>(_nisps_ml_weight_count=Module["_nisps_ml_weight_count"]=wasmExports["p"])(a0);var _nisps_ml_get_weights=Module["_nisps_ml_get_weights"]=(a0,a1)=>(_nisps_ml_get_weights=Module["_nisps_ml_get_weights"]=wasmExports["q"])(a0,a1);var _nisps_ml_set_weights=Module["_nisps_ml_set_weights"]=(a0,a1)=>(_nisps_ml_set_weights=Module["_nisps_ml_set_weights"]=wasmExports["r"])(a0,a1);var _nisps_ml_draw_weights=Module["_nisps_ml_draw_weights"]=(a0,a1)=>(_nisps_ml_draw_weights=Module["_nisps_ml_draw_weights"]=wasmExports["s"])(a0,a1);var _nisps_ml_move_weights=Module["_nisps_ml_move_weights"]=(a0,a1,a2,a3)=>(_nisps_ml_move_weights=Module["_nisps_ml_move_weights"]=wasmExports["t"])(a0,a1,a2,a3);var _nisps_ml_feedback_set_mode=Module["_nisps_ml_feedback_set_mode"]=(a0,a1)=>(_nisps_ml_feedback_set_mode=Module["_nisps_ml_feedback_set_mode"]=wasmExports["u"])(a0,a1);var _nisps_ml_feedback_get_mode=Module["_nisps_ml_feedback_get_mode"]=a0=>(_nisps_ml_feedback_get_mode=Module["_nisps_ml_feedback_get_mode"]=wasmExports["v"])(a0);var _nisps_ml_feedback_exploring=Module["_nisps_ml_feedback_exploring"]=a0=>(_nisps_ml_feedback_exploring=Module["_nisps_ml_feedback_exploring"]=wasmExports["w"])(a0);var _nisps_ml_feedback_learning_paused=Module["_nisps_ml_feedback_learning_paused"]=a0=>(_nisps_ml_feedback_learning_paused=Module["_nisps_ml_feedback_learning_paused"]=wasmExports["x"])(a0);var _nisps_ml_feedback_set_focus=Module["_nisps_ml_feedback_set_focus"]=(a0,a1,a2)=>(_nisps_ml_feedback_set_focus=Module["_nisps_ml_feedback_set_focus"]=wasmExports["y"])(a0,a1,a2);var _nisps_ml_feedback_down=Module["_nisps_ml_feedback_down"]=(a0,a1,a2,a3,a4)=>(_nisps_ml_feedback_down=Module["_nisps_ml_feedback_down"]=wasmExports["z"])(a0,a1,a2,a3,a4);var _nisps_ml_feedback_up=Module["_nisps_ml_feedback_up"]=a0=>(_nisps_ml_feedback_up=Module["_nisps_ml_feedback_up"]=wasmExports["A"])(a0);var _nisps_ml_feedback_drag=Module["_nisps_ml_feedback_drag"]=a0=>(_nisps_ml_feedback_drag=Module["_nisps_ml_feedback_drag"]=wasmExports["B"])(a0);var _nisps_ml_feedback_static_output=Module["_nisps_ml_feedback_static_output"]=(a0,a1)=>(_nisps_ml_feedback_static_output=Module["_nisps_ml_feedback_static_output"]=wasmExports["C"])(a0,a1);var _nisps_ml_feedback_enter_explore=Module["_nisps_ml_feedback_enter_explore"]=(a0,a1)=>(_nisps_ml_feedback_enter_explore=Module["_nisps_ml_feedback_enter_explore"]=wasmExports["D"])(a0,a1);var _nisps_ml_feedback_exit_explore=Module["_nisps_ml_feedback_exit_explore"]=a0=>(_nisps_ml_feedback_exit_explore=Module["_nisps_ml_feedback_exit_explore"]=wasmExports["E"])(a0);var _nisps_ml_feedback_reroll=Module["_nisps_ml_feedback_reroll"]=(a0,a1)=>(_nisps_ml_feedback_reroll=Module["_nisps_ml_feedback_reroll"]=wasmExports["F"])(a0,a1);var _nisps_ml_feedback_nudge=Module["_nisps_ml_feedback_nudge"]=(a0,a1)=>(_nisps_ml_feedback_nudge=Module["_nisps_ml_feedback_nudge"]=wasmExports["G"])(a0,a1);var _nisps_ml_feedback_undo=Module["_nisps_ml_feedback_undo"]=a0=>(_nisps_ml_feedback_undo=Module["_nisps_ml_feedback_undo"]=wasmExports["H"])(a0);var _nisps_ml_feedback_like=Module["_nisps_ml_feedback_like"]=a0=>(_nisps_ml_feedback_like=Module["_nisps_ml_feedback_like"]=wasmExports["I"])(a0);var _nisps_ml_feedback_commit_place=Module["_nisps_ml_feedback_commit_place"]=a0=>(_nisps_ml_feedback_commit_place=Module["_nisps_ml_feedback_commit_place"]=wasmExports["J"])(a0);var _nisps_ml_feedback_cancel_place=Module["_nisps_ml_feedback_cancel_place"]=a0=>(_nisps_ml_feedback_cancel_place=Module["_nisps_ml_feedback_cancel_place"]=wasmExports["K"])(a0);var _nisps_ml_feedback_placing=Module["_nisps_ml_feedback_placing"]=a0=>(_nisps_ml_feedback_placing=Module["_nisps_ml_feedback_placing"]=wasmExports["L"])(a0);var _nisps_ml_feedback_state=Module["_nisps_ml_feedback_state"]=a0=>(_nisps_ml_feedback_state=Module["_nisps_ml_feedback_state"]=wasmExports["M"])(a0);var _nisps_ml_feedback_undo_depth=Module["_nisps_ml_feedback_undo_depth"]=a0=>(_nisps_ml_feedback_undo_depth=Module["_nisps_ml_feedback_undo_depth"]=wasmExports["N"])(a0);var _nisps_ml_feedback_placed_output=Module["_nisps_ml_feedback_placed_output"]=(a0,a1)=>(_nisps_ml_feedback_placed_output=Module["_nisps_ml_feedback_placed_output"]=wasmExports["O"])(a0,a1);var _nisps_ml_feedback_dislike_geometric=Module["_nisps_ml_feedback_dislike_geometric"]=(a0,a1,a2)=>(_nisps_ml_feedback_dislike_geometric=Module["_nisps_ml_feedback_dislike_geometric"]=wasmExports["P"])(a0,a1,a2);var _nisps_ml_feedback_store_positive=Module["_nisps_ml_feedback_store_positive"]=(a0,a1)=>(_nisps_ml_feedback_store_positive=Module["_nisps_ml_feedback_store_positive"]=wasmExports["Q"])(a0,a1);var _nisps_ml_feedback_positive_count=Module["_nisps_ml_feedback_positive_count"]=a0=>(_nisps_ml_feedback_positive_count=Module["_nisps_ml_feedback_positive_count"]=wasmExports["R"])(a0);var _nisps_ml_feedback_negative_count=Module["_nisps_ml_feedback_negative_count"]=a0=>(_nisps_ml_feedback_negative_count=Module["_nisps_ml_feedback_negative_count"]=wasmExports["S"])(a0);var _nisps_ml_feedback_set_avoid_style=Module["_nisps_ml_feedback_set_avoid_style"]=(a0,a1)=>(_nisps_ml_feedback_set_avoid_style=Module["_nisps_ml_feedback_set_avoid_style"]=wasmExports["T"])(a0,a1);var _nisps_ml_jolt_press=Module["_nisps_ml_jolt_press"]=a0=>(_nisps_ml_jolt_press=Module["_nisps_ml_jolt_press"]=wasmExports["U"])(a0);var _nisps_ml_jolt_step=Module["_nisps_ml_jolt_step"]=a0=>(_nisps_ml_jolt_step=Module["_nisps_ml_jolt_step"]=wasmExports["V"])(a0);var _nisps_ml_jolt_release=Module["_nisps_ml_jolt_release"]=a0=>(_nisps_ml_jolt_release=Module["_nisps_ml_jolt_release"]=wasmExports["W"])(a0);var _nisps_ml_jolt_active=Module["_nisps_ml_jolt_active"]=a0=>(_nisps_ml_jolt_active=Module["_nisps_ml_jolt_active"]=wasmExports["X"])(a0);var _nisps_ml_jolt_lr_scale=Module["_nisps_ml_jolt_lr_scale"]=a0=>(_nisps_ml_jolt_lr_scale=Module["_nisps_ml_jolt_lr_scale"]=wasmExports["Y"])(a0);var _nisps_ml_jolt_tick_lr_ramp=Module["_nisps_ml_jolt_tick_lr_ramp"]=a0=>(_nisps_ml_jolt_tick_lr_ramp=Module["_nisps_ml_jolt_tick_lr_ramp"]=wasmExports["Z"])(a0);var _nisps_ml_explore_intensity=Module["_nisps_ml_explore_intensity"]=(a0,a1)=>(_nisps_ml_explore_intensity=Module["_nisps_ml_explore_intensity"]=wasmExports["_"])(a0,a1);var _nisps_ml_explore_get_intensity=Module["_nisps_ml_explore_get_intensity"]=a0=>(_nisps_ml_explore_get_intensity=Module["_nisps_ml_explore_get_intensity"]=wasmExports["$"])(a0);var _nisps_ml_explore_apply=Module["_nisps_ml_explore_apply"]=(a0,a1,a2)=>(_nisps_ml_explore_apply=Module["_nisps_ml_explore_apply"]=wasmExports["aa"])(a0,a1,a2);var _nisps_ml_get_layer_stats=Module["_nisps_ml_get_layer_stats"]=(a0,a1)=>(_nisps_ml_get_layer_stats=Module["_nisps_ml_get_layer_stats"]=wasmExports["ba"])(a0,a1);var _nisps_ml_example_count=Module["_nisps_ml_example_count"]=a0=>(_nisps_ml_example_count=Module["_nisps_ml_example_count"]=wasmExports["ca"])(a0);var _nisps_ml_clear_examples=Module["_nisps_ml_clear_examples"]=a0=>(_nisps_ml_clear_examples=Module["_nisps_ml_clear_examples"]=wasmExports["da"])(a0);var _nisps_ml_reset=Module["_nisps_ml_reset"]=a0=>(_nisps_ml_reset=Module["_nisps_ml_reset"]=wasmExports["ea"])(a0);var _nisps_ml_describe=Module["_nisps_ml_describe"]=(a0,a1)=>(_nisps_ml_describe=Module["_nisps_ml_describe"]=wasmExports["fa"])(a0,a1);var _nisps_pipeline_create=Module["_nisps_pipeline_create"]=()=>(_nisps_pipeline_create=Module["_nisps_pipeline_create"]=wasmExports["ga"])();var _nisps_pipeline_destroy=Module["_nisps_pipeline_destroy"]=a0=>(_nisps_pipeline_destroy=Module["_nisps_pipeline_destroy"]=wasmExports["ha"])(a0);var _nisps_input_set_config=Module["_nisps_input_set_config"]=(a0,a1,a2)=>(_nisps_input_set_config=Module["_nisps_input_set_config"]=wasmExports["ia"])(a0,a1,a2);var _nisps_input_process=Module["_nisps_input_process"]=(a0,a1,a2,a3,a4)=>(_nisps_input_process=Module["_nisps_input_process"]=wasmExports["ja"])(a0,a1,a2,a3,a4);var _nisps_input_reset=Module["_nisps_input_reset"]=a0=>(_nisps_input_reset=Module["_nisps_input_reset"]=wasmExports["ka"])(a0);var _nisps_output_set_config=Module["_nisps_output_set_config"]=(a0,a1,a2,a3,a4)=>(_nisps_output_set_config=Module["_nisps_output_set_config"]=wasmExports["la"])(a0,a1,a2,a3,a4);var _nisps_output_set_freeze_mask=Module["_nisps_output_set_freeze_mask"]=(a0,a1,a2)=>(_nisps_output_set_freeze_mask=Module["_nisps_output_set_freeze_mask"]=wasmExports["ma"])(a0,a1,a2);var _nisps_output_process=Module["_nisps_output_process"]=(a0,a1,a2,a3)=>(_nisps_output_process=Module["_nisps_output_process"]=wasmExports["na"])(a0,a1,a2,a3);var _nisps_output_reset=Module["_nisps_output_reset"]=a0=>(_nisps_output_reset=Module["_nisps_output_reset"]=wasmExports["oa"])(a0);var _nisps_pipeline_state_size=Module["_nisps_pipeline_state_size"]=a0=>(_nisps_pipeline_state_size=Module["_nisps_pipeline_state_size"]=wasmExports["pa"])(a0);var _nisps_pipeline_save_state=Module["_nisps_pipeline_save_state"]=(a0,a1)=>(_nisps_pipeline_save_state=Module["_nisps_pipeline_save_state"]=wasmExports["qa"])(a0,a1);var _nisps_pipeline_load_state=Module["_nisps_pipeline_load_state"]=(a0,a1,a2)=>(_nisps_pipeline_load_state=Module["_nisps_pipeline_load_state"]=wasmExports["ra"])(a0,a1,a2);var _nisps_curve_apply=Module["_nisps_curve_apply"]=(a0,a1,a2)=>(_nisps_curve_apply=Module["_nisps_curve_apply"]=wasmExports["sa"])(a0,a1,a2);var _nisps_curve_apply_batch=Module["_nisps_curve_apply_batch"]=(a0,a1,a2,a3,a4)=>(_nisps_curve_apply_batch=Module["_nisps_curve_apply_batch"]=wasmExports["ta"])(a0,a1,a2,a3,a4);var _nisps_engine_create=Module["_nisps_engine_create"]=(a0,a1)=>(_nisps_engine_create=Module["_nisps_engine_create"]=wasmExports["ua"])(a0,a1);var _nisps_engine_destroy=Module["_nisps_engine_destroy"]=a0=>(_nisps_engine_destroy=Module["_nisps_engine_destroy"]=wasmExports["va"])(a0);var _nisps_engine_set_params=Module["_nisps_engine_set_params"]=(a0,a1,a2)=>(_nisps_engine_set_params=Module["_nisps_engine_set_params"]=wasmExports["wa"])(a0,a1,a2);var _nisps_engine_process_block=Module["_nisps_engine_process_block"]=(a0,a1,a2,a3,a4,a5)=>(_nisps_engine_process_block=Module["_nisps_engine_process_block"]=wasmExports["xa"])(a0,a1,a2,a3,a4,a5);var _malloc=Module["_malloc"]=a0=>(_malloc=Module["_malloc"]=wasmExports["za"])(a0);var _free=Module["_free"]=a0=>(_free=Module["_free"]=wasmExports["Aa"])(a0);var __emscripten_stack_restore=a0=>(__emscripten_stack_restore=wasmExports["Ba"])(a0);var __emscripten_stack_alloc=a0=>(__emscripten_stack_alloc=wasmExports["Ca"])(a0);var _emscripten_stack_get_current=()=>(_emscripten_stack_get_current=wasmExports["Da"])();Module["ccall"]=ccall;Module["cwrap"]=cwrap;var calledRun;var calledPrerun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(){if(runDependencies>0){return}if(!calledPrerun){calledPrerun=1;preRun();if(runDependencies>0){return}}function doRun(){if(calledRun)return;calledRun=1;Module["calledRun"]=1;if(ABORT)return;initRuntime();readyPromiseResolve(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();moduleRtn=readyPromise; +var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;var readyPromise=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string"&&process.type!="renderer";var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptName){scriptDirectory=_scriptName}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=url=>fetch(url,{credentials:"same-origin"}).then(response=>{if(response.ok){return response.arrayBuffer()}return Promise.reject(new Error(response.status+" : "+response.url))})}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var wasmBinary=Module["wasmBinary"];var wasmMemory;var ABORT=false;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){var preRuns=Module["preRun"];if(preRuns){if(typeof preRuns=="function")preRuns=[preRuns];preRuns.forEach(addOnPreRun)}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){var postRuns=Module["postRun"];if(postRuns){if(typeof postRuns=="function")postRuns=[postRuns];postRuns.forEach(addOnPostRun)}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);function findWasmBinary(){var f="nisps.wasm";if(!isDataURI(f)){return locateFile(f)}return f}var wasmBinaryFile;function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary){return readAsync(binaryFile).then(response=>new Uint8Array(response),()=>getBinarySync(binaryFile))}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function getWasmImports(){return{a:wasmImports}}function createWasm(){var info=getWasmImports();function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["d"];updateMemoryViews();addOnInit(wasmExports["e"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}wasmBinaryFile??=findWasmBinary();instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var callRuntimeCallbacks=callbacks=>{callbacks.forEach(f=>f(Module))};var noExitRuntime=Module["noExitRuntime"]||true;var stackRestore=val=>__emscripten_stack_restore(val);var stackSave=()=>_emscripten_stack_get_current();var __abort_js=()=>{abort("")};var __emscripten_memcpy_js=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stackAlloc=sz=>__emscripten_stack_alloc(sz);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder:undefined;var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead=NaN)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={string:str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},array:arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return(...args)=>ccall(ident,returnType,argTypes,args,opts)};var wasmImports={c:__abort_js,b:__emscripten_memcpy_js,a:_emscripten_resize_heap};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["e"])();var _nisps_ml_create=Module["_nisps_ml_create"]=(a0,a1,a2,a3,a4)=>(_nisps_ml_create=Module["_nisps_ml_create"]=wasmExports["f"])(a0,a1,a2,a3,a4);var _nisps_ml_reshape=Module["_nisps_ml_reshape"]=(a0,a1,a2,a3,a4,a5)=>(_nisps_ml_reshape=Module["_nisps_ml_reshape"]=wasmExports["g"])(a0,a1,a2,a3,a4,a5);var _nisps_ml_destroy=Module["_nisps_ml_destroy"]=a0=>(_nisps_ml_destroy=Module["_nisps_ml_destroy"]=wasmExports["h"])(a0);var _nisps_ml_set_input=Module["_nisps_ml_set_input"]=(a0,a1,a2)=>(_nisps_ml_set_input=Module["_nisps_ml_set_input"]=wasmExports["i"])(a0,a1,a2);var _nisps_ml_process=Module["_nisps_ml_process"]=a0=>(_nisps_ml_process=Module["_nisps_ml_process"]=wasmExports["j"])(a0);var _nisps_ml_outputs=Module["_nisps_ml_outputs"]=a0=>(_nisps_ml_outputs=Module["_nisps_ml_outputs"]=wasmExports["k"])(a0);var _nisps_ml_infer_batch=Module["_nisps_ml_infer_batch"]=(a0,a1,a2,a3)=>(_nisps_ml_infer_batch=Module["_nisps_ml_infer_batch"]=wasmExports["l"])(a0,a1,a2,a3);var _nisps_ml_add_example=Module["_nisps_ml_add_example"]=(a0,a1,a2)=>(_nisps_ml_add_example=Module["_nisps_ml_add_example"]=wasmExports["m"])(a0,a1,a2);var _nisps_ml_train=Module["_nisps_ml_train"]=(a0,a1,a2,a3,a4)=>(_nisps_ml_train=Module["_nisps_ml_train"]=wasmExports["n"])(a0,a1,a2,a3,a4);var _nisps_ml_eval_loss=Module["_nisps_ml_eval_loss"]=a0=>(_nisps_ml_eval_loss=Module["_nisps_ml_eval_loss"]=wasmExports["o"])(a0);var _nisps_ml_weight_count=Module["_nisps_ml_weight_count"]=a0=>(_nisps_ml_weight_count=Module["_nisps_ml_weight_count"]=wasmExports["p"])(a0);var _nisps_ml_get_weights=Module["_nisps_ml_get_weights"]=(a0,a1)=>(_nisps_ml_get_weights=Module["_nisps_ml_get_weights"]=wasmExports["q"])(a0,a1);var _nisps_ml_set_weights=Module["_nisps_ml_set_weights"]=(a0,a1)=>(_nisps_ml_set_weights=Module["_nisps_ml_set_weights"]=wasmExports["r"])(a0,a1);var _nisps_ml_draw_weights=Module["_nisps_ml_draw_weights"]=(a0,a1)=>(_nisps_ml_draw_weights=Module["_nisps_ml_draw_weights"]=wasmExports["s"])(a0,a1);var _nisps_ml_feedback_set_mode=Module["_nisps_ml_feedback_set_mode"]=(a0,a1)=>(_nisps_ml_feedback_set_mode=Module["_nisps_ml_feedback_set_mode"]=wasmExports["t"])(a0,a1);var _nisps_ml_feedback_get_mode=Module["_nisps_ml_feedback_get_mode"]=a0=>(_nisps_ml_feedback_get_mode=Module["_nisps_ml_feedback_get_mode"]=wasmExports["u"])(a0);var _nisps_ml_feedback_exploring=Module["_nisps_ml_feedback_exploring"]=a0=>(_nisps_ml_feedback_exploring=Module["_nisps_ml_feedback_exploring"]=wasmExports["v"])(a0);var _nisps_ml_feedback_set_focus=Module["_nisps_ml_feedback_set_focus"]=(a0,a1,a2)=>(_nisps_ml_feedback_set_focus=Module["_nisps_ml_feedback_set_focus"]=wasmExports["w"])(a0,a1,a2);var _nisps_ml_feedback_down=Module["_nisps_ml_feedback_down"]=(a0,a1,a2,a3,a4)=>(_nisps_ml_feedback_down=Module["_nisps_ml_feedback_down"]=wasmExports["x"])(a0,a1,a2,a3,a4);var _nisps_ml_feedback_up=Module["_nisps_ml_feedback_up"]=a0=>(_nisps_ml_feedback_up=Module["_nisps_ml_feedback_up"]=wasmExports["y"])(a0);var _nisps_ml_feedback_static_output=Module["_nisps_ml_feedback_static_output"]=(a0,a1)=>(_nisps_ml_feedback_static_output=Module["_nisps_ml_feedback_static_output"]=wasmExports["z"])(a0,a1);var _nisps_ml_feedback_enter_explore=Module["_nisps_ml_feedback_enter_explore"]=(a0,a1)=>(_nisps_ml_feedback_enter_explore=Module["_nisps_ml_feedback_enter_explore"]=wasmExports["A"])(a0,a1);var _nisps_ml_feedback_exit_explore=Module["_nisps_ml_feedback_exit_explore"]=a0=>(_nisps_ml_feedback_exit_explore=Module["_nisps_ml_feedback_exit_explore"]=wasmExports["B"])(a0);var _nisps_ml_feedback_reroll=Module["_nisps_ml_feedback_reroll"]=(a0,a1)=>(_nisps_ml_feedback_reroll=Module["_nisps_ml_feedback_reroll"]=wasmExports["C"])(a0,a1);var _nisps_ml_feedback_nudge=Module["_nisps_ml_feedback_nudge"]=(a0,a1)=>(_nisps_ml_feedback_nudge=Module["_nisps_ml_feedback_nudge"]=wasmExports["D"])(a0,a1);var _nisps_ml_feedback_undo=Module["_nisps_ml_feedback_undo"]=a0=>(_nisps_ml_feedback_undo=Module["_nisps_ml_feedback_undo"]=wasmExports["E"])(a0);var _nisps_ml_feedback_like=Module["_nisps_ml_feedback_like"]=a0=>(_nisps_ml_feedback_like=Module["_nisps_ml_feedback_like"]=wasmExports["F"])(a0);var _nisps_ml_feedback_commit_place=Module["_nisps_ml_feedback_commit_place"]=a0=>(_nisps_ml_feedback_commit_place=Module["_nisps_ml_feedback_commit_place"]=wasmExports["G"])(a0);var _nisps_ml_feedback_cancel_place=Module["_nisps_ml_feedback_cancel_place"]=a0=>(_nisps_ml_feedback_cancel_place=Module["_nisps_ml_feedback_cancel_place"]=wasmExports["H"])(a0);var _nisps_ml_feedback_undo_depth=Module["_nisps_ml_feedback_undo_depth"]=a0=>(_nisps_ml_feedback_undo_depth=Module["_nisps_ml_feedback_undo_depth"]=wasmExports["I"])(a0);var _nisps_ml_feedback_placed_output=Module["_nisps_ml_feedback_placed_output"]=(a0,a1)=>(_nisps_ml_feedback_placed_output=Module["_nisps_ml_feedback_placed_output"]=wasmExports["J"])(a0,a1);var _nisps_ml_feedback_dislike_geometric=Module["_nisps_ml_feedback_dislike_geometric"]=(a0,a1,a2)=>(_nisps_ml_feedback_dislike_geometric=Module["_nisps_ml_feedback_dislike_geometric"]=wasmExports["K"])(a0,a1,a2);var _nisps_ml_feedback_store_positive=Module["_nisps_ml_feedback_store_positive"]=(a0,a1)=>(_nisps_ml_feedback_store_positive=Module["_nisps_ml_feedback_store_positive"]=wasmExports["L"])(a0,a1);var _nisps_ml_feedback_positive_count=Module["_nisps_ml_feedback_positive_count"]=a0=>(_nisps_ml_feedback_positive_count=Module["_nisps_ml_feedback_positive_count"]=wasmExports["M"])(a0);var _nisps_ml_feedback_negative_count=Module["_nisps_ml_feedback_negative_count"]=a0=>(_nisps_ml_feedback_negative_count=Module["_nisps_ml_feedback_negative_count"]=wasmExports["N"])(a0);var _nisps_ml_feedback_set_avoid_style=Module["_nisps_ml_feedback_set_avoid_style"]=(a0,a1)=>(_nisps_ml_feedback_set_avoid_style=Module["_nisps_ml_feedback_set_avoid_style"]=wasmExports["O"])(a0,a1);var _nisps_ml_jolt_press=Module["_nisps_ml_jolt_press"]=a0=>(_nisps_ml_jolt_press=Module["_nisps_ml_jolt_press"]=wasmExports["P"])(a0);var _nisps_ml_jolt_step=Module["_nisps_ml_jolt_step"]=a0=>(_nisps_ml_jolt_step=Module["_nisps_ml_jolt_step"]=wasmExports["Q"])(a0);var _nisps_ml_jolt_release=Module["_nisps_ml_jolt_release"]=a0=>(_nisps_ml_jolt_release=Module["_nisps_ml_jolt_release"]=wasmExports["R"])(a0);var _nisps_ml_jolt_active=Module["_nisps_ml_jolt_active"]=a0=>(_nisps_ml_jolt_active=Module["_nisps_ml_jolt_active"]=wasmExports["S"])(a0);var _nisps_ml_explore_intensity=Module["_nisps_ml_explore_intensity"]=(a0,a1)=>(_nisps_ml_explore_intensity=Module["_nisps_ml_explore_intensity"]=wasmExports["T"])(a0,a1);var _nisps_ml_explore_get_intensity=Module["_nisps_ml_explore_get_intensity"]=a0=>(_nisps_ml_explore_get_intensity=Module["_nisps_ml_explore_get_intensity"]=wasmExports["U"])(a0);var _nisps_ml_explore_apply=Module["_nisps_ml_explore_apply"]=(a0,a1,a2)=>(_nisps_ml_explore_apply=Module["_nisps_ml_explore_apply"]=wasmExports["V"])(a0,a1,a2);var _nisps_ml_get_layer_stats=Module["_nisps_ml_get_layer_stats"]=(a0,a1)=>(_nisps_ml_get_layer_stats=Module["_nisps_ml_get_layer_stats"]=wasmExports["W"])(a0,a1);var _nisps_ml_clear_examples=Module["_nisps_ml_clear_examples"]=a0=>(_nisps_ml_clear_examples=Module["_nisps_ml_clear_examples"]=wasmExports["X"])(a0);var _nisps_ml_describe=Module["_nisps_ml_describe"]=(a0,a1)=>(_nisps_ml_describe=Module["_nisps_ml_describe"]=wasmExports["Y"])(a0,a1);var _nisps_pipeline_create=Module["_nisps_pipeline_create"]=()=>(_nisps_pipeline_create=Module["_nisps_pipeline_create"]=wasmExports["Z"])();var _nisps_pipeline_destroy=Module["_nisps_pipeline_destroy"]=a0=>(_nisps_pipeline_destroy=Module["_nisps_pipeline_destroy"]=wasmExports["_"])(a0);var _nisps_input_set_config=Module["_nisps_input_set_config"]=(a0,a1,a2)=>(_nisps_input_set_config=Module["_nisps_input_set_config"]=wasmExports["$"])(a0,a1,a2);var _nisps_input_process=Module["_nisps_input_process"]=(a0,a1,a2,a3,a4)=>(_nisps_input_process=Module["_nisps_input_process"]=wasmExports["aa"])(a0,a1,a2,a3,a4);var _nisps_input_reset=Module["_nisps_input_reset"]=a0=>(_nisps_input_reset=Module["_nisps_input_reset"]=wasmExports["ba"])(a0);var _nisps_output_set_config=Module["_nisps_output_set_config"]=(a0,a1,a2,a3,a4)=>(_nisps_output_set_config=Module["_nisps_output_set_config"]=wasmExports["ca"])(a0,a1,a2,a3,a4);var _nisps_output_set_freeze_mask=Module["_nisps_output_set_freeze_mask"]=(a0,a1,a2)=>(_nisps_output_set_freeze_mask=Module["_nisps_output_set_freeze_mask"]=wasmExports["da"])(a0,a1,a2);var _nisps_output_process=Module["_nisps_output_process"]=(a0,a1,a2,a3)=>(_nisps_output_process=Module["_nisps_output_process"]=wasmExports["ea"])(a0,a1,a2,a3);var _nisps_output_reset=Module["_nisps_output_reset"]=a0=>(_nisps_output_reset=Module["_nisps_output_reset"]=wasmExports["fa"])(a0);var _nisps_curve_apply=Module["_nisps_curve_apply"]=(a0,a1,a2)=>(_nisps_curve_apply=Module["_nisps_curve_apply"]=wasmExports["ga"])(a0,a1,a2);var _nisps_curve_apply_batch=Module["_nisps_curve_apply_batch"]=(a0,a1,a2,a3,a4)=>(_nisps_curve_apply_batch=Module["_nisps_curve_apply_batch"]=wasmExports["ha"])(a0,a1,a2,a3,a4);var _nisps_engine_create=Module["_nisps_engine_create"]=(a0,a1)=>(_nisps_engine_create=Module["_nisps_engine_create"]=wasmExports["ia"])(a0,a1);var _nisps_engine_destroy=Module["_nisps_engine_destroy"]=a0=>(_nisps_engine_destroy=Module["_nisps_engine_destroy"]=wasmExports["ja"])(a0);var _nisps_engine_set_params=Module["_nisps_engine_set_params"]=(a0,a1,a2)=>(_nisps_engine_set_params=Module["_nisps_engine_set_params"]=wasmExports["ka"])(a0,a1,a2);var _nisps_engine_process_block=Module["_nisps_engine_process_block"]=(a0,a1,a2,a3,a4,a5)=>(_nisps_engine_process_block=Module["_nisps_engine_process_block"]=wasmExports["la"])(a0,a1,a2,a3,a4,a5);var _malloc=Module["_malloc"]=a0=>(_malloc=Module["_malloc"]=wasmExports["na"])(a0);var _free=Module["_free"]=a0=>(_free=Module["_free"]=wasmExports["oa"])(a0);var __emscripten_stack_restore=a0=>(__emscripten_stack_restore=wasmExports["pa"])(a0);var __emscripten_stack_alloc=a0=>(__emscripten_stack_alloc=wasmExports["qa"])(a0);var _emscripten_stack_get_current=()=>(_emscripten_stack_get_current=wasmExports["ra"])();Module["ccall"]=ccall;Module["cwrap"]=cwrap;var calledRun;var calledPrerun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(){if(runDependencies>0){return}if(!calledPrerun){calledPrerun=1;preRun();if(runDependencies>0){return}}function doRun(){if(calledRun)return;calledRun=1;Module["calledRun"]=1;if(ABORT)return;initRuntime();readyPromiseResolve(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();moduleRtn=readyPromise; return moduleRtn; diff --git a/manifold/public/nisps.wasm b/manifold/public/nisps.wasm index 89b642473a5ee9c77e176e624264ffb3933f7037..9a15915a054ab59f123f9b4296f03f02cc0597b7 100755 GIT binary patch delta 7323 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 V6KY2V{i{#NiI9_ze@=^w{|`-rahw1E delta 9654 zcmcIq4UkmTmA>b`*WIuCbx$`izz74}elx(#2sj$(84+O~2!ev3j(|oC?H}3$2*{tx z@CF2bNeMj6GrLxq%>o)LRH(GtRAl`f6O!PT*-BZ7aRvVn(T%#vZd_yS?sx9%h8{v{ z*{xbA-u=J#-0z!S!fMKYpbjN7fjX8Gg84)pf z_>Na+dxG+GqcHHjNkojTbT7rI#uU;_%cyB)q#>m=3`2^3@pyk@KrM2@G$N6K1`SHs ziKHPSaSw{w)Gh`^*DOqm}qu~anBoPT|SW&VBvKT5y#CWs#6OEFJ#ylai25O`o zl~P!akrLD(8qEl;K%YpAsE2xbWHb(F-0%J9WnsrYmRHivSmhScM7N5qL`%dnx=mb3 zw~HB65EoIG*g~{a+)K1fc(hz>q&q}6tq>b%rMQPyiM#1eaTl!?>uHVf*3nwAmez?i zv|g;HyTqMzw^&84SV>dG3YsSFpi9JZnl6^o4ADiGiUQ3Px6>?f8(k)r(Byi;=*K;QDj zd}vyqGI*&5JAKlDwEBZ_A6>^7g#ATo&@;GTD_E zv*gmem?@X##ieq2UQCyFfbh9J#4O@v~Aw4kS-&6B>(X0KgEdJz+Uzx?X>SjiYb%PrS-6z!z z^-~QqX{0~DVK}~P8XEBZZbQAlpzhw{vkjNTC|>-k! z%l(zY0TiCuY$fgLk+G{^FfKmZkqJFAb73-GJ;i79UpFS~ryXavx>YsQ|7`xS;#b!_ z`@a|-s~TQ>iR5cpv_B0hot*Mn4oF#1bG$DGXC`QV^cHJ;~skm-k z)}&tlyZ8KoUiH7d;W)kGukHTVH1yMnpX|KfU$@bxgGJl>b%JXAqYutW)MR7IQpT=K zO|k8vkr8V57d^5A-_IUdQr)(A`wNn4iX;5vH1Hqd6zNuS+V9e{I(8}1BF$ZyRPpM^ zUbc&|N81d)cK6f8-n}CwjsE)+PerJ)_{qM%8B}~>H<($9;x)hQkknfI&g&m0$SH34 zO_L#i+w6C}Gcp}jqDi)9%W6APgf2V$wwKOL`B^6Oo6?f(8LQZ}emJ(s< zb6xV&M|M)w|NfCVWc!~V8F+J)TOA8F?PP(05R0a#gsR0XHA}fEn{q|g)Gb+sY(LCS zmzo_$he|0EJ)9w~xynfwFoUv{PJPEw&MveM32Xh^kB+&h+}qSurm{ILcT_tgO4&Q6 zy?%K1#d>)wE0a*fgo?UUaH9SjN5|Gim8s%0Ae&TChZly_e!q7IVf#(*x?VJtHmV{` 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 B-bDZa diff --git a/manifold/src/engine/engine-api.ts b/manifold/src/engine/engine-api.ts index 725346b..22c5d39 100644 --- a/manifold/src/engine/engine-api.ts +++ b/manifold/src/engine/engine-api.ts @@ -26,16 +26,12 @@ export interface EngineFeedbackApi { thumbsUp(): number; /** Negative feedback (thumbs-down). Returns the FeedbackAction int. */ thumbsDown(speed?: number, spread?: number, pinMask?: Uint8Array): number; - /** Drag (continuous perturbation) tick. */ - drag(): number; setMode(mode: FeedbackMode): void; getMode(): FeedbackMode; /** Restrict feedback to a subset of outputs (solo / column-freeze). */ setFocus(mask: Uint8Array | null): void; /** True while the controller is exploring (perturbed). */ exploring(): boolean; - /** True while the controller has paused learning. */ - learningPaused(): boolean; // ---- ExploreAndPlace lifecycle (shared C++ core; mode 'explore_and_place') -- /** Idle→Exploring: snapshot the real net, randomise a scratchpad. */ @@ -54,10 +50,6 @@ export interface EngineFeedbackApi { commitPlace(): void; /** Placing→Exploring: back out without storing. */ cancelPlace(): void; - /** True while Placing (the frozen output is held). */ - placing(): boolean; - /** ExploreState int: 0=Idle 1=Exploring 2=Placing. */ - exploreState(): number; /** Scratchpad undo-ring depth available to pop. */ undoDepth(): number; /** The frozen placed / just-committed output (null if none). */ @@ -92,9 +84,6 @@ export interface EngineExploreApi { /** Release: freeze the weights where they landed (permanent). */ joltRelease(): void; joltActive(): boolean; - /** Post-release LR-ramp multiplier (0 held → 1 over ~5 s of ticks). */ - joltLrScale(): number; - joltTickLrRamp(): void; /** Exploration amount in [0,1]; 0 disables (inert — parity-safe). */ setExploreIntensity(level: number): void; exploreIntensity(): number; @@ -169,12 +158,10 @@ export class EngineApi { this.spine.routedOutput() ?? this.spine.outputs(), pinMask, ), - drag: () => this.iml.feedbackDrag(), setMode: (mode) => this.iml.feedbackSetMode(mode), getMode: () => this.iml.feedbackGetMode(), setFocus: (mask) => this.iml.feedbackSetFocus(mask), exploring: () => this.iml.feedbackExploring(), - learningPaused: () => this.iml.feedbackLearningPaused(), enterExplore: (spread = this.spread_) => this.iml.feedbackEnterExplore(spread), exitExplore: () => this.iml.feedbackExitExplore(), reroll: (spread = this.spread_) => this.iml.feedbackReroll(spread), @@ -183,8 +170,6 @@ export class EngineApi { like: () => this.iml.feedbackLike(), commitPlace: () => this.iml.feedbackCommitPlace(), cancelPlace: () => this.iml.feedbackCancelPlace(), - placing: () => this.iml.feedbackPlacing(), - exploreState: () => this.iml.feedbackState(), undoDepth: () => this.iml.feedbackUndoDepth(), placedOutput: () => this.iml.feedbackPlacedOutput(), dislikeGeometric: (heardVec?: Float32Array, lr = 0) => @@ -200,8 +185,6 @@ export class EngineApi { joltStep: () => this.iml.joltStep(), joltRelease: () => this.iml.joltRelease(), joltActive: () => this.iml.joltActive(), - joltLrScale: () => this.iml.joltLrScale(), - joltTickLrRamp: () => this.iml.joltTickLrRamp(), setExploreIntensity: (level) => this.iml.setExploreIntensity(level), exploreIntensity: () => this.iml.exploreIntensity(), exploreApply: (inout) => this.iml.exploreApply(inout), diff --git a/manifold/src/engine/sink.ts b/manifold/src/engine/sink.ts index b3acf85..acefaf7 100644 --- a/manifold/src/engine/sink.ts +++ b/manifold/src/engine/sink.ts @@ -28,8 +28,6 @@ export interface EngineSink { setState(patch: EngineStatePatch): void; /** Publish a fresh output vector (already copied; caller may keep it). */ setOutputs(out: Float32Array): void; - /** Publish a fresh flat weight array. */ - setWeights(w: Float32Array): void; /** Emit a named engine event (`ml.*`, `mode.*`, …) with an optional payload. */ emit(event: string, payload?: unknown): void; } @@ -38,6 +36,5 @@ export interface EngineSink { export const noopSink: EngineSink = { setState() {}, setOutputs() {}, - setWeights() {}, emit() {}, }; diff --git a/manifold/src/engine/spine.ts b/manifold/src/engine/spine.ts index ad40f3b..f3d7219 100644 --- a/manifold/src/engine/spine.ts +++ b/manifold/src/engine/spine.ts @@ -52,9 +52,9 @@ export interface SpineState { /** * The spine doubles as the `EngineSink` consumed by `WasmIML`. WasmIML calls - * `setState/setOutputs/setWeights/emit`; the spine merges into its state, - * stashes the live output/weight buffers, and bumps the version counter so - * `useSyncExternalStore` consumers re-read. + * `setState/setOutputs/emit`; the spine merges into its state, stashes the + * live output buffer, and bumps the version counter so `useSyncExternalStore` + * consumers re-read. */ export class Spine implements EngineSink { private state_: SpineState = { @@ -93,9 +93,8 @@ export class Spine implements EngineSink { private mlBuf: F32 = new Float32Array(126); private routedBuf: F32 | null = null; - // Last live output (post-ML, pre-routing) and weights, read imperatively. + // Last live output (post-ML, pre-routing), read imperatively. private liveOutputs: F32 = new Float32Array(126); - private liveWeights: F32 = new Float32Array(0); // Optional post-output transform, applied to the routed buffer AFTER the // output pipeline and BEFORE backend.send (exploration noise — see @@ -149,11 +148,6 @@ export class Spine implements EngineSink { this.bump_(); } - setWeights(w: Float32Array): void { - this.liveWeights = w; - this.bump_(); - } - emit(event: string, payload?: unknown): void { const set = this.eventListeners.get(event); if (set) for (const fn of set) fn(payload); @@ -333,10 +327,6 @@ export class Spine implements EngineSink { return this.routedBuf; } - weights(): Float32Array { - return this.liveWeights; - } - // ---- useSyncExternalStore plumbing --------------------------------- subscribe = (cb: () => void): (() => void) => { diff --git a/manifold/src/engine/types.ts b/manifold/src/engine/types.ts index 0ec379a..b795129 100644 --- a/manifold/src/engine/types.ts +++ b/manifold/src/engine/types.ts @@ -32,7 +32,6 @@ export interface NispsModule { // non-positive/null args fall back to the compiled defaults (32→[10,14,18]→126). _nisps_ml_create(input_size: number, output_size: number, hidden_ptr: number, n_hidden: number, seed: number): number; _nisps_ml_destroy(ml: number): void; - _nisps_ml_reset(ml: number): void; // Reshape = new net at the new dims, warm-started with the overlapping // weights; feedback state resets. Returns 1 on success (0 = no change). _nisps_ml_reshape(ml: number, input_size: number, output_size: number, hidden_ptr: number, n_hidden: number, spread: number): number; @@ -50,14 +49,12 @@ export interface NispsModule { // ML examples. _nisps_ml_clear_examples(ml: number): void; - _nisps_ml_example_count(ml: number): number; // ML weights. _nisps_ml_weight_count(ml: number): number; _nisps_ml_get_weights(ml: number, out_ptr: number): void; _nisps_ml_set_weights(ml: number, in_ptr: number): void; _nisps_ml_draw_weights(ml: number, spread: number): void; - _nisps_ml_move_weights(ml: number, speed: number, spread: number, mask_ptr: number): void; _nisps_ml_get_layer_stats(ml: number, out_ptr: number): void; // Null ml reports the DEFAULT shape; a handle reports its runtime shape. _nisps_ml_describe(ml: number, out_ptr: number): void; @@ -68,7 +65,6 @@ export interface NispsModule { _nisps_ml_feedback_set_mode(ml: number, mode: number): void; _nisps_ml_feedback_get_mode(ml: number): number; _nisps_ml_feedback_exploring(ml: number): number; // 1 = exploring - _nisps_ml_feedback_learning_paused(ml: number): number; // 1 = paused _nisps_ml_feedback_set_focus(ml: number, mask_ptr: number, n: number): void; _nisps_ml_feedback_down( ml: number, @@ -78,7 +74,6 @@ export interface NispsModule { pin_mask_ptr: number, ): number; _nisps_ml_feedback_up(ml: number): number; - _nisps_ml_feedback_drag(ml: number): number; // Returns 1 if `out` holds a static-bypass vector (skip process()); else 0. _nisps_ml_feedback_static_output(ml: number, out_ptr: number): number; @@ -94,8 +89,6 @@ export interface NispsModule { _nisps_ml_feedback_like(ml: number): void; // Exploring→Placing (freeze output) _nisps_ml_feedback_commit_place(ml: number): void; // Placing→Idle (restore real net) _nisps_ml_feedback_cancel_place(ml: number): void; // Placing→Exploring - _nisps_ml_feedback_placing(ml: number): number; // 1 = Placing - _nisps_ml_feedback_state(ml: number): number; // 0=Idle 1=Exploring 2=Placing _nisps_ml_feedback_undo_depth(ml: number): number; // Writes placed/committed output (outputSize floats) into out; returns 1 if written. _nisps_ml_feedback_placed_output(ml: number, out_ptr: number): number; @@ -123,8 +116,6 @@ export interface NispsModule { _nisps_ml_jolt_step(ml: number): void; _nisps_ml_jolt_release(ml: number): void; _nisps_ml_jolt_active(ml: number): number; // 1 = held/active - _nisps_ml_jolt_lr_scale(ml: number): number; // post-release LR ramp multiplier - _nisps_ml_jolt_tick_lr_ramp(ml: number): void; _nisps_ml_explore_intensity(ml: number, level: number): void; _nisps_ml_explore_get_intensity(ml: number): number; _nisps_ml_explore_apply(ml: number, inout_ptr: number, n: number): void; @@ -145,9 +136,6 @@ export interface NispsModule { // In place: processes the first n floats of inout_ptr. _nisps_output_process(p: number, inout_ptr: number, n: number, dt_s: number): void; _nisps_output_reset(p: number): void; - _nisps_pipeline_state_size(p: number): number; - _nisps_pipeline_save_state(p: number, out_ptr: number): void; - _nisps_pipeline_load_state(p: number, in_ptr: number, n: number): void; // Curve catalog (one-core-engine P4). ids 0..6 = nisps::Curve (param ignored); // id 7 = centred power (param = exponent). nisps/core/math.hpp is the single diff --git a/manifold/src/engine/wasm-iml.ts b/manifold/src/engine/wasm-iml.ts index b2a1289..79e749d 100644 --- a/manifold/src/engine/wasm-iml.ts +++ b/manifold/src/engine/wasm-iml.ts @@ -8,7 +8,7 @@ * `mlStore.__setState(produce(...))` / `mlStore.__setOutputs(...)` / * `mlStore.__setWeights(...)` / `coreBus.emit(...)`, this class calls the * injected {@link EngineSink} (`sink.setState({...})` with a PLAIN patch - * object — no `produce` mutator, `sink.setOutputs/setWeights/emit`). + * object — no `produce` mutator, `sink.setOutputs/emit`). * - Glue + WASM URLs resolve via `import.meta.env.BASE_URL` (not `/nisps.*`). * - The `nisps_ml_feedback_*` C ABI (already exported by the WASM build) is * now bound and surfaced via the `feedback*` methods. The playground never @@ -233,7 +233,6 @@ export class WasmIML { ready: true, }); this.sink.setOutputs(new Float32Array(this.arch_.outputSize)); - this.publishWeights_(); this.tryLoadFromStorage_(); } @@ -396,7 +395,6 @@ export class WasmIML { lossHistory: [], }); this.sink.setOutputs(new Float32Array(this.arch_.outputSize)); - this.publishWeights_(); this.sink.emit('ml.reshaped', { inputSize: this.arch_.inputSize, outputSize: this.arch_.outputSize, @@ -616,7 +614,6 @@ export class WasmIML { // The C++ MLP stores per-iter history but it isn't exposed via the WASM // bindings yet, so this is a single-element array. this.sink.setState({ lastLoss: loss, lossHistory: [loss] }); - this.publishWeights_(); this.sink.emit('ml.trained', { loss }); this.scheduleSave_(); return loss; @@ -677,18 +674,10 @@ export class WasmIML { randomiseWeights(spread = 0.6): void { this.module._nisps_ml_draw_weights(this.mlHandle, spread); - this.publishWeights_(); this.sink.emit('ml.delta_update', { reason: 'randomise' }); this.scheduleSave_(); } - moveWeights(speed: number, spread: number, pinMask?: Uint8Array): void { - const maskPtr = this.writePinMask_(pinMask); - this.module._nisps_ml_move_weights(this.mlHandle, speed, spread, maskPtr); - this.publishWeights_(); - this.sink.emit('ml.delta_update', { reason: 'thumbs_down' }); - } - private writePinMask_(pinMask?: Uint8Array): number { if (!pinMask) return 0; const sz = Math.min(pinMask.length, this.arch_.outputSize); @@ -717,10 +706,6 @@ export class WasmIML { return this.module._nisps_ml_feedback_exploring(this.mlHandle) === 1; } - feedbackLearningPaused(): boolean { - return this.module._nisps_ml_feedback_learning_paused(this.mlHandle) === 1; - } - /** Restrict feedback to a subset of outputs (solo / focus). null clears it. */ feedbackSetFocus(mask: Uint8Array | null): void { if (!mask || mask.length === 0) { @@ -735,7 +720,6 @@ export class WasmIML { /** Positive feedback (thumbs-up). Returns the FeedbackAction int. */ feedbackUp(): number { const action = this.module._nisps_ml_feedback_up(this.mlHandle); - this.publishWeights_(); this.sink.emit('feedback.up', { action }); this.scheduleSave_(); return action; @@ -755,19 +739,11 @@ export class WasmIML { } const maskPtr = this.writePinMask_(pinMask); const action = this.module._nisps_ml_feedback_down(this.mlHandle, outPtr, speed, spread, maskPtr); - this.publishWeights_(); this.sink.emit('feedback.down', { action }); this.scheduleSave_(); return action; } - /** Drag (continuous perturbation) tick. Returns the FeedbackAction int. */ - feedbackDrag(): number { - const action = this.module._nisps_ml_feedback_drag(this.mlHandle); - this.publishWeights_(); - return action; - } - /** * If a static bypass vector is active, copies it into `out` and returns true * (the caller should NOT call process()); otherwise returns false. @@ -784,38 +760,32 @@ export class WasmIML { // ---- ExploreAndPlace lifecycle (shared C++ core; mode 'explore_and_place') -- // The C++ core owns the weight snapshot / scratchpad / undo ring; THIS class - // only forwards calls + republishes weights. Example-storage + training stay - // with the caller (FeedbackController.ts), preserving the "caller owns - // training" contract. + // only forwards calls. Example-storage + training stay with the caller + // (FeedbackController.ts), preserving the "caller owns training" contract. /** Idle→Exploring: snapshot the real net, randomise a scratchpad. */ feedbackEnterExplore(spread: number): void { this.module._nisps_ml_feedback_enter_explore(this.mlHandle, spread); - this.publishWeights_(); } /** Exploring→Idle: restore the real net, discard the scratchpad. */ feedbackExitExplore(): void { this.module._nisps_ml_feedback_exit_explore(this.mlHandle); - this.publishWeights_(); } /** Exploring scratchpad op: re-randomise (undoable). */ feedbackReroll(spread: number): void { this.module._nisps_ml_feedback_reroll(this.mlHandle, spread); - this.publishWeights_(); } /** Exploring scratchpad op: small bounded perturbation (undoable). */ feedbackNudge(amount: number): void { this.module._nisps_ml_feedback_nudge(this.mlHandle, amount); - this.publishWeights_(); } /** Exploring scratchpad op: undo the last reroll/nudge. */ feedbackUndo(): void { this.module._nisps_ml_feedback_undo(this.mlHandle); - this.publishWeights_(); } /** Exploring→Placing: freeze the scratchpad output at its current input. */ @@ -826,7 +796,6 @@ export class WasmIML { /** Placing→Idle: restore the real net. Caller then stores +1 + trains. */ feedbackCommitPlace(): void { this.module._nisps_ml_feedback_commit_place(this.mlHandle); - this.publishWeights_(); } /** Placing→Exploring: back out without storing. */ @@ -834,15 +803,6 @@ export class WasmIML { this.module._nisps_ml_feedback_cancel_place(this.mlHandle); } - feedbackPlacing(): boolean { - return this.module._nisps_ml_feedback_placing(this.mlHandle) === 1; - } - - /** ExploreState: 0=Idle 1=Exploring 2=Placing. */ - feedbackState(): number { - return this.module._nisps_ml_feedback_state(this.mlHandle); - } - feedbackUndoDepth(): number { return this.module._nisps_ml_feedback_undo_depth(this.mlHandle); } @@ -867,7 +827,7 @@ export class WasmIML { * Geometric dislike: push the current mapping away from the liked centroid. * `heardVec` is the kDefaultOutputs vector the user is HEARING (post-pipeline — * with a null/raw vector the cold-start has a zero MSE derivative and is inert). - * `lr <= 0` uses the C++ controller default. Mutates weights → republishes. + * `lr <= 0` uses the C++ controller default. Mutates weights in place. * Returns the FeedbackAction int (14=GeometricPush, 15=GeometricColdStart). */ feedbackDislikeGeometric(heardVec?: Float32Array, lr = 0): number { @@ -879,7 +839,6 @@ export class WasmIML { outPtr = this.feedbackBuf.ptr; } const action = this.module._nisps_ml_feedback_dislike_geometric(this.mlHandle, outPtr, lr); - this.publishWeights_(); this.sink.emit('feedback.down', { action }); this.scheduleSave_(); return action; @@ -925,10 +884,9 @@ export class WasmIML { } /** One ~200 Hz morph tick while held (no-op when inactive). C-side get→glide→ - * set of the flat weights; republish so weight-health views + persistence follow. */ + * set of the flat weights; scheduleSave_ persists the result. */ joltStep(): void { this.module._nisps_ml_jolt_step(this.mlHandle); - this.publishWeights_(); this.scheduleSave_(); } @@ -941,15 +899,6 @@ export class WasmIML { return this.module._nisps_ml_jolt_active(this.mlHandle) === 1; } - /** Post-release LR-ramp multiplier (0 while held → 1 over ~5 s of ticks). */ - joltLrScale(): number { - return this.module._nisps_ml_jolt_lr_scale(this.mlHandle); - } - - joltTickLrRamp(): void { - this.module._nisps_ml_jolt_tick_lr_ramp(this.mlHandle); - } - /** Exploration amount in [0,1]; 0 disables (inert — parity-safe). */ setExploreIntensity(level: number): void { this.module._nisps_ml_explore_intensity(this.mlHandle, level); @@ -987,7 +936,6 @@ export class WasmIML { } this.weightsBuf.view.set(w as Float32Array, 0); this.module._nisps_ml_set_weights(this.mlHandle, this.weightsBuf.ptr); - this.publishWeights_(); } getLayerStats(): LayerStats[] { @@ -1010,20 +958,6 @@ export class WasmIML { return new Float32Array(this.statsBuf.view); } - // ------------------------------------------------------------------- - // Misc - // ------------------------------------------------------------------- - - reset(): void { - this.module._nisps_ml_reset(this.mlHandle); - this.dataset.clear(); - this.lastLoss_ = null; - this.sink.setState({ exampleCount: 0, lastLoss: null, lossHistory: [] }); - this.publishWeights_(); - this.sink.emit('ml.examples_cleared', undefined); - this.scheduleSave_(); - } - // ------------------------------------------------------------------- // Persistence // ------------------------------------------------------------------- @@ -1089,9 +1023,4 @@ export class WasmIML { console.warn('[wasm-iml] tryLoadFromStorage failed:', err); } } - - private publishWeights_(): void { - const w = this.getWeights(); - this.sink.setWeights(w); - } } diff --git a/manifold/src/engine/worklet/nisps-processor.ts b/manifold/src/engine/worklet/nisps-processor.ts index 16c692e..01d4257 100644 --- a/manifold/src/engine/worklet/nisps-processor.ts +++ b/manifold/src/engine/worklet/nisps-processor.ts @@ -102,13 +102,6 @@ class NispsProcessor extends AudioWorkletProcessor { */ private async init_(bytes: ArrayBuffer, sampleRate: number): Promise { const memory = new WebAssembly.Memory({ initial: 128, maximum: 4096, shared: false }); - const imports: WebAssembly.Imports = { - // Emscripten import "a" group; field names match the generated JS. - a: { - a: () => { throw new Error('wasm aborted'); }, - b: () => false, // _emscripten_resize_heap returning 0 disables growth - }, - }; const compiled = await WebAssembly.compile(bytes); // Discover the actual import shape from the module — names like "a", @@ -119,13 +112,20 @@ class NispsProcessor extends AudioWorkletProcessor { if (!reshaped[desc.module]) reshaped[desc.module] = {} as WebAssembly.ModuleImports; const mod = reshaped[desc.module] as WebAssembly.ModuleImports; if (desc.kind === 'function') { - if (desc.name === 'c') { - // unused + if (desc.name === 'a') { + // __abort_js + mod[desc.name] = () => { throw new Error('wasm aborted'); }; + } else if (desc.name === 'b') { + // _emscripten_resize_heap: refuse growth in the worklet. + mod[desc.name] = (_size: number) => 0; + } else { + // Unknown import — fail loudly instead of silently returning 0, so a + // missing/renamed Emscripten import surfaces immediately instead of + // manifesting as silent audio corruption. + mod[desc.name] = (..._args: unknown[]) => { + throw new Error(`worklet: missing wasm import "${desc.module}.${desc.name}"`); + }; } - mod[desc.name] = (() => { - // Generic stub: log + return 0. - return (..._args: unknown[]) => 0; - })(); } else if (desc.kind === 'memory') { mod[desc.name] = memory; } else if (desc.kind === 'table') { @@ -134,34 +134,12 @@ class NispsProcessor extends AudioWorkletProcessor { mod[desc.name] = new WebAssembly.Global({ value: 'i32', mutable: true }, 0); } } - // For known-needed Emscripten imports, supply real implementations. - for (const desc of importDesc) { - const mod = reshaped[desc.module] as WebAssembly.ModuleImports; - // __abort_js - if (desc.name === 'a' && desc.kind === 'function') { - mod[desc.name] = () => { throw new Error('wasm aborted'); }; - } - // _emscripten_resize_heap - if (desc.name === 'b' && desc.kind === 'function') { - mod[desc.name] = (_size: number) => 0; // refuse growth in worklet - } - } - void imports; // silence unused const wasmInst = await WebAssembly.instantiate(compiled, reshaped); // Many Emscripten exports use single-letter mangled names. Discover // by reading the export descriptors. const exDesc = WebAssembly.Module.exports(compiled); - const exMap = new Map(); // logical name → mangled - for (const e of exDesc) { - // The exports list includes both the original (with leading - // underscore for C funcs) and the mangled single-letter alias used - // in the import section. We only see the export side here, but - // Emscripten in modern versions also re-exports the C names with - // their leading-underscore form. Walk both. - exMap.set(e.name, e.name); - } const exports = wasmInst.exports as Record; function pickFn(...names: string[]): (...args: number[]) => number { diff --git a/nisps/wasm/README.md b/nisps/wasm/README.md index 6438cb9..5ddfc88 100644 --- a/nisps/wasm/README.md +++ b/nisps/wasm/README.md @@ -52,10 +52,10 @@ See `bindings.cpp` for the full list. Summary: | Group | Functions | |-----------|------------------------------------------------------------------------------| -| ML life | `nisps_ml_create`, `nisps_ml_destroy`, `nisps_ml_reset`, `nisps_ml_reshape` | +| ML life | `nisps_ml_create`, `nisps_ml_destroy`, `nisps_ml_reshape` | | ML I/O | `nisps_ml_set_input`, `nisps_ml_process`, `nisps_ml_outputs`, `nisps_ml_infer_batch` | -| Training | `nisps_ml_add_example`, `nisps_ml_train`, `nisps_ml_eval_loss`, `nisps_ml_clear_examples`, `nisps_ml_example_count` | -| Weights | `nisps_ml_weight_count`, `nisps_ml_get_weights`, `nisps_ml_set_weights`, `nisps_ml_draw_weights`, `nisps_ml_move_weights` | +| Training | `nisps_ml_add_example`, `nisps_ml_train`, `nisps_ml_eval_loss`, `nisps_ml_clear_examples` | +| Weights | `nisps_ml_weight_count`, `nisps_ml_get_weights`, `nisps_ml_set_weights`, `nisps_ml_draw_weights` | | Diag | `nisps_ml_get_layer_stats`, `nisps_ml_describe` | | Engines | `nisps_engine_create`, `nisps_engine_destroy`, `nisps_engine_set_params`, `nisps_engine_process_block` | diff --git a/nisps/wasm/bindings.cpp b/nisps/wasm/bindings.cpp index 691e2e6..215435c 100644 --- a/nisps/wasm/bindings.cpp +++ b/nisps/wasm/bindings.cpp @@ -548,18 +548,6 @@ void nisps_ml_draw_weights(void* ml, float spread) { h->mlp.draw_weights(spread); } -EMSCRIPTEN_KEEPALIVE -void nisps_ml_move_weights(void* ml, float speed, float spread, - const uint8_t* output_pin_mask) { - if (!ml) return; - auto* h = static_cast(ml); - std::span mask; - if (output_pin_mask) { - mask = std::span(output_pin_mask, h->n_out()); - } - h->mlp.move_weights(speed, spread, mask); -} - // --------------------------------------------------------------------------- // ML feedback — the "Down Action" state machine (Avoid / RandomiseOutputs / // RandomiseMlp). The controller decides WHAT transition happened (returns a @@ -601,12 +589,6 @@ int nisps_ml_feedback_exploring(void* ml) { return static_cast(ml)->feedback.exploring() ? 1 : 0; } -EMSCRIPTEN_KEEPALIVE -int nisps_ml_feedback_learning_paused(void* ml) { - if (!ml) return 0; - return static_cast(ml)->feedback.learning_paused() ? 1 : 0; -} - EMSCRIPTEN_KEEPALIVE void nisps_ml_feedback_set_focus(void* ml, const uint8_t* mask, int n) { if (!ml) return; @@ -640,13 +622,6 @@ int nisps_ml_feedback_up(void* ml) { return static_cast(h->feedback.on_up(h->mlp)); } -EMSCRIPTEN_KEEPALIVE -int nisps_ml_feedback_drag(void* ml) { - if (!ml) return 0; - auto* h = static_cast(ml); - return static_cast(h->feedback.on_drag(h->mlp)); -} - // If returns 1, `out` (n_out floats) holds the static bypass vector // and the caller should NOT call nisps_ml_process(); if 0, run process(). EMSCRIPTEN_KEEPALIVE @@ -738,20 +713,6 @@ void nisps_ml_feedback_cancel_place(void* ml) { h->feedback.cancel_place(); } -// 1 if currently Placing (audition is the frozen vector), else 0. -EMSCRIPTEN_KEEPALIVE -int nisps_ml_feedback_placing(void* ml) { - if (!ml) return 0; - return static_cast(ml)->feedback.placing() ? 1 : 0; -} - -// ExploreState int: 0=Idle 1=Exploring 2=Placing. -EMSCRIPTEN_KEEPALIVE -int nisps_ml_feedback_state(void* ml) { - if (!ml) return 0; - return static_cast(static_cast(ml)->feedback.explore_state()); -} - // Scratchpad undo-ring depth currently available to pop. EMSCRIPTEN_KEEPALIVE int nisps_ml_feedback_undo_depth(void* ml) { @@ -863,20 +824,6 @@ int nisps_ml_jolt_active(void* ml) { return static_cast(ml)->jolt.active() ? 1 : 0; } -// Post-release learning-rate ramp: multiply the training LR by this (0 while -// held, ramps back to 1 over ~5 s of ticks). -EMSCRIPTEN_KEEPALIVE -float nisps_ml_jolt_lr_scale(void* ml) { - if (!ml) return 1.f; - return static_cast(ml)->jolt.lr_scale(); -} - -EMSCRIPTEN_KEEPALIVE -void nisps_ml_jolt_tick_lr_ramp(void* ml) { - if (!ml) return; - static_cast(ml)->jolt.tick_lr_ramp(); -} - // Exploration amount in [0,1]; 0 disables (inert — parity-safe). EMSCRIPTEN_KEEPALIVE void nisps_ml_explore_intensity(void* ml, float level) { @@ -914,15 +861,6 @@ void nisps_ml_get_layer_stats(void* ml, float* out_stats) { } } -// Extra helper: lets JS query the example count without having to -// shadow-track it. Useful when restoring from snapshot. -EMSCRIPTEN_KEEPALIVE -int nisps_ml_example_count(void* ml) { - if (!ml) return 0; - auto* h = static_cast(ml); - return static_cast(h->mlp.example_count()); -} - EMSCRIPTEN_KEEPALIVE void nisps_ml_clear_examples(void* ml) { if (!ml) return; @@ -930,13 +868,6 @@ void nisps_ml_clear_examples(void* ml) { h->mlp.clear_examples(); } -EMSCRIPTEN_KEEPALIVE -void nisps_ml_reset(void* ml) { - if (!ml) return; - auto* h = static_cast(ml); - h->mlp.reset(); -} - // Architecture introspection — writes [in, h1, h2, h3, out, n_layers] into a // caller-supplied int buffer. Always 6 ints. With a null handle it reports // the DEFAULT shape (what create() yields for non-positive args); with a @@ -1070,34 +1001,6 @@ void nisps_output_reset(void* p) { static_cast(p)->output.reset(); } -// Persistence: [input state (3)] + [output state (1 + 2*count)]. -EMSCRIPTEN_KEEPALIVE -int nisps_pipeline_state_size(void* p) { - if (!p) return 0; - auto* h = static_cast(p); - return static_cast(h->input.state_size() + h->output.state_size()); -} - -EMSCRIPTEN_KEEPALIVE -void nisps_pipeline_save_state(void* p, float* out) { - if (!p || !out) return; - auto* h = static_cast(p); - const std::size_t in_n = h->input.state_size(); - h->input.save_state(std::span(out, in_n)); - h->output.save_state(std::span(out + in_n, h->output.state_size())); -} - -EMSCRIPTEN_KEEPALIVE -void nisps_pipeline_load_state(void* p, const float* in, int n) { - if (!p || !in || n <= 0) return; - auto* h = static_cast(p); - const std::size_t in_n = h->input.state_size(); - const std::size_t total = static_cast(n); - if (total < in_n) return; - h->input.load_state(std::span(in, in_n)); - h->output.load_state(std::span(in + in_n, total - in_n)); -} - // --------------------------------------------------------------------------- // Curve catalog (one-core-engine P4): nisps/core/math.hpp is the single // source of truth; the browser samples it instead of mirroring the maths. diff --git a/scripts/build-wasm.sh b/scripts/build-wasm.sh index 65f2c0a..a4448ab 100755 --- a/scripts/build-wasm.sh +++ b/scripts/build-wasm.sh @@ -39,32 +39,31 @@ mkdir -p "$OUT" # function is missing. EXPORTED_FUNCS='[ "_malloc","_free", - "_nisps_ml_create","_nisps_ml_destroy","_nisps_ml_reset","_nisps_ml_reshape", + "_nisps_ml_create","_nisps_ml_destroy","_nisps_ml_reshape", "_nisps_ml_set_input","_nisps_ml_process","_nisps_ml_outputs","_nisps_ml_infer_batch", "_nisps_ml_add_example","_nisps_ml_train","_nisps_ml_eval_loss", - "_nisps_ml_clear_examples","_nisps_ml_example_count", + "_nisps_ml_clear_examples", "_nisps_ml_weight_count","_nisps_ml_get_weights","_nisps_ml_set_weights", - "_nisps_ml_draw_weights","_nisps_ml_move_weights", + "_nisps_ml_draw_weights", "_nisps_ml_feedback_set_mode","_nisps_ml_feedback_get_mode", - "_nisps_ml_feedback_exploring","_nisps_ml_feedback_learning_paused", + "_nisps_ml_feedback_exploring", "_nisps_ml_feedback_set_focus","_nisps_ml_feedback_down", - "_nisps_ml_feedback_up","_nisps_ml_feedback_drag","_nisps_ml_feedback_static_output", + "_nisps_ml_feedback_up","_nisps_ml_feedback_static_output", "_nisps_ml_feedback_enter_explore","_nisps_ml_feedback_exit_explore", "_nisps_ml_feedback_reroll","_nisps_ml_feedback_nudge","_nisps_ml_feedback_undo", "_nisps_ml_feedback_like","_nisps_ml_feedback_commit_place","_nisps_ml_feedback_cancel_place", - "_nisps_ml_feedback_placing","_nisps_ml_feedback_state","_nisps_ml_feedback_undo_depth", + "_nisps_ml_feedback_undo_depth", "_nisps_ml_feedback_placed_output", "_nisps_ml_feedback_dislike_geometric","_nisps_ml_feedback_store_positive", "_nisps_ml_feedback_positive_count","_nisps_ml_feedback_negative_count", "_nisps_ml_feedback_set_avoid_style", "_nisps_ml_jolt_press","_nisps_ml_jolt_step","_nisps_ml_jolt_release", - "_nisps_ml_jolt_active","_nisps_ml_jolt_lr_scale","_nisps_ml_jolt_tick_lr_ramp", + "_nisps_ml_jolt_active", "_nisps_ml_explore_intensity","_nisps_ml_explore_get_intensity","_nisps_ml_explore_apply", "_nisps_pipeline_create","_nisps_pipeline_destroy", "_nisps_input_set_config","_nisps_input_process","_nisps_input_reset", "_nisps_output_set_config","_nisps_output_set_freeze_mask", "_nisps_output_process","_nisps_output_reset", - "_nisps_pipeline_state_size","_nisps_pipeline_save_state","_nisps_pipeline_load_state", "_nisps_curve_apply","_nisps_curve_apply_batch", "_nisps_ml_get_layer_stats","_nisps_ml_describe", "_nisps_engine_create","_nisps_engine_destroy", diff --git a/tests/cpp/parity_wasm.mjs b/tests/cpp/parity_wasm.mjs index 91dd4a3..d359e98 100644 --- a/tests/cpp/parity_wasm.mjs +++ b/tests/cpp/parity_wasm.mjs @@ -100,7 +100,6 @@ function bind(Module) { weightCount: cwrap('nisps_ml_weight_count', 'number', ['number']), getWeights: cwrap('nisps_ml_get_weights', null, ['number','number']), drawWeights: cwrap('nisps_ml_draw_weights', null, ['number','number']), - moveWeights: cwrap('nisps_ml_move_weights', null, ['number','number','number','number']), feedbackSetMode: cwrap('nisps_ml_feedback_set_mode', null, ['number','number']), feedbackDown: cwrap('nisps_ml_feedback_down', 'number', ['number','number','number','number','number']), feedbackUp: cwrap('nisps_ml_feedback_up', 'number', ['number']),