Skip to content

Commit ffdbee3

Browse files
authored
Merge pull request #5 from JetBrains-Research/master
Pulling changes from main repository
2 parents f865336 + 85401cd commit ffdbee3

Some content is hidden

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

42 files changed

+655
-390
lines changed

.github/workflows/ubuntu.yml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,10 @@ jobs:
6262

6363
- name: Run unit-tests (sequential backend)
6464
working-directory: ${{ env.build_dir }}
65-
run: bash scripts/tests_run_fallback.sh
65+
run: bash scripts/run_tests_fallback.sh
6666
shell: bash
6767

6868
- name: Run regression-tests (sequential backend)
69-
working-directory: ${{ env.build_dir }}
70-
run: |
71-
cd python
72-
export PYTHONPATH="`pwd`:$PYTHONPATH"
73-
cd tests
74-
python3 -m unittest discover -v
69+
working-directory: ${{ env.build_dir }}/python
70+
run: bash run_tests.sh
7571
shell: bash

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# CuBool library Cmake config file
22
# Add this file as sub-directory to your project to use library functionality
33

4-
cmake_minimum_required(VERSION 3.17 FATAL_ERROR)
4+
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
55
project(cubool LANGUAGES CXX)
66

77
# Exposed to the user build options

README.md

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ work with sparse matrices written on the NVIDIA CUDA platform. The primary
1212
goal of the library is implementation, testing and profiling algorithms for
1313
solving *formal-language-constrained problems*, such as *context-free*
1414
and *regular* path queries with various semantics for graph databases.
15-
The library provides C-compatible API, written in the GraphBLAS style,
16-
as well as python high-level wrapper with automated resources management and fancy syntax sugar.
15+
The library provides C-compatible API, written in the GraphBLAS style.
16+
17+
**The library** is shipped with python package **pycubool** - wrapper for
18+
cuBool library C API. This package exports library features and primitives
19+
in high-level format with automated resources management and fancy syntax sugar.
1720

1821
**The primary library primitive** is a sparse boolean matrix. The library provides
1922
the most popular operations for matrix manipulation, such as construction from
@@ -34,7 +37,7 @@ prototyping algorithms on a local computer for later running on a powerful serve
3437
- [X] Sparse matrix element-wise addition
3538
- [X] Sparse matrix kronecker
3639
- [X] Sparse matrix transpose
37-
- [X] Sparse matrix submatrix
40+
- [X] Sparse matrix extract sub-matrix
3841
- [X] Sparse matrix reduce
3942
- [X] Sparse matrix slicing
4043
- [X] Matrix cached filling
@@ -54,12 +57,28 @@ prototyping algorithms on a local computer for later running on a powerful serve
5457
- [ ] Publish built artifacts and shared libs
5558
- [ ] Publish stable source code archives
5659

60+
## Installation
61+
62+
If you are running OS **Ubuntu 20.04** or higher you can download the official
63+
PyPI **pycubool** python package, which includes compiled library source code
64+
with Cuda and Sequential computations support. Installation process
65+
requires only `python3` to be installed on your machine. Python can be installed
66+
as follows [link](https://phoenixnap.com/kb/how-to-install-python-3-ubuntu).
67+
68+
If all requirements are satisfied, run the following command to install PyPI package:
69+
```shell script
70+
$ python3 -m pip install -i https://test.pypi.org/simple/ pycubool
71+
```
72+
5773
## Getting Started
5874

75+
This section gives instructions to build the library from sources.
76+
These steps are required if you want to build library for your specific platform with custom build settings.
77+
5978
### Requirements
6079

6180
- Linux Ubuntu (tested on 20.04)
62-
- CMake Version 3.17 or higher
81+
- CMake Version 3.15 or higher
6382
- CUDA Compatible GPU device
6483
- GCC Compiler
6584
- NVIDIA CUDA toolkit
@@ -141,7 +160,7 @@ Configure build in Release mode with tests and run actual compilation process:
141160
```shell script
142161
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCUBOOL_BUILD_TESTS=ON
143162
$ cmake --build . --target all -j `nproc`
144-
$ bash ./scripts/tests_run_all.sh
163+
$ bash ./scripts/run_tests_all.sh
145164
```
146165

147166
By default, the following cmake options will be automatically enabled:
@@ -255,9 +274,10 @@ cuBool
255274
│ │ └── sequential - fallback cpu backend
256275
│ ├── utils - testing utilities
257276
│ └── tests - gtest-based unit-tests collection
258-
├── python - pycubool related source
277+
├── python - pycubool related sources
259278
│ ├── pycubool - cubool library wrapper for python (similar to pygraphblas)
260-
│ └── tests - tests for python wrapper
279+
│ ├── tests - regression tests for python wrapper
280+
│ └── data - generate data for pycubool regression tests
261281
├── deps - project dependencies
262282
│ ├── cub - cuda utility, required for nsparse
263283
│ ├── gtest - google test framework for unit testing
@@ -273,6 +293,18 @@ cuBool
273293
- Pavel Alimov (Github : [Krekep](https://github.com/Krekep))
274294
- Semyon Grigorev (Github: [gsvgit](https://github.com/gsvgit))
275295
296+
## Citation
297+
298+
```ignorelang
299+
@online{cuBool,
300+
author = {Orachyov, Egor and Alimov, Pavel and Grigorev, Semyon},
301+
title = {cuBool: sparse Boolean linear algebra for Nvidia Cuda},
302+
year = 2020,
303+
url = {https://github.com/JetBrains-Research/cuBool},
304+
note = {Version Alpha}
305+
}
306+
```
307+
276308
## License
277309
278310
This project is licensed under MIT License. License text can be found in the

cubool/CMakeLists.txt

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ set(CUBOOL_SOURCES
2626
sources/io/logger.hpp
2727
sources/utils/exclusive_scan.hpp
2828
sources/utils/timer.hpp
29+
sources/utils/csr_utils.cpp
30+
sources/utils/csr_utils.hpp
2931
)
3032

3133
set(CUBOOL_C_API_SOURCES
@@ -72,6 +74,8 @@ if (CUBOOL_WITH_CUDA)
7274
sources/cuda/instance.cpp
7375
sources/cuda/matrix_csr.hpp
7476
sources/cuda/matrix_csr.cu
77+
sources/cuda/matrix_csr_build.cu
78+
sources/cuda/matrix_csr_extract.cu
7579
sources/cuda/matrix_csr_ewiseadd.cu
7680
sources/cuda/matrix_csr_kronecker.cu
7781
sources/cuda/matrix_csr_multiply.cu
@@ -142,13 +146,15 @@ if (CUBOOL_WITH_CUDA)
142146
set_target_properties(cubool PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
143147

144148
# Settings: https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/
145-
target_compile_options(cubool PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:
146-
-arch=sm_30
147-
-gencode=arch=compute_30,code=sm_30
148-
-gencode=arch=compute_35,code=sm_35
149-
-gencode=arch=compute_50,code=sm_50
150-
-gencode=arch=compute_52,code=sm_52
151-
-gencode=arch=compute_52,code=compute_52>)
149+
#target_compile_options(cubool PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:
150+
# # todo: fix this flag later -arch=sm_30 ?
151+
# # todo: can we omit arch flag?
152+
# -gencode=arch=compute_30,code=sm_30
153+
# -gencode=arch=compute_50,code=sm_50
154+
# -gencode=arch=compute_52,code=sm_52
155+
# -gencode=arch=compute_60,code=sm_60
156+
# -gencode=arch=compute_61,code=sm_61
157+
# -gencode=arch=compute_61,code=compute_61>)
152158

153159
target_compile_options(cubool PRIVATE $<$<COMPILE_LANGUAGE:CUDA>: -use_fast_math -Xptxas -O2>)
154160

cubool/include/cubool/cubool.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,27 +73,27 @@ typedef enum cuBool_Status {
7373
/** Generic lib hits for matrix processing */
7474
typedef enum cuBool_Hint {
7575
/** No hints passed */
76-
CUBOOL_HINT_NO = 0x0,
76+
CUBOOL_HINT_NO = 0,
7777
/** Force Cpu based backend usage */
78-
CUBOOL_HINT_CPU_BACKEND = 0x1,
78+
CUBOOL_HINT_CPU_BACKEND = 1,
7979
/** Use managed gpu memory type instead of default (device) memory */
80-
CUBOOL_HINT_GPU_MEM_MANAGED = 0x2,
80+
CUBOOL_HINT_GPU_MEM_MANAGED = 2,
8181
/** Mark input data as row-col sorted */
82-
CUBOOL_HINT_VALUES_SORTED = 0x4,
82+
CUBOOL_HINT_VALUES_SORTED = 4,
8383
/** Accumulate result of the operation in the result matrix */
84-
CUBOOL_HINT_ACCUMULATE = 0x8,
84+
CUBOOL_HINT_ACCUMULATE = 8,
8585
/** Finalize library state, even if not all resources were explicitly released */
86-
CUBOOL_HINT_RELAXED_FINALIZE = 0x16,
86+
CUBOOL_HINT_RELAXED_FINALIZE = 16,
8787
/** Logging hint: log includes error message */
88-
CUBOOL_HINT_LOG_ERROR = 0x32,
88+
CUBOOL_HINT_LOG_ERROR = 32,
8989
/** Logging hint: log includes warning message */
90-
CUBOOL_HINT_LOG_WARNING = 0x64,
90+
CUBOOL_HINT_LOG_WARNING = 64,
9191
/** Logging hint: log includes all types of messages */
92-
CUBOOL_HINT_LOG_ALL = 0x128,
92+
CUBOOL_HINT_LOG_ALL = 128,
9393
/** No duplicates in the build data */
94-
CUBOOL_HINT_NO_DUPLICATES = 0x256,
94+
CUBOOL_HINT_NO_DUPLICATES = 256,
9595
/** Performs time measurement and logs elapsed operation time */
96-
CUBOOL_HINT_TIME_CHECK = 0x512
96+
CUBOOL_HINT_TIME_CHECK = 512
9797
} cuBool_Hint;
9898

9999
/** Hit mask */

cubool/sources/core/library.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ namespace cubool {
179179
logDeviceInfo();
180180
}
181181

182-
MatrixBase *Library::createMatrix(size_t nrows, size_t ncols) {
182+
Matrix *Library::createMatrix(size_t nrows, size_t ncols) {
183183
CHECK_RAISE_ERROR(nrows > 0, InvalidArgument, "Cannot create matrix with zero dimension");
184184
CHECK_RAISE_ERROR(ncols > 0, InvalidArgument, "Cannot create matrix with zero dimension");
185185

@@ -193,17 +193,16 @@ namespace cubool {
193193
return m;
194194
}
195195

196-
void Library::releaseMatrix(MatrixBase *matrixBase) {
196+
void Library::releaseMatrix(Matrix *matrix) {
197197
if (mRelaxedRelease && !mBackend) return;
198198

199-
auto m = (Matrix*)(matrixBase);
200-
CHECK_RAISE_ERROR(mAllocated.find(m) != mAllocated.end(), InvalidArgument, "No such matrix was allocated");
199+
CHECK_RAISE_ERROR(mAllocated.find(matrix) != mAllocated.end(), InvalidArgument, "No such matrix was allocated");
201200

202201
LogStream stream(*getLogger());
203-
stream << Logger::Level::Info << "Release Matrix " << m->getDebugMarker() << LogStream::cmt;
202+
stream << Logger::Level::Info << "Release Matrix " << matrix->getDebugMarker() << LogStream::cmt;
204203

205-
mAllocated.erase(m);
206-
delete m;
204+
mAllocated.erase(matrix);
205+
delete matrix;
207206
}
208207

209208
void Library::handleError(const std::exception& error) {

cubool/sources/core/library.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ namespace cubool {
3838
static void finalize();
3939
static void validate();
4040
static void setupLogging(const char* logFileName, cuBool_Hints hints);
41-
static class MatrixBase *createMatrix(size_t nrows, size_t ncols);
42-
static void releaseMatrix(class MatrixBase *matrixBase);
41+
static class Matrix *createMatrix(size_t nrows, size_t ncols);
42+
static void releaseMatrix(class Matrix *matrix);
4343
static void handleError(const std::exception& error);
4444
static void queryCapabilities(cuBool_DeviceCaps& caps);
4545
static void logDeviceInfo();

cubool/sources/core/matrix.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ namespace cubool {
6969
CHECK_RAISE_ERROR(cols != nullptr || nvals == 0, InvalidArgument, "Null ptr cols array");
7070

7171
this->releaseCache();
72+
73+
LogStream stream(*Library::getLogger());
74+
stream << Logger::Level::Info
75+
<< "Matrix:build:" << this->getDebugMarker() << " "
76+
<< "isSorted=" << isSorted << ", "
77+
<< "noDuplicates=" << noDuplicates << LogStream::cmt;
78+
7279
mHnd->build(rows, cols, nvals, isSorted, noDuplicates);
7380
}
7481

@@ -98,7 +105,8 @@ namespace cubool {
98105
CHECK_RAISE_ERROR(nrows == this->getNrows(), InvalidArgument, "Result matrix has incompatible size for extracted sub-matrix range");
99106
CHECK_RAISE_ERROR(ncols == this->getNcols(), InvalidArgument, "Result matrix has incompatible size for extracted sub-matrix range");
100107

101-
this->commitCache();
108+
other->commitCache();
109+
this->releaseCache(); // Values of this matrix won't be used any more
102110

103111
if (checkTime) {
104112
TIMER_ACTION(timer, mHnd->extractSubMatrix(*other->mHnd, i, j, nrows, ncols, false));
@@ -122,13 +130,18 @@ namespace cubool {
122130

123131
CHECK_RAISE_ERROR(other != nullptr, InvalidArgument, "Passed matrix does not belong to core matrix class");
124132

133+
if (this == other)
134+
return;
135+
125136
auto M = other->getNrows();
126137
auto N = other->getNcols();
127138

128139
CHECK_RAISE_ERROR(M == this->getNrows(), InvalidArgument, "Cloned matrix has incompatible size");
129140
CHECK_RAISE_ERROR(N == this->getNcols(), InvalidArgument, "Cloned matrix has incompatible size");
130141

131-
this->commitCache();
142+
other->commitCache();
143+
this->releaseCache(); // Values of this matrix won't be used any more
144+
132145
mHnd->clone(*other->mHnd);
133146
}
134147

@@ -144,6 +157,7 @@ namespace cubool {
144157
CHECK_RAISE_ERROR(N == this->getNrows(), InvalidArgument, "Transposed matrix has incompatible size");
145158

146159
this->commitCache();
160+
this->releaseCache(); // Values of this matrix won't be used any more
147161

148162
if (checkTime) {
149163
TIMER_ACTION(timer, mHnd->transpose(*other->mHnd, false));
@@ -171,7 +185,8 @@ namespace cubool {
171185
CHECK_RAISE_ERROR(M == this->getNrows(), InvalidArgument, "Matrix has incompatible size");
172186
CHECK_RAISE_ERROR(1 == this->getNcols(), InvalidArgument, "Matrix has incompatible size");
173187

174-
this->commitCache();
188+
other->commitCache();
189+
this->releaseCache(); // Values of this matrix won't be used any more
175190

176191
if (checkTime) {
177192
TIMER_ACTION(timer, mHnd->reduce(*other->mHnd, false));
@@ -204,7 +219,13 @@ namespace cubool {
204219
CHECK_RAISE_ERROR(N == this->getNcols(), InvalidArgument, "Matrix has incompatible size for operation result");
205220
CHECK_RAISE_ERROR(T == b->getNrows(), InvalidArgument, "Cannot multiply passed matrices");
206221

207-
this->commitCache();
222+
a->commitCache();
223+
b->commitCache();
224+
225+
if (accumulate)
226+
this->commitCache();
227+
else
228+
this->releaseCache();
208229

209230
if (checkTime) {
210231
TIMER_ACTION(timer, mHnd->multiply(*a->mHnd, *b->mHnd, accumulate, false));
@@ -238,7 +259,9 @@ namespace cubool {
238259
CHECK_RAISE_ERROR(M * K == this->getNrows(), InvalidArgument, "Matrix has incompatible size for operation result");
239260
CHECK_RAISE_ERROR(N * T == this->getNcols(), InvalidArgument, "Matrix has incompatible size for operation result");
240261

241-
this->commitCache();
262+
a->commitCache();
263+
b->commitCache();
264+
this->releaseCache();
242265

243266
if (checkTime) {
244267
TIMER_ACTION(timer, mHnd->kronecker(*a->mHnd, *b->mHnd, false));
@@ -273,7 +296,9 @@ namespace cubool {
273296
CHECK_RAISE_ERROR(M == this->getNrows(), InvalidArgument, "Matrix has incompatible size for operation result");
274297
CHECK_RAISE_ERROR(N == this->getNcols(), InvalidArgument, "Matrix has incompatible size for operation result");
275298

276-
this->commitCache();
299+
a->commitCache();
300+
b->commitCache();
301+
this->releaseCache();
277302

278303
if (checkTime) {
279304
TIMER_ACTION(timer, mHnd->eWiseAdd(*a->mHnd, *b->mHnd, false));
@@ -339,17 +364,17 @@ namespace cubool {
339364
bool isSorted = false;
340365
bool noDuplicates = false;
341366

342-
// We will have to join old and new values
343367
if (mHnd->getNvals() > 0) {
344-
// Build tmp matrix with new values
368+
// We will have to join old and new values
369+
// Create tmp matrix and merge values
370+
345371
MatrixBase* tmp = mProvider->createMatrix(getNrows(), getNcols());
346372
tmp->build(mCachedI.data(), mCachedJ.data(), cachedNvals, isSorted, noDuplicates);
347-
348-
// Add new values to current matrix content
349373
mHnd->eWiseAdd(*mHnd, *tmp, false);
374+
mProvider->releaseMatrix(tmp);
350375
}
351-
// Otherwise, new values are used to build matrix content
352376
else {
377+
// Otherwise, new values are used to build matrix content
353378
mHnd->build(mCachedI.data(), mCachedJ.data(), cachedNvals, isSorted, noDuplicates);
354379
}
355380

0 commit comments

Comments
 (0)