feat: some stuff
Some checks failed
Deploy to GitHub Pages / build_site (push) Failing after 1m21s

This commit is contained in:
max_richter 2024-04-26 16:09:00 +02:00
parent cafe9bff84
commit 10e99754d0
6 changed files with 45 additions and 38 deletions

View File

@ -7,12 +7,10 @@
Float32BufferAttribute, Float32BufferAttribute,
Vector3, Vector3,
} from "three"; } from "three";
import { decodeFloat } from "@nodes/utils"; import { decodeFloat, fastHashArrayBuffer } from "@nodes/utils";
import type { PerformanceStore } from "$lib/performance"; import type { PerformanceStore } from "$lib/performance";
import { AppSettings } from "$lib/settings/app-settings"; import { AppSettings } from "$lib/settings/app-settings";
export let result: Int32Array;
export let centerCamera: boolean = true; export let centerCamera: boolean = true;
export let perf: PerformanceStore; export let perf: PerformanceStore;
@ -22,6 +20,22 @@
let totalVertices = 0; let totalVertices = 0;
let totalFaces = 0; let totalFaces = 0;
function fastArrayHash(arr: ArrayBuffer) {
let ints = new Uint8Array(arr);
const sampleDistance = Math.max(Math.floor(ints.length / 100), 1);
const sampleCount = Math.floor(ints.length / sampleDistance);
let hash = new Uint8Array(sampleCount);
for (let i = 0; i < sampleCount; i++) {
const index = i * sampleDistance;
hash[i] = ints[index];
}
return fastHashArrayBuffer(hash.buffer);
}
function createGeometryFromEncodedData( function createGeometryFromEncodedData(
encodedData: Int32Array, encodedData: Int32Array,
geometry = new BufferGeometry(), geometry = new BufferGeometry(),
@ -47,6 +61,10 @@
vertexCount * 3, vertexCount * 3,
); );
index = index + vertexCount * 3; index = index + vertexCount * 3;
let hash = fastArrayHash(vertices);
if (geometry.userData?.hash === hash) {
return geometry;
}
const normals = new Float32Array( const normals = new Float32Array(
encodedData.buffer, encodedData.buffer,
@ -90,6 +108,7 @@
geometry.userData = { geometry.userData = {
vertexCount, vertexCount,
faceCount, faceCount,
hash,
}; };
return geometry; return geometry;
@ -153,11 +172,11 @@
return positions; return positions;
} }
$: if (result) { export const update = function updateGeometries(result: Int32Array) {
let a = performance.now(); let a = performance.now();
const inputs = parse_args(result); const inputs = parse_args(result);
let b = performance.now(); let b = performance.now();
perf?.addPoint("parse-args", b - a); perf?.addPoint("split-result", b - a);
totalVertices = 0; totalVertices = 0;
totalFaces = 0; totalFaces = 0;
@ -185,14 +204,9 @@
.filter(Boolean) as BufferGeometry[]; .filter(Boolean) as BufferGeometry[];
b = performance.now(); b = performance.now();
perf?.addPoint("create-geometries", b - a); perf?.addPoint("create-geometries", b - a);
for (const geometry of geometries) {
geometry.needsUpdate = true;
}
perf?.addPoint("total-vertices", totalVertices); perf?.addPoint("total-vertices", totalVertices);
perf?.addPoint("total-faces", totalFaces); perf?.addPoint("total-faces", totalFaces);
} };
</script> </script>
<Canvas> <Canvas>

View File

@ -1,5 +1,5 @@
import type { Graph, NodeRegistry, NodeDefinition, RuntimeExecutor, NodeInput } from "@nodes/types"; import type { Graph, NodeRegistry, NodeDefinition, RuntimeExecutor, NodeInput } from "@nodes/types";
import { concatEncodedArrays, encodeFloat, fastHashArray } from "@nodes/utils" import { concatEncodedArrays, encodeFloat, fastHashArrayBuffer } from "@nodes/utils"
import { createLogger } from "./helpers"; import { createLogger } from "./helpers";
import type { RuntimeCache } from "@nodes/types"; import type { RuntimeCache } from "@nodes/types";
import type { PerformanceStore } from "./performance"; import type { PerformanceStore } from "./performance";
@ -138,7 +138,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
const [outputNode, nodes] = await this.addMetaData(graph); const [outputNode, nodes] = await this.addMetaData(graph);
let b = performance.now(); let b = performance.now();
this.perf?.addPoint("metadata", b - a); this.perf?.addPoint("collect-metadata", b - a);
/* /*
* Here we sort the nodes into buckets, which we then execute one by one * Here we sort the nodes into buckets, which we then execute one by one
@ -211,7 +211,10 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
b = performance.now(); b = performance.now();
this.perf?.addPoint("encoded-inputs", b - a); this.perf?.addPoint("encoded-inputs", b - a);
let inputHash = `node-${node.id}-${fastHashArray(encoded_inputs)}`; a = performance.now();
let inputHash = `node-${node.id}-${fastHashArrayBuffer(encoded_inputs)}`;
b = performance.now();
this.perf?.addPoint("hash-inputs", b - a);
let cachedValue = this.cache?.get(inputHash); let cachedValue = this.cache?.get(inputHash);
if (cachedValue !== undefined) { if (cachedValue !== undefined) {
log.log(`Using cached value for ${node_type.id || node.id}`); log.log(`Using cached value for ${node_type.id || node.id}`);

View File

@ -14,11 +14,6 @@
import NodeStore from "$lib/node-store/NodeStore.svelte"; import NodeStore from "$lib/node-store/NodeStore.svelte";
import type { GraphManager } from "$lib/graph-interface/graph-manager"; import type { GraphManager } from "$lib/graph-interface/graph-manager";
import { setContext } from "svelte"; import { setContext } from "svelte";
import {
decodeFloat,
decodeNestedArray,
encodeNestedArray,
} from "@nodes/utils";
import ActiveNodeSettings from "$lib/settings/panels/ActiveNodeSettings.svelte"; import ActiveNodeSettings from "$lib/settings/panels/ActiveNodeSettings.svelte";
import PerformanceViewer from "$lib/performance/PerformanceViewer.svelte"; import PerformanceViewer from "$lib/performance/PerformanceViewer.svelte";
import Panel from "$lib/settings/Panel.svelte"; import Panel from "$lib/settings/Panel.svelte";
@ -26,28 +21,22 @@
import NestedSettings from "$lib/settings/panels/NestedSettings.svelte"; import NestedSettings from "$lib/settings/panels/NestedSettings.svelte";
import { createPerformanceStore } from "$lib/performance"; import { createPerformanceStore } from "$lib/performance";
import { type PerformanceData } from "$lib/performance/store"; import { type PerformanceData } from "$lib/performance/store";
import { RemoteRuntimeExecutor } from "$lib/remote-runtime-executor";
const nodeRegistry = new RemoteNodeRegistry(""); const nodeRegistry = new RemoteNodeRegistry("");
const workerRuntime = new WorkerRuntimeExecutor(); const workerRuntime = new WorkerRuntimeExecutor();
// const remoteRuntime = new RemoteRuntimeExecutor("/runtime");
let performanceData: PerformanceData; let performanceData: PerformanceData;
let viewerPerformance = createPerformanceStore(); let viewerPerformance = createPerformanceStore();
globalThis.decode = decodeNestedArray;
globalThis.encode = encodeNestedArray;
globalThis.decodeFloat = decodeFloat;
let res: Int32Array; let res: Int32Array;
let activeNode: Node | undefined; let activeNode: Node | undefined;
let updateViewer: (arg: Int32Array) => void;
let graph = localStorage.getItem("graph") let graph = localStorage.getItem("graph")
? JSON.parse(localStorage.getItem("graph")!) ? JSON.parse(localStorage.getItem("graph")!)
: templates.plant; : templates.plant;
console.log({ graph });
let manager: GraphManager; let manager: GraphManager;
let managerStatus: Writable<"loading" | "error" | "idle">; let managerStatus: Writable<"loading" | "error" | "idle">;
$: if (manager) { $: if (manager) {
@ -80,8 +69,9 @@
try { try {
let a = performance.now(); let a = performance.now();
// res = await remoteRuntime.execute(_graph, _settings); // res = await remoteRuntime.execute(_graph, _settings);
res = await workerRuntime.execute(_graph, _settings); let res = await workerRuntime.execute(_graph, _settings);
let b = performance.now(); let b = performance.now();
updateViewer(res);
let perfData = await workerRuntime.getPerformanceData(); let perfData = await workerRuntime.getPerformanceData();
let lastRun = perfData.runs?.at(-1); let lastRun = perfData.runs?.at(-1);
if (lastRun) { if (lastRun) {
@ -125,7 +115,7 @@
<Grid.Row> <Grid.Row>
<Grid.Cell> <Grid.Cell>
<Viewer <Viewer
result={res} bind:update={updateViewer}
perf={viewerPerformance} perf={viewerPerformance}
centerCamera={$AppSettings.centerCamera} centerCamera={$AppSettings.centerCamera}
/> />

View File

@ -13,7 +13,7 @@ export interface NodeRegistry {
* @throws An error if the nodes could not be loaded * @throws An error if the nodes could not be loaded
* @remarks This method should be called before calling getNode or getAllNodes * @remarks This method should be called before calling getNode or getAllNodes
*/ */
load: (nodeIds: (NodeId | string)[]) => Promise<NodeDefinition[]>; load: (nodeIds: NodeId[]) => Promise<NodeDefinition[]>;
/** /**
* Get a node by id * Get a node by id
* @param id - The id of the node to get * @param id - The id of the node to get

View File

@ -14,10 +14,10 @@ test("fastHashArray doesnt product collisions", () => {
const a = new Int32Array(1000); const a = new Int32Array(1000);
const hash_a = fastHashArray(a); const hash_a = fastHashArray(a.buffer);
a[0] = 1; a[0] = 1;
const hash_b = fastHashArray(a); const hash_b = fastHashArray(a.buffer);
expect(hash_a).not.toEqual(hash_b); expect(hash_a).not.toEqual(hash_b);
@ -28,13 +28,13 @@ test('fastHashArray is fast(ish) < 20ms', () => {
const a = new Int32Array(10_000); const a = new Int32Array(10_000);
const t0 = performance.now(); const t0 = performance.now();
fastHashArray(a); fastHashArray(a.buffer);
const t1 = performance.now(); const t1 = performance.now();
a[0] = 1; a[0] = 1;
fastHashArray(a); fastHashArray(a.buffer);
const t2 = performance.now(); const t2 = performance.now();
@ -48,7 +48,7 @@ test('fastHashArray is deterministic', () => {
a[42] = 69; a[42] = 69;
const b = new Int32Array(1000); const b = new Int32Array(1000);
b[42] = 69; b[42] = 69;
const hashA = fastHashArray(a); const hashA = fastHashArray(a.buffer);
const hashB = fastHashArray(b); const hashB = fastHashArray(b.buffer);
expect(hashA).toEqual(hashB); expect(hashA).toEqual(hashB);
}); });

View File

@ -83,8 +83,8 @@ function sha256(data?: string | Uint8Array) {
return { add, digest }; return { add, digest };
} }
export function fastHashArray(arr: Int32Array): string { export function fastHashArrayBuffer(buffer: ArrayBuffer): string {
return sha256(new Uint8Array(arr.buffer)).digest(); return sha256(new Uint8Array(buffer)).digest();
} }
// Shamelessly copied from // Shamelessly copied from