指南:基于 Doxygen 的源碼注釋規(guī)范與文檔構(gòu)建實(shí)踐)
數(shù)據(jù)分析數(shù)據(jù)工程機(jī)器學(xué)習(xí)【免費(fèi)下載鏈接】cudfcuDF - GPU DataFrame Library項(xiàng)目地址https://gitcode.com/gh_mirrors/cu/cudf點(diǎn)擊查看免費(fèi)下載本文是 cuDFGPU DataFrame LibraryC 底層庫(kù) libcudf 的開(kāi)發(fā)者文檔指南完整梳理了倉(cāng)庫(kù)內(nèi) cpp/doxygen/developer_guide/DOCUMENTATION.md 所規(guī)定的 Doxygen 注釋規(guī)范、標(biāo)簽用法與文檔構(gòu)建流程并結(jié)合倉(cāng)庫(kù)中的 Doxyfile、doxygen_groups.h、頭文件注釋實(shí)例與 CI 腳本講解如何為 libcudf 公開(kāi) C API 編寫(xiě)規(guī)范、完整、可被自動(dòng)解析的文檔。讀完本文你將掌握 libcudf 的注釋書(shū)寫(xiě)約定版權(quán)頭、塊注釋、常用標(biāo)簽、模塊分組機(jī)制ingroup/addtogroup以及本地構(gòu)建與 CI 校驗(yàn) HTML 文檔的完整方法。適用范圍與總體原則這些規(guī)范適用于 libcudf所有 C 源文件的 Doxygen 風(fēng)格注釋但只有公開(kāi) API 與公開(kāi)類會(huì)被真正發(fā)布到線上 API 文檔頁(yè)。Doxygen 生成的 libcudf 文檔是 cuDF 官方文檔體系中 libcudf API 參考的組成部分因此注釋質(zhì)量直接決定了下游用戶與工具包括搜索引擎、Agent 與 LLM對(duì)庫(kù)接口的理解程度。libcudf 文檔化的核心原則只對(duì)公開(kāi)接口投入完整的文檔編寫(xiě)精力內(nèi)部實(shí)現(xiàn)detail目錄、src目錄不在發(fā)布范圍內(nèi)Doxyfile 中通過(guò)排除規(guī)則將其過(guò)濾每個(gè)公開(kāi)函數(shù)、類、枚舉、命名空間的注釋都應(yīng)清晰說(shuō)明輸入到輸出的轉(zhuǎn)換邏輯并覆蓋性能、邊界、參數(shù)限制、默認(rèn)值以及 null 值的處理方式注釋是源碼的一部分書(shū)寫(xiě)時(shí)應(yīng)兼顧編輯器中的可讀性與Doxygen 渲染頁(yè)面中的可讀性。版權(quán)聲明頭Copyright License每個(gè) C 源文件開(kāi)頭都應(yīng)包含如下許可證頭注釋在 cpp/doxygen/developer_guide/DOCUMENTATION.md 中給出實(shí)際源碼如 doxygen_groups.h 頂部即按此格式書(shū)寫(xiě)/* * SPDX-FileCopyrightText: Copyright (c) 2021-2022, NVIDIA CORPORATION. * SPDX-License-Identifier: Apache-2.0 */要點(diǎn)注釋必須以/*開(kāi)頭而非/**否則會(huì)被 Doxygen 當(dāng)作文檔塊處理版權(quán)年份規(guī)則新文件寫(xiě)創(chuàng)建年份被修改的文件寫(xiě)成區(qū)間形式如2019-2021如果只是格式化等無(wú)實(shí)質(zhì)內(nèi)容變更可不更新年份。Doxygen 工具與 Doxyfile 定制Doxygen 負(fù)責(zé)從 C 注釋中生成 HTML 頁(yè)面它能識(shí)別并解析塊注釋并在遇到 Doxygen 命令本文檔中亦稱 tag時(shí)進(jìn)行專門(mén)的輸出格式化。Doxygen 可識(shí)別的命令有近 200 個(gè)本文檔只給出 libcudf 實(shí)際使用與推薦的子集。Doxygen 的處理過(guò)程可通過(guò) Doxyfile 中的選項(xiàng)定制該文件位于cpp/doxygen/目錄。原文檔給出了四個(gè)關(guān)鍵選項(xiàng)結(jié)合當(dāng)前倉(cāng)庫(kù)中 Doxyfile 的實(shí)際內(nèi)容cpp/doxygen/Doxyfile完整整理如下OptionSetting說(shuō)明PROJECT_NAMElibcudf主頁(yè)使用的項(xiàng)目標(biāo)題Doxyfile 第 35 行PROJECT_NUMBER$(RAPIDS_VERSION)版本號(hào)。原文檔表格中示例為22.02.00當(dāng)前 Doxyfile 已改為由構(gòu)建/CI 注入的RAPIDS_VERSION變量第 41 行與倉(cāng)庫(kù) VERSION 文件對(duì)應(yīng)EXTENSION_MAPPINGcuC cuhC將cu與cuh文件按 C 解析第 322-323 行使 CUDA 源文件也能被正確文檔化INPUTmain_page.md regex.md unicode.md developer_guide/BENCHMARKING.md developer_guide/DOCUMENTATION.md developer_guide/DEVELOPER_GUIDE.md developer_guide/PROFILING.md developer_guide/TESTING.md ../include 以及 cudf_test 工具頭文件與 ../libcudf_kafka/include內(nèi)嵌 Markdown 文件與要處理的源碼目錄第 860-875 行。比原文檔表格更完整還包含developer_guide/下的多篇開(kāi)發(fā)者指南與 Kafka 擴(kuò)展頭文件FILE_PATTERNS*.cpp *.hpp *.h *.c *.cu *.cuh需要處理的文件擴(kuò)展名第 904-909 行RECURSIVEYES遞歸搜索輸入目錄第 915 行EXCLUDE_PATTERNS/nvtx//detail//cudf_test/排除 NVTX、內(nèi)部實(shí)現(xiàn)detail與測(cè)試工具目錄第 940-942 行確保只發(fā)布公開(kāi) APIEXCLUDE_SYMBOLSorg::apache *_impl *Impl排除特定符號(hào)第 953-955 行USE_MDFILE_AS_MAINPAGEmain_page.md將 main_page.md 作為主頁(yè)內(nèi)容第 1037 行FILTER_PATTERNS*.md./modify_fences.sh對(duì) Markdown 輸入應(yīng)用 modify_fences.sh 過(guò)濾第 1015 行SEARCHENGINEYES生成內(nèi)置搜索框第 1650 行INPUT中的相對(duì)路徑是相對(duì)于cpp/doxygen目錄解析的因此../include實(shí)際指向倉(cāng)庫(kù)的cpp/include。塊注釋Block Comments書(shū)寫(xiě)風(fēng)格描述函數(shù)、類、其他類型、分組與文件的塊注釋統(tǒng)一采用如下風(fēng)格/** * description text and * doxygen tags go here */規(guī)則細(xì)節(jié)Doxygen 注釋塊以/**開(kāi)始、以*/結(jié)束且首尾行不允許再有其他內(nèi)容——不要在首尾行添加橫線-----或星號(hào)*****塊必須緊鄰其所描述的源碼行之前塊可以按需縮進(jìn)以便與所描述條目在垂直方向上對(duì)齊/**與*/之間的每一行應(yīng)以「一個(gè)空格 一個(gè)星號(hào)」開(kāi)頭星號(hào)之后的所有文本包括標(biāo)簽聲明再空一格書(shū)寫(xiě)。標(biāo)簽/命令命名約定統(tǒng)一使用作為 Doxygen 命令前綴例如brief、code等而不是反斜杠\形式。Markdown 支持與限制Doxygen 的 Markdown 支持是受限的注釋塊內(nèi)可以使用鏈接、表格、列表等格式。在源碼文本可讀性與 Doxygen 網(wǎng)頁(yè)可讀性之間有時(shí)需要權(quán)衡——例如 Markdown 表格中的%字符與管道符|存在可讀性限制%在 Doxygen 中另有禁用自動(dòng)鏈接的語(yǔ)義見(jiàn) Doxyfile 的AUTOLINK_SUPPORT相關(guān)說(shuō)明。應(yīng)避免直接使用 HTML 標(biāo)簽雖然 Doxygen 的 Markdown 支持 HTML 標(biāo)簽但其 HTML 支持同樣是受限的混用容易造成渲染異常。完整示例注釋塊與標(biāo)簽的典型用法以下是 cpp/doxygen/developer_guide/DOCUMENTATION.md 給出的示例幾乎覆蓋了 libcudf 中 Doxygen 塊注釋與標(biāo)簽的全部常見(jiàn)形態(tài)/** * file source_file.cpp * brief Description of source file contents * * Longer description of the source file contents. */ /** * brief One line 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 line description of the member function * * A more detailed description of what this function does and what * its logic does. * * code * example_classint 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 line description of this free function * * ingroup optional_predefined_group_id * * A detailed description must start after a blank line. * * code * templatetypename T * struct myfunctor { * bool operator()(T input) { return input % 2 0; } * }; * free_functionmyfunctor,int(myfunctor{},12); * endcode * * throw cudf::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) { CUDF_EXPECTS( input_argument 0, input_argument must be positive); return functor(input_argument); } /** * brief Short, one line 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 };示例中值得注意的細(xì)節(jié)單行成員與枚舉值可使用行尾///形式快速注釋函數(shù)邏輯的注釋?xiě)?yīng)使用普通//注釋不要用 Doxygen 風(fēng)格塊注釋詳細(xì)描述必須與brief之間留一個(gè)空行函數(shù)體內(nèi)的局部注釋不屬于 API 文檔范疇。描述規(guī)范Descriptions注釋描述應(yīng)清楚說(shuō)明輸出如何由輸入產(chǎn)生并包含性能考量與邊界情況說(shuō)明參數(shù)值的限制與是否聲明了默認(rèn)值不要忘記說(shuō)明 null 值如何處理或產(chǎn)生條件允許時(shí)盡量附帶一個(gè)簡(jiǎn)短示例。briefbrief文本應(yīng)是一行簡(jiǎn)短描述。Doxygen 在輸出頁(yè)面中給 brief 文本的空間很小因此它更像標(biāo)題而非句子通常不需要句號(hào)除非它確實(shí)是完整句子。brief行之后必須跟一個(gè)空的注釋行之后才是長(zhǎng)描述即注釋塊中未被任何 Doxygen 命令標(biāo)記的其余文本/** * brief Short description or title * * Long description. *copydoc頭文件中的聲明文檔應(yīng)當(dāng)清晰完整。為避免函數(shù)定義處重復(fù)整段注釋可使用copydoc標(biāo)簽引用已有注釋/** * copydoc complicated_function(int,double*,float*) * * Any extra documentation. */copydoc在文檔化僅因stream參數(shù)不同而不同的detail函數(shù)時(shí)特別有用——公開(kāi)函數(shù)與 detail 版本共享文檔只追加說(shuō)明 stream 參數(shù)/** * copydoc cudf::segmented_count_set_bits(bitmask_type const*,std::vectorsize_type const) * * param[in] stream Optional CUDA stream on which to execute kernels */ std::vectorsize_type segmented_count_set_bits(bitmask_type const* bitmask, std::vectorsize_type const indices, cuda::stream_ref stream cudf::get_default_stream());必須寫(xiě)出函數(shù)的完整簽名包括可選參數(shù)Doxygen 才能正確定位被復(fù)制的注釋。這一模式在倉(cāng)庫(kù)中廣泛使用例如 cpp/include/cudf/copying.hpp 中slice/split的 column 與 table 重載即通過(guò)copydoc cudf::slice(...)復(fù)用注釋。函數(shù)參數(shù)標(biāo)簽的順序以下標(biāo)簽應(yīng)出現(xiàn)在函數(shù)注釋塊末尾附近并按下表順序排列CommandDescriptionthrow說(shuō)明函數(shù)可能拋出異常的條件tparam每個(gè)模板參數(shù)的說(shuō)明param每個(gè)函數(shù)參數(shù)的說(shuō)明return返回對(duì)象或值的簡(jiǎn)短說(shuō)明throw為函數(shù)可能拋出的每一個(gè)異常添加一行throw注釋。只需包含函數(shù)自身拋出的異常如果函數(shù)調(diào)用了其他可能拋異常的函數(shù)不需要在此記錄那些異常。異常名不要加反引號(hào)以便 Doxygen 正確生成引用鏈接* * throw cudf::logic_error if input_argument is negative or zero *使用throws亦可但 VS Code 等工具只對(duì)throw做語(yǔ)法高亮因此統(tǒng)一推薦throw。倉(cāng)庫(kù)中的實(shí)際例子可參考 cpp/include/cudf/filling.hppfill的 in-place 版本用多個(gè)throws cudf::logic_error分別說(shuō)明「需要內(nèi)存重分配」「范圍無(wú)效begin 0 等」「destination 與 value 類型不同」「value 非法而 destination 非空」等條件。tparam為函數(shù)聲明的每個(gè)模板參數(shù)添加一行tparam標(biāo)簽后指定的參數(shù)名必須與模板參數(shù)名完全一致。定義應(yīng)說(shuō)明參數(shù)的要求例如若模板是 functor 或 predicate則描述期望的輸入類型與輸出* * tparam functor_type The type of the functor * tparam input_type The datatype of the input argument *param為傳給函數(shù)的每個(gè)參數(shù)添加一行param參數(shù)名必須與函數(shù)參數(shù)名匹配。若參數(shù)方向無(wú)法從聲明與命名中明確看出應(yīng)追加[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 *建議盡量將三列文本垂直對(duì)齊便于在源碼編輯器中閱讀。描述通常也如標(biāo)題一般僅當(dāng)是完整句子時(shí)才加句號(hào)。return若函數(shù)返回對(duì)象或值在注釋塊末尾添加一行return并簡(jiǎn)要描述返回內(nèi)容。不要在return注釋中包含返回類型類型信息由聲明給出/** * ... * * return A new column of type INT32 and no nulls */內(nèi)聯(lián)示例Inline Examples在注釋塊中附帶源代碼示例通常很有幫助使用code與endcode標(biāo)簽對(duì)* * code * auto result cudf::make_column( ); * endcode *Doxygen 支持 C 及多種語(yǔ)言如 Python、Java的語(yǔ)法高亮默認(rèn)code按所在源碼的語(yǔ)言高亮??赏ㄟ^(guò)標(biāo)簽內(nèi)指定文件擴(kuò)展名切換語(yǔ)言* * code{.py} * import cudf * s cudf.Series([1,2,3]) * endcode *需要偽代碼時(shí)可使用{.pseudo}* * Sometimes pseudocode 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 *編寫(xiě)示例片段時(shí)使用全限定類名可讓 Doxygen 在示例中生成引用鏈接* * code * auto result1 make_column( ); // reference link will not be created * auto result2 cudf::make_column( ); // reference link will be created * endcode *雖然三個(gè)反引號(hào) 的代碼塊也能工作但在 VS Code 等源碼編輯器中不夠醒目故不推薦。切勿在聲明注釋中使用example標(biāo)簽——Doxygen 會(huì)把整個(gè)源文件當(dāng)作示例源代碼并將其發(fā)布到輸出中獨(dú)立的Examples頁(yè)面。棄用標(biāo)記Deprecations對(duì)將在未來(lái)版本移除的 API添加一行deprecated注釋并在注釋中提及替代/替換 API/** * ... * * deprecated This function is deprecated. Use another new function instead. */命名空間NamespacesDoxygen 輸出包含一個(gè)Namespaces頁(yè)面展示所有帶注釋塊的命名空間聲明。示例/** * brief cuDF interfaces * * This is the top-level namespace which contains all cuDF functions and types. */ namespace CUDF_EXPORT cudf {規(guī)則每個(gè)唯一的命名空間聲明只寫(xiě)一次描述注釋。若同一命名空間出現(xiàn)多處描述Doxygen 會(huì)以任意順序聚合這些描述導(dǎo)致輸出混亂。引入新命名空間時(shí)只需為一個(gè)聲明提供描述塊。分組與模塊Groups/Modules將聲明歸組到模塊中有助于用戶在 Doxygen 頁(yè)面中快速找到 API。雖然公共函數(shù)通常已在頭文件中按邏輯分組但 Doxygen不會(huì)自動(dòng)按此方式組織輸出。Doxygen 輸出包含一個(gè)Modules頁(yè)面它使用 Doxygen 的分組命令將條目組織為組。分組命令可以跨頭文件、源文件甚至命名空間對(duì)公共函數(shù)分組組之間還可以嵌套在已有組內(nèi)定義新組。doxygen_groups.h分組的單一事實(shí)來(lái)源libcudf 的全部組層級(jí)都定義在 cpp/include/doxygen_groups.h 頭文件中。該文件不需要被任何源文件包含——其中的定義只被 Doxygen 工具用于生成Modules頁(yè)面因此修改此文件只應(yīng)為添加或更新組。既有的組經(jīng)過(guò)了精心結(jié)構(gòu)與命名新增組時(shí)應(yīng)謹(jǐn)慎考量。從倉(cāng)庫(kù)中的 doxygen_groups.h 可以看到完整的組樹(shù)結(jié)構(gòu)頂層包括default_stream、memory_resource、cudf_classesClasses含 Column/Table/Scalar/Fixed Point 等子組、column_apisColumn and Table含 Copying/Sorting/Searching/Hashing/Merging/Joining/Quantiles/Reduction/Aggregation/Transformation/Reshaping/Reordering/Interop 等子組、datetime_apis、strings_apis、dictionary_apis、io_apis、json_apis、lists_apis、nvtext_apis、utility_apis、labeling_apis、expressions與tdigest等。新增 API 時(shí)從其對(duì)應(yīng)功能域如字符串、IO、Lists查找并復(fù)用已有組 id 即可。使用 ingroup 歸組創(chuàng)建新 API 時(shí)用ingroup標(biāo)簽并指定 doxygen_groups.h 中的組引用 idnamespace CUDF_EXPORT cudf { /** * brief ... * * ingroup transformation_fill * * param ... * return ... */ std::unique_ptrcolumn fill(table_view const input,...); } // namespace cudf使用 addtogroup 批量歸組也可用addtogroup配合{ ... }標(biāo)簽對(duì)將文件內(nèi)的 Doxygen 注釋塊自動(dòng)納入某個(gè)組namespace CUDF_EXPORT cudf { /** * addtogroup transformation_fill * { */ /** * brief ... * * param ... * return ... */ std::unique_ptrcolumn fill(table_view const input,...); /** } */ } // namespace cudf這可以省去在文件內(nèi)每個(gè)注釋塊中單獨(dú)寫(xiě)ingroup。注意事項(xiàng)addtogroup命令塊之后必須保留一個(gè)空行讓 Doxygen 知道它不作用于后續(xù)源碼若addtogroup與{ ... }對(duì)包含命名空間聲明Doxygen 不會(huì)將組賦給條目——因此必須像上面的示例那樣把a(bǔ)ddtogroup與{ ... }放在命名空間聲明的大括號(hào)之間。分組標(biāo)簽速查表Tag/CommandWhere to usedefgroup僅用于 doxygen_groups.h且應(yīng)包含組的標(biāo)題ingroup在頭文件聲明語(yǔ)句的單個(gè) Doxygen 注釋塊內(nèi)使用addtogroup對(duì)同一文件、同一命名空間內(nèi)的多個(gè)聲明使用替代逐個(gè)ingroup不要指定組標(biāo)題{ ... }僅與addtogroup搭配使用構(gòu)建 Doxygen 輸出安裝 Doxygen推薦通過(guò) condaconda install doxygen或 Linux 包管理器sudo apt install doxygen安裝 Doxygen也可從源碼自行構(gòu)建。注意當(dāng)前倉(cāng)庫(kù) CI 校驗(yàn)?zāi)_本 ci/checks/doxygen.sh 期望的 Doxygen 版本為1.18.0版本不匹配時(shí)會(huì)直接跳過(guò)校驗(yàn)并給出 warning。兩種構(gòu)建方式方式一直接運(yùn)行 doxygen 命令在包含 Doxyfile 的cpp/doxygen目錄中運(yùn)行cd cpp/doxygen doxygenDoxygen 讀取并處理cpp/include/下所有符合條件的源文件輸出生成到cpp/doxygen/html/目錄Doxyfile 中HTML_OUTPUT html且OUTPUT_DIRECTORY留空表示當(dāng)前目錄??梢灾苯佑脼g覽器打開(kāi)本地生成的index.html查看結(jié)果。方式二通過(guò) CMake 目標(biāo)構(gòu)建在 cmake 構(gòu)建目錄如cpp/build中運(yùn)行cmake --build . --target docs_cudf倉(cāng)庫(kù) cpp/CMakeLists.txt 中定義了docs_cudf自定義目標(biāo)它通過(guò)add_custom_command在${CUDF_SOURCE_DIR}/doxygen工作目錄下執(zhí)行doxygen Doxyfile并注入RAPIDS_VERSION與RAPIDS_VERSION_MAJOR_MINOR環(huán)境變量——這正是 Doxyfile 中PROJECT_NUMBER $(RAPIDS_VERSION)變量值的來(lái)源。遠(yuǎn)程查看文檔若文檔構(gòu)建在遠(yuǎn)程服務(wù)器上可用 Python 啟動(dòng)簡(jiǎn)易 HTTP 服務(wù)器cd html python -m http.server然后在本地瀏覽器中打開(kāi)http://IP地址:8000將 IP 替換為運(yùn)行 HTTP 服務(wù)器機(jī)器的地址。發(fā)布范圍與 CI 校驗(yàn)Doxygen 輸出只面向公開(kāi) API 與公開(kāi)類例如輸出不應(yīng)包含detail或src文件這些目錄已在 Doxyfile 的EXCLUDE_PATTERNS*/nvtx/*、*/detail/*、*/cudf_test/*與EXCLUDE_SYMBOLSorg::apache、*_impl、*Impl中排除。構(gòu)建/CI 系統(tǒng)發(fā)布后doxygen 輸出會(huì)成為 cuDF 官方文檔中 libcudf API 參考的一部分。倉(cāng)庫(kù)還提供了一鍵校驗(yàn)?zāi)_本 ci/checks/doxygen.sh它會(huì)從倉(cāng)庫(kù)根目錄的 VERSION 文件解析出RAPIDS_VERSION然后以QUIET YES、GENERATE_HTML NO的追加配置運(yùn)行 doxygen并過(guò)濾掉缺失 tag 文件類錯(cuò)誤任何剩余 stderr 輸出都會(huì)導(dǎo)致校驗(yàn)失敗——這保證了文檔注釋在 CI 層面持續(xù)保持無(wú)告警狀態(tài)。延伸閱讀完整的開(kāi)發(fā)者規(guī)范體系見(jiàn) cpp/doxygen/developer_guide/DEVELOPER_GUIDE.md基準(zhǔn)測(cè)試、性能分析與測(cè)試相關(guān)的文檔規(guī)范見(jiàn) cpp/doxygen/developer_guide/BENCHMARKING.md、cpp/doxygen/developer_guide/PROFILING.md 與 cpp/doxygen/developer_guide/TESTING.md文檔主頁(yè)內(nèi)容與正則、Unicode 專題分別見(jiàn) cpp/doxygen/main_page.md、cpp/doxygen/regex.md 與 cpp/doxygen/unicode.md分組定義的唯一權(quán)威文件是 cpp/include/doxygen_groups.h新增 API 時(shí)按其中已有組 id 使用ingroup或addtogroup想觀察標(biāo)簽在真實(shí)代碼中的落地形態(tài)可參考 cpp/include/cudf/filling.hppbrief/throws/param的密集使用與 cpp/include/cudf/copying.hppcopydoc復(fù)用聲明文檔。贊分享數(shù)據(jù)分析數(shù)據(jù)工程機(jī)器學(xué)習(xí)【免費(fèi)下載鏈接】cudfcuDF - GPU DataFrame Library項(xiàng)目地址https://gitcode.com/gh_mirrors/cu/cudf點(diǎn)擊查看免費(fèi)下載相關(guān)推薦libcudf C 文檔編寫(xiě)指南Doxygen 注釋規(guī)范與 API 文檔構(gòu)建實(shí)踐cuDFlibcudf C 文檔編寫(xiě)指南Doxygen 注釋規(guī)范與 API 文檔構(gòu)建實(shí)踐cuDF cuDF 是 NVIDIA 開(kāi)源的 GPU 加速 DataF數(shù)據(jù)分析數(shù)據(jù)工程機(jī)器學(xué)習(xí)uWebSockets源碼注釋規(guī)范Doxygen與文檔生成uWebSockets源碼注釋規(guī)范Doxygen與文檔生成 項(xiàng)目概述 uWebSockets是一個(gè)簡(jiǎn)單、安全且符合標(biāo)準(zhǔn)的Web服務(wù)器適用于最苛刻的應(yīng)用場(chǎng)景。后端網(wǎng)絡(luò)消息路由WebSocketReactiveCocoa 代碼注釋規(guī)范基于 Xcode Markup 的 Swift 文檔編寫(xiě)實(shí)戰(zhàn)指南ReactiveCocoa 代碼注釋規(guī)范基于 Xcode Markup 的 Swift 文檔編寫(xiě)實(shí)戰(zhàn)指南 導(dǎo)讀 本文以 ReactiveCocoa 倉(cāng)庫(kù)中的UI組件創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考