Skip to content

Commit 0ffe5db

Browse files
committed
init
0 parents  commit 0ffe5db

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+5705
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/Makefile
2+
CTestTestfile.cmake
3+
Testing/
4+
*.a
5+
generated
6+
*.so
7+
*.dylib
8+
/3rdparty

CMakeLists.txt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
2+
PROJECT(pytorch-quiver)
3+
4+
SET(CMAKE_CXX_STANDARD 17)
5+
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY bin)
6+
SET(CMAKE_BUILD_TYPE Release)
7+
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/srcs/cmake)
8+
9+
OPTION(USE_STRICT "Enable strict build options." OFF)
10+
IF(USE_STRICT)
11+
ADD_DEFINITIONS(-Wall)
12+
ADD_DEFINITIONS(-Werror)
13+
ADD_DEFINITIONS(-Wfatal-errors)
14+
ENDIF()
15+
16+
INCLUDE_DIRECTORIES(cuda-sample ${CMAKE_SOURCE_DIR}/srcs/cpp/include)
17+
18+
FIND_PACKAGE(stdtracer REQUIRED)
19+
20+
IF(ENABLE_CUDA)
21+
INCLUDE(srcs/cmake/cuda.cmake)
22+
ENDIF()
23+
IF(BUILD_TORCH_EXTENSION)
24+
INCLUDE(srcs/cmake/torch.cmake)
25+
ENDIF()
26+
27+
FUNCTION(ADD_SOURCE target)
28+
TARGET_SOURCES(${target} PRIVATE ${ARGN})
29+
ENDFUNCTION()
30+
31+
ADD_LIBRARY(quiver SHARED)
32+
ADD_SOURCE(quiver ${CMAKE_SOURCE_DIR}/srcs/cpp/src/quiver/quiver.cpp)
33+
IF(ENABLE_CUDA)
34+
ADD_SOURCE(quiver ${CMAKE_SOURCE_DIR}/srcs/cpp/src/quiver/cuda/quiver.cu)
35+
ENDIF()
36+
37+
# ADD_EXECUTABLE(example examples/cpp/torch-example.cpp)
38+
# TARGET_LINK_LIBRARIES(example c10) TARGET_LINK_LIBRARIES(example torch)
39+
40+
ADD_EXECUTABLE(cpu-sample examples/cpu_sample.cpp)
41+
ADD_EXECUTABLE(quiver-example examples/quiver_example.cpp)
42+
TARGET_LINK_LIBRARIES(quiver-example quiver)
43+
TARGET_USE_STDTRACER(quiver-example)
44+
45+
IF(ENABLE_CUDA)
46+
ADD_EXECUTABLE(cuda-sample examples/cuda_sample.cpp)
47+
ENDIF()
48+
49+
ENABLE_TESTING()

README

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Quiver
2+
3+
Graph Neural Network Operators for heterogeneous hardware.
4+
5+
code structure
6+
7+
*.cu.hpp // cuda template
8+
*.hpp // c++ header or template
9+
*.cu // cuda kernels
10+
*.cpp // c++ implementations

REFERENCE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://docs.nvidia.com/cuda/cusparse/index.html

U

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/sh
2+
set -e
3+
4+
notify() {
5+
if [ -f ~/.slack/notify ]; then
6+
~/.slack/notify "$@"
7+
fi
8+
}
9+
10+
. ./scripts/measure.sh
11+
12+
# [done] q $ pip3 install --no-index -U . took 42s
13+
# measure pip3 install --no-index -U .
14+
15+
p=$(basename $(pwd))
16+
notify "Building $p from $(hostname)"
17+
measure pip3 install --no-index -U .
18+
notify "Built $p from $(hostname)"

auto/cmake

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# -*- mode: sh -*-
2+
3+
QUIET=0
4+
5+
CMAKE_FLAGS=
6+
7+
add_cmake_flag() {
8+
if [ $QUIET -eq 0 ]; then
9+
echo "Using $1=$2"
10+
fi
11+
CMAKE_FLAGS="${CMAKE_FLAGS} -D$1=$2"
12+
}
13+
14+
pass_cmake_flag_from_env() {
15+
local name=$1
16+
local env_key=$2
17+
if [ -z ${env_key} ]; then
18+
env_key=$name
19+
fi
20+
local val=$(eval echo \$$env_key)
21+
if [ ! -z "$val" ]; then
22+
add_cmake_flag $name $val
23+
fi
24+
}
25+
26+
CMAKE_PREFIX_PATH=
27+
28+
add_cmake_prefix() {
29+
if [ $QUIET -eq 0 ]; then
30+
echo "adding to CMAKE_PREFIX_PATH with $1"
31+
fi
32+
CMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH;$1"
33+
}
34+
35+
cleanup_cmake_cache() {
36+
if [ -f CMakeCache.txt ]; then
37+
rm CMakeCache.txt
38+
fi
39+
if [ -d 3rdparty ]; then
40+
for cmake_cache in $(find 3rdparty/ | grep CMakeCache.txt); do
41+
rm $cmake_cache
42+
done
43+
fi
44+
}
45+
46+
get_dep() {
47+
local name=$1
48+
head -n 1 ./deps/$name | awk '{print $1}'
49+
}
50+
51+
log_config_var() {
52+
local name=$1
53+
local val=$(eval echo \$$name)
54+
if [ $QUIET -eq 0 ]; then
55+
echo "$name=$val"
56+
fi
57+
}
58+
59+
config_cmake() {
60+
add_cmake_prefixes
61+
add_cmake_flags
62+
cleanup_cmake_cache
63+
cmake . $CMAKE_FLAGS
64+
}

azure-pipelines.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Python package
2+
# Create and test a Python package on multiple Python versions.
3+
# Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more:
4+
# https://docs.microsoft.com/azure/devops/pipelines/languages/python
5+
6+
trigger:
7+
- master
8+
9+
pool:
10+
vmImage: 'ubuntu-latest'
11+
12+
strategy:
13+
matrix:
14+
Python36:
15+
python.version: '3.6'
16+
17+
steps:
18+
- task: UsePythonVersion@0
19+
inputs:
20+
versionSpec: '$(python.version)'
21+
displayName: 'Use Python $(python.version)'
22+
23+
- script: pip install -U pip
24+
displayName: Upgrade pip
25+
26+
- script: pip install -U wheel
27+
displayName: Install wheel
28+
29+
- script: pip install -U pytest
30+
displayName: Install pytest
31+
32+
- script: pip install -f https://download.pytorch.org/whl/torch_stable.html torch==1.6.0+cpu
33+
displayName: Install PyTorch
34+
35+
- script: ./configure && make -j $(nproc)
36+
displayName: Build
37+
38+
- script: git clean -fdx
39+
displayName: Clean
40+
41+
- script: pip install --no-index .
42+
displayName: Install
43+
44+
- script: |
45+
python examples/e1.py
46+
displayName: Run
47+
timeoutInMinutes: 1
48+
49+
- script: |
50+
pytest
51+
displayName: Test
52+
timeoutInMinutes: 1

b

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
set -e
3+
4+
./benchmarks/bench-pyg-product.py 2> err.txt > out.txt

benchmarks/bench-pyg-product.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env python3
2+
3+
import copy
4+
import os
5+
import os.path as osp
6+
import time
7+
from typing import List, NamedTuple, Optional, Tuple
8+
9+
import torch
10+
import torch_quiver as qv
11+
from ogb.nodeproppred import PygNodePropPredDataset
12+
13+
14+
def info(t, name=None):
15+
msg = ''
16+
if name:
17+
msg += name
18+
msg += ' ' + str(t.type())
19+
msg += ' ' + str(t.shape)
20+
print(msg)
21+
22+
23+
class CudaNeighborSampler(torch.utils.data.DataLoader):
24+
def __init__(self,
25+
edge_index: torch.Tensor,
26+
sizes: List[int],
27+
node_idx: Optional[torch.Tensor] = None,
28+
num_nodes: Optional[int] = None,
29+
**kwargs):
30+
31+
N = int(edge_index.max() + 1) if num_nodes is None else num_nodes
32+
print('building quiver')
33+
t0 = time.time()
34+
self.quiver = qv.new_quiver_from_edge_index(N, edge_index)
35+
d = time.time() - t0
36+
print('build quiver took %fms' % (d * 1000))
37+
38+
if node_idx is None:
39+
node_idx = torch.arange(N)
40+
elif node_idx.dtype == torch.bool:
41+
node_idx = node_idx.nonzero().view(-1)
42+
43+
self.sizes = sizes
44+
45+
super(CudaNeighborSampler, self).__init__(node_idx.tolist(),
46+
collate_fn=self.sample,
47+
**kwargs)
48+
49+
def sample(self, batch):
50+
t0 = time.time()
51+
ret = self._sample(batch)
52+
d = time.time() - t0
53+
print('sample took %fms' % (d * 1000))
54+
return ret
55+
56+
def _sample(self, batch):
57+
if not isinstance(batch, torch.Tensor):
58+
batch = torch.tensor(batch)
59+
60+
batch_size: int = len(batch)
61+
print('sample batch size %d' % (batch_size))
62+
63+
# adjs: List[Adj] = []
64+
65+
n_id = batch
66+
for size in self.sizes:
67+
result = self.quiver.sample_adj(n_id, size)
68+
info(result)
69+
n_id = result
70+
# adj, n_id = self.adj.sample_adj(n_id, size, replace=False)
71+
# if self.flow == 'source_to_target':
72+
# adj = adj.t()
73+
# row, col, e_id = adj.coo()
74+
# size = adj.sparse_sizes()
75+
# edge_index = torch.stack([row, col], dim=0)
76+
77+
# adjs.append(Adj(edge_index, e_id, size))
78+
79+
return batch_size, batch
80+
# if len(adjs) > 1:
81+
# return batch_size, n_id, adjs[::-1]
82+
# else:
83+
# return batch_size, n_id, adjs[0]
84+
85+
def __repr__(self):
86+
return '{}(sizes={})'.format(self.__class__.__name__, self.sizes)
87+
88+
89+
def load_data():
90+
home = os.getenv('HOME')
91+
data_dir = os.path.join(home, '.pyg')
92+
root = os.path.join(data_dir, 'data', 'products')
93+
filename = os.path.join(
94+
root, 'ogbn_products_pyg/processed/geometric_data_processed.pt')
95+
data, _ = torch.load(filename)
96+
return data.edge_index
97+
98+
99+
def load_dataset():
100+
home = os.getenv('HOME')
101+
data_dir = osp.join(home, '.pyg')
102+
root = osp.join(data_dir, 'data', 'products')
103+
dataset = PygNodePropPredDataset('ogbn-products', root)
104+
split_idx = dataset.get_idx_split()
105+
data = dataset[0]
106+
return data, split_idx
107+
108+
109+
def main():
110+
data, split_idx = load_dataset()
111+
train_idx = split_idx['train']
112+
sampler = CudaNeighborSampler(
113+
data.edge_index,
114+
node_idx=train_idx,
115+
sizes=[15, 10, 5],
116+
batch_size=1024,
117+
)
118+
119+
# for idx, (batch_size, n_id, adjs) in enumerate(train_loader):
120+
for idx, (batch_size, batch) in enumerate(sampler):
121+
print('#%d' % (idx))
122+
123+
124+
main()

benchmarks/show-data-info.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
5+
import torch
6+
7+
8+
def info(t, name=None):
9+
msg = ''
10+
if name:
11+
msg += name
12+
msg += ' ' + str(t.type())
13+
msg += ' ' + str(t.shape)
14+
print(msg)
15+
16+
17+
def main():
18+
home = os.getenv('HOME')
19+
data_dir = os.path.join(home, '.pyg')
20+
root = os.path.join(data_dir, 'data', 'products')
21+
filename = os.path.join(
22+
root, 'ogbn_products_pyg/processed/geometric_data_processed.pt')
23+
print(filename)
24+
data, kvs = torch.load(filename)
25+
print(data.__class__) # torch_geometric.data.data.Data
26+
27+
for idx, d in enumerate(dir(data)):
28+
print('[%d]=%s' % (idx, d))
29+
30+
info(data.x, 'data.x')
31+
info(data.y, 'data.y')
32+
info(data.edge_index, 'data.edge_index')
33+
34+
for k, v in kvs.items():
35+
print(k)
36+
print(v.__class__)
37+
38+
info(kvs['x'], 'x')
39+
info(kvs['y'], 'y')
40+
info(kvs['edge_index'], 'edge_index')
41+
42+
print(kvs['x']) # tensor([ 0, 2449029])
43+
print(kvs['y']) # tensor([ 0, 2449029])
44+
print(kvs['edge_index']) # tensor([ 0, 123718280])
45+
46+
47+
main()

0 commit comments

Comments
 (0)