简短描述。*。
这些指南适用于使用 doxygen 格式记录所有 libcuspatial C++ 源文件,尽管实际上只有公共 API 和类会被发布。
以下是应出现在每个 C++ 源文件开头的许可头注释。
/* * Copyright (c) 2022, 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 * * https://apache.ac.cn/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. */
注释应以 /*
开头,而不是 /**
,这样它就不会被 doxygen 处理。
此外,以下是关于版权年份的规则。
2019-2021
)如果内容没有改变(例如,仅重新格式化),则可能无需更改版权年份。
doxygen 工具用于从源代码中的 C++ 注释生成 HTML 页面。doxygen 识别并解析块注释,并在遇到doxygen 命令时执行专门的输出格式化。
doxygen 在注释块中识别近 200 个命令(本文档中也称为标签)。本文档提供了关于在 libcuspatial C++ 源代码中使用哪些命令/标签以及如何使用它们的指南。
doxygen 进程可以通过Doxyfile 中的选项进行定制。
以下是一些 libcuspatial 的 Doxyfile 中的自定义选项。
选项 | 设置 | 描述 |
---|---|---|
PROJECT_NAME | libcuspatial | 主页上使用的标题 |
PROJECT_NUMBER | 22.10.00 | 版本号 |
EXTENSION_MAPPING | cu=C++ cuh=C++ | 将 cu 和 cuh 文件作为 C++ 处理 |
INPUT | main_page.md ../include | 要处理的嵌入式 markdown 文件和源代码目录 |
FILE_PATTERNS | *.cpp *.hpp *.h *.c *.cu *.cuh | 要处理的文件扩展名 |
EXCLUDE_PATTERNS | */detail/* */nvtx/* | 用于排除路径/文件名的通配符模式 |
TAGFILES | rmm.tag=https://docs.rapids.org.cn/api/librmm/22.10 "libcudf.tag=https://docs.rapids.org.cn/api/libcudf/22.10" | 外部文档 tagfile 的链接。版本在每次发布时自动更新 |
PREDEFINED | device= \ host= | 预定义宏。有助于 CUDA 声明说明符。 |
使用以下样式编写描述函数、类及其他类型、组和文件的块注释。
/** * description text and * doxygen tags go here */
doxygen 注释块仅以 /**
开头并以 */
结尾,这两行上不应有其他内容。不要在 doxygen 块的第一行和最后一行添加破折号 -----
或额外的星号 *****
。注释块必须紧接在它所引用的源代码行之前。块可以适当缩进,使其与所描述的项目垂直对齐。请参阅下面的示例部分。
在 /**
和 */
行之间的注释块中的每一行都应以一个空格后跟一个星号开头。这些行上的任何文本,包括标签声明,都应在星号后的一个空格后开始。
使用 @ 作为 doxygen 命令的前缀(例如 @brief、@code 等)
doxygen 工具在注释块中支持有限的 markdown 格式,包括链接、表格、列表等。在某些情况下,可能需要在源文本文件中的可读性与 doxygen 格式化网页中的可读性之间进行权衡。例如,在 markdown 表格中使用 '' 字符和竖线 '|' 字符在可读性方面存在一些限制。
避免使用直接的 HTML 标签。尽管 doxygen 支持 markdown,而 markdown 支持 HTML 标签,但 doxygen 对 markdown 中的 HTML 支持也是有限的。
以下示例涵盖了在 libcuspatial 中记录 C++ 代码的大部分 doxygen 块注释和标签样式。
/** * @file source_file.cpp * @brief Description of source file contents * * Longer description of the source file contents. */ /** * @brief One sentence description of the class. * * @ingroup optional_predefined_group_id * * Longer, more detailed description of the class. * * @tparam T Short description of each template parameter * @tparam U Short description of each template parameter */ template <typename T, typename U> class example_class { void get_my_int(); ///< Simple members can be documented like this void set_my_int( int value ); ///< Try to use descriptive member names /** * @brief Short, one sentence description of the member function. * * A more detailed description of what this function does and what * its logic does. * * @code * example_class<int> inst; * inst.set_my_int(5); * int output = inst.complicated_function(1,dptr,fptr); * @endcode * * @param[in] first This parameter is an input parameter to the function * @param[in,out] second This parameter is used both as an input and output * @param[out] third This parameter is an output of the function * * @return The result of the complex function */ T complicated_function(int first, double* second, float* third) { // Do not use doxygen-style block comments // for code logic documentation. } private: int my_int; ///< An example private member variable }; /** * @brief Short, one sentence description of this free function. * * @ingroup optional_predefined_group_id * * A detailed description must start after a blank line. * * @code * template<typename T> * struct myfunctor { * bool operator()(T input) { return input % 2 > 0; } * }; * free_function<myfunctor,int>(myfunctor{},12); * @endcode * * @throw cuspatial::logic_error if `input_argument` is negative or zero * * @tparam functor_type The type of the functor * @tparam input_type The datatype of the input argument * * @param[in] functor The functor to be called on the input argument * @param[in] input_argument The input argument passed into the functor * @return The result of calling the functor on the input argument */ template <class functor_type, typename input_type> bool free_function(functor_type functor, input_type input_argument) { CUSPATIAL_EXPECTS( input_argument > 0, "input_argument must be positive"); return functor(input_argument); } /** * @brief Short, one sentence description. * * @ingroup optional_predefined_group_id * * Optional, longer description. */ enum class example_enum { first_enum, ///< Description of the first enum second_enum, ///< Description of the second enum third_enum ///< Description of the third enum }; /** * @internal * @brief The "@internal" tag can be used to indicate rendered HTML docs for a function should not * be generated. */ void internal_function() { ... }
注释描述应清楚详细说明如何从任何输入创建输出。包括任何性能和边界考虑事项。此外,包括对参数值的任何限制以及是否声明了任何默认值。如果可能,也尝试包含一个简短示例。
@brief 文本应是一个简短的单句描述。doxygen 在输出页面中显示此文本的空间不多。@brief 行后面务必跟随一个空白注释行。
更长的描述是注释文本中未被任何 doxygen 命令标记的其余部分。
/**
头文件中的声明文档应清晰完整。您可以使用@copydoc 标签来避免为函数定义重复注释块。
/** * @copydoc complicated_function(int,double*,float*) * * Any extra documentation. */
此外,@copydoc 在记录仅因 stream
参数而不同的 detail
函数时非常有用。
/**
[in] | stream | 用于执行内核的可选 CUDA 流 */ std::vector<size_type> segmented_count_set_bits(bitmask_type const* bitmask, std::vector<size_type> const& indices, rmm::cuda_stream_view stream = cudf::default_stream_value); |
以下标签应按照此处指定的顺序出现在函数注释块的末尾
命令 | 描述 |
---|---|
@throw | 指定函数可能抛出异常的条件 |
@tparam | 每个模板参数的描述 |
@param | 每个函数参数的描述 |
@return | 返回对象或值的简短描述 |
@pre | 指定函数的任何前置条件/要求 |
对于函数可能抛出的每个异常,在 doxygen 块中添加一个@throw 注释行。您只需包含函数本身抛出的异常。如果函数调用了另一个可能抛出异常的函数,则无需在此处记录这些异常。
包含异常的名称,不带反引号,以便 doxygen 可以正确添加引用链接。
/** * ... * @throw cuspatial::logic_error if `input_argument` is negative or zero */
使用 @throws 也是可以接受的,但 VS code 和其他工具仅对 @throw 进行语法高亮。
对于此函数声明的每个模板参数,添加一个@tparam 注释行。doxygen 标签后指定的参数名称必须与模板参数名称完全匹配。
/** * ... * @tparam functor_type The type of the functor * @tparam input_type The datatype of the input argument */
定义应详细说明参数的要求。例如,如果模板用于仿函数或谓词,则描述预期的输入类型和输出。
对于传递给此函数的每个函数参数,添加一个@param 注释行。doxygen 标签后指定的参数名称必须与函数的参数名称匹配。如果从声明和参数名称本身不清楚,则在 @param 后附加 [in]
、[out]
或 [in,out]
。
/** * ... * @param[in] first This parameter is an input parameter to the function * @param[in,out] second This parameter is used both as an input and output * @param[out] third This parameter is an output of the function */
如果可能,还建议垂直对齐这 3 列文本,以便在源代码编辑器中更容易阅读。
如果函数返回对象或值,则在注释块的末尾添加一个@return 注释行。包含对返回内容的简要描述。
/** * ... * * @return A new column of type INT32 and no nulls */
不要在 @return
注释中包含返回对象的类型。
对于函数的每个前置条件,添加一个@pre 注释行。例如,关于迭代器可访问性或范围的假设。
/** * ... * * @pre All iterators must have the same `Location` type, with the same underlying floating-point * coordinate type (e.g. `cuspatial::vec_2d<float>`). */
在文档化函数或其他声明时,通常将源代码示例包含在注释块内是很有帮助的。使用@code 和@endcode 对来包含内联示例。
Doxygen 支持 C++ 和其他几种编程语言(例如 Python、Java)的语法高亮。默认情况下,@code 标签会根据其所在的源代码进行语法高亮。
/** * ... * * @code * auto result = rmm::device_uvector(...); * @endcode */
您可以通过在标签中指定文件扩展名来指定不同的语言
/** * ... * * @code{.py} * import cudf * s = cudf.Series([1,2,3]) * @endcode */
如果您希望在示例中使用伪代码,请使用以下方式
/** * ... * * Sometimes pseudo-code is clearer. * @code{.pseudo} * s = int column of [ 1, 2, null, 4 ] * r = fill( s, [1, 2], 0 ) * r is now [ 1, 0, 0, 4 ] * @endcode */
编写示例片段时,使用完全限定的类名允许 doxygen 向示例添加引用链接。
/** * ... * * @code * auto result1 = make_column( ); // reference link will not be created * auto result2 = cudf::make_column( ); // reference link will be created * @endcode */
虽然使用三个反引号 ``` 来表示示例块也可以,但在 VS code 和其他源代码编辑器中它们并不那么醒目。
不要在声明的注释中使用 @example 标签,否则 doxygen 会将整个源文件解释为示例源代码。然后,该源文件会在输出中发布在单独的示例页面下。
对于将在未来版本中移除的 API,在注释块中添加一个@deprecated 注释行。在弃用注释中提及替代/替换 API。
/** * ... * * @deprecated This function is deprecated. Use another new function instead. */
Doxygen 输出包含一个命名空间页面,其中显示了处理过的文件中所有用注释块声明的命名空间。这是一个 doxygen 描述注释的示例,用于命名空间声明。
/** * @brief cuSpatial interfaces * * This is the top-level namespace which contains all cuSpatial functions and types. */ namespace cuspatial {
对于每个唯一的命名空间声明,描述注释应只包含一次。否则,如果找到多个描述,doxygen 会以任意顺序在输出页面中聚合这些描述。
如果您引入一个新的命名空间,只需为一个声明提供描述块,而不是为每个出现的地方提供。
将声明分组到模块中有助于用户在 doxygen 页面中查找 API。通常,常用函数已逻辑地分组到头文件中,但 doxygen 在其输出中不会自动以这种方式分组。
doxygen 输出包含一个模块页面,该页面使用分组 doxygen 命令将项目组织成指定的组。这些命令可以跨头文件、源文件甚至命名空间对常用函数进行分组。通过在现有组内定义新组,组也可以嵌套。
对于 libcuspatial,所有组的层次结构都在doxygen_groups.h 头文件中定义。doxygen_groups.h
文件无需包含在任何其他源文件中,因为此文件中的定义仅由 doxygen 工具用于在模块页面中生成组。仅修改此文件以添加或更新组。现有组经过精心构建和命名,因此应审慎添加新组。
创建新 API 时,使用@ingroup 标签以及doxygen_groups.h 文件中的组引用 ID 来指定其所属组。
namespace cuspatial { /** * @brief ... * * @ingroup distance * * @tparam... * @param ... * @return ... */ template <class Cart2dItA, class Cart2dItB, class OutputIt> OutputIt pairwise_point_distance(Cart2dItA points1_first, ...); } // namespace cuspatial
当一个文件包含同一组中的多个函数、类或结构体时,您应该改用带有 @{ ... @}
对的 @addtogroup 来自动将 doxygen 注释块包含为组的一部分。
namespace cuspatial { /** * @addtogroup distance * @{ */ /** * @brief ... * * @param ... * @return ... */ template <class Cart2dItA, class Cart2dItB, class OutputIt> OutputIt pairwise_point_distance(Cart2dItA points1_first, ...); /** @} */ } // namespace cuspatial
这样做可以省去在文件内单独的 doxygen 注释块中添加 @ingroup。确保在 @addtogroup 命令块后包含一个空行,以便 doxygen 知道它不适用于源代码中紧随其后的内容。注意,如果带有 @{ ... @}
对的 @addtogroup 包含命名空间声明,doxygen 不会将组分配给项目。因此,如上例所示,将 @addtogroup 和 @{ ... @}
包含在命名空间声明的大括号之间。
组标签摘要
标签/命令 | 使用位置 |
---|---|
@defgroup | 仅用于doxygen_groups.h,应包含组的标题。 |
@ingroup | 在头文件中的声明语句的独立 doxygen 块注释内部使用。 |
@addtogroup | 在命名空间声明内的同一文件中包含多个声明时,用此代替 @ingroup。不要指定组标题。 |
@{ ... @} | 仅与 @addtogroup 一起使用。 |
请参阅doxygen_groups.h 查看现有组的列表。
我们建议使用 conda (conda install doxygen
) 或 Linux 包管理器 (sudo apt install doxygen
) 安装 Doxygen。或者,您可以从源代码构建和安装 doxygen。
要构建 libcuspatial 的 HTML 文档,只需在包含 Doxyfile
的 cpp/doxygen
目录中运行 doxygen
命令即可。libcuspatial 文档也可以从 cmake 构建目录(例如 cpp/build/release
)使用 cmake --build . --target docs_cuspatial
进行构建。
Doxygen 读取并处理 cpp/include/
目录下的所有适当源文件。输出生成在 cpp/doxygen/html/
目录中。您可以将此处生成的本地 index.html
文件加载到任何网络浏览器中查看结果。
要在远程服务器上查看构建的文档,您可以使用 Python 运行一个简单的 HTTP 服务器:cd html && python -m http.server
。然后,在本地网络浏览器中打开 http://<IP address>:8000
,其中 <IP address> 替换为您运行 HTTP 服务器的机器的 IP 地址。
doxygen 输出仅用于构建公共 API 和类的文档。例如,输出不应包含 detail
或 /src
文件的文档,这些目录已在 Doxyfile
配置中排除。当由 RAPIDS 构建/CI 系统发布时,doxygen 输出会显示在RAPIDS 网站上。