From bbf4451b44928d7612282ee7365d43bc3d7008a0 Mon Sep 17 00:00:00 2001 From: Fribbels Date: Thu, 5 Sep 2024 17:27:41 -0700 Subject: [PATCH] feat: bit pack relic set solutions array --- src/lib/gpu/injection/generateWgsl.ts | 8 +++++++- src/lib/gpu/webgpuOptimizer.ts | 27 +++++++++++++++++++++++++++ src/lib/optimizer/relicSetSolver.js | 3 ++- src/lib/worker/optimizerWorker.ts | 7 ++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/lib/gpu/injection/generateWgsl.ts b/src/lib/gpu/injection/generateWgsl.ts index 0c05d48c1..a92160a1a 100644 --- a/src/lib/gpu/injection/generateWgsl.ts +++ b/src/lib/gpu/injection/generateWgsl.ts @@ -64,7 +64,13 @@ function format(text: string) { function injectSetFilters(wgsl: string, gpuParams: GpuConstants) { // CTRL+ F: RESULTS ASSIGNMENT return wgsl.replace('/* INJECT SET FILTERS */', indent(` -if (relicSetSolutionsMatrix[relicSetIndex] < 1 || ornamentSetSolutionsMatrix[ornamentSetIndex] < 1) { + +let arrayIndex = relicSetIndex >> 5u; +let bitPosition = relicSetIndex & 31u; +let packedValue: i32 = relicSetSolutionsMatrix[arrayIndex]; +let unpackedValue = (u32(packedValue) >> (31u - bitPosition)) & 1u; + +if (unpackedValue < 1 || ornamentSetSolutionsMatrix[ornamentSetIndex] < 1) { results[index] = ${gpuParams.DEBUG ? 'ComputedStats()' : '-failures; failures = failures + 1'}; continue; } diff --git a/src/lib/gpu/webgpuOptimizer.ts b/src/lib/gpu/webgpuOptimizer.ts index 1c00e6c5d..8763de9aa 100644 --- a/src/lib/gpu/webgpuOptimizer.ts +++ b/src/lib/gpu/webgpuOptimizer.ts @@ -12,6 +12,33 @@ import { COMPUTE_ENGINE_GPU_EXPERIMENTAL } from 'lib/constants' import { getWebgpuDevice } from 'lib/gpu/webgpuDevice' import { GpuExecutionContext, RelicsByPart } from 'lib/gpu/webgpuTypes' +export function condenseRelicSetSolutions(relicSetSolutions: number[]) { + function bitPackArray(arr: number[]) { + const paddedLength = Math.ceil(arr.length / 32) * 32 + const paddedArray = new Array(paddedLength).fill(0) + + for (let i = 0; i < arr.length; i++) { + paddedArray[i] = arr[i] + } + + const result: number[] = [] + + for (let i = 0; i < paddedArray.length; i += 32) { + let packedValue = 0 + + for (let j = 0; j < 32; j++) { + packedValue |= (paddedArray[i + j] << (31 - j)) + } + + result.push(packedValue >>> 0) + } + + return result + } + + return bitPackArray(relicSetSolutions) +} + export async function gpuOptimize(props: { params: OptimizerParams request: Form diff --git a/src/lib/optimizer/relicSetSolver.js b/src/lib/optimizer/relicSetSolver.js index d65fc6516..b59f011cd 100644 --- a/src/lib/optimizer/relicSetSolver.js +++ b/src/lib/optimizer/relicSetSolver.js @@ -1,5 +1,6 @@ import { Constants, RelicSetFilterOptions } from 'lib/constants' import { Utils } from 'lib/utils' +import { condenseRelicSetSolutions } from 'lib/gpu/webgpuOptimizer' // Here be dragons export function generateRelicSetSolutions(request) { @@ -221,7 +222,7 @@ function convertRelicSetIndicesTo1D(setIndices) { } } - return arr + return condenseRelicSetSolutions(arr) } const permutator = (inputArr) => { diff --git a/src/lib/worker/optimizerWorker.ts b/src/lib/worker/optimizerWorker.ts index 225eecc98..75dce4f91 100644 --- a/src/lib/worker/optimizerWorker.ts +++ b/src/lib/worker/optimizerWorker.ts @@ -105,8 +105,13 @@ self.onmessage = function (e: MessageEvent) { const relicSetIndex = setH + setB * relicSetCount + setG * relicSetCount * relicSetCount + setF * relicSetCount * relicSetCount * relicSetCount const ornamentSetIndex = setP + setL * ornamentSetCount + const arrayIndex = relicSetIndex >> 5 + const bitPosition = relicSetIndex & 31 + const packedValue = relicSetSolutions[arrayIndex] + const unpackedValue = (packedValue >> (31 - bitPosition)) & 1 + // Exit early if sets don't match - if (relicSetSolutions[relicSetIndex] != 1 || ornamentSetSolutions[ornamentSetIndex] != 1) { + if (unpackedValue != 1 || ornamentSetSolutions[ornamentSetIndex] != 1) { continue }