加载中...
搜索中...
无匹配项
libcuspatial C++ 文档指南

简短描述。*。

这些指南适用于使用 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

doxygen 工具用于从源代码中的 C++ 注释生成 HTML 页面。doxygen 识别并解析块注释,并在遇到doxygen 命令时执行专门的输出格式化。

doxygen 在注释块中识别近 200 个命令(本文档中也称为标签)。本文档提供了关于在 libcuspatial C++ 源代码中使用哪些命令/标签以及如何使用它们的指南。

doxygen 进程可以通过Doxyfile 中的选项进行定制。

以下是一些 libcuspatial 的 Doxyfile 中的自定义选项。

选项设置描述
PROJECT_NAMElibcuspatial主页上使用的标题
PROJECT_NUMBER22.10.00 版本号
EXTENSION_MAPPINGcu=C++ cuh=C++cucuh 文件作为 C++ 处理
INPUTmain_page.md ../include要处理的嵌入式 markdown 文件和源代码目录
FILE_PATTERNS*.cpp *.hpp *.h *.c *.cu *.cuh要处理的文件扩展名
EXCLUDE_PATTERNS*/detail/* */nvtx/*用于排除路径/文件名的通配符模式
TAGFILESrmm.tag=https://docs.rapids.org.cn/api/librmm/22.10 "libcudf.tag=https://docs.rapids.org.cn/api/libcudf/22.10"外部文档 tagfile 的链接。版本在每次发布时自动更新
PREDEFINEDdevice= \ host=预定义宏。有助于 CUDA 声明说明符。

块注释

使用以下样式编写描述函数、类及其他类型、组和文件的块注释。

/**
 * description text and
 * doxygen tags go here
 */

doxygen 注释块仅以 /** 开头并以 */ 结尾,这两行上不应有其他内容。不要在 doxygen 块的第一行和最后一行添加破折号 ----- 或额外的星号 *****。注释块必须紧接在它所引用的源代码行之前。块可以适当缩进,使其与所描述的项目垂直对齐。请参阅下面的示例部分。

/***/ 行之间的注释块中的每一行都应以一个空格后跟一个星号开头。这些行上的任何文本,包括标签声明,都应在星号后的一个空格后开始。

标签/命令名称

使用 @ 作为 doxygen 命令的前缀(例如 @brief、@code 等)

Markdown

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

@brief 文本应是一个简短的单句描述。doxygen 在输出页面中显示此文本的空间不多。@brief 行后面务必跟随一个空白注释行。

更长的描述是注释文本中未被任何 doxygen 命令标记的其余部分。

/**

  • * 更长的描述。*/

@copydoc

头文件中的声明文档应清晰完整。您可以使用@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);
    注意,您必须指定函数的完整签名,包括可选参数,以便 doxygen 能够找到它。

函数参数

以下标签应按照此处指定的顺序出现在函数注释块的末尾

命令描述
@throw指定函数可能抛出异常的条件
@tparam每个模板参数的描述
@param每个函数参数的描述
@return返回对象或值的简短描述
@pre指定函数的任何前置条件/要求

@throw

对于函数可能抛出的每个异常,在 doxygen 块中添加一个@throw 注释行。您只需包含函数本身抛出的异常。如果函数调用了另一个可能抛出异常的函数,则无需在此处记录这些异常。

包含异常的名称,不带反引号,以便 doxygen 可以正确添加引用链接。

/**
 * ...
 * @throw cuspatial::logic_error if `input_argument` is negative or zero
 */

使用 @throws 也是可以接受的,但 VS code 和其他工具仅对 @throw 进行语法高亮。

@tparam

对于此函数声明的每个模板参数,添加一个@tparam 注释行。doxygen 标签后指定的参数名称必须与模板参数名称完全匹配。

/**
 * ...
 * @tparam functor_type The type of the functor
 * @tparam input_type The datatype of the input argument
 */

定义应详细说明参数的要求。例如,如果模板用于仿函数或谓词,则描述预期的输入类型和输出。

@param

对于传递给此函数的每个函数参数,添加一个@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 注释行。包含对返回内容的简要描述。

/**
 * ...
 *
 * @return A new column of type INT32 and no nulls
 */

不要在 @return 注释中包含返回对象的类型。

@pre

对于函数的每个前置条件,添加一个@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 查看现有组的列表。

构建 Doxygen 输出

我们建议使用 conda (conda install doxygen) 或 Linux 包管理器 (sudo apt install doxygen) 安装 Doxygen。或者,您可以从源代码构建和安装 doxygen

要构建 libcuspatial 的 HTML 文档,只需在包含 Doxyfilecpp/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 网站上。