From 5bfe89bdb1caed4bfc72f810f8ceb60ceb7de44e Mon Sep 17 00:00:00 2001 From: Awni Hannun Date: Fri, 26 Apr 2024 12:56:05 -0700 Subject: [PATCH] Cpp docs (#1036) * start of C++ docs * fix stream doc * only include ops for now --- docs/Doxyfile | 50 +++++++++++++++++++++++++++++++++ docs/README.md | 14 +++++---- docs/requirements.txt | 3 ++ docs/src/conf.py | 4 +++ docs/src/cpp/ops.rst | 3 +- mlx/backend/metal/allocator.cpp | 9 ++++++ mlx/fast_primitives.h | 2 +- mlx/ops.h | 17 ++++------- python/src/stream.cpp | 5 ++-- 9 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 docs/Doxyfile create mode 100644 docs/requirements.txt diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 000000000..460e6b503 --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,50 @@ +################################################################################ +# Primary project setup. # +################################################################################ + +PROJECT_NAME = "MLX" +OUTPUT_DIRECTORY = build +XML_OUTPUT = xml +HTML_OUTPUT = html +STRIP_FROM_PATH = ../ +INPUT = ../mlx +FILE_PATTERNS = *.h +EXCLUDE_PATTERNS = */private/* +CREATE_SUBDIRS = NO +FULL_PATH_NAMES = YES +RECURSIVE = YES +GENERATE_HTML = YES +GENERATE_LATEX = NO +GENERATE_XML = YES +XML_PROGRAMLISTING = YES + +################################################################################ +# Doxygen preprocessor / parser control. # +################################################################################ + +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SKIP_FUNCTION_MACROS = NO + +################################################################################ +# Compound extraction control. # +################################################################################ + +EXTRACT_ALL = YES +EXTRACT_PACKAGE = YES +EXTRACT_STATIC = YES +CASE_SENSE_NAMES = NO + +################################################################################ +# Docstring control / customization. # +################################################################################ + +JAVADOC_AUTOBRIEF = YES + +################################################################################ +# Warning suppression. # +################################################################################ + +QUIET = YES +WARN_IF_UNDOCUMENTED = NO diff --git a/docs/README.md b/docs/README.md index 01d41d697..cfa872417 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,12 +2,16 @@ ### Setup (do once) -Install [sphinx](https://www.sphinx-doc.org/en/master/usage/installation.html) -for example with `conda`: +Install Doxygen: ``` -conda install sphinx -pip install sphinx-book-theme +brew install doxygen +``` + +Install Python packages: + +``` +pip install -r requirements.txt ``` ### Build @@ -15,7 +19,7 @@ pip install sphinx-book-theme Build the docs from `mlx/docs/` ``` -make html +doxygen && make html ``` View the docs by running a server in `mlx/docs/build/html/`: diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..d9db77517 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,3 @@ +sphinx +breathe +sphinx-book-theme diff --git a/docs/src/conf.py b/docs/src/conf.py index 3348c2f46..da967f4c4 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -22,6 +22,7 @@ extensions = [ "sphinx.ext.autosummary", "sphinx.ext.intersphinx", "sphinx.ext.napoleon", + "breathe", ] python_use_unqualified_type_names = True @@ -33,6 +34,9 @@ intersphinx_mapping = { "numpy": ("https://numpy.org/doc/stable/", None), } +breathe_projects = {"mlx": "../build/xml"} +breathe_default_project = "mlx" + templates_path = ["_templates"] html_static_path = ["_static"] source_suffix = ".rst" diff --git a/docs/src/cpp/ops.rst b/docs/src/cpp/ops.rst index 4d2d1404e..009a10b1e 100644 --- a/docs/src/cpp/ops.rst +++ b/docs/src/cpp/ops.rst @@ -3,4 +3,5 @@ Operations ========== - +.. doxygengroup:: ops + :content-only: diff --git a/mlx/backend/metal/allocator.cpp b/mlx/backend/metal/allocator.cpp index cc4945d29..528e1db76 100644 --- a/mlx/backend/metal/allocator.cpp +++ b/mlx/backend/metal/allocator.cpp @@ -165,6 +165,15 @@ Buffer MetalAllocator::malloc(size_t size, bool allow_swap /* = false */) { return Buffer{nullptr}; } + // More helpful message if maximum buffer length is exceeded + if (size > device_->maxBufferLength()) { + std::ostringstream msg; + msg << "Attempting to allocate " << size << " bytes which is greater than" + << " the maximum allowed buffer size of " << device_->maxBufferLength() + << " bytes."; + throw std::runtime_error(msg.str()); + } + // Align up memory if (size > vm_page_size) { size = vm_page_size * ((size + vm_page_size - 1) / vm_page_size); diff --git a/mlx/fast_primitives.h b/mlx/fast_primitives.h index a956afec8..0bf5b511a 100644 --- a/mlx/fast_primitives.h +++ b/mlx/fast_primitives.h @@ -204,7 +204,7 @@ class ScaledDotProductAttention : public Custom { void eval_gpu(const std::vector& inputs, array& out); bool is_equivalent(const Primitive& other) const override; - DEFINE_PRINT(ScaledDotProductAttention) + DEFINE_PRINT(ScaledDotProductAttention); private: std::function(std::vector)> fallback_; diff --git a/mlx/ops.h b/mlx/ops.h index d3f0b8f30..15efee204 100644 --- a/mlx/ops.h +++ b/mlx/ops.h @@ -11,7 +11,10 @@ namespace mlx::core { -/** Creation operations */ +/** + * \defgroup ops Core array operations + * @{ + */ /** * A 1D array of numbers starting at `start` (optional), @@ -115,8 +118,6 @@ inline array tri(int n, Dtype type, StreamOrDevice s = {}) { array tril(array x, int k = 0, StreamOrDevice s = {}); array triu(array x, int k = 0, StreamOrDevice s = {}); -/** array manipulation */ - /** Reshape an array to the given shape. */ array reshape(const array& a, std::vector shape, StreamOrDevice s = {}); @@ -289,8 +290,6 @@ std::vector broadcast_arrays( const std::vector& inputs, StreamOrDevice s = {}); -/** Comparison operations */ - /** Returns the bool array with (a == b) element-wise. */ array equal(const array& a, const array& b, StreamOrDevice s = {}); inline array operator==(const array& a, const array& b) { @@ -401,8 +400,6 @@ array where( const array& y, StreamOrDevice s = {}); -/** Reduction operations */ - /** True if all elements in the array are true (or non-zero). **/ array all(const array& a, bool keepdims, StreamOrDevice s = {}); inline array all(const array& a, StreamOrDevice s = {}) { @@ -710,8 +707,6 @@ array logsumexp( bool keepdims = false, StreamOrDevice s = {}); -/** Simple arithmetic operations */ - /** Absolute value of elements in an array. */ array abs(const array& a, StreamOrDevice s = {}); @@ -1076,8 +1071,6 @@ array cummin( bool inclusive = true, StreamOrDevice s = {}); -/** Convolution operations */ - /** General convolution with a filter */ array conv_general( array input, @@ -1246,4 +1239,6 @@ array number_of_elements( Dtype dtype = int32, StreamOrDevice s = {}); +/** @} */ + } // namespace mlx::core diff --git a/python/src/stream.cpp b/python/src/stream.cpp index 7eb8c6bf3..95ddd20ed 100644 --- a/python/src/stream.cpp +++ b/python/src/stream.cpp @@ -139,7 +139,8 @@ void init_stream(nb::module_& m) { Synchronize with the given stream. Args: - (Stream, optional): The stream to synchronize with. If ``None`` then - the default stream of the default device is used. Default: ``None``. + stream (Stream, optional): The stream to synchronize with. If ``None`` + then the default stream of the default device is used. + Default: ``None``. )pbdoc"); }