Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitonic Sort Update 2 #318

Merged
merged 29 commits into from
Dec 4, 2023
Merged
Changes from 22 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d51dc45
Merge pull request #1 from webgpu/main
cmhhelgeson Oct 18, 2023
32ec9b1
Changed default values and added auto sort at start
cmhhelgeson Oct 26, 2023
acdc040
Added stepIndex and totalStep to execution Information and allowed fo…
cmhhelgeson Oct 26, 2023
33bce15
Scaffolding for global sort and renaming of controller elements from …
cmhhelgeson Oct 27, 2023
4b65446
removed anys for greggman
cmhhelgeson Oct 27, 2023
766427d
Merge pull request #2 from webgpu/main
cmhhelgeson Oct 27, 2023
ebf1684
Safety commit
cmhhelgeson Oct 30, 2023
181164c
Adjusted bindGroups and uniform placement and added different visuali…
cmhhelgeson Oct 30, 2023
fc40521
Adjusted bindGroups, adjusted uniforms, and added a new visualization…
cmhhelgeson Oct 30, 2023
50a1bae
Finished adding updates
cmhhelgeson Oct 30, 2023
174db18
Removed pointerEvents from non-interactive gui elements and added ato…
cmhhelgeson Oct 31, 2023
1a4a0d1
Made totalSwaps non-interactive :(
cmhhelgeson Oct 31, 2023
415bd67
Merge pull request #3 from webgpu/main
cmhhelgeson Oct 31, 2023
bd83e37
Sketched out new branch
cmhhelgeson Oct 31, 2023
3751527
Sketch
cmhhelgeson Nov 1, 2023
bb85b16
Condense information in multiple Gui elements down to single Gui elem…
cmhhelgeson Nov 2, 2023
c63125c
Added thread constraint
cmhhelgeson Nov 2, 2023
354aeeb
Merge branch 'bitonic_sort_branch' of https://github.com/cmhhelgeson/…
cmhhelgeson Nov 2, 2023
706e090
Added ability to constrain maximum number of threads/invocations per …
cmhhelgeson Nov 2, 2023
80596b3
Get rid of todos
cmhhelgeson Nov 2, 2023
e240142
Remove unused folder
cmhhelgeson Nov 2, 2023
e0df2ea
Removed unintended addition to slug file
cmhhelgeson Nov 2, 2023
63d98ee
removed references to threads in main.ts, removed references to remov…
cmhhelgeson Nov 30, 2023
32db6c9
Removed all references to threads in bitonicCompute.ts
cmhhelgeson Nov 30, 2023
927ae5d
Added new descriptions for each of the settings elements
cmhhelgeson Dec 2, 2023
10d94cb
Implemented most ben-clayton naming suggestions
cmhhelgeson Dec 2, 2023
0e4b4f9
Fixed minor spacing issue to make prettier happy
cmhhelgeson Dec 2, 2023
04360b6
Added additional comments
cmhhelgeson Dec 4, 2023
ba7bba1
Final changes
cmhhelgeson Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 86 additions & 22 deletions src/sample/bitonicSort/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@ type DisplayType = 'Elements' | 'Swap Highlight';
// Gui settings object
interface SettingsInterface {
'Total Elements': number;
'Thread Constraint': number;
'Grid Width': number;
'Grid Height': number;
'Grid Dimensions': string;
'Total Threads': number;
'Hovered Cell': number;
'Swapped Cell': number;
'Current Step': string;
'Step Index': number;
'Total Steps': number;
'Prev Step': StepType;
Expand Down Expand Up @@ -66,6 +69,11 @@ SampleInitFactoryWebGPU(
totalElementLengths.push(i);
}

const totalThreadLengths = [];
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
for (let i = maxThreadsX; i >= 2; i /= 2) {
totalThreadLengths.push(i);
}

const defaultGridWidth =
Math.sqrt(maxElements) % 2 === 0
? Math.floor(Math.sqrt(maxElements))
Expand All @@ -76,10 +84,14 @@ SampleInitFactoryWebGPU(
const settings: SettingsInterface = {
// number of cellElements. Must equal gridWidth * gridHeight and 'Total Threads' * 2
'Total Elements': maxElements,
// Artificially constrain the maximum number of threads/invocations that can be executed per workgroup
'Thread Constraint': maxThreadsX,
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
// width of screen in cells.
'Grid Width': defaultGridWidth,
// height of screen in cells
'Grid Height': defaultGridHeight,
// Grid Dimensions as string
'Grid Dimensions': `${defaultGridWidth}x${defaultGridHeight}`,
// number of threads to execute in a workgroup ('Total Threads', 1, 1)
'Total Threads': maxThreadsX,
// Cell in element grid mouse element is hovering over
Expand All @@ -90,6 +102,8 @@ SampleInitFactoryWebGPU(
'Step Index': 0,
// Total steps to sort current number of elements
'Total Steps': getNumSteps(maxElements),
//Step Info as string
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
'Current Step': `0 of 91`,
// Previously executed step
'Prev Step': 'NONE',
// Next step to execute
Expand Down Expand Up @@ -234,29 +248,33 @@ SampleInitFactoryWebGPU(
);

const resetExecutionInformation = () => {
// Total threads are either elements / 2 or maxWorkgroupsSizeX
// Total threads are either elements / 2 or Max Threads X
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
totalThreadsController.setValue(
Math.min(settings['Total Elements'] / 2, maxThreadsX)
Math.min(settings['Total Elements'] / 2, settings['Thread Constraint'])
);

// Dispatch a workgroup for every (Max threads * 2) elements
const workgroupsPerStep =
(settings['Total Elements'] - 1) / (maxThreadsX * 2);
(settings['Total Elements'] - 1) / (settings['Thread Constraint'] * 2);

totalWorkgroupsController.setValue(Math.ceil(workgroupsPerStep));

// Reset step Index and number of steps based on elements size
stepIndexController.setValue(0);
totalStepsController.setValue(getNumSteps(settings['Total Elements']));
settings['Step Index'] = 0;
settings['Total Steps'] = getNumSteps(settings['Total Elements']);
currentStepController.setValue(
`${settings['Step Index']} of ${settings['Total Steps']}`
);

// Get new width and height of screen display in cells
const newCellWidth =
Math.sqrt(settings['Total Elements']) % 2 === 0
? Math.floor(Math.sqrt(settings['Total Elements']))
: Math.floor(Math.sqrt(settings['Total Elements'] / 2));
const newCellHeight = settings['Total Elements'] / newCellWidth;
gridWidthController.setValue(newCellWidth);
gridHeightController.setValue(newCellHeight);
settings['Grid Width'] = newCellWidth;
settings['Grid Height'] = newCellHeight;
gridDimensionsController.setValue(`${newCellWidth}x${newCellHeight}`);

// Set prevStep to None (restart) and next step to FLIP
prevStepController.setValue('NONE');
Expand Down Expand Up @@ -308,14 +326,20 @@ SampleInitFactoryWebGPU(
}),
compute: {
module: device.createShaderModule({
code: NaiveBitonicCompute(settings['Total Elements'] / 2),
code: NaiveBitonicCompute(
Math.min(
settings['Total Elements'] / 2,
settings['Thread Constraint']
)
),
}),
entryPoint: 'computeMain',
},
});
// Randomize array elements
randomizeElementArray();
highestBlockHeight = 2;
// Unlock thread
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
};

randomizeElementArray();
Expand Down Expand Up @@ -370,6 +394,7 @@ SampleInitFactoryWebGPU(
if (settings['Next Step'] === 'NONE') {
clearInterval(completeSortIntervalID);
completeSortIntervalID = null;
threadConstraintCell.domElement.style.pointerEvents = 'auto';
}
if (settings['Sort Speed'] !== currentIntervalSpeed) {
clearInterval(completeSortIntervalID);
Expand All @@ -389,6 +414,36 @@ SampleInitFactoryWebGPU(
.onChange(() => {
endSortInterval();
resizeElementArray();
threadConstraintCell.domElement.style.pointerEvents = 'auto';
});
const threadConstraintCell = computeResourcesFolder
.add(settings, 'Thread Constraint', totalThreadLengths)
.onChange(() => {
const constraint = Math.min(
settings['Total Elements'] / 2,
settings['Thread Constraint']
);
const workgroupsPerStep =
(settings['Total Elements'] - 1) /
(settings['Thread Constraint'] * 2);
totalThreadsController.setValue(constraint);
totalWorkgroupsController.setValue(Math.ceil(workgroupsPerStep));
computePipeline = computePipeline = device.createComputePipeline({
layout: device.createPipelineLayout({
bindGroupLayouts: [computeBGCluster.bindGroupLayout],
}),
compute: {
module: device.createShaderModule({
code: NaiveBitonicCompute(
Math.min(
settings['Total Elements'] / 2,
settings['Thread Constraint']
)
),
}),
entryPoint: 'computeMain',
},
});
});
const totalThreadsController = computeResourcesFolder.add(
settings,
Expand All @@ -404,39 +459,45 @@ SampleInitFactoryWebGPU(
const controlFolder = gui.addFolder('Sort Controls');
controlFolder.add(settings, 'Sort Speed', 50, 1000).step(50);
controlFolder.add(settings, 'Execute Sort Step').onChange(() => {
// Thread number locked upon sort
threadConstraintCell.domElement.style.pointerEvents = 'none';
endSortInterval();
settings.executeStep = true;
});
controlFolder.add(settings, 'Randomize Values').onChange(() => {
endSortInterval();
randomizeElementArray();
resetExecutionInformation();
// Unlock threadChange since sort has stopped
threadConstraintCell.domElement.style.pointerEvents = 'auto';
});
controlFolder
.add(settings, 'Log Elements')
.onChange(() => console.log(elements));
controlFolder.add(settings, 'Complete Sort').onChange(startSortInterval);
controlFolder.add(settings, 'Complete Sort').onChange(() => {
// Thread number locked upon sort
threadConstraintCell.domElement.style.pointerEvents = 'none';
startSortInterval();
});
controlFolder.open();

// Information about grid display
const gridFolder = gui.addFolder('Grid Information');
gridFolder.add(settings, 'Display Mode', ['Elements', 'Swap Highlight']);
const gridWidthController = gridFolder.add(settings, 'Grid Width');
const gridHeightController = gridFolder.add(settings, 'Grid Height');
const gridDimensionsController = gridFolder.add(
settings,
'Grid Dimensions'
);
const hoveredCellController = gridFolder
.add(settings, 'Hovered Cell')
.onChange(setSwappedCell);
const swappedCellController = gridFolder.add(settings, 'Swapped Cell');

// Additional Information about the execution state of the sort
const executionInformationFolder = gui.addFolder('Execution Information');
const stepIndexController = executionInformationFolder.add(
const currentStepController = executionInformationFolder.add(
settings,
'Step Index'
);
const totalStepsController = executionInformationFolder.add(
settings,
'Total Steps'
'Current Step'
);
const prevStepController = executionInformationFolder.add(
settings,
Expand Down Expand Up @@ -485,18 +546,17 @@ SampleInitFactoryWebGPU(
});

// Deactivate interaction with select GUI elements
threadConstraintCell.domElement.style.pointerEvents = 'none';
totalWorkgroupsController.domElement.style.pointerEvents = 'none';
hoveredCellController.domElement.style.pointerEvents = 'none';
swappedCellController.domElement.style.pointerEvents = 'none';
stepIndexController.domElement.style.pointerEvents = 'none';
totalStepsController.domElement.style.pointerEvents = 'none';
currentStepController.domElement.style.pointerEvents = 'none';
prevStepController.domElement.style.pointerEvents = 'none';
prevBlockHeightController.domElement.style.pointerEvents = 'none';
nextStepController.domElement.style.pointerEvents = 'none';
nextBlockHeightController.domElement.style.pointerEvents = 'none';
totalThreadsController.domElement.style.pointerEvents = 'none';
gridWidthController.domElement.style.pointerEvents = 'none';
gridHeightController.domElement.style.pointerEvents = 'none';
gridDimensionsController.domElement.style.pointerEvents = 'none';
totalSwapsController.domElement.style.pointerEvents = 'none';

let highestBlockHeight = 2;
Expand Down Expand Up @@ -550,7 +610,11 @@ SampleInitFactoryWebGPU(
computePassEncoder.setBindGroup(0, computeBGCluster.bindGroups[0]);
computePassEncoder.dispatchWorkgroups(settings['Total Workgroups']);
computePassEncoder.end();
stepIndexController.setValue(settings['Step Index'] + 1);
//stepIndexController.setValue(settings['Step Index'] + 1);
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
settings['Step Index'] = settings['Step Index'] + 1;
currentStepController.setValue(
`${settings['Step Index']} of ${settings['Total Steps']}`
);
prevStepController.setValue(settings['Next Step']);
prevBlockHeightController.setValue(settings['Next Swap Span']);
nextBlockHeightController.setValue(settings['Next Swap Span'] / 2);
Expand Down
Loading