From fa8cb8c2266791f05e4c19f6943e276e57a94887 Mon Sep 17 00:00:00 2001
From: Michael Demoret <mdemoret@nvidia.com>
Date: Mon, 3 Aug 2020 17:19:58 -0600
Subject: [PATCH 01/13] Updating the Cython build with a custom build_ext to
 allow for late determination of cython options

---
 python/cython_build_ext.py | 102 ++++++++++++++++++++
 python/setup.cfg           |   7 ++
 python/setup.py            | 186 ++++++++++++++++++-------------------
 3 files changed, 202 insertions(+), 93 deletions(-)
 create mode 100644 python/cython_build_ext.py

diff --git a/python/cython_build_ext.py b/python/cython_build_ext.py
new file mode 100644
index 0000000000..3a9f8004c4
--- /dev/null
+++ b/python/cython_build_ext.py
@@ -0,0 +1,102 @@
+import sys
+
+# TODO: It should be possible to support Cython-less distribution following
+# this guide and removing the direct import of Cython:
+# https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules
+
+# Must import in this order:
+#   setuptools -> Cython.Distutils.build_ext -> setuptools.command.build_ext
+# Otherwise, setuptools.command.build_ext ends up inheriting from
+# Cython.Distutils.old_build_ext which we do not want
+import setuptools
+from Cython.Distutils.build_ext import new_build_ext as _build_ext
+import setuptools.command.build_ext
+
+
+class cython_build_ext(_build_ext, object):
+    user_options = [
+        ('language-level=', None,
+         'Sets the python language syntax to use "2", "3", "3str".'),
+        ("binding", None, "Sets the binding Cython binding directive"),
+        ("profile", None, "Sets the profile Cython binding directive"),
+        ("embedsignature", None, "Sets the binding Cython binding directive"),
+        ("cython-exclude=", None, "Sets the binding Cython binding directive")
+    ] + _build_ext.user_options
+
+    boolean_options = ["binding", "profile", "embedsignature"
+                       ] + _build_ext.boolean_options
+
+    def initialize_options(self):
+
+        self.language_level = None
+        self.binding = None
+        self.profile = None
+        self.embedsignature = None
+        self.cython_exclude = None
+        super().initialize_options()
+
+    def finalize_options(self):
+
+        # Ensure the base build class options get set so we can use parallel
+        self.set_undefined_options(
+            'build',
+            ('build_lib', 'build_lib'),
+            ('build_temp', 'build_temp'),
+            ('compiler', 'compiler'),
+            ('debug', 'debug'),
+            ('force', 'force'),
+            ('parallel', 'parallel'),
+            ('plat_name', 'plat_name'),
+        )
+
+        # If ext_modules is set, then build the cythonize argument list
+        if self.distribution.ext_modules:
+            if self.language_level is None:
+                self.language_level = str(sys.version_info[0])
+
+            assert self.language_level in (
+                '2', '3',
+                '3str'), 'Incorrect Cython language level ("{0}")'.format(
+                    self.language_level)
+
+            compiler_directives = dict(language_level=self.language_level)
+
+            if (self.binding is not None):
+                self.binding = bool(self.binding)
+                compiler_directives.update({"binding": self.binding})
+
+            if (self.profile is not None):
+                self.profile = bool(self.profile)
+                compiler_directives.update({"profile": self.profile})
+
+            if (self.embedsignature is not None):
+                self.embedsignature = bool(self.embedsignature)
+                compiler_directives.update(
+                    {"embedsignature": self.embedsignature})
+
+            cythonize_kwargs = {}
+
+            if (self.cython_exclude is not None):
+
+                if (isinstance(self.cython_exclude, str)):
+                    self.cython_exclude = list(self.cython_exclude)
+
+                cythonize_kwargs.update({"exclude": self.cython_exclude})
+
+            # Handle nthreads separately to mimic what Cython does
+            nthreads = getattr(self, 'parallel', None)  # -j option in Py3.5+
+            nthreads = int(nthreads) if nthreads else None
+
+            # Delay import this to allow for Cython-less installs
+            from Cython.Build.Dependencies import cythonize
+
+            # Finally, cythonize the arguments
+            self.distribution.ext_modules = cythonize(
+                self.distribution.ext_modules,
+                nthreads=nthreads,
+                force=self.force,
+                compiler_directives=compiler_directives,
+                **cythonize_kwargs)
+
+        # Skip calling super() and jump straight to setuptools
+        setuptools.command.build_ext.build_ext.finalize_options(self)
diff --git a/python/setup.cfg b/python/setup.cfg
index 677d3c1763..c335d8a459 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -16,3 +16,10 @@ parentdir_prefix = cuml-
 
 [tool:pytest]
 testpaths = cuml/test
+
+# Project wide, Cython settings
+[build_ext]
+binding = True
+language_level = 3
+profile = False
+embedsignature = True
\ No newline at end of file
diff --git a/python/setup.py b/python/setup.py
index e462234b51..854a37b4b7 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -24,6 +24,7 @@
 from setuputils import get_environment_option
 from setuputils import get_cli_option
 from setuputils import use_raft_package
+from cython_build_ext import cython_build_ext
 
 import glob
 import numpy
@@ -34,20 +35,7 @@
 import versioneer
 import warnings
 
-
-if "--singlegpu" in sys.argv:
-    from Cython.Build import cythonize
-    from setuptools.command.build_ext import build_ext
-else:
-    try:
-        from Cython.Distutils.build_ext import new_build_ext as build_ext
-    except ImportError:
-        from setuptools.command.build_ext import build_ext
-
-install_requires = [
-    'numba',
-    'cython'
-]
+install_requires = ['numba', 'cython']
 
 ##############################################################################
 # - Print of build options used by setup.py  --------------------------------
@@ -57,7 +45,6 @@
 raft_path = get_environment_option('RAFT_PATH')
 
 clean_artifacts = get_cli_option('clean')
-single_gpu_build = get_cli_option('--singlegpu')
 
 ##############################################################################
 # - Dependencies include and lib folder setup --------------------------------
@@ -69,6 +56,7 @@
 
     cuda_home = str(Path(nvcc_path).parent.parent)
     print("-- Using nvcc to detect CUDA, found at " + str(cuda_home))
+
 cuda_include_dir = os.path.join(cuda_home, "include")
 cuda_lib_dir = os.path.join(cuda_home, "lib64")
 
@@ -114,87 +102,103 @@
 
 raft_include_dir = use_raft_package(raft_path, libcuml_path)
 
-##############################################################################
-# - Cython extensions build and parameters -----------------------------------
-
-# cumlcomms and nccl are still needed for multigpu algos not based
-# on libcumlprims
-libs = ['cuda',
-        'cuml++',
-        'rmm']
-
-include_dirs = ['../cpp/src',
-                '../cpp/include',
-                '../cpp/src_prims',
-                raft_include_dir,
-                '../cpp/comms/std/src',
-                '../cpp/comms/std/include',
-                cuda_include_dir,
-                numpy.get_include(),
-                os.path.dirname(sysconfig.get_path("include"))]
-
-# Exclude multigpu components that use libcumlprims if --singlegpu is used
-cython_exc_list = []
-python_exc_list = []
-
 if "--multigpu" in sys.argv:
     warnings.warn("Flag --multigpu is deprecated. By default cuML is"
                   "built with multi GPU support. To disable it use the flag"
                   "--singlegpu")
     sys.argv.remove('--multigpu')
 
-if "--singlegpu" in sys.argv:
-    cython_exc_list = glob.glob('cuml/*/*_mg.pyx')
-    cython_exc_list = cython_exc_list + glob.glob('cuml/*/*_mg.pxd')
-    cython_exc_list.append('cuml/nccl/nccl.pyx')
-    cython_exc_list.append('cuml/dask/common/comms_utils.pyx')
+if not libcuml_path:
+    libcuml_path = '../cpp/build/'
 
-    print('--singlegpu: excluding the following Cython components:')
-    pprint(cython_exc_list)
+##############################################################################
+# - Cython extensions build and parameters -----------------------------------
+# Derive from `cython_build_ext` to add --singlegpu customization
 
-    python_exc_list = ["*.dask", "*.dask.*"]
-else:
-    libs.append('cumlprims')
-    libs.append('cumlcomms')
-    libs.append('nccl')
 
-    sys_include = os.path.dirname(sysconfig.get_path("include"))
-    include_dirs.append("%s/cumlprims" % sys_include)
+class cuml_build_ext(cython_build_ext, object):
+    user_options = [
+        ("singlegpu", None, "Specifies whether to include multi-gpu or not"),
+    ] + cython_build_ext.user_options
 
-cmdclass = dict()
-cmdclass.update(versioneer.get_cmdclass())
-cmdclass["build_ext"] = build_ext
+    boolean_options = ["singlegpu"] + cython_build_ext.boolean_options
 
-if not libcuml_path:
-    libcuml_path = '../cpp/build/'
+    def initialize_options(self):
+
+        self.singlegpu = False
 
-extensions = [
-    Extension("*",
-              sources=["cuml/**/**/*.pyx"],
-              include_dirs=include_dirs,
-              library_dirs=[get_python_lib(), libcuml_path],
-              runtime_library_dirs=[cuda_lib_dir,
-                                    os.path.join(os.sys.prefix, "lib")],
-              libraries=libs,
-              language='c++',
-              extra_compile_args=['-std=c++11'])
-]
-
-for e in extensions:
-    # TODO: this exclude is not working, need to research way to properly
-    # exclude files for parallel build. See issue
-    # https://github.com/rapidsai/cuml/issues/2037
-    # e.exclude = cython_exc_list
-    e.cython_directives = dict(
-        profile=False, language_level=3, embedsignature=True
-    )
-
-if "--singlegpu" in sys.argv:
-    print("Full cythonization in parallel is not supported for singlegpu " +
-          "target for now.")
-    extensions = cythonize(extensions,
-                           exclude=cython_exc_list)
-    sys.argv.remove('--singlegpu')
+        super().initialize_options()
+
+    def finalize_options(self):
+
+        # cumlcomms and nccl are still needed for multigpu algos not based
+        # on libcumlprims
+        libs = ['cuda', 'cuml++', 'rmm']
+
+        include_dirs = ['../cpp/src',
+                        '../cpp/include',
+                        '../cpp/src_prims',
+                        raft_include_dir,
+                        '../cpp/comms/std/src',
+                        '../cpp/comms/std/include',
+                        cuda_include_dir,
+                        numpy.get_include(),
+                        os.path.dirname(sysconfig.get_path("include"))]
+
+        # Exclude multigpu components that use libcumlprims if
+        # --singlegpu is used
+        python_exc_list = []
+
+        if (self.singlegpu):
+            cython_exc_list = glob.glob('cuml/*/*_mg.pyx')
+            cython_exc_list = cython_exc_list + glob.glob('cuml/*/*_mg.pxd')
+            cython_exc_list.append('cuml/nccl/nccl.pyx')
+            cython_exc_list.append('cuml/dask/common/comms_utils.pyx')
+
+            print('--singlegpu: excluding the following Cython components:')
+            pprint(cython_exc_list)
+
+            python_exc_list = ["*.dask", "*.dask.*"]
+
+            # Append to base excludes
+            self.cython_exclude = cython_exc_list + \
+                (self.cython_exclude or [])
+        else:
+            libs.append('cumlprims')
+            libs.append('cumlcomms')
+            libs.append('nccl')
+
+            sys_include = os.path.dirname(sysconfig.get_path("include"))
+            include_dirs.append("%s/cumlprims" % sys_include)
+
+        # Find packages now that --singlegpu has been determined
+        self.distribution.packages = find_packages(include=['cuml', 'cuml.*'],
+                                                   exclude=python_exc_list)
+
+        # Build the extensions list
+        extensions = [
+            Extension("*",
+                      sources=["cuml/**/*.pyx"],
+                      include_dirs=include_dirs,
+                      library_dirs=[get_python_lib(), libcuml_path],
+                      runtime_library_dirs=[
+                          cuda_lib_dir,
+                          os.path.join(os.sys.prefix, "lib")
+                      ],
+                      libraries=libs,
+                      language='c++',
+                      extra_compile_args=['-std=c++11'])
+        ]
+
+        self.distribution.ext_modules = extensions
+
+        super().finalize_options()
+
+
+# Specify the custom build class
+cmdclass = dict()
+cmdclass.update(versioneer.get_cmdclass())
+cmdclass["build_ext"] = cuml_build_ext
 
 ##############################################################################
 # - Python package generation ------------------------------------------------
@@ -203,18 +207,14 @@
       description="cuML - RAPIDS ML Algorithms",
       version=versioneer.get_version(),
       classifiers=[
-        "Intended Audience :: Developers",
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7"
+          "Intended Audience :: Developers",
+          "Programming Language :: Python",
+          "Programming Language :: Python :: 3.6",
+          "Programming Language :: Python :: 3.7"
       ],
       author="NVIDIA Corporation",
       setup_requires=['cython'],
-      ext_modules=extensions,
-      packages=find_packages(include=['cuml', 'cuml.*'],
-                             exclude=python_exc_list),
       install_requires=install_requires,
       license="Apache",
       cmdclass=cmdclass,
-      zip_safe=False
-      )
+      zip_safe=False)

From cc393112e6763d763872e5cf20df97889cae0602 Mon Sep 17 00:00:00 2001
From: Michael Demoret <mdemoret@nvidia.com>
Date: Mon, 3 Aug 2020 17:42:27 -0600
Subject: [PATCH 02/13] Adding CHANGELOG message

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5c35743ef9..fcf1bb07d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@
 - PR #2211: MNMG KNN Classifier & Regressor
 - PR #2461: Add KNN Sparse Output Functionality
 - PR #2607: Add support for probability estimates in SVC
+- PR #2638: Improve cython build with custom `build_ext`
 
 ## Improvements
 - PR #2336: Eliminate `rmm.device_array` usage

From 57eaa61ad26a3d35e20803212aaffa34c3b85dd8 Mon Sep 17 00:00:00 2001
From: Michael Demoret <mdemoret@nvidia.com>
Date: Tue, 4 Aug 2020 15:39:40 -0600
Subject: [PATCH 03/13] Fixing build system so it works in CI

---
 python/cython_build_ext.py |   7 +-
 python/setup.cfg           |   1 +
 python/setup.py            | 185 ++++++++++++++++++++++---------------
 3 files changed, 120 insertions(+), 73 deletions(-)

diff --git a/python/cython_build_ext.py b/python/cython_build_ext.py
index 3a9f8004c4..b41c8f0755 100644
--- a/python/cython_build_ext.py
+++ b/python/cython_build_ext.py
@@ -9,7 +9,12 @@
 # Otherwise, setuptools.command.build_ext ends up inheriting from
 # Cython.Distutils.old_build_ext which we do not want
 import setuptools
-from Cython.Distutils.build_ext import new_build_ext as _build_ext
+
+try:
+    from Cython.Distutils.build_ext import new_build_ext as _build_ext
+except ImportError:
+    from setuptools.command.build_ext import build_ext as _build_ext
+
 import setuptools.command.build_ext
 
 
diff --git a/python/setup.cfg b/python/setup.cfg
index c335d8a459..a4c9a02e46 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -19,6 +19,7 @@ testpaths = cuml/test
 
 # Project wide, Cython settings
 [build_ext]
+inplace = True
 binding = True
 language_level = 3
 profile = False
diff --git a/python/setup.py b/python/setup.py
index 854a37b4b7..da2ac0084d 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -14,32 +14,39 @@
 # limitations under the License.
 #
 
-from distutils.sysconfig import get_python_lib
-from pathlib import Path
+import glob
+import os
+import shutil
+import sys
+import sysconfig
+import warnings
 from pprint import pprint
+from pathlib import Path
+
 from setuptools import find_packages
 from setuptools import setup
 from setuptools.extension import Extension
+from distutils.sysconfig import get_python_lib
+from distutils.command.clean import clean as _clean
+from distutils.command.build import build as _build
+
+import numpy
+
 from setuputils import clean_folder
 from setuputils import get_environment_option
 from setuputils import get_cli_option
 from setuputils import use_raft_package
-from cython_build_ext import cython_build_ext
 
-import glob
-import numpy
-import os
-import shutil
-import sys
-import sysconfig
 import versioneer
-import warnings
+from cython_build_ext import cython_build_ext
 
 install_requires = ['numba', 'cython']
 
 ##############################################################################
 # - Print of build options used by setup.py  --------------------------------
 
+global libcuml_path
+
 cuda_home = get_environment_option("CUDA_HOME")
 libcuml_path = get_environment_option('CUML_BUILD_PATH')
 raft_path = get_environment_option('RAFT_PATH')
@@ -60,41 +67,6 @@
 cuda_include_dir = os.path.join(cuda_home, "include")
 cuda_lib_dir = os.path.join(cuda_home, "lib64")
 
-##############################################################################
-# - Clean target -------------------------------------------------------------
-
-if clean_artifacts:
-    print("-- Cleaning all Python and Cython build artifacts...")
-
-    treelite_path = ""
-    libcuml_path = ""
-
-    try:
-        setup_file_path = str(Path(__file__).parent.absolute())
-        shutil.rmtree(setup_file_path + '/.pytest_cache', ignore_errors=True)
-        shutil.rmtree(setup_file_path + '/_external_repositories',
-                      ignore_errors=True)
-        shutil.rmtree(setup_file_path + '/cuml.egg-info', ignore_errors=True)
-        shutil.rmtree(setup_file_path + '/__pycache__', ignore_errors=True)
-
-        os.remove(setup_file_path + '/cuml/raft')
-
-        clean_folder(setup_file_path + '/cuml')
-        shutil.rmtree(setup_file_path + '/build')
-
-    except IOError:
-        pass
-
-    # need to terminate script so cythonizing doesn't get triggered after
-    # cleanup unintendedly
-    sys.argv.remove("clean")
-
-    if "--all" in sys.argv:
-        sys.argv.remove("--all")
-
-    if len(sys.argv) == 1:
-        sys.exit(0)
-
 ##############################################################################
 # - Cloning RAFT and dependencies if needed ----------------------------------
 
@@ -111,17 +83,56 @@
 if not libcuml_path:
     libcuml_path = '../cpp/build/'
 
+##############################################################################
+# - Clean target -------------------------------------------------------------
+# This derives from distutils clean to so we can use the derived values of
+# 'build' and the base clean implementation
+
+
+class cuml_clean(_clean):
+    def run(self):
+
+        global libcuml_path
+
+        # Call the base first to get info from build
+        super().run()
+
+        if (self.all):
+            # Reset libcuml_path
+            libcuml_path = ""
+
+            try:
+                setup_file_path = str(Path(__file__).parent.absolute())
+                shutil.rmtree(os.path.join(setup_file_path, ".pytest_cache"),
+                              ignore_errors=True)
+                shutil.rmtree(os.path.join(setup_file_path,
+                                           '/_external_repositories'),
+                              ignore_errors=True)
+                shutil.rmtree(os.path.join(setup_file_path, '/cuml.egg-info'),
+                              ignore_errors=True)
+                shutil.rmtree(os.path.join(setup_file_path, '/__pycache__'),
+                              ignore_errors=True)
+
+                os.remove(setup_file_path + '/cuml/raft')
+
+                clean_folder(setup_file_path + '/cuml')
+
+            except IOError:
+                pass
+
+
 ##############################################################################
 # - Cython extensions build and parameters -----------------------------------
 # Derive from `cython_build_ext` to add --singlegpu customization
 
 
-class cuml_build_ext(cython_build_ext, object):
+class cuml_build(_build):
+
     user_options = [
-        ("singlegpu", None, "Specifies whether to include multi-gpu or not"),
-    ] + cython_build_ext.user_options
+        ("singlegpu", None, "Specifies whether to include multi-gpu or not")
+    ] + _build.user_options
 
-    boolean_options = ["singlegpu"] + cython_build_ext.boolean_options
+    boolean_options = ["singlegpu"] + _build.boolean_options
 
     def initialize_options(self):
 
@@ -131,38 +142,26 @@ def initialize_options(self):
 
     def finalize_options(self):
 
+        global libcuml_path
+
         # cumlcomms and nccl are still needed for multigpu algos not based
         # on libcumlprims
         libs = ['cuda', 'cuml++', 'rmm']
 
-        include_dirs = ['../cpp/src',
-                        '../cpp/include',
-                        '../cpp/src_prims',
-                        raft_include_dir,
-                        '../cpp/comms/std/src',
-                        '../cpp/comms/std/include',
-                        cuda_include_dir,
-                        numpy.get_include(),
-                        os.path.dirname(sysconfig.get_path("include"))]
+        include_dirs = [
+            '../cpp/src', '../cpp/include', '../cpp/src_prims',
+            raft_include_dir, '../cpp/comms/std/src',
+            '../cpp/comms/std/include', cuda_include_dir,
+            numpy.get_include(),
+            os.path.dirname(sysconfig.get_path("include"))
+        ]
 
         # Exclude multigpu components that use libcumlprims if
         # --singlegpu is used
         python_exc_list = []
 
         if (self.singlegpu):
-            cython_exc_list = glob.glob('cuml/*/*_mg.pyx')
-            cython_exc_list = cython_exc_list + glob.glob('cuml/*/*_mg.pxd')
-            cython_exc_list.append('cuml/nccl/nccl.pyx')
-            cython_exc_list.append('cuml/dask/common/comms_utils.pyx')
-
-            print('--singlegpu: excluding the following Cython components:')
-            pprint(cython_exc_list)
-
             python_exc_list = ["*.dask", "*.dask.*"]
-
-            # Append to base excludes
-            self.cython_exclude = cython_exc_list + \
-                (self.cython_exclude or [])
         else:
             libs.append('cumlprims')
             libs.append('cumlcomms')
@@ -195,9 +194,52 @@ def finalize_options(self):
         super().finalize_options()
 
 
+# This custom build_ext is only responsible for setting cython_exclude when
+# --singlegpu is specified
+class cuml_build_ext(cython_build_ext, object):
+    user_options = [
+        ("singlegpu", None, "Specifies whether to include multi-gpu or not"),
+    ] + cython_build_ext.user_options
+
+    boolean_options = ["singlegpu"] + cython_build_ext.boolean_options
+
+    def initialize_options(self):
+
+        self.singlegpu = None
+
+        super().initialize_options()
+
+    def finalize_options(self):
+
+        # Ensure the base build class options get set so we can use singlegpu
+        self.set_undefined_options(
+            'build',
+            ('singlegpu', 'singlegpu'),
+        )
+
+        # Exclude multigpu components that use libcumlprims if
+        # --singlegpu is used
+        if (self.singlegpu):
+            cython_exc_list = glob.glob('cuml/*/*_mg.pyx')
+            cython_exc_list = cython_exc_list + glob.glob('cuml/*/*_mg.pxd')
+            cython_exc_list.append('cuml/nccl/nccl.pyx')
+            cython_exc_list.append('cuml/dask/common/comms_utils.pyx')
+
+            print('--singlegpu: excluding the following Cython components:')
+            pprint(cython_exc_list)
+
+            # Append to base excludes
+            self.cython_exclude = cython_exc_list + \
+                (self.cython_exclude or [])
+
+        super().finalize_options()
+
+
 # Specify the custom build class
 cmdclass = dict()
 cmdclass.update(versioneer.get_cmdclass())
+cmdclass["clean"] = cuml_clean
+cmdclass["build"] = cuml_build
 cmdclass["build_ext"] = cuml_build_ext
 
 ##############################################################################
@@ -207,8 +249,7 @@ def finalize_options(self):
       description="cuML - RAPIDS ML Algorithms",
       version=versioneer.get_version(),
       classifiers=[
-          "Intended Audience :: Developers",
-          "Programming Language :: Python",
+          "Intended Audience :: Developers", "Programming Language :: Python",
           "Programming Language :: Python :: 3.6",
           "Programming Language :: Python :: 3.7"
       ],

From a97579e9fc6709726d475dd2ebdc41ac0c703191 Mon Sep 17 00:00:00 2001
From: Michael Demoret <mdemoret@nvidia.com>
Date: Wed, 5 Aug 2020 13:45:35 -0600
Subject: [PATCH 04/13] Reverting clean changes back to original

---
 python/setup.py | 89 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 27 deletions(-)

diff --git a/python/setup.py b/python/setup.py
index da2ac0084d..017b4f3b49 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -67,6 +67,41 @@
 cuda_include_dir = os.path.join(cuda_home, "include")
 cuda_lib_dir = os.path.join(cuda_home, "lib64")
 
+##############################################################################
+# - Clean target -------------------------------------------------------------
+
+if clean_artifacts:
+    print("-- Cleaning all Python and Cython build artifacts...")
+
+    treelite_path = ""
+    libcuml_path = ""
+
+    try:
+        setup_file_path = str(Path(__file__).parent.absolute())
+        shutil.rmtree(setup_file_path + '/.pytest_cache', ignore_errors=True)
+        shutil.rmtree(setup_file_path + '/_external_repositories',
+                      ignore_errors=True)
+        shutil.rmtree(setup_file_path + '/cuml.egg-info', ignore_errors=True)
+        shutil.rmtree(setup_file_path + '/__pycache__', ignore_errors=True)
+
+        os.remove(setup_file_path + '/cuml/raft')
+
+        clean_folder(setup_file_path + '/cuml')
+        shutil.rmtree(setup_file_path + '/build')
+
+    except IOError:
+        pass
+
+    # need to terminate script so cythonizing doesn't get triggered after
+    # cleanup unintendedly
+    sys.argv.remove("clean")
+
+    if "--all" in sys.argv:
+        sys.argv.remove("--all")
+
+    if len(sys.argv) == 1:
+        sys.exit(0)
+
 ##############################################################################
 # - Cloning RAFT and dependencies if needed ----------------------------------
 
@@ -84,41 +119,41 @@
     libcuml_path = '../cpp/build/'
 
 ##############################################################################
-# - Clean target -------------------------------------------------------------
-# This derives from distutils clean to so we can use the derived values of
-# 'build' and the base clean implementation
+# # - Clean target -------------------------------------------------------------
+# # This derives from distutils clean to so we can use the derived values of
+# # 'build' and the base clean implementation
 
 
-class cuml_clean(_clean):
-    def run(self):
+# class cuml_clean(_clean):
+#     def run(self):
 
-        global libcuml_path
+#         global libcuml_path
 
-        # Call the base first to get info from build
-        super().run()
+#         # Call the base first to get info from build
+#         super().run()
 
-        if (self.all):
-            # Reset libcuml_path
-            libcuml_path = ""
+#         if (self.all):
+#             # Reset libcuml_path
+#             libcuml_path = ""
 
-            try:
-                setup_file_path = str(Path(__file__).parent.absolute())
-                shutil.rmtree(os.path.join(setup_file_path, ".pytest_cache"),
-                              ignore_errors=True)
-                shutil.rmtree(os.path.join(setup_file_path,
-                                           '/_external_repositories'),
-                              ignore_errors=True)
-                shutil.rmtree(os.path.join(setup_file_path, '/cuml.egg-info'),
-                              ignore_errors=True)
-                shutil.rmtree(os.path.join(setup_file_path, '/__pycache__'),
-                              ignore_errors=True)
+#             try:
+#                 setup_file_path = str(Path(__file__).parent.absolute())
+#                 shutil.rmtree(os.path.join(setup_file_path, ".pytest_cache"),
+#                               ignore_errors=True)
+#                 shutil.rmtree(os.path.join(setup_file_path,
+#                                            '/_external_repositories'),
+#                               ignore_errors=True)
+#                 shutil.rmtree(os.path.join(setup_file_path, '/cuml.egg-info'),
+#                               ignore_errors=True)
+#                 shutil.rmtree(os.path.join(setup_file_path, '/__pycache__'),
+#                               ignore_errors=True)
 
-                os.remove(setup_file_path + '/cuml/raft')
+#                 os.remove(setup_file_path + '/cuml/raft')
 
-                clean_folder(setup_file_path + '/cuml')
+#                 clean_folder(setup_file_path + '/cuml')
 
-            except IOError:
-                pass
+#             except IOError:
+#                 pass
 
 
 ##############################################################################
@@ -238,7 +273,7 @@ def finalize_options(self):
 # Specify the custom build class
 cmdclass = dict()
 cmdclass.update(versioneer.get_cmdclass())
-cmdclass["clean"] = cuml_clean
+# cmdclass["clean"] = cuml_clean
 cmdclass["build"] = cuml_build
 cmdclass["build_ext"] = cuml_build_ext
 

From 4f32eb916ef1c3abf82eb29452712b7b5e9dbec4 Mon Sep 17 00:00:00 2001
From: Michael Demoret <mdemoret@nvidia.com>
Date: Wed, 5 Aug 2020 13:52:13 -0600
Subject: [PATCH 05/13] Fixing style issues

---
 python/setup.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/python/setup.py b/python/setup.py
index 017b4f3b49..57018d2068 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -27,7 +27,7 @@
 from setuptools import setup
 from setuptools.extension import Extension
 from distutils.sysconfig import get_python_lib
-from distutils.command.clean import clean as _clean
+# from distutils.command.clean import clean as _clean
 from distutils.command.build import build as _build
 
 import numpy
@@ -118,10 +118,10 @@
 if not libcuml_path:
     libcuml_path = '../cpp/build/'
 
-##############################################################################
-# # - Clean target -------------------------------------------------------------
-# # This derives from distutils clean to so we can use the derived values of
-# # 'build' and the base clean implementation
+#############################################################################
+# - Clean target -------------------------------------------------------------
+# This derives from distutils clean to so we can use the derived values of
+# 'build' and the base clean implementation
 
 
 # class cuml_clean(_clean):
@@ -143,7 +143,7 @@
 #                 shutil.rmtree(os.path.join(setup_file_path,
 #                                            '/_external_repositories'),
 #                               ignore_errors=True)
-#                 shutil.rmtree(os.path.join(setup_file_path, '/cuml.egg-info'),
+#                shutil.rmtree(os.path.join(setup_file_path, '/cuml.egg-info'),
 #                               ignore_errors=True)
 #                 shutil.rmtree(os.path.join(setup_file_path, '/__pycache__'),
 #                               ignore_errors=True)

From d2a97d2349eeeb680982e26c8ae8b14159855470 Mon Sep 17 00:00:00 2001
From: Michael Demoret <mdemoret@nvidia.com>
Date: Wed, 5 Aug 2020 13:55:07 -0600
Subject: [PATCH 06/13] Adding debug code for when raft is not found and must
 be cloned

---
 python/setuputils.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/python/setuputils.py b/python/setuputils.py
index a4d2094e43..a236fd28f8 100644
--- a/python/setuputils.py
+++ b/python/setuputils.py
@@ -186,7 +186,8 @@ def get_submodule_dependency(repo,
         print("-- Third party repositories have not been found so they " +
               "will be cloned. To avoid this set the environment " +
               "variable CUML_BUILD_PATH, containing the absolute " +
-              "path to the build folder where libcuml++ was built.")
+              "path to the build folder where libcuml++ was built. " +
+              "cpp_build_path: {}".format(cpp_build_path))
 
         for repo in repos:
             clone_repo(repo, repo_info[repo][0], repo_info[repo][1])

From 916bda854d8c7b80a2d307ed4561cb5f1771b141 Mon Sep 17 00:00:00 2001
From: Michael Demoret <mdemoret@nvidia.com>
Date: Wed, 5 Aug 2020 16:23:20 -0600
Subject: [PATCH 07/13] Reverting the clean command and cleaning up the
 comments to add insight.

---
 python/setup.py      | 83 ++++++++++++++++----------------------------
 python/setuputils.py |  3 +-
 2 files changed, 31 insertions(+), 55 deletions(-)

diff --git a/python/setup.py b/python/setup.py
index 57018d2068..7082ab9655 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -27,7 +27,6 @@
 from setuptools import setup
 from setuptools.extension import Extension
 from distutils.sysconfig import get_python_lib
-# from distutils.command.clean import clean as _clean
 from distutils.command.build import build as _build
 
 import numpy
@@ -45,8 +44,6 @@
 ##############################################################################
 # - Print of build options used by setup.py  --------------------------------
 
-global libcuml_path
-
 cuda_home = get_environment_option("CUDA_HOME")
 libcuml_path = get_environment_option('CUML_BUILD_PATH')
 raft_path = get_environment_option('RAFT_PATH')
@@ -73,8 +70,9 @@
 if clean_artifacts:
     print("-- Cleaning all Python and Cython build artifacts...")
 
-    treelite_path = ""
-    libcuml_path = ""
+    # Reset these paths since they may be deleted below
+    treelite_path = False
+    libcuml_path = False
 
     try:
         setup_file_path = str(Path(__file__).parent.absolute())
@@ -118,47 +116,25 @@
 if not libcuml_path:
     libcuml_path = '../cpp/build/'
 
-#############################################################################
-# - Clean target -------------------------------------------------------------
-# This derives from distutils clean to so we can use the derived values of
-# 'build' and the base clean implementation
-
-
-# class cuml_clean(_clean):
-#     def run(self):
-
-#         global libcuml_path
-
-#         # Call the base first to get info from build
-#         super().run()
-
-#         if (self.all):
-#             # Reset libcuml_path
-#             libcuml_path = ""
-
-#             try:
-#                 setup_file_path = str(Path(__file__).parent.absolute())
-#                 shutil.rmtree(os.path.join(setup_file_path, ".pytest_cache"),
-#                               ignore_errors=True)
-#                 shutil.rmtree(os.path.join(setup_file_path,
-#                                            '/_external_repositories'),
-#                               ignore_errors=True)
-#                shutil.rmtree(os.path.join(setup_file_path, '/cuml.egg-info'),
-#                               ignore_errors=True)
-#                 shutil.rmtree(os.path.join(setup_file_path, '/__pycache__'),
-#                               ignore_errors=True)
-
-#                 os.remove(setup_file_path + '/cuml/raft')
-
-#                 clean_folder(setup_file_path + '/cuml')
-
-#             except IOError:
-#                 pass
-
-
 ##############################################################################
 # - Cython extensions build and parameters -----------------------------------
-# Derive from `cython_build_ext` to add --singlegpu customization
+#
+# We create custom build steps for both `build` and `build_ext` for several
+#   reasons:
+# 1) Custom `build_ext` is needed to set `cython_build_ext.cython_exclude` when
+#    `--singlegpu=True`
+# 2) Custom `build` is needed to exclude pacakges and directories when
+#    `--singlegpu=True`
+# 3) These cannot be combined because `build` is used by both `build_ext` and
+#    `install` commands and it would be difficult to set
+#    `cython_build_ext.cython_exclude` from `cuml_build` since the property
+#    exists on a different command.
+#
+# Using custom commands also allows combining commands at the command line. For
+# example, the following will all work as expected: `python setup.py clean
+# --all build --singlegpu build_ext --inplace` `python setup.py clean --all
+# build --singlegpu install --record=record.txt` `python setup.py build_ext
+# --debug --singlegpu`
 
 
 class cuml_build(_build):
@@ -177,16 +153,18 @@ def initialize_options(self):
 
     def finalize_options(self):
 
-        global libcuml_path
-
         # cumlcomms and nccl are still needed for multigpu algos not based
         # on libcumlprims
         libs = ['cuda', 'cuml++', 'rmm']
 
         include_dirs = [
-            '../cpp/src', '../cpp/include', '../cpp/src_prims',
-            raft_include_dir, '../cpp/comms/std/src',
-            '../cpp/comms/std/include', cuda_include_dir,
+            '../cpp/src',
+            '../cpp/include',
+            '../cpp/src_prims',
+            raft_include_dir,
+            '../cpp/comms/std/src',
+            '../cpp/comms/std/include',
+            cuda_include_dir,
             numpy.get_include(),
             os.path.dirname(sysconfig.get_path("include"))
         ]
@@ -216,8 +194,7 @@ def finalize_options(self):
                       include_dirs=include_dirs,
                       library_dirs=[get_python_lib(), libcuml_path],
                       runtime_library_dirs=[
-                          cuda_lib_dir,
-                          os.path.join(os.sys.prefix, "lib")
+                          cuda_lib_dir, os.path.join(os.sys.prefix, "lib")
                       ],
                       libraries=libs,
                       language='c++',
@@ -273,7 +250,6 @@ def finalize_options(self):
 # Specify the custom build class
 cmdclass = dict()
 cmdclass.update(versioneer.get_cmdclass())
-# cmdclass["clean"] = cuml_clean
 cmdclass["build"] = cuml_build
 cmdclass["build_ext"] = cuml_build_ext
 
@@ -284,7 +260,8 @@ def finalize_options(self):
       description="cuML - RAPIDS ML Algorithms",
       version=versioneer.get_version(),
       classifiers=[
-          "Intended Audience :: Developers", "Programming Language :: Python",
+          "Intended Audience :: Developers",
+          "Programming Language :: Python",
           "Programming Language :: Python :: 3.6",
           "Programming Language :: Python :: 3.7"
       ],
diff --git a/python/setuputils.py b/python/setuputils.py
index a236fd28f8..64e14dd9d2 100644
--- a/python/setuputils.py
+++ b/python/setuputils.py
@@ -186,8 +186,7 @@ def get_submodule_dependency(repo,
         print("-- Third party repositories have not been found so they " +
               "will be cloned. To avoid this set the environment " +
               "variable CUML_BUILD_PATH, containing the absolute " +
-              "path to the build folder where libcuml++ was built. " +
-              "cpp_build_path: {}".format(cpp_build_path))
+              "path to the build folder where libcuml++ was built. ")
 
         for repo in repos:
             clone_repo(repo, repo_info[repo][0], repo_info[repo][1])

From b475baebe4cf3e8db882d19e63bdafb708f18a07 Mon Sep 17 00:00:00 2001
From: Michael Demoret <mdemoret@nvidia.com>
Date: Wed, 26 Aug 2020 15:11:08 -0600
Subject: [PATCH 08/13] Updating build.sh since --inplace is set in setup.cfg
 now

---
 build.sh        |  5 ++---
 python/setup.py | 10 +++++-----
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/build.sh b/build.sh
index d561f6d328..f961c1f9e6 100755
--- a/build.sh
+++ b/build.sh
@@ -226,10 +226,9 @@ fi
 if completeBuild || hasArg cuml || hasArg pydocs; then
     cd ${REPODIR}/python
     if [[ ${INSTALL_TARGET} != "" ]]; then
-        python setup.py build_ext -j${PARALLEL_LEVEL:-1} --inplace ${SINGLEGPU_PYTHON_FLAG}
-        python setup.py install --single-version-externally-managed --record=record.txt ${SINGLEGPU_PYTHON_FLAG}
+        python setup.py build_ext -j${PARALLEL_LEVEL:-1} ${SINGLEGPU_PYTHON_FLAG} install --single-version-externally-managed --record=record.txt
     else
-        python setup.py build_ext -j${PARALLEL_LEVEL:-1} --inplace --library-dir=${LIBCUML_BUILD_DIR} ${SINGLEGPU_PYTHON_FLAG}
+        python setup.py build_ext -j${PARALLEL_LEVEL:-1} --library-dir=${LIBCUML_BUILD_DIR} ${SINGLEGPU_PYTHON_FLAG}
     fi
 
     if hasArg pydocs; then
diff --git a/python/setup.py b/python/setup.py
index 2963564533..fb9ba1e8da 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -131,10 +131,10 @@
 #    exists on a different command.
 #
 # Using custom commands also allows combining commands at the command line. For
-# example, the following will all work as expected: `python setup.py clean
-# --all build --singlegpu build_ext --inplace` `python setup.py clean --all
-# build --singlegpu install --record=record.txt` `python setup.py build_ext
-# --debug --singlegpu`
+# example, the following will all work as expected:
+# `python setup.py clean --all build --singlegpu build_ext --inplace`
+# `python setup.py clean --all build --singlegpu install --record=record.txt`
+# `python setup.py build_ext --debug --singlegpu`
 
 
 class cuml_build(_build):
@@ -198,7 +198,7 @@ def finalize_options(self):
                       ],
                       libraries=libs,
                       language='c++',
-              extra_compile_args=['-std=c++14'])
+                      extra_compile_args=['-std=c++14'])
         ]
 
         self.distribution.ext_modules = extensions

From 44cd3cbbbe47510b17b08c16408f531048eb4aee Mon Sep 17 00:00:00 2001
From: Michael Demoret <42954918+mdemoret-nv@users.noreply.github.com>
Date: Wed, 26 Aug 2020 16:21:23 -0600
Subject: [PATCH 09/13] Moving the CHANGELOG PR from 0.15 to 0.16

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3f274b9d5b..9338b738ab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 # cuML 0.16.0 (Date TBD)
 
 ## New Features
+- PR #2638: Improve cython build with custom `build_ext`
 
 ## Improvements
 - PR #2735: Update seed to random_state in random forest and associated tests
@@ -44,7 +45,6 @@
 - PR #2661: CUDA-11 support for single-gpu code
 - PR #2322: Sparse FIL forests with 8-byte nodes
 - PR #2675: Update conda recipes to support CUDA 11
-- PR #2638: Improve cython build with custom `build_ext`
 
 ## Improvements
 - PR #2336: Eliminate `rmm.device_array` usage

From 6574dd4049cbb1724074f9d84ff21e4471e3ab52 Mon Sep 17 00:00:00 2001
From: Michael Demoret <42954918+mdemoret-nv@users.noreply.github.com>
Date: Wed, 2 Sep 2020 15:31:07 -0600
Subject: [PATCH 10/13] Adding more documentation and comments based on PR
 feedback. Also added the `gdb_debug` option for future debugging capability
 (untested).

---
 python/cython_build_ext.py | 95 +++++++++++++++++++++++++++++++++++---
 python/setup.py            |  8 +---
 2 files changed, 91 insertions(+), 12 deletions(-)

diff --git a/python/cython_build_ext.py b/python/cython_build_ext.py
index b41c8f0755..8abb02210f 100644
--- a/python/cython_build_ext.py
+++ b/python/cython_build_ext.py
@@ -1,3 +1,19 @@
+#
+# Copyright (c) 2018-2020, NVIDIA CORPORATION.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
 import sys
 
 # TODO: It should be possible to support Cython-less distribution following
@@ -19,28 +35,91 @@
 
 
 class cython_build_ext(_build_ext, object):
+    """
+    This class follows the design of `Cython.Distutils.build_ext.new_build_ext`
+    to allow for parallel `cythonize()` but adds options for the various
+    arguments that can be passed to `cythonize()` including separate options
+    for `compiler_directives`. This build extension can be directly used in
+    place of `new_build_ext` for any Cython project that needs to set global
+    parameters in the build phase. See the documentation for more information
+    on the `cythonize()` arguments.
+
+    Parameters
+    ----------
+    language_level : {"2", "3", "3str"}, default="2"
+        Globally set the Python language level to be used for module
+        compilation. Default is compatibility with Python 2. To enable Python 3
+        source code semantics, set this to 3 (or 3str)
+    binding : bool, default=True
+        Controls whether free functions behave more like Python’s CFunctions
+        (e.g. len()) or, when set to True, more like Python’s functions. When
+        enabled, functions will bind to an instance when looked up as a class
+        attribute (hence the name) and will emulate the attributes of Python
+        functions, including introspections like argument names and
+        annotations.
+
+        Changed in version 3.0.0: Default changed from False to True
+    profile : bool, default=False
+        Write hooks for Python profilers into the compiled C code.
+    embedsignature : bool, default=False
+        If set to True, Cython will embed a textual copy of the call signature
+        in the docstring of all Python visible functions and classes. Tools
+        like IPython and epydoc can thus display the signature, which cannot
+        otherwise be retrieved after compilation.
+    cython_exclude : list of str
+        When passing glob patterns as module_list, you can exclude certain
+        module names explicitly by passing them into the exclude option.
+    gdb_debug : bool, default=False
+        Passes the `gdb_debug` argument to `cythonize()`. Setting up debugging
+        for Cython can be difficult. See the debugging docs here
+        https://cython.readthedocs.io/en/latest/src/userguide/debugging.html
+    """
     user_options = [
         ('language-level=', None,
          'Sets the python language syntax to use "2", "3", "3str".'),
-        ("binding", None, "Sets the binding Cython binding directive"),
-        ("profile", None, "Sets the profile Cython binding directive"),
-        ("embedsignature", None, "Sets the binding Cython binding directive"),
-        ("cython-exclude=", None, "Sets the binding Cython binding directive")
+        ("binding", None,
+         "Sets the binding Cython compiler directive. See the Cython docs for "
+         "more info."),
+        ("profile", None,
+         "Sets the profile Cython compiler directive. See the Cython docs for "
+         "more info."),
+        ("embedsignature", None,
+         "Sets the `embedsignature` Cython compiler directive. See the Cython "
+         "docs for more info."),
+        ("cython-exclude=", None,
+         "Sets the exclude argument for `cythonize()`. See the Cython docs for"
+         " more info."),
+        ("gdb-debug=", None,
+         "Passes the `gdb_debug` argument to `cythonize()`. See the Cython "
+         "docs for more info.")
     ] + _build_ext.user_options
 
-    boolean_options = ["binding", "profile", "embedsignature"
-                       ] + _build_ext.boolean_options
+    boolean_options = [
+        "binding",
+        "profile",
+        "embedsignature",
+        "gdb-debug",
+    ] + _build_ext.boolean_options
 
     def initialize_options(self):
+        """
+        Set the default values for the `user_options` to None to allow us to
+        detect if they were set by the user
+        """
 
         self.language_level = None
         self.binding = None
         self.profile = None
         self.embedsignature = None
         self.cython_exclude = None
+        self.gdb_debug = None
         super().initialize_options()
 
     def finalize_options(self):
+        """
+        Determines any user defined options and finalizes the Cython
+        configuration before compilation
+        """
 
         # Ensure the base build class options get set so we can use parallel
         self.set_undefined_options(
@@ -88,6 +167,10 @@ def finalize_options(self):
 
                 cythonize_kwargs.update({"exclude": self.cython_exclude})
 
+            if (self.gdb_debug is not None):
+
+                cythonize_kwargs.update({"gdb_debug": self.gdb_debug})
+
             # Handle nthreads separately to mimic what Cython does
             nthreads = getattr(self, 'parallel', None)  # -j option in Py3.5+
             nthreads = int(nthreads) if nthreads else None
diff --git a/python/setup.py b/python/setup.py
index fb9ba1e8da..6dc503792c 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -153,8 +153,6 @@ def initialize_options(self):
 
     def finalize_options(self):
 
-        # cumlcomms and nccl are still needed for multigpu algos not based
-        # on libcumlprims
         libs = ['cuda', 'cuml++', 'rmm']
 
         include_dirs = [
@@ -169,8 +167,6 @@ def finalize_options(self):
             os.path.dirname(sysconfig.get_path("include"))
         ]
 
-        # Exclude multigpu components that use libcumlprims if
-        # --singlegpu is used
         python_exc_list = []
 
         if (self.singlegpu):
@@ -262,8 +258,8 @@ def finalize_options(self):
       classifiers=[
           "Intended Audience :: Developers",
           "Programming Language :: Python",
-          "Programming Language :: Python :: 3.6",
-          "Programming Language :: Python :: 3.7"
+          "Programming Language :: Python :: 3.7",
+          "Programming Language :: Python :: 3.8"
       ],
       author="NVIDIA Corporation",
       setup_requires=['cython'],

From a62815d116f689d7645d8022ec0cce5247b55ee0 Mon Sep 17 00:00:00 2001
From: Michael Demoret <42954918+mdemoret-nv@users.noreply.github.com>
Date: Wed, 2 Sep 2020 16:23:46 -0600
Subject: [PATCH 11/13] Removing the compiler directives from each file since
 its set globally in setup.cfg

---
 python/cuml/cluster/dbscan.pyx                      | 3 ---
 python/cuml/cluster/kmeans.pyx                      | 3 ---
 python/cuml/cluster/kmeans_mg.pyx                   | 3 ---
 python/cuml/common/base.pyx                         | 3 ---
 python/cuml/common/cuda.pyx                         | 3 ---
 python/cuml/common/handle.pyx                       | 3 ---
 python/cuml/common/logger.pyx                       | 3 ---
 python/cuml/common/pointer_utils.pyx                | 3 ---
 python/cuml/dask/common/comms_utils.pyx             | 3 ---
 python/cuml/datasets/arima.pyx                      | 3 ---
 python/cuml/datasets/regression.pyx                 | 3 ---
 python/cuml/decomposition/base_mg.pyx               | 3 ---
 python/cuml/decomposition/pca.pyx                   | 3 ---
 python/cuml/decomposition/pca_mg.pyx                | 3 ---
 python/cuml/decomposition/tsvd.pyx                  | 3 ---
 python/cuml/decomposition/tsvd_mg.pyx               | 3 ---
 python/cuml/ensemble/randomforest_shared.pyx        | 3 ---
 python/cuml/ensemble/randomforestclassifier.pyx     | 3 ---
 python/cuml/ensemble/randomforestregressor.pyx      | 3 ---
 python/cuml/fil/fil.pyx                             | 3 ---
 python/cuml/internals/internals.pyx                 | 3 ---
 python/cuml/linear_model/base_mg.pyx                | 3 ---
 python/cuml/linear_model/elastic_net.pyx            | 3 ---
 python/cuml/linear_model/lasso.pyx                  | 3 ---
 python/cuml/linear_model/linear_regression.pyx      | 3 ---
 python/cuml/linear_model/linear_regression_mg.pyx   | 3 ---
 python/cuml/linear_model/logistic_regression.pyx    | 3 ---
 python/cuml/linear_model/mbsgd_classifier.pyx       | 3 ---
 python/cuml/linear_model/mbsgd_regressor.pyx        | 3 ---
 python/cuml/linear_model/ridge.pyx                  | 3 ---
 python/cuml/linear_model/ridge_mg.pyx               | 3 ---
 python/cuml/manifold/t_sne.pyx                      | 5 ++---
 python/cuml/manifold/umap.pyx                       | 3 ---
 python/cuml/metrics/accuracy.pyx                    | 3 ---
 python/cuml/metrics/cluster/adjustedrandindex.pyx   | 3 ---
 python/cuml/metrics/cluster/completeness_score.pyx  | 3 ---
 python/cuml/metrics/cluster/entropy.pyx             | 3 ---
 python/cuml/metrics/cluster/homogeneity_score.pyx   | 3 ---
 python/cuml/metrics/cluster/mutual_info_score.pyx   | 3 ---
 python/cuml/metrics/cluster/utils.pyx               | 3 ---
 python/cuml/metrics/pairwise_distances.pyx          | 3 ---
 python/cuml/metrics/regression.pyx                  | 3 ---
 python/cuml/metrics/trustworthiness.pyx             | 3 ---
 python/cuml/nccl/nccl.pyx                           | 3 ---
 python/cuml/neighbors/kneighbors_classifier.pyx     | 3 ---
 python/cuml/neighbors/kneighbors_classifier_mg.pyx  | 3 ---
 python/cuml/neighbors/kneighbors_mg.pyx             | 3 ---
 python/cuml/neighbors/kneighbors_regressor.pyx      | 3 ---
 python/cuml/neighbors/kneighbors_regressor_mg.pyx   | 3 ---
 python/cuml/neighbors/nearest_neighbors.pyx         | 3 ---
 python/cuml/neighbors/nearest_neighbors_mg.pyx      | 3 ---
 python/cuml/random_projection/random_projection.pyx | 3 ---
 python/cuml/solvers/cd.pyx                          | 3 ---
 python/cuml/solvers/cd_mg.pyx                       | 3 ---
 python/cuml/solvers/qn.pyx                          | 3 ---
 python/cuml/solvers/sgd.pyx                         | 3 ---
 python/cuml/svm/svc.pyx                             | 3 ---
 python/cuml/svm/svm_base.pyx                        | 3 ---
 python/cuml/svm/svr.pyx                             | 3 ---
 python/cuml/tsa/arima.pyx                           | 3 ---
 python/cuml/tsa/auto_arima.pyx                      | 3 ---
 python/cuml/tsa/holtwinters.pyx                     | 3 ---
 python/cuml/tsa/seasonality.pyx                     | 3 ---
 python/cuml/tsa/stationarity.pyx                    | 3 ---
 64 files changed, 2 insertions(+), 192 deletions(-)

diff --git a/python/cuml/cluster/dbscan.pyx b/python/cuml/cluster/dbscan.pyx
index dca5f98352..58f2fbcf7e 100644
--- a/python/cuml/cluster/dbscan.pyx
+++ b/python/cuml/cluster/dbscan.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/cluster/kmeans.pyx b/python/cuml/cluster/kmeans.pyx
index e85475f052..c44d9bb4e4 100644
--- a/python/cuml/cluster/kmeans.pyx
+++ b/python/cuml/cluster/kmeans.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/cluster/kmeans_mg.pyx b/python/cuml/cluster/kmeans_mg.pyx
index 4374fa36a9..78017358e9 100644
--- a/python/cuml/cluster/kmeans_mg.pyx
+++ b/python/cuml/cluster/kmeans_mg.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/common/base.pyx b/python/cuml/common/base.pyx
index b8a6e8ff32..e3f44053c2 100644
--- a/python/cuml/common/base.pyx
+++ b/python/cuml/common/base.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cuml
 import cuml.common.cuda
diff --git a/python/cuml/common/cuda.pyx b/python/cuml/common/cuda.pyx
index 13ec55f481..c99e697568 100644
--- a/python/cuml/common/cuda.pyx
+++ b/python/cuml/common/cuda.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import functools
 from libcpp.string cimport string
diff --git a/python/cuml/common/handle.pyx b/python/cuml/common/handle.pyx
index 1682cb2b2a..f7c2ca1854 100644
--- a/python/cuml/common/handle.pyx
+++ b/python/cuml/common/handle.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 
 import cuml
diff --git a/python/cuml/common/logger.pyx b/python/cuml/common/logger.pyx
index 63f0d085e4..bf8a6b52d9 100644
--- a/python/cuml/common/logger.pyx
+++ b/python/cuml/common/logger.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 
 from libcpp.string cimport string
diff --git a/python/cuml/common/pointer_utils.pyx b/python/cuml/common/pointer_utils.pyx
index 3a28e53de7..c3c61cdd4c 100644
--- a/python/cuml/common/pointer_utils.pyx
+++ b/python/cuml/common/pointer_utils.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from libc.stdint cimport uintptr_t
 
diff --git a/python/cuml/dask/common/comms_utils.pyx b/python/cuml/dask/common/comms_utils.pyx
index a8a89b093e..30587af76a 100644
--- a/python/cuml/dask/common/comms_utils.pyx
+++ b/python/cuml/dask/common/comms_utils.pyx
@@ -12,10 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from libc.stdlib cimport malloc, free
 from cython.operator cimport dereference as deref
diff --git a/python/cuml/datasets/arima.pyx b/python/cuml/datasets/arima.pyx
index a59a02155f..66e43628ba 100644
--- a/python/cuml/datasets/arima.pyx
+++ b/python/cuml/datasets/arima.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cuml
 import numpy as np
diff --git a/python/cuml/datasets/regression.pyx b/python/cuml/datasets/regression.pyx
index b2c929fffc..0c9e241567 100644
--- a/python/cuml/datasets/regression.pyx
+++ b/python/cuml/datasets/regression.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cuml
 import numpy as np
diff --git a/python/cuml/decomposition/base_mg.pyx b/python/cuml/decomposition/base_mg.pyx
index 2f8bf7bc15..76d43a6ff0 100644
--- a/python/cuml/decomposition/base_mg.pyx
+++ b/python/cuml/decomposition/base_mg.pyx
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 
 import ctypes
diff --git a/python/cuml/decomposition/pca.pyx b/python/cuml/decomposition/pca.pyx
index 52ab2c62a7..3ef8c60a8d 100644
--- a/python/cuml/decomposition/pca.pyx
+++ b/python/cuml/decomposition/pca.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/decomposition/pca_mg.pyx b/python/cuml/decomposition/pca_mg.pyx
index f25c503bd8..efa5d2e795 100644
--- a/python/cuml/decomposition/pca_mg.pyx
+++ b/python/cuml/decomposition/pca_mg.pyx
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 
 import ctypes
diff --git a/python/cuml/decomposition/tsvd.pyx b/python/cuml/decomposition/tsvd.pyx
index c39c78ea59..4448652c32 100644
--- a/python/cuml/decomposition/tsvd.pyx
+++ b/python/cuml/decomposition/tsvd.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/decomposition/tsvd_mg.pyx b/python/cuml/decomposition/tsvd_mg.pyx
index c80957e2ef..a225cdf670 100644
--- a/python/cuml/decomposition/tsvd_mg.pyx
+++ b/python/cuml/decomposition/tsvd_mg.pyx
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/ensemble/randomforest_shared.pyx b/python/cuml/ensemble/randomforest_shared.pyx
index c8fe539f59..b58b2a442f 100644
--- a/python/cuml/ensemble/randomforest_shared.pyx
+++ b/python/cuml/ensemble/randomforest_shared.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from libcpp.vector cimport vector
 from cython.operator cimport dereference as deref, preincrement as inc
diff --git a/python/cuml/ensemble/randomforestclassifier.pyx b/python/cuml/ensemble/randomforestclassifier.pyx
index bc47ac8bbd..c566adff34 100644
--- a/python/cuml/ensemble/randomforestclassifier.pyx
+++ b/python/cuml/ensemble/randomforestclassifier.pyx
@@ -15,10 +15,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 import rmm
diff --git a/python/cuml/ensemble/randomforestregressor.pyx b/python/cuml/ensemble/randomforestregressor.pyx
index 9d3a496b9e..38ab53ef21 100644
--- a/python/cuml/ensemble/randomforestregressor.pyx
+++ b/python/cuml/ensemble/randomforestregressor.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 import rmm
diff --git a/python/cuml/fil/fil.pyx b/python/cuml/fil/fil.pyx
index 94fee82b40..5318586624 100644
--- a/python/cuml/fil/fil.pyx
+++ b/python/cuml/fil/fil.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import copy
 import cudf
diff --git a/python/cuml/internals/internals.pyx b/python/cuml/internals/internals.pyx
index 1f07625cb9..784ecf6844 100644
--- a/python/cuml/internals/internals.pyx
+++ b/python/cuml/internals/internals.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 
 from libc.stdint cimport uintptr_t
diff --git a/python/cuml/linear_model/base_mg.pyx b/python/cuml/linear_model/base_mg.pyx
index eb8f751556..bf76bd1d08 100644
--- a/python/cuml/linear_model/base_mg.pyx
+++ b/python/cuml/linear_model/base_mg.pyx
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 
 import ctypes
diff --git a/python/cuml/linear_model/elastic_net.pyx b/python/cuml/linear_model/elastic_net.pyx
index f4f42c021b..8f35367265 100644
--- a/python/cuml/linear_model/elastic_net.pyx
+++ b/python/cuml/linear_model/elastic_net.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.solvers import CD
 from cuml.common.base import Base, RegressorMixin
diff --git a/python/cuml/linear_model/lasso.pyx b/python/cuml/linear_model/lasso.pyx
index 12afee5597..6b0f368748 100644
--- a/python/cuml/linear_model/lasso.pyx
+++ b/python/cuml/linear_model/lasso.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.solvers import CD
 from cuml.common.base import Base, RegressorMixin
diff --git a/python/cuml/linear_model/linear_regression.pyx b/python/cuml/linear_model/linear_regression.pyx
index b6fb239f65..d50a4da146 100644
--- a/python/cuml/linear_model/linear_regression.pyx
+++ b/python/cuml/linear_model/linear_regression.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/linear_model/linear_regression_mg.pyx b/python/cuml/linear_model/linear_regression_mg.pyx
index 9c56a9f395..eae387df23 100644
--- a/python/cuml/linear_model/linear_regression_mg.pyx
+++ b/python/cuml/linear_model/linear_regression_mg.pyx
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/linear_model/logistic_regression.pyx b/python/cuml/linear_model/logistic_regression.pyx
index 876b22367b..92b8070d9f 100644
--- a/python/cuml/linear_model/logistic_regression.pyx
+++ b/python/cuml/linear_model/logistic_regression.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cupy as cp
 import pprint
diff --git a/python/cuml/linear_model/mbsgd_classifier.pyx b/python/cuml/linear_model/mbsgd_classifier.pyx
index c2364563df..6aa8380d7f 100644
--- a/python/cuml/linear_model/mbsgd_classifier.pyx
+++ b/python/cuml/linear_model/mbsgd_classifier.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 from cuml.common.base import Base, ClassifierMixin
 from cuml.common.doc_utils import generate_docstring
 from cuml.solvers import SGD
diff --git a/python/cuml/linear_model/mbsgd_regressor.pyx b/python/cuml/linear_model/mbsgd_regressor.pyx
index faa2c602fb..dd213b0d62 100644
--- a/python/cuml/linear_model/mbsgd_regressor.pyx
+++ b/python/cuml/linear_model/mbsgd_regressor.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 from cuml.common.base import Base, RegressorMixin
 from cuml.common.doc_utils import generate_docstring
 from cuml.solvers import SGD
diff --git a/python/cuml/linear_model/ridge.pyx b/python/cuml/linear_model/ridge.pyx
index 0a45377307..1a1a41dd98 100644
--- a/python/cuml/linear_model/ridge.pyx
+++ b/python/cuml/linear_model/ridge.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/linear_model/ridge_mg.pyx b/python/cuml/linear_model/ridge_mg.pyx
index 7551cb7e3e..13ee0cee35 100644
--- a/python/cuml/linear_model/ridge_mg.pyx
+++ b/python/cuml/linear_model/ridge_mg.pyx
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/manifold/t_sne.pyx b/python/cuml/manifold/t_sne.pyx
index 8d09ab70c0..05bc0a2978 100644
--- a/python/cuml/manifold/t_sne.pyx
+++ b/python/cuml/manifold/t_sne.pyx
@@ -14,11 +14,10 @@
 # limitations under the License.
 #
 
-# cython: profile = False
 # distutils: language = c++
 # distutils: extra_compile_args = -Ofast
-# cython: embedsignature = True, language_level = 3
-# cython: boundscheck = False, wraparound = False
+# cython: boundscheck = False
+# cython: wraparound = False
 
 import cudf
 import cuml
diff --git a/python/cuml/manifold/umap.pyx b/python/cuml/manifold/umap.pyx
index 32b440c64d..89a89402e2 100644
--- a/python/cuml/manifold/umap.pyx
+++ b/python/cuml/manifold/umap.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cudf
 import cuml
diff --git a/python/cuml/metrics/accuracy.pyx b/python/cuml/metrics/accuracy.pyx
index 393a53c16d..5c1350f77f 100644
--- a/python/cuml/metrics/accuracy.pyx
+++ b/python/cuml/metrics/accuracy.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 
diff --git a/python/cuml/metrics/cluster/adjustedrandindex.pyx b/python/cuml/metrics/cluster/adjustedrandindex.pyx
index cf2b4307c5..2e0e2a2bce 100644
--- a/python/cuml/metrics/cluster/adjustedrandindex.pyx
+++ b/python/cuml/metrics/cluster/adjustedrandindex.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cupy as cp
 import warnings
diff --git a/python/cuml/metrics/cluster/completeness_score.pyx b/python/cuml/metrics/cluster/completeness_score.pyx
index 2b317e69fd..9ed9abc06c 100644
--- a/python/cuml/metrics/cluster/completeness_score.pyx
+++ b/python/cuml/metrics/cluster/completeness_score.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.common.handle cimport cumlHandle
 from libc.stdint cimport uintptr_t
diff --git a/python/cuml/metrics/cluster/entropy.pyx b/python/cuml/metrics/cluster/entropy.pyx
index 085b800b81..c153f5d999 100644
--- a/python/cuml/metrics/cluster/entropy.pyx
+++ b/python/cuml/metrics/cluster/entropy.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 import math
 
 import numpy as np
diff --git a/python/cuml/metrics/cluster/homogeneity_score.pyx b/python/cuml/metrics/cluster/homogeneity_score.pyx
index a27bea0f33..9d8bb098c2 100644
--- a/python/cuml/metrics/cluster/homogeneity_score.pyx
+++ b/python/cuml/metrics/cluster/homogeneity_score.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.common.handle cimport cumlHandle
 from libc.stdint cimport uintptr_t
diff --git a/python/cuml/metrics/cluster/mutual_info_score.pyx b/python/cuml/metrics/cluster/mutual_info_score.pyx
index a8bc9e3020..52d6561522 100644
--- a/python/cuml/metrics/cluster/mutual_info_score.pyx
+++ b/python/cuml/metrics/cluster/mutual_info_score.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.common.handle cimport cumlHandle
 from libc.stdint cimport uintptr_t
diff --git a/python/cuml/metrics/cluster/utils.pyx b/python/cuml/metrics/cluster/utils.pyx
index 0b134e39be..da57c3058b 100644
--- a/python/cuml/metrics/cluster/utils.pyx
+++ b/python/cuml/metrics/cluster/utils.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 import cupy as cp
 from cuml.metrics.utils import sorted_unique_labels
 from cuml.prims.label import make_monotonic
diff --git a/python/cuml/metrics/pairwise_distances.pyx b/python/cuml/metrics/pairwise_distances.pyx
index 7c65171b79..b5b32e7929 100644
--- a/python/cuml/metrics/pairwise_distances.pyx
+++ b/python/cuml/metrics/pairwise_distances.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from libcpp cimport bool
 from libc.stdint cimport uintptr_t
diff --git a/python/cuml/metrics/regression.pyx b/python/cuml/metrics/regression.pyx
index 49ae63acf0..1f20c12705 100644
--- a/python/cuml/metrics/regression.pyx
+++ b/python/cuml/metrics/regression.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 import cupy as cp
diff --git a/python/cuml/metrics/trustworthiness.pyx b/python/cuml/metrics/trustworthiness.pyx
index 6ec5cc0da6..ae3b7d9582 100644
--- a/python/cuml/metrics/trustworthiness.pyx
+++ b/python/cuml/metrics/trustworthiness.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cudf
 import numpy as np
diff --git a/python/cuml/nccl/nccl.pyx b/python/cuml/nccl/nccl.pyx
index 3cfe67cb4d..2a368d46ae 100644
--- a/python/cuml/nccl/nccl.pyx
+++ b/python/cuml/nccl/nccl.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cuml.common.logger as logger
 
diff --git a/python/cuml/neighbors/kneighbors_classifier.pyx b/python/cuml/neighbors/kneighbors_classifier.pyx
index 5aef40ba09..53b7098e99 100644
--- a/python/cuml/neighbors/kneighbors_classifier.pyx
+++ b/python/cuml/neighbors/kneighbors_classifier.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.neighbors.nearest_neighbors import NearestNeighbors
 
diff --git a/python/cuml/neighbors/kneighbors_classifier_mg.pyx b/python/cuml/neighbors/kneighbors_classifier_mg.pyx
index 3a0147ebc2..e00ca5b594 100644
--- a/python/cuml/neighbors/kneighbors_classifier_mg.pyx
+++ b/python/cuml/neighbors/kneighbors_classifier_mg.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 
diff --git a/python/cuml/neighbors/kneighbors_mg.pyx b/python/cuml/neighbors/kneighbors_mg.pyx
index 1c57c608eb..51d72f2c76 100644
--- a/python/cuml/neighbors/kneighbors_mg.pyx
+++ b/python/cuml/neighbors/kneighbors_mg.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 
diff --git a/python/cuml/neighbors/kneighbors_regressor.pyx b/python/cuml/neighbors/kneighbors_regressor.pyx
index 3444510f45..eb17ea160f 100644
--- a/python/cuml/neighbors/kneighbors_regressor.pyx
+++ b/python/cuml/neighbors/kneighbors_regressor.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.neighbors.nearest_neighbors import NearestNeighbors
 
diff --git a/python/cuml/neighbors/kneighbors_regressor_mg.pyx b/python/cuml/neighbors/kneighbors_regressor_mg.pyx
index 1c63987626..39d34eb38b 100644
--- a/python/cuml/neighbors/kneighbors_regressor_mg.pyx
+++ b/python/cuml/neighbors/kneighbors_regressor_mg.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 
diff --git a/python/cuml/neighbors/nearest_neighbors.pyx b/python/cuml/neighbors/nearest_neighbors.pyx
index 75e017140f..c7bd62ee14 100644
--- a/python/cuml/neighbors/nearest_neighbors.pyx
+++ b/python/cuml/neighbors/nearest_neighbors.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 import cupy as cp
diff --git a/python/cuml/neighbors/nearest_neighbors_mg.pyx b/python/cuml/neighbors/nearest_neighbors_mg.pyx
index b3a43f5e2b..aee23eee8c 100644
--- a/python/cuml/neighbors/nearest_neighbors_mg.pyx
+++ b/python/cuml/neighbors/nearest_neighbors_mg.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.neighbors import NearestNeighbors
 
diff --git a/python/cuml/random_projection/random_projection.pyx b/python/cuml/random_projection/random_projection.pyx
index 00d71cf5cc..d1cf79cb63 100644
--- a/python/cuml/random_projection/random_projection.pyx
+++ b/python/cuml/random_projection/random_projection.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cudf
 import numpy as np
diff --git a/python/cuml/solvers/cd.pyx b/python/cuml/solvers/cd.pyx
index bdefa09fd4..eb9ea1d3d2 100644
--- a/python/cuml/solvers/cd.pyx
+++ b/python/cuml/solvers/cd.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/solvers/cd_mg.pyx b/python/cuml/solvers/cd_mg.pyx
index 4981cf0f1a..ed602ab477 100644
--- a/python/cuml/solvers/cd_mg.pyx
+++ b/python/cuml/solvers/cd_mg.pyx
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/solvers/qn.pyx b/python/cuml/solvers/qn.pyx
index b65df9fad6..0ae06bdb2a 100644
--- a/python/cuml/solvers/qn.pyx
+++ b/python/cuml/solvers/qn.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cudf
 import cupy as cp
diff --git a/python/cuml/solvers/sgd.pyx b/python/cuml/solvers/sgd.pyx
index 74dd42b6c1..c8c65218a7 100644
--- a/python/cuml/solvers/sgd.pyx
+++ b/python/cuml/solvers/sgd.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/svm/svc.pyx b/python/cuml/svm/svc.pyx
index 8389fdee8b..414903eb8a 100644
--- a/python/cuml/svm/svc.pyx
+++ b/python/cuml/svm/svc.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/svm/svm_base.pyx b/python/cuml/svm/svm_base.pyx
index 0b53488d90..57c5d396d7 100644
--- a/python/cuml/svm/svm_base.pyx
+++ b/python/cuml/svm/svm_base.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/svm/svr.pyx b/python/cuml/svm/svr.pyx
index b70d689957..652e96c81f 100644
--- a/python/cuml/svm/svr.pyx
+++ b/python/cuml/svm/svr.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import cudf
diff --git a/python/cuml/tsa/arima.pyx b/python/cuml/tsa/arima.pyx
index ed577e65ad..6a0aa6c419 100644
--- a/python/cuml/tsa/arima.pyx
+++ b/python/cuml/tsa/arima.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import numpy as np
 import sys
diff --git a/python/cuml/tsa/auto_arima.pyx b/python/cuml/tsa/auto_arima.pyx
index 29d1862def..40aa3c65f4 100644
--- a/python/cuml/tsa/auto_arima.pyx
+++ b/python/cuml/tsa/auto_arima.pyx
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import itertools
diff --git a/python/cuml/tsa/holtwinters.pyx b/python/cuml/tsa/holtwinters.pyx
index 192a5faf8a..b54e622ebd 100644
--- a/python/cuml/tsa/holtwinters.pyx
+++ b/python/cuml/tsa/holtwinters.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import cudf
 import cupy as cp
diff --git a/python/cuml/tsa/seasonality.pyx b/python/cuml/tsa/seasonality.pyx
index c89f3d418f..35ed876445 100644
--- a/python/cuml/tsa/seasonality.pyx
+++ b/python/cuml/tsa/seasonality.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import numpy as np
diff --git a/python/cuml/tsa/stationarity.pyx b/python/cuml/tsa/stationarity.pyx
index ac022b9544..a7697749d3 100644
--- a/python/cuml/tsa/stationarity.pyx
+++ b/python/cuml/tsa/stationarity.pyx
@@ -13,10 +13,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import numpy as np

From 81ffd4a89c5495070cef173a6129ec5b2f81f9a2 Mon Sep 17 00:00:00 2001
From: Michael Demoret <42954918+mdemoret-nv@users.noreply.github.com>
Date: Tue, 8 Sep 2020 20:16:30 -0600
Subject: [PATCH 12/13] Fixing copyright and removing cython directives from
 .py and .pxd files that are no longer necessary

---
 python/cuml/cluster/kmeans_utils.pxd          | 3 ---
 python/cuml/common/cuda.pxd                   | 3 ---
 python/cuml/common/handle.pxd                 | 3 ---
 python/cuml/common/opg_data_utils_mg.pxd      | 4 +---
 python/cuml/dask/linear_model/elastic_net.py  | 5 -----
 python/cuml/dask/linear_model/lasso.py        | 5 -----
 python/cuml/dask/metrics/utils.py             | 5 -----
 python/cuml/decomposition/utils.pxd           | 3 ---
 python/cuml/ensemble/randomforest_shared.pxd  | 3 ---
 python/cuml/metrics/confusion_matrix.py       | 5 -----
 python/cuml/metrics/regression.pxd            | 3 ---
 python/cuml/metrics/utils.py                  | 5 -----
 python/cuml/preprocessing/onehotencoder_mg.py | 4 ----
 python/cuml/tsa/arima.pxd                     | 4 ----
 python/cython_build_ext.py                    | 2 +-
 15 files changed, 2 insertions(+), 55 deletions(-)

diff --git a/python/cuml/cluster/kmeans_utils.pxd b/python/cuml/cluster/kmeans_utils.pxd
index 7bdb36541b..de305589dd 100644
--- a/python/cuml/cluster/kmeans_utils.pxd
+++ b/python/cuml/cluster/kmeans_utils.pxd
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 from libcpp cimport bool
diff --git a/python/cuml/common/cuda.pxd b/python/cuml/common/cuda.pxd
index e407213f44..6eaa3712a8 100644
--- a/python/cuml/common/cuda.pxd
+++ b/python/cuml/common/cuda.pxd
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 
 # Populate this with more typedef's (eg: events) as and when needed
diff --git a/python/cuml/common/handle.pxd b/python/cuml/common/handle.pxd
index dcf21c9643..5dfa0ff7ce 100644
--- a/python/cuml/common/handle.pxd
+++ b/python/cuml/common/handle.pxd
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 
 from libcpp.memory cimport shared_ptr
diff --git a/python/cuml/common/opg_data_utils_mg.pxd b/python/cuml/common/opg_data_utils_mg.pxd
index bc3c5fafd9..7c7a2f2795 100644
--- a/python/cuml/common/opg_data_utils_mg.pxd
+++ b/python/cuml/common/opg_data_utils_mg.pxd
@@ -13,10 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# cython: profile=False
+
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 # Util functions, will be moved to their own file as the other methods are
 # refactored
diff --git a/python/cuml/dask/linear_model/elastic_net.py b/python/cuml/dask/linear_model/elastic_net.py
index cfdd4181e2..e8a6fc55dc 100644
--- a/python/cuml/dask/linear_model/elastic_net.py
+++ b/python/cuml/dask/linear_model/elastic_net.py
@@ -14,11 +14,6 @@
 # limitations under the License.
 #
 
-# cython: profile=False
-# distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
-
 from cuml.dask.solvers import CD
 from cuml.dask.common.base import BaseEstimator
 
diff --git a/python/cuml/dask/linear_model/lasso.py b/python/cuml/dask/linear_model/lasso.py
index d6cbd3585b..b66de734c3 100644
--- a/python/cuml/dask/linear_model/lasso.py
+++ b/python/cuml/dask/linear_model/lasso.py
@@ -14,11 +14,6 @@
 # limitations under the License.
 #
 
-# cython: profile=False
-# distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
-
 from cuml.dask.solvers import CD
 from cuml.dask.common.base import BaseEstimator
 
diff --git a/python/cuml/dask/metrics/utils.py b/python/cuml/dask/metrics/utils.py
index 60df622845..011b3d8e5c 100644
--- a/python/cuml/dask/metrics/utils.py
+++ b/python/cuml/dask/metrics/utils.py
@@ -14,11 +14,6 @@
 # limitations under the License.
 #
 
-# cython: profile=False
-# distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
-
 import cupy as cp
 
 
diff --git a/python/cuml/decomposition/utils.pxd b/python/cuml/decomposition/utils.pxd
index e5719921be..911a86487a 100644
--- a/python/cuml/decomposition/utils.pxd
+++ b/python/cuml/decomposition/utils.pxd
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from libcpp cimport bool
 
diff --git a/python/cuml/ensemble/randomforest_shared.pxd b/python/cuml/ensemble/randomforest_shared.pxd
index 97a51ad6bd..cb5e4deeaa 100644
--- a/python/cuml/ensemble/randomforest_shared.pxd
+++ b/python/cuml/ensemble/randomforest_shared.pxd
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 import ctypes
 import math
diff --git a/python/cuml/metrics/confusion_matrix.py b/python/cuml/metrics/confusion_matrix.py
index 25272b56c6..81901feaa9 100644
--- a/python/cuml/metrics/confusion_matrix.py
+++ b/python/cuml/metrics/confusion_matrix.py
@@ -14,11 +14,6 @@
 # limitations under the License.
 #
 
-# cython: profile=False
-# distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
-
 import numpy as np
 import cupy as cp
 import cupyx
diff --git a/python/cuml/metrics/regression.pxd b/python/cuml/metrics/regression.pxd
index 5abcf33d73..a6acd29336 100644
--- a/python/cuml/metrics/regression.pxd
+++ b/python/cuml/metrics/regression.pxd
@@ -14,10 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 
 from cuml.common.handle cimport cumlHandle
 
diff --git a/python/cuml/metrics/utils.py b/python/cuml/metrics/utils.py
index bd865b1a53..efef1eb832 100644
--- a/python/cuml/metrics/utils.py
+++ b/python/cuml/metrics/utils.py
@@ -14,11 +14,6 @@
 # limitations under the License.
 #
 
-# cython: profile=False
-# distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
-
 import cupy as cp
 
 
diff --git a/python/cuml/preprocessing/onehotencoder_mg.py b/python/cuml/preprocessing/onehotencoder_mg.py
index 6456cdfbd8..080a52868b 100644
--- a/python/cuml/preprocessing/onehotencoder_mg.py
+++ b/python/cuml/preprocessing/onehotencoder_mg.py
@@ -14,10 +14,6 @@
 # limitations under the License.
 #
 
-# cython: profile=False
-# distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
 from cuml.preprocessing.encoders import OneHotEncoder
 import dask
 import cupy as cp
diff --git a/python/cuml/tsa/arima.pxd b/python/cuml/tsa/arima.pxd
index 1ba9a72680..e3aba3809a 100644
--- a/python/cuml/tsa/arima.pxd
+++ b/python/cuml/tsa/arima.pxd
@@ -14,11 +14,7 @@
 # limitations under the License.
 #
 
-# cython: profile=False
 # distutils: language = c++
-# cython: embedsignature = True
-# cython: language_level = 3
-
 
 cdef extern from "cuml/tsa/arima_common.h" namespace "ML":
     ctypedef struct ARIMAOrder:
diff --git a/python/cython_build_ext.py b/python/cython_build_ext.py
index 8abb02210f..dc5f502d4b 100644
--- a/python/cython_build_ext.py
+++ b/python/cython_build_ext.py
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2020, NVIDIA CORPORATION.
+# Copyright (c) 2020, NVIDIA CORPORATION.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.

From 34fa7a74867758b01de60e0db4ad3844acee3948 Mon Sep 17 00:00:00 2001
From: Michael Demoret <42954918+mdemoret-nv@users.noreply.github.com>
Date: Wed, 9 Sep 2020 14:49:33 -0600
Subject: [PATCH 13/13] Removing `# distutils:` from *.pxd files

---
 python/cuml/cluster/kmeans_utils.pxd         | 2 --
 python/cuml/common/cuda.pxd                  | 3 ---
 python/cuml/common/handle.pxd                | 3 ---
 python/cuml/common/opg_data_utils_mg.pxd     | 2 --
 python/cuml/decomposition/utils.pxd          | 2 --
 python/cuml/ensemble/randomforest_shared.pxd | 2 --
 python/cuml/metrics/regression.pxd           | 2 --
 python/cuml/tsa/arima.pxd                    | 2 --
 8 files changed, 18 deletions(-)

diff --git a/python/cuml/cluster/kmeans_utils.pxd b/python/cuml/cluster/kmeans_utils.pxd
index de305589dd..5ae36f1ca6 100644
--- a/python/cuml/cluster/kmeans_utils.pxd
+++ b/python/cuml/cluster/kmeans_utils.pxd
@@ -14,8 +14,6 @@
 # limitations under the License.
 #
 
-# distutils: language = c++
-
 import ctypes
 from libcpp cimport bool
 
diff --git a/python/cuml/common/cuda.pxd b/python/cuml/common/cuda.pxd
index 6eaa3712a8..5ac815cbb8 100644
--- a/python/cuml/common/cuda.pxd
+++ b/python/cuml/common/cuda.pxd
@@ -14,9 +14,6 @@
 # limitations under the License.
 #
 
-# distutils: language = c++
-
-
 # Populate this with more typedef's (eg: events) as and when needed
 cdef extern from * nogil:
     ctypedef void* _Stream "cudaStream_t"
diff --git a/python/cuml/common/handle.pxd b/python/cuml/common/handle.pxd
index 5dfa0ff7ce..89eb8d9ee6 100644
--- a/python/cuml/common/handle.pxd
+++ b/python/cuml/common/handle.pxd
@@ -14,9 +14,6 @@
 # limitations under the License.
 #
 
-# distutils: language = c++
-
-
 from libcpp.memory cimport shared_ptr
 cimport cuml.common.cuda
 
diff --git a/python/cuml/common/opg_data_utils_mg.pxd b/python/cuml/common/opg_data_utils_mg.pxd
index 7c7a2f2795..ba49faf1e5 100644
--- a/python/cuml/common/opg_data_utils_mg.pxd
+++ b/python/cuml/common/opg_data_utils_mg.pxd
@@ -14,8 +14,6 @@
 # limitations under the License.
 #
 
-# distutils: language = c++
-
 # Util functions, will be moved to their own file as the other methods are
 # refactored
 # todo: use cuda_array_interface instead of arr_interfaces for building this
diff --git a/python/cuml/decomposition/utils.pxd b/python/cuml/decomposition/utils.pxd
index 911a86487a..07d20d5f96 100644
--- a/python/cuml/decomposition/utils.pxd
+++ b/python/cuml/decomposition/utils.pxd
@@ -14,8 +14,6 @@
 # limitations under the License.
 #
 
-# distutils: language = c++
-
 from libcpp cimport bool
 
 ctypedef int underlying_type_t_solver
diff --git a/python/cuml/ensemble/randomforest_shared.pxd b/python/cuml/ensemble/randomforest_shared.pxd
index cb5e4deeaa..2bf903c34d 100644
--- a/python/cuml/ensemble/randomforest_shared.pxd
+++ b/python/cuml/ensemble/randomforest_shared.pxd
@@ -14,8 +14,6 @@
 # limitations under the License.
 #
 
-# distutils: language = c++
-
 import ctypes
 import math
 import numpy as np
diff --git a/python/cuml/metrics/regression.pxd b/python/cuml/metrics/regression.pxd
index a6acd29336..6e5463e541 100644
--- a/python/cuml/metrics/regression.pxd
+++ b/python/cuml/metrics/regression.pxd
@@ -14,8 +14,6 @@
 # limitations under the License.
 #
 
-# distutils: language = c++
-
 from cuml.common.handle cimport cumlHandle
 
 cdef extern from "cuml/metrics/metrics.hpp" namespace "ML::Metrics":
diff --git a/python/cuml/tsa/arima.pxd b/python/cuml/tsa/arima.pxd
index e3aba3809a..12095ed20e 100644
--- a/python/cuml/tsa/arima.pxd
+++ b/python/cuml/tsa/arima.pxd
@@ -14,8 +14,6 @@
 # limitations under the License.
 #
 
-# distutils: language = c++
-
 cdef extern from "cuml/tsa/arima_common.h" namespace "ML":
     ctypedef struct ARIMAOrder:
         int p  # Basic order