diff --git a/.gitignore b/.gitignore index ae4c19b503..163f62534f 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ doxygen_check/ ## Doxygen cpp/html +cpp/xml cpp/Doxyfile # clang tooling diff --git a/conda/environments/all_cuda-129_arch-aarch64.yaml b/conda/environments/all_cuda-129_arch-aarch64.yaml index ffcccab8d2..97332972b1 100644 --- a/conda/environments/all_cuda-129_arch-aarch64.yaml +++ b/conda/environments/all_cuda-129_arch-aarch64.yaml @@ -5,6 +5,7 @@ channels: - rapidsai - conda-forge dependencies: +- breathe - c-compiler - ccache - certifi diff --git a/conda/environments/all_cuda-129_arch-x86_64.yaml b/conda/environments/all_cuda-129_arch-x86_64.yaml index 4a781091df..b21220862a 100644 --- a/conda/environments/all_cuda-129_arch-x86_64.yaml +++ b/conda/environments/all_cuda-129_arch-x86_64.yaml @@ -5,6 +5,7 @@ channels: - rapidsai - conda-forge dependencies: +- breathe - c-compiler - ccache - certifi diff --git a/conda/environments/all_cuda-133_arch-aarch64.yaml b/conda/environments/all_cuda-133_arch-aarch64.yaml index cabab5ef63..a29f5f9573 100644 --- a/conda/environments/all_cuda-133_arch-aarch64.yaml +++ b/conda/environments/all_cuda-133_arch-aarch64.yaml @@ -5,6 +5,7 @@ channels: - rapidsai - conda-forge dependencies: +- breathe - c-compiler - ccache - certifi diff --git a/conda/environments/all_cuda-133_arch-x86_64.yaml b/conda/environments/all_cuda-133_arch-x86_64.yaml index 1be35700f1..70eba24a9a 100644 --- a/conda/environments/all_cuda-133_arch-x86_64.yaml +++ b/conda/environments/all_cuda-133_arch-x86_64.yaml @@ -5,6 +5,7 @@ channels: - rapidsai - conda-forge dependencies: +- breathe - c-compiler - ccache - certifi diff --git a/cpp/Doxyfile.in b/cpp/Doxyfile.in index 5486118f70..abb1c34acc 100644 --- a/cpp/Doxyfile.in +++ b/cpp/Doxyfile.in @@ -2011,7 +2011,7 @@ MAN_LINKS = NO # captures the structure of the code including all documentation. # The default value is: NO. -GENERATE_XML = NO +GENERATE_XML = YES # The XML_OUTPUT tag is used to specify where the XML pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of diff --git a/dependencies.yaml b/dependencies.yaml index db5556af88..08c7662597 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -509,6 +509,7 @@ dependencies: common: - output_types: [conda, requirements] packages: + - breathe - graphviz - ipython - ipykernel diff --git a/docs/source/conf.py b/docs/source/conf.py index ba3d0f3c6c..7f140c48db 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,9 +16,11 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import datetime +import glob import os import sys import textwrap +import xml.etree.ElementTree as ET from packaging.version import Version @@ -43,6 +45,7 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + "breathe", "numpydoc", "sphinx.ext.autodoc", "sphinx.ext.autosummary", @@ -58,6 +61,55 @@ "sphinx_design", ] +breathe_projects = { + "cuml": os.path.abspath( + os.path.join(os.path.dirname(__file__), "../../cpp/xml") + ) +} +breathe_default_project = "cuml" + + +def clean_doxygen_xml(path: str) -> None: + # Doxygen 1.9.1 emits concepts and instantiations that Sphinx cannot parse, + # duplicates enum IDs, and gives TSNE_INIT::PCA the same C++ target as ML::PCA. + for filename in glob.glob(os.path.join(path, "*.xml")): + tree = ET.parse(filename) + changed = False + for section in tree.findall(".//sectiondef"): + for member in list(section.findall("memberdef")): + type_node = member.find("type") + type_text = ( + "".join(type_node.itertext()) + if type_node is not None + else "" + ) + if type_text in {"concept", "template void"}: + section.remove(member) + changed = True + continue + + if member.get("kind") != "enum": + continue + member_id = member.get("id", "") + for value in list(member.findall("enumvalue")): + if ( + member.findtext("name") == "TSNE_INIT" + and value.findtext("name") == "PCA" + ): + member.remove(value) + changed = True + elif not value.get("id", "").startswith(member_id): + value.set( + "id", f"{member_id}_{value.findtext('name')}" + ) + changed = True + if changed: + tree.write(filename, encoding="UTF-8", xml_declaration=True) + + +for project_path in breathe_projects.values(): + clean_doxygen_xml(project_path) + ipython_mplbackend = "str" # Add any paths that contain templates here, relative to this directory. diff --git a/docs/source/cpp/genetic.rst b/docs/source/cpp/genetic.rst new file mode 100644 index 0000000000..072f76d341 --- /dev/null +++ b/docs/source/cpp/genetic.rst @@ -0,0 +1,5 @@ +cuml::genetic Namespace +======================= + +.. doxygennamespace:: cuml::genetic + :members: diff --git a/docs/source/cpp/index.rst b/docs/source/cpp/index.rst new file mode 100644 index 0000000000..89ecdf5367 --- /dev/null +++ b/docs/source/cpp/index.rst @@ -0,0 +1,11 @@ +C++ API +======== + +This section documents the C++ API for cuML, also called ``libcuml``. + +.. toctree:: + :maxdepth: 1 + + ml + mlcommon + genetic diff --git a/docs/source/cpp/ml.rst b/docs/source/cpp/ml.rst new file mode 100644 index 0000000000..6135faab15 --- /dev/null +++ b/docs/source/cpp/ml.rst @@ -0,0 +1,5 @@ +ML Namespace +============ + +.. doxygennamespace:: ML + :members: diff --git a/docs/source/cpp/mlcommon.rst b/docs/source/cpp/mlcommon.rst new file mode 100644 index 0000000000..e409e4b4aa --- /dev/null +++ b/docs/source/cpp/mlcommon.rst @@ -0,0 +1,5 @@ +MLCommon Namespace +================== + +.. doxygennamespace:: MLCommon + :members: diff --git a/docs/source/index.rst b/docs/source/index.rst index f2db8ff3b2..2ecee066df 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -78,4 +78,5 @@ Community & Support user_guide.rst Zero Code Change Acceleration api/index + cpp/index cuml_blogs.rst