Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ es
dist
*.pem
!mock-cert.pem
pnpm-lock.yaml
tsconfig.tsbuildinfo
7 changes: 0 additions & 7 deletions lerna.json

This file was deleted.

23 changes: 15 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@
"name": "@antv/algorithm",
"private": true,
"scripts": {
"build": "lerna build",
"lint": "lerna run lint",
"test": "lerna run test --no-private",
"dev": "vite",
"build": "pnpm -r run build",
"lint": "pnpm -r run lint",
"test": "pnpm -r run test --no-private",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"pretty-quick": "pretty-quick",
"clean": "lerna clean",
"clear": "lerna clean && lerna clean -y",
"clean": "pnpm -r run clean",
"clean:modules": "rimraf node_modules",
"bootstrap": "lerna bootstrap",
"ls": "lerna list"
"ls": "pnpm -r list",
"build:site": "vite build",
"deploy": "gh-pages -d site/dist"
},
"devDependencies": {
"lerna": "^3.20.2"
"@antv/graphlib": "^2.0.0",
"graphology": "^0.25.1",
"graphology-generators": "^0.11.2",
"graphology-types": "^0.24.7",
"graphology-metrics": "^2.1.0",
"graphology-shortest-path": "^2.0.2",
"vite": "^4.3.8"
}
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ document.head.appendChild(tokenElement);
均为异步调用,以 pageRank 为例:

```js
import { pageRank, WebGPUGraph } from '@antv/webgpu-graph';
import { pageRank, WebGPUGraph } from '@antv/graph-gpu';

// 初始化
const graph = new WebGPUGraph();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AntV Graph Algorithm based on WebGPU

`webgpu-graph` is a GPU accelerated graph analytics library, with functionality like [WebGPU](https://www.w3.org/TR/webgpu/) which provides modern features such as compute shader(in [WGSL](https://www.w3.org/TR/WGSL/)). Compared with CPU version, we almost gain ~100x speed up with big datasets.
`graph-gpu` is a GPU accelerated graph analytics library, with functionality like [WebGPU](https://www.w3.org/TR/webgpu/) which provides modern features such as compute shader(in [WGSL](https://www.w3.org/TR/WGSL/)). Compared with CPU version, we almost gain ~100x speed up with big datasets.

It's inspired by [cuGraph](https://github.com/rapidsai/cugraph) and other implementations based on CUDA.

Expand All @@ -22,7 +22,7 @@ Since we are using latest syntax of WGSL, you'd better update your Chrome to the
## Usage

```js
import { pageRank, WebGPUGraph } from '@antv/webgpu-graph';
import { pageRank, WebGPUGraph } from '@antv/graph-gpu';

// initialize WebGPU context
const graph = new WebGPUGraph();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@antv/webgpu-graph",
"name": "@antv/graph-gpu",
"version": "1.0.0",
"description": "provide common graph algorithms implemented with WebGPU",
"keywords": [
Expand All @@ -14,23 +14,23 @@
},
"files": [
"package.json",
"es",
"lib",
"dist",
"LICENSE",
"README.md",
"README-zh_CN.md"
],
"main": "lib/index.js",
"module": "es/index.js",
"main": "dist/index.min.js",
"module": "lib/index.js",
"types": "lib/index.d.ts",
"unpkg": "dist/index.min.js",
"scripts": {
"build": "npm run clean && father build && npm run build:umd",
"build": "npm run clean && npm run build:esm && npm run build:umd",
"build:esm": "tsc",
"build:umd": "webpack --config webpack.config.js --mode production",
"dev:umd": "webpack --config webpack.dev.config.js --mode development",
"ci": "npm run build && npm run coverage",
"clean": "rimraf es lib dist",
"clean": "rimraf lib dist",
"coverage": "jest --coverage",
"lint": "eslint --ext .js,.jsx,.ts,.tsx --format=pretty \"./\"",
"lint:src": "eslint --ext .ts --format=pretty \"./src\"",
Expand Down Expand Up @@ -59,23 +59,22 @@
"@types/jest": "^26.0.18",
"@umijs/fabric": "^2.5.6",
"babel-loader": "^8.2.2",
"father": "^2.30.0",
"jest": "^26.6.3",
"jest-electron": "^0.1.11",
"rimraf": "^3.0.2",
"ts-jest": "^26.4.4",
"ts-loader": "^8.0.14",
"tslint": "^6.1.3",
"typescript": "^4.1.3",
"webpack": "^5.17.0",
"webpack-cli": "^4.9.1"
"webpack": "^5.38.1",
"webpack-cli": "^5.0.2"
},
"dependencies": {
"@antv/g": "^5.0.16",
"@antv/g-webgl": "^1.0.19",
"@antv/g-plugin-gpgpu": "^1.0.14",
"@antv/g": "^5.16.26",
"@antv/g-webgpu": "^1.7.67",
"@antv/g-plugin-gpgpu": "^1.7.49",
"@antv/graphlib": "^2.0.0",
"@types/offscreencanvas": "^2019.6.4",
"@webgpu/types": "^0.1.6",
"tslib": "^2.0.0"
"tslib": "^2.5.2"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Canvas } from '@antv/g';
import { Renderer } from '@antv/g-webgl';
import { Renderer } from '@antv/g-webgpu';
import { Plugin } from '@antv/g-plugin-gpgpu';
import { pageRank } from './link-analysis';
import { sssp } from './traversal';
import type { GraphData } from './types';
import { Graph } from './types';

export interface WebGPUGraphOptions {
canvas: HTMLCanvasElement | OffscreenCanvas;
Expand All @@ -17,14 +17,15 @@ export class WebGPUGraph {
const { canvas } = options;

// FIXME: use OffscreenCanvas instead of a real <canvas> DOM
const $canvas = canvas || window.document.createElement('canvas');
const $canvas = (canvas || window.document.createElement('canvas')) as HTMLCanvasElement;

// use WebGPU
this.renderer = new Renderer({ targets: ['webgpu'] });
this.renderer = new Renderer();
this.renderer.registerPlugin(new Plugin());

// create a canvas
this.canvas = new Canvas({
// @ts-ignore
canvas: $canvas,
width: 1,
height: 1,
Expand All @@ -36,15 +37,16 @@ export class WebGPUGraph {
// wait for canvas' services ready
await this.canvas.ready;
// get GPU Device
return this.renderer.getDevice();
const plugin = this.renderer.getPlugin('device-renderer') as any;
return plugin.getDevice();
}

async pageRank(graphData: GraphData, eps = 1e-5, alpha = 0.85, maxIteration = 1000) {
async pageRank(graphData: Graph, eps = 1e-5, alpha = 0.85, maxIteration = 1000) {
const device = await this.getDevice();
return pageRank(device, graphData, eps, alpha, maxIteration);
}

async sssp(graphData: GraphData, sourceId: string, weightPropertyName: string = '') {
async sssp(graphData: Graph, sourceId: string, weightPropertyName: string = 'weight') {
const device = await this.getDevice();
return sssp(device, graphData, sourceId, weightPropertyName);
}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import type { WebGLRenderer } from '@antv/g-webgl';
import { Kernel, BufferUsage } from '@antv/g-plugin-gpgpu';
import type { GraphData } from '../types';
import { DeviceRenderer } from '@antv/g-webgpu';
import { Kernel } from '@antv/g-plugin-gpgpu';
import { convertGraphData2CSC } from '../util';
import { Graph } from '../types';

const { BufferUsage } = DeviceRenderer;

/**
* Pagerank using power method, ported from CUDA
*
*
* @param graphData
* @param eps Set the tolerance the approximation, this parameter should be a small magnitude value. The lower the tolerance the better the approximation.
* @param alpha The damping factor alpha represents the probability to follow an outgoing edge, standard value is 0.85.
* @param maxIteration Set the maximum number of iterations.
*
*
* @see https://github.com/princeofpython/PageRank-with-CUDA/blob/main/parallel.cu
*/
export async function pageRank(device: WebGLRenderer.Device, graphData: GraphData, eps = 1e-05, alpha = 0.85, maxIteration = 1000) {
export async function pageRank(
device: DeviceRenderer.Device,
graphData: Graph,
eps = 1e-5,
alpha = 0.85,
maxIteration = 1000,
) {
const BLOCK_SIZE = 1;
const BLOCKS = 256;

Expand Down Expand Up @@ -46,13 +54,13 @@ export async function pageRank(device: WebGLRenderer.Device, graphData: GraphDat
const storeKernel = new Kernel(device, {
computeShader: `
struct Buffer {
data: array<f32>;
data: array<f32>,
};

@group(0) @binding(0) var<storage, read> r : Buffer;
@group(0) @binding(1) var<storage, write> r_last : Buffer;
@group(0) @binding(1) var<storage, read_write> r_last : Buffer;

@stage(compute) @workgroup_size(${BLOCKS}, ${BLOCK_SIZE})
@compute @workgroup_size(${BLOCKS}, ${BLOCK_SIZE})
fn main(
@builtin(global_invocation_id) global_id : vec3<u32>
) {
Expand All @@ -66,14 +74,14 @@ fn main(
const matmulKernel = new Kernel(device, {
computeShader: `
struct Buffer {
data: array<f32>;
data: array<f32>,
};

@group(0) @binding(0) var<storage, read> graph : Buffer;
@group(0) @binding(1) var<storage, read_write> r : Buffer;
@group(0) @binding(2) var<storage, read> r_last : Buffer;

@stage(compute) @workgroup_size(${BLOCKS}, ${BLOCK_SIZE})
@compute @workgroup_size(${BLOCKS}, ${BLOCK_SIZE})
fn main(
@builtin(global_invocation_id) global_id : vec3<u32>
) {
Expand All @@ -92,13 +100,13 @@ fn main(
const rankDiffKernel = new Kernel(device, {
computeShader: `
struct Buffer {
data: array<f32>;
data: array<f32>,
};

@group(0) @binding(0) var<storage, read> r : Buffer;
@group(0) @binding(1) var<storage, read_write> r_last : Buffer;

@stage(compute) @workgroup_size(${BLOCKS}, ${BLOCK_SIZE})
@compute @workgroup_size(${BLOCKS}, ${BLOCK_SIZE})
fn main(
@builtin(global_invocation_id) global_id : vec3<u32>
) {
Expand Down Expand Up @@ -142,15 +150,15 @@ fn main(
matmulKernel.dispatch(grids, 1);
rankDiffKernel.dispatch(grids, 1);

const last = await readback.readBuffer(rLastBuffer) as Float32Array;
const last = (await readback.readBuffer(rLastBuffer)) as Float32Array;
const result = last.reduce((prev, cur) => prev + cur, 0);
if (result < eps) {
break;
}
}

const out = await readback.readBuffer(rBuffer) as Float32Array;
const out = (await readback.readBuffer(rBuffer)) as Float32Array;
return Array.from(out)
.map((score, index) => ({ id: graphData.nodes[index].id, score }))
.map((score, index) => ({ id: graphData.getAllNodes()[index].id, score }))
.sort((a, b) => b.score - a.score);
}
}
10 changes: 10 additions & 0 deletions packages/graph-gpu/src/traversal/bfs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { DeviceRenderer } from '@antv/g-webgpu';
import { Graph } from '../types';

/**
* Scalable GPU Graph Traversal
* @see https://research.nvidia.com/publication/scalable-gpu-graph-traversal
* @see https://github.com/rafalk342/bfs-cuda
* @see https://github.com/kaletap/bfs-cuda-gpu
*/
export async function bfs(device: DeviceRenderer.Device, graphData: Graph) {}
Loading