Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify dense and sparse import in FIL #4328

Merged
merged 25 commits into from
Dec 17, 2021

Conversation

levsnv
Copy link
Contributor

@levsnv levsnv commented Nov 4, 2021

No description provided.

@caryr35 caryr35 added this to PR-WIP in v21.12 Release via automation Nov 8, 2021
@levsnv levsnv added non-breaking Non-breaking change Tech Debt Issues related to debt 3 - Ready for Review Ready for review by team improvement Improvement / enhancement to an existing function labels Nov 11, 2021
@levsnv levsnv marked this pull request as ready for review November 11, 2021 08:28
@levsnv levsnv requested a review from a team as a code owner November 11, 2021 08:28
@levsnv
Copy link
Contributor Author

levsnv commented Nov 11, 2021

rerun tests:

cuml.test.test_metrics.test_sparse_pairwise_distances_sklearn_comparison[matrix_size0-0.4-hellinger]
metric = 'hellinger', matrix_size = (1000, 100), density = 0.4
AssertionError: 
Arrays are not almost equal to 9 decimals

Mismatched elements: 529 / 1000000 (0.0529%)
Max absolute difference: 2.35608046e-08
Max relative difference: 1.44948974
cuml.test.test_metrics.test_sparse_pairwise_distances_sklearn_comparison[matrix_size1-0.01-hellinger]
metric = 'hellinger', matrix_size = (20, 10000), density = 0.01
AssertionError: 
Arrays are not almost equal to 9 decimals

Mismatched elements: 13 / 400 (3.25%)
Max absolute difference: 2.58095683e-08
Max relative difference: 1.


Copy link
Contributor

@canonizer canonizer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the overall direction where it is going. This pull request is in good shape, but there are still some comments.

Most of the comments are technical, but here are the points I'd like to highlight:

  1. It would be better to combine various compile-time node properties into node_traits<node_t>.
  2. I like the introduction of a separate conversion type tl2fil_t to hold all conversion-related state. I think functions like tree2fil could be methods of this type as well.

@@ -114,6 +114,16 @@ struct sparse_storage : storage_base {
typedef sparse_storage<sparse_node16> sparse_storage16;
typedef sparse_storage<sparse_node8> sparse_storage8;

template <typename fil_node_t>
struct node2storage {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several types like this in this pull request. It would be better to unify them into a single node_traits type. E.g.

// for sparse nodes
template <typename node_t>
struct node_traits {
  using storage = sparse_storage<node_t>;
  using forest = sparse_forest<node_t>;
  static const bool IS_DENSE = false;
};

// for dense nodes
template<> 
struct node_traits<dense_node> {
  using forest = dense_forest;
  using storage = dense_storage;
  static const bool IS_DENSE = true;
};

It is also possible to include the check() method that checks whether the number of nodes fits into sparse_node8, but that's up to you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

definitely! I assume putting them all into the dense_node, sparse_node* themselves will not be as neat?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though possible, it won't be as neat, as it would mix the node data structure with unrelated information.

A separate node_traits data type looks better.

cpp/src/fil/fil.cu Outdated Show resolved Hide resolved
cpp/src/fil/fil.cu Outdated Show resolved Hide resolved
check_params(params, false);
sparse_forest<fil_node_t>* f = new sparse_forest<fil_node_t>(h);
check_params(params, is_dense<fil_node_t>());
auto f = new typename node2forest<fil_node_t>::T(h);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to split this line:

using forest_type = typename node_traits<fil_node_t>::forest;
forest f = new forest_type(h);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrote forest_type* f = new forest_type(h); because you chose to make void init(...) non-virtual and not part of struct forest base class. Did you intend for me to make it virtual?

Copy link
Contributor

@canonizer canonizer Nov 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to make init() virtual if it would simplify things.

cpp/src/fil/internal.cuh Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Show resolved Hide resolved
v21.12 Release automation moved this from PR-WIP to PR-Needs review Nov 12, 2021
cpp/src/fil/common.cuh Show resolved Hide resolved
cpp/src/fil/common.cuh Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
@levsnv
Copy link
Contributor Author

levsnv commented Nov 24, 2021

rerun tests:

Test Result (2 failures / +2)
cuml.test.test_nearest_neighbors.test_nearest_neighbors_rbc[10000-4-euclidean]
cuml.test.test_nearest_neighbors.test_nearest_neighbors_rbc[10000-25-euclidean]
--
distance = 'euclidean', n_neighbors = 4, nrows = 10000

    @pytest.mark.parametrize('distance', ["euclidean", "haversine"])
    @pytest.mark.parametrize('n_neighbors', [4, 25])
    @pytest.mark.parametrize('nrows', [unit_param(10000), stress_param(70000)])
    def test_nearest_neighbors_rbc(distance, n_neighbors, nrows):
        X, y = make_blobs(n_samples=nrows,
                          centers=25,
                          shuffle=True,
                          n_features=2,
                          cluster_std=3.0,
                          random_state=42)
    
        knn_cu = cuKNN(metric=distance, algorithm="rbc")
        knn_cu.fit(X)
    
        query_rows = int(nrows/2)
    
        rbc_d, rbc_i = knn_cu.kneighbors(X[:query_rows, :],
                                         n_neighbors=n_neighbors)
    
        if distance == 'euclidean':
            # Need to use unexpanded euclidean distance
            pw_dists = cuPW(X, metric="l2")
            brute_i = cp.argsort(pw_dists, axis=1)[:query_rows, :n_neighbors]
            brute_d = cp.sort(pw_dists, axis=1)[:query_rows, :n_neighbors]
        else:
            knn_cu_brute = cuKNN(metric=distance, algorithm="brute")
            knn_cu_brute.fit(X)
    
            brute_d, brute_i = knn_cu_brute.kneighbors(
                X[:query_rows, :], n_neighbors=n_neighbors)
    
        rbc_i = cp.sort(rbc_i, axis=1)
        brute_i = cp.sort(brute_i, axis=1)
    
        # TODO: These are failing with 1 or 2 mismatched elements
        # for very small values of k:
        # https://github.com/rapidsai/cuml/issues/4262
>       assert len(brute_d[brute_d != rbc_d]) <= 1
E       assert 139 <= 1
E        +  where 139 = len(array([0.26635543, 0.14040843, 0.15865709, 0.224747  , 0.22284727,\n       0.31209642, 0.196584  , 0.4371513 , 0.459564... 0.09977522, 0.20649612, 0.20396307, 0.18100378,\n       0.36238492, 0.41610897, 0.14166015, 0.17231807], dtype=float32))

cuml/test/test_nearest_neighbors.py:556: AssertionError

@levsnv
Copy link
Contributor Author

levsnv commented Nov 25, 2021

same test error

@levsnv
Copy link
Contributor Author

levsnv commented Dec 2, 2021

rerun tests

@dantegd dantegd removed this from PR-Needs review in v21.12 Release Dec 2, 2021
@dantegd dantegd added this to PR-WIP in v22.02 Release via automation Dec 2, 2021
@levsnv
Copy link
Contributor Author

levsnv commented Dec 3, 2021

C++ test failed: 20:02:37 [ FAILED ] UMAPParametrizableTest.Result

@dantegd
Copy link
Member

dantegd commented Dec 13, 2021

rerun tests

@levsnv
Copy link
Contributor Author

levsnv commented Dec 15, 2021

lots of C++ tests fail with
C++ exception with description "CUDA error encountered at: file=_deps/raft-src/cpp/include/raft/handle.hpp line=250: call='cudaEventCreateWithFlags(&event_, cudaEventDisableTiming)', Reason=cudaErrorIllegalAddress:an illegal memory access was encountered

@levsnv
Copy link
Contributor Author

levsnv commented Dec 15, 2021

rerun tests

Copy link
Contributor

@wphicks wphicks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beautiful work! Just a couple stray C types and one spot where we can avoid a raw loop. Other than that, it looks perfect.

cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
cpp/src/fil/treelite_import.cu Outdated Show resolved Hide resolved
v22.02 Release automation moved this from PR-WIP to PR-Needs review Dec 16, 2021
v22.02 Release automation moved this from PR-Needs review to PR-Reviewer approved Dec 17, 2021
@wphicks
Copy link
Contributor

wphicks commented Dec 17, 2021

@gpucibot merge

@codecov-commenter
Copy link

Codecov Report

❗ No coverage uploaded for pull request base (branch-22.02@1b46ec4). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@               Coverage Diff               @@
##             branch-22.02    #4328   +/-   ##
===============================================
  Coverage                ?   85.72%           
===============================================
  Files                   ?      236           
  Lines                   ?    19326           
  Branches                ?        0           
===============================================
  Hits                    ?    16568           
  Misses                  ?     2758           
  Partials                ?        0           
Flag Coverage Δ
dask 46.51% <0.00%> (?)
non-dask 78.62% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1b46ec4...fe38a39. Read the comment docs.

@levsnv levsnv added 5 - Ready to Merge Testing and reviews complete, ready to merge and removed 3 - Ready for Review Ready for review by team labels Dec 17, 2021
@wphicks
Copy link
Contributor

wphicks commented Dec 17, 2021

@gpucibot merge

@rapids-bot rapids-bot bot merged commit 3ae44b9 into rapidsai:branch-22.02 Dec 17, 2021
v22.02 Release automation moved this from PR-Reviewer approved to Done Dec 17, 2021
rapids-bot bot pushed a commit that referenced this pull request Dec 18, 2021
The pull request includes changes from #4328. To view only changes pertinent to unifying tests, see
https://github.com/levsnv/cuml/pull/3/files?diff=unified&w=1

Authors:
  - Levs Dolgovs (https://github.com/levsnv)

Approvers:
  - Andy Adinets (https://github.com/canonizer)
  - William Hicks (https://github.com/wphicks)

URL: #4417
vimarsh6739 pushed a commit to vimarsh6739/cuml that referenced this pull request Oct 9, 2023
vimarsh6739 pushed a commit to vimarsh6739/cuml that referenced this pull request Oct 9, 2023
The pull request includes changes from rapidsai#4328. To view only changes pertinent to unifying tests, see
https://github.com/levsnv/cuml/pull/3/files?diff=unified&w=1

Authors:
  - Levs Dolgovs (https://github.com/levsnv)

Approvers:
  - Andy Adinets (https://github.com/canonizer)
  - William Hicks (https://github.com/wphicks)

URL: rapidsai#4417
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
5 - Ready to Merge Testing and reviews complete, ready to merge CUDA/C++ improvement Improvement / enhancement to an existing function non-breaking Non-breaking change Tech Debt Issues related to debt
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

5 participants