Skip to content

Commit

Permalink
Merge pull request #587 from ajschmidt8/fix-merge-conflicts
Browse files Browse the repository at this point in the history
Fix merge conflicts [skip gpuci]
  • Loading branch information
ajschmidt8 authored Mar 23, 2022
2 parents 522cf8a + 5e8b466 commit b59a0a1
Show file tree
Hide file tree
Showing 96 changed files with 3,972 additions and 349 deletions.
2 changes: 1 addition & 1 deletion .github/ops-bot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ auto_merger: true
branch_checker: true
label_checker: true
release_drafter: true
external_contributors: true
external_contributors: false
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ build/
build_prims/
dist/
python/**/**/*.cpp
python/external_repositories
python/record.txt
python/raft/record.txt
python/pylibraft/record.txt
log
.ipynb_checkpoints
.DS_Store
Expand Down
139 changes: 94 additions & 45 deletions BUILD.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ into three categories:

### Your first issue

1. Read the project's [README.md](https://github.com/rapidsai/RAFT/blob/main/README.md)
1. Read the project's [README.md](https://github.com/rapidsai/raft)
to learn how to setup the development environment
2. Find an issue to work on. The best way is to look for the [good first issue](https://github.com/rapidsai/RAFT/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
or [help wanted](https://github.com/rapidsai/RAFT/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) labels
Expand Down
2 changes: 1 addition & 1 deletion DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Devloping features and fixing bugs for the RAFT library itself is straightforward and only requires building and installing the relevant RAFT artifacts.

The process for working on a CUDA/C++ feature which spans RAFT and one or more consumers can vary slightly depending on whether the consuming project relies on a source build (as outlined in the [BUILD](BUILD.md#building-raft-c-from-source) docs). In such a case, the option `CPM_raft_SOURCE=/path/to/raft/source` can be passed to the cmake of the consuming project in order to build the local RAFT from source. The PR with relevant changes to the consuming project can also pin the RAFT version temporarily by explicitly changing the `FORK` and `PINNED_TAG` arguments to the RAFT branch containing their changes when invoking `find_and_configure_raft`. The pin should be reverted after the changed is merged to the RAFT project and before it is merged to the dependent project(s) downstream.
The process for working on a CUDA/C++ feature which spans RAFT and one or more consumers can vary slightly depending on whether the consuming project relies on a source build (as outlined in the [BUILD](BUILD.md#install_header_only_cpp) docs). In such a case, the option `CPM_raft_SOURCE=/path/to/raft/source` can be passed to the cmake of the consuming project in order to build the local RAFT from source. The PR with relevant changes to the consuming project can also pin the RAFT version temporarily by explicitly changing the `FORK` and `PINNED_TAG` arguments to the RAFT branch containing their changes when invoking `find_and_configure_raft`. The pin should be reverted after the changed is merged to the RAFT project and before it is merged to the dependent project(s) downstream.

If building a feature which spans projects and not using the source build in cmake, the RAFT changes (both C++ and Python) will need to be installed into the environment of the consuming project before they can be used. The ideal integration of RAFT into consuming projects will enable both the source build in the consuming project only for this case but also rely on a more stable packaging (such as conda packaging) otherwise.

Expand Down
123 changes: 76 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
# <div align="left"><img src="https://rapids.ai/assets/images/rapids_logo.png" width="90px"/>&nbsp;RAFT: RAPIDS Analytics Framework Toolkit</div>
# <div align="left"><img src="https://rapids.ai/assets/images/rapids_logo.png" width="90px"/>&nbsp;RAFT: Reusable Accelerated Functions and Tools</div>

RAFT contains fundamental widely-used algorithms and primitives for data science, graph and machine learning. The algorithms are CUDA-accelerated and form building-blocks for rapidly composing analytics in the [RAPIDS](https://rapids.ai) ecosystem.
RAFT contains fundamental widely-used algorithms and primitives for data science, graph and machine learning. The algorithms are CUDA-accelerated and form building-blocks for rapidly composing analytics.

By taking a primitives-based approach to algorithm development, RAFT
By taking a primitives-based approach to algorithm development, RAFT
- accelerates algorithm construction time
- reduces the maintenance burden by maximizing reuse across projects, and
- centralizes the core computations, allowing future optimizations to benefit all algorithms that use them.
- centralizes core reusable computations, allowing future optimizations to benefit all algorithms that use them.

The algorithms in RAFT span the following general categories:
While not exhaustive, the following general categories help summarize the accelerated functions in RAFT:
#####
| Category | Examples |
| --- | --- |
| **Data Formats** | sparse & dense, conversions, data generation |
| **Data Generation** | sparse, spatial, machine learning datasets |
| **Dense Linear Algebra** | matrix arithmetic, norms, factorization, least squares, svd & eigenvalue problems |
| **Spatial** | pairwise distances, nearest neighbors, neighborhood graph construction |
| **Sparse Operations** | linear algebra, eigenvalue problems, slicing, symmetrization, labeling |
Expand All @@ -23,18 +22,15 @@ The algorithms in RAFT span the following general categories:

RAFT provides a header-only C++ library and pre-compiled shared libraries that can 1) speed up compile times and 2) enable the APIs to be used without CUDA-enabled compilers.

RAFT also provides a Python library that is currently limited to
1. a python wrapper around the `raft::handle_t` for managing cuda library resources
2. definitions for using `raft::handle_t` directly in cython
3. tools for building multi-node multi-GPU algorithms that leverage [Dask](https://dask.org/)

The Python API is being improved to wrap the algorithms and primitives from the categories above.
RAFT also provides 2 Python libraries:
- `pylibraft` - low-level Python wrappers around RAFT algorithms and primitives.
- `pyraft` - reusable infrastructure for building analytics, including tools for building both single-GPU and multi-node multi-GPU algorithms.

## Getting started

### Rapids Memory Manager (RMM)
### RAPIDS Memory Manager (RMM)

RAFT relies heavily on RMM which, like other projects in the RAPIDS ecosystem, eases the burden of configuring different allocation strategies globally across the libraries that use it.
RAFT relies heavily on RMM which eases the burden of configuring different allocation strategies globally across the libraries that use it.

### Multi-dimensional Arrays

Expand All @@ -48,9 +44,9 @@ The `mdarray` forms a convenience layer over RMM and can be constructed in RAFT
int n_rows = 10;
int n_cols = 10;

auto scalar = raft::make_device_scalar(handle, 1.0);
auto vector = raft::make_device_vector(handle, n_cols);
auto matrix = raft::make_device_matrix(handle, n_rows, n_cols);
auto scalar = raft::make_device_scalar<float>(handle, 1.0);
auto vector = raft::make_device_vector<float>(handle, n_cols);
auto matrix = raft::make_device_matrix<float>(handle, n_rows, n_cols);
```

### C++ Example
Expand Down Expand Up @@ -80,38 +76,61 @@ auto metric = raft::distance::DistanceType::L2SqrtExpanded;
raft::distance::pairwise_distance(handle, input.view(), input.view(), output.view(), metric);
```
### Python Example
The `pylibraft` package contains a Python API for RAFT algorithms and primitives. The package is currently limited to pairwise distances, and we will continue adding more.
The example below demonstrates computing the pairwise Euclidean distances between cupy arrays. `pylibraft` is a low-level API that prioritizes efficiency and simplicity over being pythonic, which is shown here by pre-allocating the output memory before invoking the `pairwise_distance` function.
```python
import cupy as cp
from pylibraft.distance import pairwise_distance
n_samples = 5000
n_features = 50
in1 = cp.random.random_sample((n_samples, n_features), dtype=cp.float32)
in2 = cp.random.random_sample((n_samples, n_features), dtype=cp.float32)
output = cp.empty((n_samples, n_samples), dtype=cp.float32)
pairwise_distance(in1, in2, output, metric="euclidean")
```

## Installing

RAFT can be installed through conda, cmake-package-manager (cpm), or by building the repository from source.
RAFT itself can be installed through conda, [Cmake Package Manager (CPM)](https://github.com/cpm-cmake/CPM.cmake), or by building the repository from source. Please refer to the [build instructions](BUILD.md) for more a comprehensive guide on building RAFT and using it in downstream projects.

### Conda

The easiest way to install RAFT is through conda and several packages are provided.
- `libraft-headers` contains all the CUDA/C++ headers
- `libraft-nn` (optional) contains precompiled shared libraries for the nearest neighbors algorithms. If FAISS is not already installed in your environment, this will need to be installed to use the nearest neighbors headers.
- `libraft-distance` (optional) contains shared libraries for distance algorithms.
- `pyraft` (optional) contains the Python library
- `libraft-headers` RAFT headers
- `libraft-nn` (optional) contains shared libraries for the nearest neighbors primitives.
- `libraft-distance` (optional) contains shared libraries for distance primitives.
- `pylibraft` (optional) Python wrappers around RAFT algorithms and primitives
- `pyraft` (optional) contains reusable Python infrastructure and tools to accelerate Python algorithm development.

To install RAFT with conda (change to `rapidsai-nightly` for more up-to-date but less stable nightly packages)
Use the following command to install RAFT with conda (replace `rapidsai` with `rapidsai-nightly` to install more up-to-date but less stable nightly packages). `mamba` is preferred over the `conda` command.
```bash
conda install -c rapidsai libraft-headers libraft-nn libraft-distance pyraft
mamba install -c rapidsai libraft-headers libraft-nn libraft-distance pyraft pylibraft
```

After installing RAFT, `find_package(raft COMPONENTS nn distance)` can be used in your CUDA/C++ build. Note that the `COMPONENTS` are optional and will depend on the packages installed.
After installing RAFT, `find_package(raft COMPONENTS nn distance)` can be used in your CUDA/C++ build. `COMPONENTS` are optional and will depend on the packages installed.

### CPM

RAFT uses the [RAPIDS cmake](https://github.com/rapidsai/rapids-cmake) library, which makes it simple to include in downstream cmake projects. RAPIDS cmake provides a convenience layer around the [Cmake Package Manager (CPM)](https://github.com/cpm-cmake/CPM.cmake).
RAFT uses the [RAPIDS-CMake](https://github.com/rapidsai/rapids-cmake) library, which makes it simple to include in downstream cmake projects. RAPIDS CMake provides a convenience layer around CPM.

After [installing](https://github.com/rapidsai/rapids-cmake#installation) rapids-cmake in your project, you can begin using RAFT by placing the code snippet below in a file named `get_raft.cmake` and including it in your cmake build with `include(get_raft.cmake)`. This will create the `raft::raft` target to add to configure the link libraries for your artifacts.
After [installing](https://github.com/rapidsai/rapids-cmake#installation) rapids-cmake in your project, you can begin using RAFT by placing the code snippet below in a file named `get_raft.cmake` and including it in your cmake build with `include(get_raft.cmake)`. This will make available several targets to add to configure the link libraries for your artifacts.

```cmake
set(RAFT_VERSION "22.04")
set(RAFT_FORK "rapidsai")
set(RAFT_PINNED_TAG "branch-${RAFT_VERSION}")
function(find_and_configure_raft)
set(oneValueArgs VERSION FORK PINNED_TAG USE_FAISS_STATIC
COMPILE_LIBRARIES ENABLE_NN_DEPENDENCIES)
set(oneValueArgs VERSION FORK PINNED_TAG COMPILE_LIBRARIES)
cmake_parse_arguments(PKG "${options}" "${oneValueArgs}"
"${multiValueArgs}" ${ARGN} )
Expand All @@ -121,16 +140,15 @@ function(find_and_configure_raft)
rapids_cpm_find(raft ${PKG_VERSION}
GLOBAL_TARGETS raft::raft
BUILD_EXPORT_SET proj-exports
INSTALL_EXPORT_SET proj-exports
BUILD_EXPORT_SET projname-exports
INSTALL_EXPORT_SET projname-exports
CPM_ARGS
GIT_REPOSITORY https://github.com/${PKG_FORK}/raft.git
GIT_TAG ${PKG_PINNED_TAG}
SOURCE_SUBDIR cpp
OPTIONS
"BUILD_TESTS OFF"
"RAFT_ENABLE_NN_DEPENDENCIES ${PKG_ENABLE_NN_DEPENDENCIES}"
"RAFT_USE_FAISS_STATIC ${PKG_USE_FAISS_STATIC}"
"BUILD_BENCH OFF"
"RAFT_COMPILE_LIBRARIES ${PKG_COMPILE_LIBRARIES}"
)
Expand All @@ -140,35 +158,46 @@ endfunction()
# To use a different RAFT locally, set the CMake variable
# CPM_raft_SOURCE=/path/to/local/raft
find_and_configure_raft(VERSION ${RAFT_VERSION}.00
FORK rapidsai
PINNED_TAG branch-${RAFT_VERSION}
FORK ${RAFT_FORK}
PINNED_TAG ${RAFT_PINNED_TAG}
COMPILE_LIBRARIES NO
ENABLE_NN_DEPENDENCIES NO
USE_FAISS_STATIC NO
)
```

Several CMake targets can be made available by adding components in the table below to the `RAFT_COMPONENTS` list above, separated by spaces. The `raft::raft` target will always be available.

| Component | Target | Description | Base Dependencies |
| --- | --- | --- | --- |
| n/a | `raft::raft` | Full RAFT header library | CUDA toolkit library, RMM, std::mdspan, cuCollections, Thrust, NVTools |
| distance | `raft::distance` | Pre-compiled template specializations for raft::distance | raft::raft |
| nn | `raft::nn` | Pre-compiled template specializations for raft::spatial::knn | raft::raft, FAISS |

### Source

The easiest way to build RAFT from source is to use the `build.sh` script at the root of the repository,
1. create an environment with the RAFT dependencies: `conda env create --name raft_dev -f conda/environments/raft_dev_cuda11.5.yml`
2. run the build script from the repository root: `./build.sh pyraft libraft --compile-libs`
The easiest way to build RAFT from source is to use the `build.sh` script at the root of the repository:
1. Create an environment with the needed dependencies:
```
mamba env create --name raft_dev_env -f conda/environments/raft_dev_cuda11.5.yml
mamba activate raft_dev_env
```
```
./build.sh pyraft pylibraft libraft tests bench --compile-libs
```

The [Build](BUILD.md) instructions contain more details on building RAFT from source and including it in downstream projects. You can also find a more comprehensive version of the above CPM code snippet the [Building RAFT C++ from source](BUILD.md#build_cxx_source) guide.
The [build](BUILD.md) instructions contain more details on building RAFT from source and including it in downstream projects. You can also find a more comprehensive version of the above CPM code snippet the [Building RAFT C++ from source](BUILD.md#build_cxx_source) section of the build instructions.

## Folder Structure and Contents

The folder structure mirrors other RAPIDS repos (cuDF, cuML, cuGraph...), with the following folders:
The folder structure mirrors other RAPIDS repos, with the following folders:

- `ci`: Scripts for running CI in PRs
- `conda`: Conda recipes and development conda environments
- `cpp`: Source code for all C++ code.
- `cpp`: Source code for C++ libraries.
- `docs`: Doxygen configuration
- `include`: The C++ API is fully-contained here
- `include`: The C++ API is fully-contained here
- `src`: Compiled template specializations for the shared libraries
- `docs`: Source code and scripts for building library documentation (doxygen + pydocs)
- `python`: Source code for all Python source code.
- `python`: Source code for Python libraries.

## Contributing

Expand All @@ -195,4 +224,4 @@ If citing the sparse pairwise distances API, please consider using the following
journal={arXiv preprint arXiv:2104.06357},
year={2021}
}
```
```
Loading

0 comments on commit b59a0a1

Please sign in to comment.