Skip to content

Commit b58430f

Browse files
authored
Sigma.js demo using node-rapids (#392)
Creation of `node/modules/demo/api-demo` and all supporting packages.
1 parent e142ed7 commit b58430f

File tree

20 files changed

+2069
-44
lines changed

20 files changed

+2069
-44
lines changed

lerna.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"modules/demo/ssr/*",
1616
"modules/demo/tfjs/*",
1717
"modules/demo/client-server",
18+
"modules/demo/api-server",
1819
"modules/demo/viz-app",
1920
"modules/demo/sql/*"
2021
]

modules/demo/.vscode/launch.json

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,27 @@
1313
}
1414
],
1515
"configurations": [
16+
{
17+
"name": "Attach Test",
18+
"port": 9229,
19+
"request": "attach",
20+
"skipFiles": [
21+
"<node_internals>/**"
22+
],
23+
"type": "node"
24+
},
1625
{
1726
"type": "node",
1827
"request": "launch",
1928
"name": "Debug Demo (TS only)",
2029
"program": "${workspaceFolder}/${input:DEMO_NAME}",
2130
"stopOnEntry": false,
22-
"args": ["${input:DEMO_ARGS}"],
23-
"runtimeArgs": ["--experimental-vm-modules"],
31+
"args": [
32+
"${input:DEMO_ARGS}"
33+
],
34+
"runtimeArgs": [
35+
"--experimental-vm-modules"
36+
],
2437
"cwd": "${workspaceFolder}/${input:DEMO_NAME}",
2538
"console": "integratedTerminal",
2639
"internalConsoleOptions": "neverOpen",
@@ -44,7 +57,9 @@
4457
{
4558
"name": "Debug Demo (launch gdb)",
4659
// hide the individual configurations from the debug dropdown list
47-
"presentation": { "hidden": true },
60+
"presentation": {
61+
"hidden": true
62+
},
4863
"type": "cppdbg",
4964
"request": "launch",
5065
"stopAtEntry": false,
@@ -62,9 +77,18 @@
6277
],
6378
"program": "${input:NODE_BINARY}",
6479
"environment": [
65-
{ "name": "NODE_DEBUG", "value": "1" },
66-
{ "name": "NODE_NO_WARNINGS", "value": "1" },
67-
{ "name": "NODE_ENV", "value": "production" },
80+
{
81+
"name": "NODE_DEBUG",
82+
"value": "1"
83+
},
84+
{
85+
"name": "NODE_NO_WARNINGS",
86+
"value": "1"
87+
},
88+
{
89+
"name": "NODE_ENV",
90+
"value": "production"
91+
},
6892
// { "name": "READABLE_STREAM", "value": "disable" },
6993
],
7094
"args": [
@@ -80,7 +104,9 @@
80104
"type": "node",
81105
"request": "attach",
82106
// hide the individual configurations from the debug dropdown list
83-
"presentation": { "hidden": true },
107+
"presentation": {
108+
"hidden": true
109+
},
84110
"port": 9229,
85111
"timeout": 60000,
86112
"cwd": "${workspaceFolder}",
@@ -113,7 +139,7 @@
113139
"command": "shellCommand.execute",
114140
"args": {
115141
"description": "Select a demo to debug",
116-
"command": "echo client-server viz-app luma graph spatial xterm $(find modules/demo/deck modules/demo/tfjs modules/demo/ipc modules/demo/ssr modules/demo/sql -maxdepth 2 -type f -name 'package.json' -print0 | grep -z -v node_modules | tr -d '\\0' | sed -r 's@modules/demo/@@g' | sed -r 's@/package.json@ @g') | sort -Vr | sed -r 's@\\s@\\n@g'",
142+
"command": "echo client-server viz-app api-server luma graph spatial xterm $(find modules/demo/deck modules/demo/tfjs modules/demo/ipc modules/demo/ssr modules/demo/sql -maxdepth 2 -type f -name 'package.json' -print0 | grep -z -v node_modules | tr -d '\\0' | sed -r 's@modules/demo/@@g' | sed -r 's@/package.json@ @g') | sort -Vr | sed -r 's@\\s@\\n@g'",
117143
}
118144
},
119145
]

modules/demo/api-server/.gitignore

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
6+
# Runtime data
7+
pids
8+
*.pid
9+
*.seed
10+
11+
# Directory for instrumented libs generated by jscoverage/JSCover
12+
lib-cov
13+
14+
# Coverage directory used by tools like istanbul
15+
coverage
16+
17+
# nyc test coverage
18+
.nyc_output
19+
20+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21+
.grunt
22+
23+
# node-waf configuration
24+
.lock-wscript
25+
26+
# Compiled binary addons (http://nodejs.org/api/addons.html)
27+
build/Release
28+
29+
# Dependency directories
30+
node_modules
31+
jspm_packages
32+
33+
# Optional npm cache directory
34+
.npm
35+
36+
# Optional REPL history
37+
.node_repl_history
38+
39+
# 0x
40+
profile-*
41+
42+
# mac files
43+
.DS_Store
44+
45+
# vim swap files
46+
*.swp
47+
48+
# webstorm
49+
.idea
50+
51+
# vscode
52+
.vscode
53+
*code-workspace
54+
55+
# clinic
56+
profile*
57+
*clinic*
58+
*flamegraph*
59+
60+
# Node-rapids .cache symlink
61+
.cache

modules/demo/api-server/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Fastify HTTP Server Demo
2+
3+
This project is a Fastify-based node http server that allows
4+
commands and data to be sent to and from the NVIDIA GPUs installed
5+
on the host machine.
6+
7+
Essentially, the node-rapids system is provided as a backend to any
8+
HTTP client. At this time only limited functionality is available to
9+
load JSON files in the `graphology` graph dataset format, plus API
10+
requests to request Dataframes and their Columns via `apache-arrow`.
11+
12+
Two endpoints, `graphology/nodes` and `graphology/edges` specifically
13+
return pre-formatted arrays that can be used directly with the
14+
[sigma.js](https://github.com/jacomyal/sigma.js) renderer. An
15+
[extra-large-graphs](https://github.com/jacomyal/sigma.js/pull/1252) example PR is in the works
16+
that utilizes this GPU-accelerated data for rendering larger datasets
17+
than available via only CPU.
18+
19+
## Main Dependencies
20+
- @rapidsai/cudf
21+
- fastify
22+
- fastify-arrow
23+
- apache-arrow
24+
25+
An example project that demonstrates this API has a PR being reviewed at [sigma.js](https://github.com/jacomyal/sigma.js),
26+
but this project does not depend on sigma.js.j
27+
28+
## Installation
29+
30+
To install dependencies, run the following from the root directory for `node-rapids`
31+
32+
```bash
33+
yarn
34+
```
35+
36+
To run the demo
37+
```bash
38+
# Select the api-server demo from the list of demos
39+
yarn demo
40+
# OR specifically with
41+
cd modules/demo/api-server
42+
yarn start
43+
```
44+
45+
## Dataset
46+
47+
Run the graph generator at https://github.com/thomcom/sigma.js/blob/add-gpu-graph-to-example/examples/extra-large-graphs/generate-graph.js
48+
to create a very large graph using the object
49+
50+
```js
51+
const state = {
52+
order: 1000000,
53+
size: 2000000,
54+
clusters: 3,
55+
edgesRenderer: 'edges-fast'
56+
};
57+
```
58+
59+
You don't need to edit the file in order to create a graph of the above size. Simply call the .js via node:
60+
61+
```bash
62+
node graph-generator.js
63+
```
64+
65+
Which will create a file `./large-graph.json`. Copy `./large-graph.json` into `api-server/` and then set your
66+
API request to the location of the file relative to `routes/graphology/index.js`:
67+
68+
```
69+
curl http://localhost:3000/graphology/read_large_demo?filename=../../large-graph.json
70+
```
71+
72+
Which will use parallel JSON parsing to load the graph onto the GPU.
73+
74+
## Routes
75+
76+
```txt
77+
/
78+
/graphology
79+
/graphology/read_json
80+
/graphology/read_large_demo
81+
/graphology/list_tables
82+
/graphology/get_table/:table
83+
/graphology/get_column/:table/:column
84+
/graphology/nodes/bounds
85+
/graphology/nodes
86+
/graphology/edges
87+
/graphology/release
88+
```
89+

modules/demo/api-server/app.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict'
2+
3+
const path = require('path')
4+
const AutoLoad = require('@fastify/autoload')
5+
6+
module.exports = async function(fastify, opts) {
7+
// Place here your custom code!
8+
9+
// Do not touch the following lines
10+
11+
// This loads all plugins defined in plugins
12+
// those should be support plugins that are reused
13+
// through your application
14+
fastify.register(AutoLoad,
15+
{dir: path.join(__dirname, 'plugins'), options: Object.assign({}, opts)})
16+
17+
// This loads all plugins defined in routes
18+
// define your routes in one of these
19+
fastify.register(
20+
AutoLoad,
21+
{dir: path.join(__dirname, 'routes'), options: Object.assign({}, opts), ignorePattern: /.*.ts/})
22+
}

modules/demo/api-server/index.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env node
2+
3+
// Copyright (c) 2022, NVIDIA CORPORATION.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
const Path = require('path');
18+
19+
// Change cwd to the example dir so relative file paths are resolved
20+
process.chdir(__dirname);
21+
22+
const fastify = require.resolve('fastify-cli/cli.js');
23+
24+
const {spawnSync} = require('child_process');
25+
26+
const env = {
27+
NEXT_TELEMETRY_DISABLED: 1, // disable https://fastifyjs.org/telemetry
28+
...process.env,
29+
};
30+
31+
spawnSync(process.execPath,
32+
[fastify, 'start', '-l', 'info', '-P', '-w', 'app.js'],
33+
{env, cwd: __dirname, stdio: 'inherit'});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"private": true,
3+
"name": "@rapidsai/demo-api-server",
4+
"main": "index.js",
5+
"version": "0.0.1",
6+
"license": "Apache-2.0",
7+
"author": "NVIDIA, Inc. (https://nvidia.com/)",
8+
"maintainers": [
9+
"Thomson Comer <[email protected]>"
10+
],
11+
"bin": "index.js",
12+
"description": "A fastify-based web server that provides browser-access to GPU resources.",
13+
"scripts": {
14+
"test": "tap \"test/**/*.test.js\"",
15+
"start": "fastify start -l info -P -p 3010 -w app.js",
16+
"dev": "fastify start -w -l info -P -p 3010 app.js"
17+
},
18+
"keywords": ["rapids.ai", "node", "NVIDIA", "gpu", "Dataframe", "pandas"],
19+
"dependencies": {
20+
"@fastify/autoload": "^4.0.0",
21+
"@fastify/sensible": "^4.0.0",
22+
"@types/node": "17.0.33",
23+
"fastify": "^3.0.0",
24+
"fastify-arrow": "1.0.0",
25+
"fastify-cli": "^3.0.1",
26+
"fastify-plugin": "^3.0.0",
27+
"@fastify/cors": "latest"
28+
},
29+
"devDependencies": {
30+
"path": "0.12.7",
31+
"tap": "^16.1.0"
32+
}
33+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Plugins Folder
2+
3+
Plugins define behavior that is common to all the routes in your
4+
application. Authentication, caching, templates, and all the other cross
5+
cutting concerns should be handled by plugins placed in this folder.
6+
7+
Files in this folder are typically defined through the
8+
[`fastify-plugin`](https://github.com/fastify/fastify-plugin) module,
9+
making them non-encapsulated. They can define decorators and set hooks
10+
that will then be used in the rest of your application.
11+
12+
Check out:
13+
14+
* [The hitchhiker's guide to plugins](https://www.fastify.io/docs/latest/Guides/Plugins-Guide/)
15+
* [Fastify decorators](https://www.fastify.io/docs/latest/Reference/Decorators/).
16+
* [Fastify lifecycle](https://www.fastify.io/docs/latest/Reference/Lifecycle/).
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict'
2+
3+
const fp = require('fastify-plugin')
4+
5+
/**
6+
* This plugins adds some utilities to handle http errors
7+
*
8+
* @see https://github.com/fastify/fastify-sensible
9+
*/
10+
module.exports = fp(async function (fastify, opts) {
11+
fastify.register(require('@fastify/sensible'), {
12+
errorHandler: false
13+
})
14+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict'
2+
3+
const fp = require('fastify-plugin')
4+
5+
// the use of fastify-plugin is required to be able
6+
// to export the decorators to the outer scope
7+
8+
module.exports = fp(async function (fastify, opts) {
9+
fastify.decorate('someSupport', function () {
10+
return 'hugs'
11+
})
12+
})

0 commit comments

Comments
 (0)