Skip to content

Commit e8a5633

Browse files
committed
[Project/Code] Graph Viz:
- Bug fixes for python gviz - Add gviz matrices export function - Update readme/python readme - Add more pycubool examples
1 parent 1d831de commit e8a5633

File tree

7 files changed

+313
-65
lines changed

7 files changed

+313
-65
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Add this file as sub-directory to your project to use library functionality
33

44
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
5-
project(cubool LANGUAGES CXX)
5+
project(cuBool LANGUAGES CXX)
66

77
# Exposed to the user build options
88
option(CUBOOL_WITH_CUDA "Build library with cuda backend (default)" ON)

README.md

+31-10
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,48 @@ prototyping algorithms on a local computer for later running on a powerful serve
4545
- [X] Device capabilities query
4646
- [X] IO matrix loading from mtx file
4747
- [X] IO matrix saving into mtx file
48-
- [ ] IO matrix saving into gviz format
48+
- [X] IO matrix saving into gviz format
4949
- [X] IO user-defined file logging
5050
- [X] Wrapper for Python API
5151
- [X] Wrapper syntax sugar
5252
- [X] Tests for Python wrapper
5353
- [X] Pip package
54-
- [ ] Code examples
54+
- [X] Code examples
5555
- [ ] User guide
5656
- [X] Unit Tests collection
57-
- [ ] Publish built artifacts and shared libs
57+
- [X] Publish built artifacts and shared libs
5858
- [ ] Publish stable source code archives
5959

60+
## Simple example
61+
62+
Create sparse matrices, compute matrix-matrix product and print the result to the output:
63+
64+
```python
65+
import pycubool as cb
66+
67+
a = cb.Matrix.empty(shape=(2, 3))
68+
a[0, 0] = True
69+
a[1, 2] = True
70+
71+
b = cb.Matrix.empty(shape=(3, 4))
72+
b[0, 1] = True
73+
b[0, 2] = True
74+
b[1, 3] = True
75+
b[2, 1] = True
76+
77+
print(a, b, a.mxm(b), sep="\n")
78+
```
79+
6080
## Installation
6181

62-
If you are running OS **Ubuntu 20.04** or higher you can download the official
82+
If you are running **Linux based** OS (tested on Ubuntu 20.04) you can download the official
6383
PyPI **pycubool** python package, which includes compiled library source code
6484
with Cuda and Sequential computations support. Installation process
6585
requires only `python3` to be installed on your machine. Python can be installed
6686
as follows [link](https://phoenixnap.com/kb/how-to-install-python-3-ubuntu).
6787

6888
If all requirements are satisfied, run the following command to install PyPI package:
89+
6990
```shell script
7091
$ python3 -m pip install -i https://test.pypi.org/simple/ pycubool
7192
```
@@ -77,11 +98,11 @@ These steps are required if you want to build library for your specific platform
7798

7899
### Requirements
79100

80-
- Linux Ubuntu (tested on 20.04)
101+
- Linux based (tested on Ubuntu 20.04)
81102
- CMake Version 3.15 or higher
82-
- CUDA Compatible GPU device
103+
- CUDA Compatible GPU device (to run Cuda computations)
83104
- GCC Compiler
84-
- NVIDIA CUDA toolkit
105+
- NVIDIA CUDA toolkit (to build Cuda backend)
85106
- Python 3 (for `pycubool` library)
86107
- Git (to get source code)
87108

@@ -237,9 +258,9 @@ wrapper can be used to compute the same transitive closure problem for the
237258
directed graph within python environment:
238259
239260
```python
240-
import pycubool
261+
import pycubool as cb
241262
242-
def transitive_closure(a: pycubool.Matrix):
263+
def transitive_closure(a: cb.Matrix):
243264
"""
244265
Evaluates transitive closure for the provided
245266
adjacency matrix of the graph.
@@ -296,7 +317,7 @@ cuBool
296317
## Citation
297318
298319
```ignorelang
299-
@online{cuBool,
320+
@MISC{cuBool,
300321
author = {Orachyov, Egor and Alimov, Pavel and Grigorev, Semyon},
301322
title = {cuBool: sparse Boolean linear algebra for Nvidia Cuda},
302323
year = 2020,

docs/pictures/gviz_example.png

24.6 KB
Loading

python/README.md

+115-19
Original file line numberDiff line numberDiff line change
@@ -29,43 +29,139 @@ for computations on CPU side only. This backend is selected automatically
2929
if Cuda compatible device is not presented in the system. This can be quite handy for
3030
prototyping algorithms on a local computer for later running on a powerful server.
3131

32-
## Sparse Boolean Matrix Features
32+
## Features
3333

3434
- Matrix creation (empty, from data, with random data)
3535
- Matrix-matrix operations (multiplication, element-wise addition, kronecker product)
3636
- Matrix operations (equality, transpose, reduce to vector, extract sub-matrix)
3737
- Matrix data extraction (as lists, as list of pairs)
3838
- Matrix syntax sugar (pretty string printing, slicing, iterating through non-zero values)
3939
- IO (import/export matrix from/to `.mtx` file format)
40+
- GraphViz (export single matrix or set of matrices as a graph with custom color and label settings)
4041
- Debug (matrix string debug markers, logging)
4142

42-
## Example
43+
## Simple example
4344

44-
The following Python code snippet demonstrates, how the **pycubool**
45-
wrapper can be used to compute the transitive closure problem for the
46-
directed graph within python environment:
45+
Create sparse matrices, compute matrix-matrix product and print the result to the output:
4746

4847
```python
49-
import pycubool
48+
import pycubool as cb
5049

51-
def transitive_closure(a: pycubool.Matrix):
52-
"""
53-
Evaluates transitive closure for the provided
54-
adjacency matrix of the graph.
50+
a = cb.Matrix.empty(shape=(2, 3))
51+
a[0, 0] = True
52+
a[1, 2] = True
5553

56-
:param a: Adjacency matrix of the graph
57-
:return: The transitive closure adjacency matrix
58-
"""
54+
b = cb.Matrix.empty(shape=(3, 4))
55+
b[0, 1] = True
56+
b[0, 2] = True
57+
b[1, 3] = True
58+
b[2, 1] = True
5959

60-
t = a.dup() # Duplicate matrix where to store result
61-
total = 0 # Current number of values
60+
print(a, b, a.mxm(b), sep="\n")
61+
```
62+
63+
Output:
64+
65+
```
66+
0 1 2
67+
0 | 1 . . | 0
68+
1 | . . 1 | 1
69+
0 1 2
70+
71+
0 1 2 3
72+
0 | . 1 1 . | 0
73+
1 | . . . 1 | 1
74+
2 | . 1 . . | 2
75+
0 1 2 3
76+
77+
0 1 2 3
78+
0 | . 1 1 . | 0
79+
1 | . 1 . . | 1
80+
0 1 2 3
81+
```
82+
83+
## Transitive closure example
84+
85+
Compute the transitive closure problem for the directed graph and print the result:
86+
87+
```python
88+
import pycubool as cb
89+
90+
a = cb.Matrix.empty(shape=(4, 4))
91+
a[0, 1] = True
92+
a[1, 2] = True
93+
a[2, 0] = True
94+
a[2, 3] = True
95+
a[3, 2] = True
96+
97+
t = a.dup() # Duplicate matrix where to store result
98+
total = 0 # Current number of values
99+
100+
while total != t.nvals:
101+
total = t.nvals
102+
t.mxm(t, out=t, accumulate=True) # t += t * t
62103

63-
while total != t.nvals:
64-
total = t.nvals
65-
t.mxm(t, out=t, accumulate=True) # t += t * t
104+
print(a, t, sep="\n")
105+
```
106+
107+
Output:
66108

67-
return t
68109
```
110+
0 1 2 3
111+
0 | . 1 . . | 0
112+
1 | . . 1 . | 1
113+
2 | 1 . . 1 | 2
114+
3 | . . 1 . | 3
115+
0 1 2 3
116+
117+
0 1 2 3
118+
0 | 1 1 1 1 | 0
119+
1 | 1 1 1 1 | 1
120+
2 | 1 1 1 1 | 2
121+
3 | 1 1 1 1 | 3
122+
0 1 2 3
123+
```
124+
125+
## GraphViz example
126+
127+
Generate GraphViz graph script for a graph stored as a set of adjacency matrices:
128+
129+
```python
130+
import pycubool as cb
131+
132+
name = "Test" # Displayed graph name
133+
shape = (4, 4) # Adjacency matrices shape
134+
colors = {"a": "red", "b": "green"} # Colors per label
135+
136+
a = cb.Matrix.empty(shape=shape) # Edges labeled as 'a'
137+
a[0, 1] = True
138+
a[1, 2] = True
139+
a[2, 0] = True
140+
141+
b = cb.Matrix.empty(shape=shape) # Edges labeled as 'b'
142+
b[2, 3] = True
143+
b[3, 2] = True
144+
145+
print(cb.matrices_to_gviz(matrices={"a": a, "b": b}, graph_name=name, edge_colors=colors))
146+
```
147+
148+
Output:
149+
150+
```
151+
digraph G {
152+
graph [label=Test];
153+
node [color=black];
154+
0 -> 1 [label=a,color=red];
155+
1 -> 2 [label=a,color=red];
156+
2 -> 0 [label=a,color=red];
157+
2 -> 3 [label=b,color=green];
158+
3 -> 2 [label=b,color=green];
159+
}
160+
```
161+
162+
As an image:
163+
164+
![gviz-example](https://raw.githubusercontent.com/JetBrains-Research/cuBool/master/docs/pictures/gviz_example.png)
69165

70166
## Contributors
71167

python/examples.py

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import pycubool as cb
2+
3+
#
4+
# Basic setup example
5+
#
6+
7+
a = cb.Matrix.empty(shape=(2, 3))
8+
a[0, 0] = True
9+
a[1, 2] = True
10+
11+
b = cb.Matrix.empty(shape=(3, 4))
12+
b[0, 1] = True
13+
b[0, 2] = True
14+
b[1, 3] = True
15+
b[2, 1] = True
16+
17+
print(a, b, a.mxm(b), sep="\n")
18+
19+
#
20+
# Transitive closure example
21+
#
22+
23+
a = cb.Matrix.empty(shape=(4, 4))
24+
a[0, 1] = True
25+
a[1, 2] = True
26+
a[2, 0] = True
27+
a[2, 3] = True
28+
a[3, 2] = True
29+
30+
t = a.dup() # Duplicate matrix where to store result
31+
total = 0 # Current number of values
32+
33+
while total != t.nvals:
34+
total = t.nvals
35+
t.mxm(t, out=t, accumulate=True) # t += t * t
36+
37+
print(a, t, sep="\n")
38+
39+
#
40+
# Export matrices set to graph viz graph
41+
#
42+
43+
name = "Test" # Displayed graph name
44+
shape = (4, 4) # Adjacency matrices shape
45+
colors = {"a": "red", "b": "green"} # Colors per label
46+
47+
a = cb.Matrix.empty(shape=shape) # Edges labeled as 'a'
48+
a[0, 1] = True
49+
a[1, 2] = True
50+
a[2, 0] = True
51+
52+
b = cb.Matrix.empty(shape=shape) # Edges labeled as 'b'
53+
b[2, 3] = True
54+
b[3, 2] = True
55+
56+
print(cb.matrices_to_gviz(matrices={"a": a, "b": b}, graph_name=name, edge_colors=colors))
57+
58+
59+
File renamed without changes.

0 commit comments

Comments
 (0)