Skip to content

Commit

Permalink
Merge pull request #4 from rapidsai/bug-tsvd-explainedvar
Browse files Browse the repository at this point in the history
Bug tsvd explained_var
  • Loading branch information
dantegd authored Oct 17, 2018
2 parents fdb3957 + 34d25c8 commit 4cdb34f
Show file tree
Hide file tree
Showing 13 changed files with 642 additions and 361 deletions.
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ The cuML repository contains:
1. ***python***: Python based GPU Dataframe (GDF) machine learning package that takes [cuDF](https://github.com/rapidsai/cudf-alpha) dataframes as input. cuML connects the data to C++/CUDA based cuML and ml-prims libraries without ever leaving GPU memory.

2. ***cuML***: C++/CUDA machine learning algorithms. This library currently includes the following five algorithms;
a. Single GPU Truncated Singular Value Decomposition (tSVD).
b. Single GPU Principal Component Analysis (PCA).
c. Single GPU Density-based Spatial Clustering of Applications with Noise (DBSCAN).
d. Single GPU Kalman Filtering
e. Multi-GPU K-Means Clustering
a. Single GPU Truncated Singular Value Decomposition (tSVD),
b. Single GPU Principal Component Analysis (PCA),
c. Single GPU Density-based Spatial Clustering of Applications with Noise (DBSCAN),
d. Single GPU Kalman Filtering,
e. Multi-GPU K-Means Clustering.

3. ***ml-prims***: Low level machine learning primitives used in cuML. ml-prims is comprised of the following components;
a. Linear Algebra
b. Statistics
c. Basic Matrix Operations
d. Distance Functions
e. Random Number Generation
a. Linear Algebra,
b. Statistics,
c. Basic Matrix Operations,
d. Distance Functions,
e. Random Number Generation.

#### Available Algorithms for version 0.1alpha:

Expand All @@ -30,7 +30,7 @@ The cuML repository contains:

Upcoming algorithms for version 0.1:

- kmeans
- K-Means Clustering

- Kalman Filter

Expand All @@ -49,7 +49,7 @@ List of dependencies:

1. zlib
2. cmake (>= 3.8, version 3.11.4 is recommended and there are issues with version 3.12)
3. CUDA Toolkit (>= 9.0)
3. CUDA (>= 9.0)
4. Cython (>= 0.28)
5. gcc (>=5.4.0)
6. [cuDF](https://github.com/rapidsai/cudf-alpha)
Expand All @@ -65,27 +65,27 @@ git clone --recurse-submodules https://github.com/rapidsai/cuml.git
To build the python package, in the repository root folder:

```
cd python
python setup.py install
```

### Building CuML:

### Running tests

To test the C++ algorithms using googletests, without compiling the
To test the C++ algorithms using googletests, in the repository root folder:

```bash
$ cd cuML
$ mkdir build
$ cd build
$ cmake ..
$ make -j
$ ./ml_test
```

### Python Tests
### Python Notebooks

Additional python tests can be found in the pythontests folder, along some useful scripts. Py.test based unit testing are being added for the final version 0.1.
Demo notebooks can be found in python/notebooks folder.

## External

Expand Down
72 changes: 48 additions & 24 deletions cuML/src/pca/pca.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,39 @@ namespace ML {

using namespace MLCommon;

// TODO: Implement for the case prms.trans_input = false
// TODO: Check sign flip algorithm
template<typename math_t>
void truncCompExpVars(math_t *in, math_t *components, math_t *explained_var,
math_t *explained_var_ratio, paramsTSVD prms,
cusolverDnHandle_t cusolver_handle, cublasHandle_t cublas_handle) {

math_t *components_all;
math_t *explained_var_all;
math_t *explained_var_ratio_all;

int len = prms.n_cols * prms.n_cols;
allocate(components_all, len);
allocate(explained_var_all, prms.n_cols);
allocate(explained_var_ratio_all, prms.n_cols);

calEig(in, components_all, explained_var_all, prms, cusolver_handle,
cublas_handle);

Matrix::truncZeroOrigin(components_all, prms.n_cols, components,
prms.n_components, prms.n_cols);

Matrix::ratio(explained_var_all, explained_var_ratio_all, prms.n_cols);

Matrix::truncZeroOrigin(explained_var_all, prms.n_cols, explained_var,
prms.n_components, 1);

Matrix::truncZeroOrigin(explained_var_ratio_all, prms.n_cols,
explained_var_ratio, prms.n_components, 1);

CUDA_CHECK(cudaFree(components_all));
CUDA_CHECK(cudaFree(explained_var_all));
CUDA_CHECK(cudaFree(explained_var_ratio_all));
}

/**
* @brief perform fit operation for the pca. Generates eigenvectors, explained vars, singular vals, etc.
* @input param input: the data is fitted to PCA. Size n_rows x n_cols. The size of the data is indicated in prms.
Expand Down Expand Up @@ -66,27 +97,19 @@ void pcaFit(math_t *input, math_t *components, math_t *explained_var,

Stats::mean(mu, input, prms.n_cols, prms.n_rows, true, false);

if (prms.algorithm == solver::RANDOMIZED) {
Stats::meanCenter(input, mu, prms.n_cols, prms.n_rows, false);
calCompExpVarsSvd(input, components, singular_vals, explained_var,
explained_var_ratio, prms, cusolver_handle, cublas_handle);
} else {
math_t *cov;
int len = prms.n_cols * prms.n_cols;
allocate(cov, len);

Stats::cov(cov, input, mu, prms.n_cols, prms.n_rows, true, false, true,
cublas_handle);
calCompExpVarsEig(cov, components, explained_var, explained_var_ratio,
prms, cusolver_handle, cublas_handle);

math_t scalar = (prms.n_rows - 1);
Matrix::seqRoot(explained_var, singular_vals, scalar,
prms.n_components);

if (cov)
CUDA_CHECK(cudaFree(cov));
}
math_t *cov;
int len = prms.n_cols * prms.n_cols;
allocate(cov, len);

Stats::cov(cov, input, mu, prms.n_cols, prms.n_rows, true, false, true,
cublas_handle);
truncCompExpVars(cov, components, explained_var, explained_var_ratio, prms,
cusolver_handle, cublas_handle);

math_t scalar = (prms.n_rows - 1);
Matrix::seqRoot(explained_var, singular_vals, scalar, prms.n_components);

CUDA_CHECK(cudaFree(cov));

Stats::meanAdd(input, mu, prms.n_cols, prms.n_rows, false);
}
Expand Down Expand Up @@ -117,7 +140,8 @@ void pcaFitTransform(math_t *input, math_t *trans_input, math_t *components,
pcaTransform(input, components, trans_input, singular_vals, mu, prms,
cublas_handle);

signFlip(trans_input, prms.n_rows, prms.n_components, components, prms.n_cols);
signFlip(trans_input, prms.n_rows, prms.n_components, components,
prms.n_cols);
}

// TODO: implement pcaGetCovariance function
Expand Down
12 changes: 4 additions & 8 deletions cuML/src/tsvd/tsvd.cu
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,27 @@ namespace ML {

using namespace MLCommon;

void tsvdFit(float *input, float *components, float *explained_var,
float *explained_var_ratio, float *singular_vals, paramsTSVD prms) {
void tsvdFit(float *input, float *components, float *singular_vals, paramsTSVD prms) {
cublasHandle_t cublas_handle;
CUBLAS_CHECK(cublasCreate(&cublas_handle));

cusolverDnHandle_t cusolver_handle = NULL;
CUSOLVER_CHECK(cusolverDnCreate(&cusolver_handle));

tsvdFit(input, components, explained_var, explained_var_ratio,
singular_vals, prms, cublas_handle, cusolver_handle);
tsvdFit(input, components, singular_vals, prms, cublas_handle, cusolver_handle);

CUBLAS_CHECK(cublasDestroy(cublas_handle));
CUSOLVER_CHECK(cusolverDnDestroy(cusolver_handle));
}

void tsvdFit(double *input, double *components, double *explained_var,
double *explained_var_ratio, double *singular_vals, paramsTSVD prms) {
void tsvdFit(double *input, double *components, double *singular_vals, paramsTSVD prms) {
cublasHandle_t cublas_handle;
CUBLAS_CHECK(cublasCreate(&cublas_handle));

cusolverDnHandle_t cusolver_handle = NULL;
CUSOLVER_CHECK(cusolverDnCreate(&cusolver_handle));

tsvdFit(input, components, explained_var, explained_var_ratio,
singular_vals, prms, cublas_handle, cusolver_handle);
tsvdFit(input, components, singular_vals, prms, cublas_handle, cusolver_handle);

CUBLAS_CHECK(cublasDestroy(cublas_handle));
CUSOLVER_CHECK(cusolverDnDestroy(cusolver_handle));
Expand Down
Loading

0 comments on commit 4cdb34f

Please sign in to comment.