diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..a7225339 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,3 @@ +sphinx-cpp/_build +sphinx-python/_build +sphinx-cpp/_doxygen diff --git a/docs/build_combined_docs.sh b/docs/build_combined_docs.sh new file mode 100755 index 00000000..116e0430 --- /dev/null +++ b/docs/build_combined_docs.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BUILD_DIR="${SCRIPT_DIR}/sphinx-combined/_build" +DOXYGEN_DIR="${SCRIPT_DIR}/sphinx-combined/_doxygen" + +mkdir -p "${BUILD_DIR}" "${DOXYGEN_DIR}" + +echo "Running Doxygen for combined C++ API..." +(cd "${SCRIPT_DIR}/sphinx-combined" && doxygen Doxyfile) + +echo "Building combined Sphinx docs..." +sphinx-build -b html "${SCRIPT_DIR}/sphinx-combined" "${BUILD_DIR}" + +echo "Combined docs available at ${BUILD_DIR}/index.html" diff --git a/docs/sphinx-combined/Doxyfile b/docs/sphinx-combined/Doxyfile new file mode 100644 index 00000000..9321c86c --- /dev/null +++ b/docs/sphinx-combined/Doxyfile @@ -0,0 +1,43 @@ +PROJECT_NAME = "NVBench" +PROJECT_BRIEF = "C++ NVBench Library" +OUTPUT_DIRECTORY = _doxygen +GENERATE_XML = YES +GENERATE_HTML = NO +GENERATE_LATEX = NO +QUIET = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_LOGFILE = _doxygen/warnings.log +INPUT = ../../nvbench +EXCLUDE = ../../nvbench/cupti_profiler.cxx +EXCLUDE_SYMBOLS = type_strings \ + nvbench::detail \ + nvbench::internal \ + nvbench::tl \ + UNUSED \ + M_PI \ + NVBENCH_UNIQUE_IDENTIFIER_IMPL1 \ + NVBENCH_UNIQUE_IDENTIFIER_IMPL2 \ + main +FILE_PATTERNS = *.cuh *.cxx *.cu *.h *.hpp +EXTENSION_MAPPING = cuh=C++ cu=C++ +RECURSIVE = YES +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = YES +STRIP_FROM_PATH = ../../ +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +GENERATE_TAGFILE = +XML_PROGRAMLISTING = NO +PREDEFINED = __device__= \ + __host__= \ + __global__= \ + __forceinline__= \ + __shared__= \ + __align__(x)= \ + __launch_bounds__(x)= \ + NVBENCH_HAS_CUDA=1 diff --git a/docs/sphinx-combined/_static/nvidia-logo.png b/docs/sphinx-combined/_static/nvidia-logo.png new file mode 100644 index 00000000..1779ad93 Binary files /dev/null and b/docs/sphinx-combined/_static/nvidia-logo.png differ diff --git a/docs/sphinx-combined/conf.py b/docs/sphinx-combined/conf.py new file mode 100644 index 00000000..c3a1ea48 --- /dev/null +++ b/docs/sphinx-combined/conf.py @@ -0,0 +1,105 @@ +import os + +project = "NVBench API" +author = "NVIDIA Corporation" + +extensions = [ + "breathe", + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.autosummary", +] + +templates_path = ["_templates"] +exclude_patterns = ["_build", "_doxygen"] + +autosummary_generate = True +autodoc_default_options = {"members": True, "undoc-members": True} + +napoleon_custom_sections = ["Note", "Parameters"] + +release = "0.2.0" + +_here = os.path.abspath(os.path.dirname(__file__)) +_doxygen_xml = os.path.join(_here, "_doxygen", "xml") + +breathe_projects = {"nvbench": _doxygen_xml} +breathe_default_project = "nvbench" +breathe_domain_by_extension = {"cuh": "cpp", "cxx": "cpp", "cu": "cpp"} + + +def _patch_breathe_namespace_declarations() -> None: + try: + import breathe.renderer.sphinxrenderer as sphinxrenderer + from docutils import nodes + from sphinx import addnodes + except Exception: + return + + original = sphinxrenderer.SphinxRenderer.handle_declaration + + def handle_declaration(self, nodeDef, declaration, *args, **kwargs): + is_namespace = getattr(nodeDef, "kind", None) == "namespace" + if not is_namespace: + return original(self, nodeDef, declaration, *args, **kwargs) + + name = (declaration or "").strip() + if name.startswith("namespace "): + name = name[len("namespace ") :].strip() + if not name: + name = "" + + keyword = addnodes.desc_sig_keyword("namespace", "namespace") + sig_name = addnodes.desc_sig_name(name, name) + return [keyword, nodes.Text(" "), sig_name] + + sphinxrenderer.SphinxRenderer.handle_declaration = handle_declaration + + +def setup(app): + _patch_breathe_namespace_declarations() + + +###################################################### + +# -- Options for HTML output ------------------------------------------------- + +html_theme = "nvidia_sphinx_theme" + +html_logo = "_static/nvidia-logo.png" + +html_baseurl = ( + os.environ.get("NVBENCH_DOCS_BASE_URL", "https://nvidia.github.io/nvbench/").rstrip( + "/" + ) + + "/" +) + +html_theme_options = { + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/NVIDIA/nvbench", + "icon": "fa-brands fa-github", + "type": "fontawesome", + } + ], + "navigation_depth": 4, + "show_toc_level": 2, + "navbar_start": ["navbar-logo"], + "navbar_end": ["theme-switcher", "navbar-icon-links"], + "footer_start": ["copyright"], + "footer_end": ["sphinx-version"], + "sidebar_includehidden": True, + "collapse_navigation": False, + # "switcher": { + # "json_url": f"{html_baseurl}nv-versions.json", + # "version_match": release, + # }, +} + +html_static_path = ["_static"] if os.path.exists("_static") else [] + +# Images directory +if os.path.exists("img"): + html_static_path.append("img") diff --git a/docs/sphinx-combined/cpp_api.rst b/docs/sphinx-combined/cpp_api.rst new file mode 100644 index 00000000..e59af260 --- /dev/null +++ b/docs/sphinx-combined/cpp_api.rst @@ -0,0 +1,5 @@ +NVBench C++ API Reference +========================= + +.. doxygenindex:: + :project: nvbench diff --git a/docs/sphinx-combined/index.rst b/docs/sphinx-combined/index.rst new file mode 100644 index 00000000..3f30d51e --- /dev/null +++ b/docs/sphinx-combined/index.rst @@ -0,0 +1,10 @@ +NVBench API +=========== + +Combined C++ and Python API documentation. + +.. toctree:: + :maxdepth: 2 + + cpp_api + python_api diff --git a/docs/sphinx-combined/python_api.rst b/docs/sphinx-combined/python_api.rst new file mode 100644 index 00000000..22e24eff --- /dev/null +++ b/docs/sphinx-combined/python_api.rst @@ -0,0 +1,8 @@ +cuda.bench Python API Reference +=============================== + +.. automodule:: cuda.bench + :members: + :imported-members: + :undoc-members: + :show-inheritance: diff --git a/python/cuda/bench/__init__.py b/python/cuda/bench/__init__.py index e6e7753c..09022112 100644 --- a/python/cuda/bench/__init__.py +++ b/python/cuda/bench/__init__.py @@ -69,8 +69,8 @@ def _get_cuda_major_version(): State = _nvbench_module.State register = _nvbench_module.register run_all_benchmarks = _nvbench_module.run_all_benchmarks -test_cpp_exception = _nvbench_module.test_cpp_exception -test_py_exception = _nvbench_module.test_py_exception +_test_cpp_exception = _nvbench_module._test_cpp_exception +_test_py_exception = _nvbench_module._test_py_exception # Expose the module as _nvbench for backward compatibility (e.g., for tests) _nvbench = _nvbench_module diff --git a/python/src/py_nvbench.cpp b/python/src/py_nvbench.cpp index aeadcc24..fd206c87 100644 --- a/python/src/py_nvbench.cpp +++ b/python/src/py_nvbench.cpp @@ -273,7 +273,7 @@ static void def_class_CudaStream(py::module_ m) // nvbench::cuda_stream::get_stream static constexpr const char *class_CudaStream_doc = R"XXX( -Represents CUDA stream + Represents CUDA stream Note ---- @@ -321,7 +321,7 @@ void def_class_Launch(py::module_ m) // nvbench::launch::get_stream -> nvbench::cuda_stream static constexpr const char *class_Launch_doc = R"XXXX( -Configuration object for function launch. + Configuration object for function launch. Note ---- @@ -363,7 +363,7 @@ static void def_class_Benchmark(py::module_ m) // nvbench::benchmark_base::set_min_samples static constexpr const char *class_Benchmark_doc = R"XXXX( -Represents NVBench benchmark. + Represents NVBench benchmark. Note ---- @@ -691,7 +691,7 @@ void def_class_State(py::module_ m) using state_ref_t = std::reference_wrapper; static constexpr const char *class_State_doc = R"XXXX( -Represent benchmark configuration state. + Represents benchmark configuration state. Note ---- @@ -1014,7 +1014,7 @@ Use argument True to disable use of blocking kernel by NVBench" } }; static constexpr const char *method_exec_doc = R"XXXX( -Execute callable running the benchmark. + Execute callable running the benchmark. The callable may be executed multiple times. The callable will be passed `~Launch` object argument. @@ -1194,8 +1194,8 @@ Register benchmark function of type Callable[[nvbench.State], None] py::arg("argv") = py::list()); // Testing utilities - m.def("test_cpp_exception", []() { throw nvbench_run_error("Test"); }); - m.def("test_py_exception", []() { + m.def("_test_cpp_exception", []() { throw nvbench_run_error("Test"); }); + m.def("_test_py_exception", []() { py::set_error(exc_storage.get_stored(), "Test"); throw py::error_already_set(); }); diff --git a/python/test/test_cuda_bench.py b/python/test/test_cuda_bench.py index 7d927e8f..b63d24d8 100644 --- a/python/test/test_cuda_bench.py +++ b/python/test/test_cuda_bench.py @@ -6,12 +6,12 @@ def test_cpp_exception(): with pytest.raises(RuntimeError, match="Test"): - bench._nvbench.test_cpp_exception() + bench._nvbench._test_cpp_exception() def test_py_exception(): with pytest.raises(bench.NVBenchRuntimeError, match="Test"): - bench._nvbench.test_py_exception() + bench._nvbench._test_py_exception() @pytest.mark.parametrize(