From 18fc31483421da3da271c2abdaa765a88cad9eac Mon Sep 17 00:00:00 2001 From: jayshah1819 Date: Wed, 17 Dec 2025 22:24:53 -0500 Subject: [PATCH] Conditional buffer clearing --- benchmarking.mjs | 6 ++---- onesweep.mjs | 37 +++++++++++++++++++++++-------------- primitive.mjs | 15 +++++++++------ 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/benchmarking.mjs b/benchmarking.mjs index a7b548e..429da92 100644 --- a/benchmarking.mjs +++ b/benchmarking.mjs @@ -23,8 +23,6 @@ if (typeof process !== "undefined" && process.release.name === "node") { /* begin https://github.com/sharonchoong/svg-exportJS */ /* svg-exportJS prerequisite: canvg */ await import("https://cdnjs.cloudflare.com/ajax/libs/canvg/3.0.9/umd.js"); - /* svg-exportJS plugin */ - await import("https://sharonchoong.github.io/svg-exportJS/svg-export.min.js"); await import("https://cdn.jsdelivr.net/gh/sharonchoong/svg-exportJS@master/dist/umd/svg-export.umd.min.js"); /* end https://github.com/sharonchoong/svg-exportJS */ const urlParams = new URL(window.location.href).searchParams; @@ -136,13 +134,13 @@ async function main(navigator) { //); // let testSuites = [DLDFScanMiniSuite]; // let testSuites = [DLDFScanAccuracyRegressionSuite]; - let testSuites = [DLDFPerfSuite]; + //let testSuites = [DLDFPerfSuite]; // let testSuites = [DLDFDottedCachePerfTestSuite]; // let testSuites = [DLDFDottedCachePerf2TestSuite]; // let testSuites = [DLDFSingletonWithTimingSuite]; // let testSuites = [DLDFFailureSuite]; // let testSuites = [StoneberryScanMiniSuite]; - // let testSuites = [SortOneSweepFunctionalRegressionSuite]; + let testSuites = [SortOneSweepFunctionalRegressionSuite]; // let testSuites = [SortOneSweep64v32Suite]; // let testSuites = [SortOneSweep64v321MNoPlotSuite]; diff --git a/onesweep.mjs b/onesweep.mjs index 543c501..8e2086e 100644 --- a/onesweep.mjs +++ b/onesweep.mjs @@ -20,6 +20,11 @@ import { Datatype } from "./datatype.mjs"; export class OneSweepSort extends BaseSort { constructor(args) { super(args); + + // OneSweep is a multi-pass algorithm that requires preserving data between passes + // Must disable buffer clearing on reuse + this.clearBuffersOnReuse = false; + if (this.direction === undefined) { this.direction = "ascending"; } @@ -1322,6 +1327,7 @@ export class OneSweepSort extends BaseSort { label: `OneSweep sort (${this.type}, ${this.direction}) global_hist [subgroups: ${this.useSubgroups}]`, logKernelCodeToConsole: false, getDispatchGeometry: () => { + console.log(`[OneSweepSort] global_hist: workgroupCount=${this.reduceWorkgroupCount}, maxDim=${this.device.limits.maxComputeWorkgroupsPerDimension}`); return [this.reduceWorkgroupCount]; }, }), @@ -1333,6 +1339,7 @@ export class OneSweepSort extends BaseSort { label: `OneSweep sort (${this.type}, ${this.direction}) onesweep_scan [subgroups: ${this.useSubgroups}]`, logKernelCodeToConsole: false, getDispatchGeometry: () => { + console.log(`[OneSweepSort] onesweep_scan: SORT_PASSES=${this.SORT_PASSES}, maxDim=${this.device.limits.maxComputeWorkgroupsPerDimension}`); return [this.SORT_PASSES]; }, }), @@ -1351,6 +1358,7 @@ export class OneSweepSort extends BaseSort { logKernelCodeToConsole: pass === 0 ? false : false, logLaunchParameters: pass === 0 ? false : false, getDispatchGeometry: () => { + console.log(`[OneSweepSort] onesweep_pass[${pass}]: passWorkgroupCount=${this.passWorkgroupCount}, maxDim=${this.device.limits.maxComputeWorkgroupsPerDimension}`); return [this.passWorkgroupCount]; }, }) @@ -1702,7 +1710,7 @@ export class OneSweepSort extends BaseSort { const OneSweep64v32BW = { x: { field: "inputBytes", label: "Input array size (B)" }, y: { field: "bandwidth", label: "Achieved bandwidth (GB/s)" }, - stroke: { field: "datatype" }, + stroke: { field: "timing" }, test_br: "gpuinfo.description", fy: { field: "timing" }, }; @@ -1710,7 +1718,7 @@ const OneSweep64v32BW = { const OneSweep64v32Runtime = { x: { field: "inputBytes", label: "Input array size (B)" }, y: { field: "time", label: "Runtime (ns)" }, - stroke: { field: "datatype" }, + stroke: { field: "timing" }, test_br: "gpuinfo.description", fy: { field: "timing" }, }; @@ -1749,26 +1757,26 @@ const SortOneSweepRegressionParams = { }; const SortOneSweepFunctionalParams = { - inputLength: [2 ** 25], + inputLength: [2 ** 22], // inputLength: [2048, 4096], // inputLength: range(10, 27).map((i) => 2 ** i), // datatype: ["u64" /*"u32", "i32", "f32" */ /*, "u64"*/], - datatype: ["u32", "i32", "f32", "u64"], + datatype: ["u32", "u64"], type: ["keysonly" /* "keyvalue", */], direction: ["ascending"], disableSubgroups: [false], }; const Sort64v32Params = { - inputLength: range(18, 25).map((i) => 2 ** i), - datatype: ["u64", "u32"], + inputLength: [2 ** 22], + datatype: ["u64"], type: ["keysonly" /* "keyvalue", */], direction: ["ascending"], disableSubgroups: [false], }; const Sort64PHDParams = { - inputLength: range(18, 25).map((i) => 2 ** i), + inputLength: [2 ** 22], datatype: ["u64"], passHistDelta: [/* 128,*/ 0 /*, 256, 512, 1024*/], type: ["keysonly" /* "keyvalue", */], @@ -1785,12 +1793,12 @@ const Sort64v321MParams = { }; const SortOneSweepSingletonParams = { - inputLength: [2 ** 25], + inputLength: [2 ** 22], // inputLength: [2048, 4096], // inputLength: range(10, 27).map((i) => 2 ** i), datatype: ["u32"], - type: ["keysonly", "keyvalue"], - direction: ["ascending", "descending"], + type: ["keysonly"], + direction: ["ascending"], disableSubgroups: [false], }; @@ -1834,27 +1842,28 @@ export const SortOneSweepRegressionSuite = new BaseTestSuite({ testSuite: "onesweep", initializeCPUBuffer: "fisher-yates", // initializeCPUBuffer: "randomizeAbsUnder1024", - trials: 2, + trials: 1, params: SortOneSweepSingletonParams, primitive: OneSweepSort, // primitiveArgs: { validate: false }, - // plots: [OneSweepKeyvKeyValuePlot], + plots: [OneSweep64v32BW, OneSweep64v32Runtime], }); export const SortOneSweepFunctionalRegressionSuite = new BaseTestSuite({ category: "sort", testSuite: "onesweep", initializeCPUBuffer: "fisher-yates", - trials: 2, + trials: 1, params: SortOneSweepFunctionalParams, primitive: OneSweepSort, + plots: [OneSweep64v32BW, OneSweep64v32Runtime], }); export const SortOneSweep64v32Suite = new BaseTestSuite({ category: "sort", testSuite: "onesweep", initializeCPUBuffer: "randomBytes", - trials: 5, + trials: 1, params: Sort64PHDParams, // params: Sort64v32Params, primitive: OneSweepSort, diff --git a/primitive.mjs b/primitive.mjs index b5c1e56..3e542fb 100644 --- a/primitive.mjs +++ b/primitive.mjs @@ -174,6 +174,12 @@ export class BasePrimitive { // not sure a Map gives me anything I don't get from {} this.__buffers = {}; // this is essentially private + + // Set default for buffer clearing on reuse + if (!('clearBuffersOnReuse' in this)) { + this.clearBuffersOnReuse = true; + } + this.useSubgroups = this.device.features.has("subgroups"); if (args.disableSubgroups) { this.useSubgroups = false; @@ -797,11 +803,8 @@ dispatchGeometry: ${dispatchGeometry}`); */ const existingBuffer = this.getBuffer(action.label); if (existingBuffer && existingBuffer.size === action.size) { - /* just use the existing buffer, but it might be full of non-zero data */ - if (action.populateWith) { - /* do nothing, because we will fill the buffer with data */ - } else { - /* this is the default -- clear the buffer */ + /* just use the existing buffer */ + if (this.clearBuffersOnReuse && !action.populateWith) { encoder.clearBuffer(existingBuffer.buffer.buffer); } } else { @@ -964,4 +967,4 @@ export class CopyBufferToBuffer { constructor(args) { Object.assign(this, args); } -} +} \ No newline at end of file