Commit 1fad4d65 authored by Nicolas Denoyelle's avatar Nicolas Denoyelle Committed by Swann Perarnau
Browse files

[doc] Add doxygen documentation to the project

parent 10a2b644
......@@ -3,6 +3,7 @@
# unignore files with extensions
!*.*
# unignore special files
!AUTHORS
!LICENSE
......@@ -50,7 +51,7 @@ stamp-h1
/install-sh
/missing
/stamp-h1
version.h
/version.h
/m4/libtool.m4
/m4/ltmain.sh
/m4/ltoptions.m4
......
......@@ -4,6 +4,7 @@ variables:
stages:
- style
- build
- release
make:generic:
stage: build
......@@ -53,3 +54,12 @@ checkpatch:
stage: style
script:
- nix run -f "$ARGOPKGS" checkpatch --command checkpatch.pl
readthedocs:
stage: release
when: on_success
only:
- master
- /v\.[0-9]+\.[0-9]+\.[0-9]+/
script:
- nix run nixpkgs.curl -c curl -X POST -d "branch=$CI_COMMIT_REF_NAME" -d "token=$READTHEDOCS_TOKEN" https://readthedocs.org/api/v2/webhook/argo-aml/83161/
Contributing to The Project
===========================
AML Contribution Guide {#contributing_page}
============
The following is a set of guidelines for contributing to this project. These
are guidelines, not rules, so use your best judgment and feel free to propose
changes. For information about the overall design of the library and general
coding guidelines, see the `DESIGN.markdown` file.
Welcome to AML contribution guide.
This page walk through the main library expectations.
When contributing to AML, contributors should write
features aligned with AML goal and AML spirit.
Additionnally, several good practices are requested, some beeing inforced
through the continuous integration (CI) pipeline.
For readability and maintainability, coding conventions need to be respected,
code needs to be tested, documented and integrated with the main AML branch
and its build tool-chain.
## Contribution Workflow
## General Guidelines
At its core, AML is able to provide access to established, well known
abstractions inside a common toolbox, with the more flexibility possible.
Abstractions are made available through __building blocks__, each representing
a single abstraction. Each building block is separated into a __generic__ API
for operations that the abstraction provides, and __implementations__ of those
operations for a specific implementation of the abstraction.
__generic__ API, i.e the first layer exposed to users
through a generic interface declares a table of operations common to the
abstraction, the main abstraction structure containing a such a table
and an opaque handle to store implementation specific data.
```
struct aml_building_block_ops{
aml_building_block_op0();
...
};
struct aml_building_block_data;
struct aml_building_block{
struct aml_building_block_ops *ops;
struct aml_building_block_data *data;
};
```
A set of generic functions taking the abstraction as first argument
is supposed to be exposed while it will de-reference underlying
implementation function table to implement expected behavior.
Such generic functions are supposed to return an AML error code as defined
in [error header](@ref error.h).
```
int aml_building_block_feature(struct aml_building_block *, ...);
```
Building blocks should interact with each other through the generic API, but
specific implementations are allowed to break this rule for
performance-oriented reasons. A generic version should still be available.
It is expected that these will be transparent and composable,
because low-level optimizations require control.
Therefore, most implementation details (structures, functions) will be exposed
to the user in a dedicated header, and use of opaque structures, static functions
and variables there should be avoided.
Moreover, customization of a building block should happen at creation time: the goal
is to make it easy for users to evaluate different configurations options with
minimal impact on the inner code of the application.
Therefore, building blocks specialized implementation, must declare a dynamic allocator, free,
initialization and finish functions, and stack declaration.
```
int aml_building_block_create (struct aml_building_block **, ...);
void aml_building_block_destroy(struct aml_building_block *);
int aml_building_block_init (struct aml_building_block *, ...);
void aml_building_block_fini (struct aml_building_block *);
#define AML_BUILDING_BLOCK_DECL(name) \
struct aml_building_block_data __ ##name## _inner_data; \
struct aml_building_block name = { \
&aml_building_block_ops, \
(struct aml_building_block_data *)&__ ## name ## _inner_data, \
}
```
Usually a building blocks implementation would declare an exportable (`extern`)
`struct aml_building_block_ops`, and `struct aml_building_block`, to provide
users with a default static implementation of the block.
Finally, building blocks headers, sources and tests go to a dedicated folder
located respectively in `include`, `src` and `tests`.
## Coding Convention
AML code respects several coding conventions. Some of them are enforced through
the CI pipeline.
Prior to start coding AML, you might want to set your editor to minimize
the process of code formatting.
Most of the formatting can also be scripted with `indent` program.
Code formatting compliance with AML requirements can be checked by running
[linux kernel linter](https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl)
at the root of AML project.
The list of coding convention is the following:
* use tabulation of 8 characters,
* remove trailing white spaces,
* lines may not exceed 80 characters,
* pointers star have to stick to the variable name: `void *var;`,
* function return type is on the same line as function name,
* curly braces are on the same line as the statement or function,
* A new line must appear after curly braces.
* macros are UPPERCASE_WITH_UNDERSCORES, function lowercase_with_underscores
* All functions/macros should start with aml/AML followed by the name of the building block involved.
## Versioning and Submission Workflow
AML code and CI runners is hosted on Argonne National Laboratory
[gitlab](https://xgitlab.cels.anl.gov/argo/aml) infrastructure under git version control.
New user may create new branches upon request to host and test their code.
New branched must be created from the master branch and merging is done
via git or gitlab pull request interface.
We basically follow the [Gitlab Flow](https://docs.gitlab.com/ee/workflow/gitlab_flow.html)
model:
- `master` is the primary branch for up-to-date development
- any new feature/development should go into a `feature-branch` based of
- any new feature/development should go into a `feature-branch` based on
`master` and merge into `master` after.
- we follow a `semi-linear history with merge commits` strategy: each merge
request should include clean commits, but only the HEAD and merge commit
......@@ -21,7 +126,8 @@ model:
change should appear in its own commit.
- to help with in-development work, CI will not activate on branches with
names started with wip/
## Commit Messages Styleguide
### Commit Messages Styleguide
- use present tense, imperative mood
- reference issues and merge requests
......@@ -59,7 +165,7 @@ commit.template my-config-template.txt` to use it automatically.
# --------------------
```
## Signoff on Contributions:
### Signoff on Contributions:
The project uses the [Developer Certificate of
Origin](https://developercertificate.org/) for copyright and license
......@@ -69,3 +175,98 @@ the `LICENSE` file) and that you agree to the DCO.
To signoff commits, use: `git commit --signoff`.
To signoff a branch after the fact: `git rebase --signoff`
## Testing
AML project includes a set of unit and integration tests.
Each AML building block has its own set of tests in a separate directory.
Tests are launched together with automake test suite with the `make check` command.
Building blocks should be tested as thoroughly as possible and whenever
relevant, integration tests with other components should be available.
Tests compilation and launch are implemented together in `tests/Makefile.am`.
Whenever a branch is pushed to AML repository, it automatically triggers
the CI pipeline, unless branch name starts with `wip/`.
The CI pipeline must be successful for a merge request to be accepted.
## Documentation
For obvious reasons, the code and building block must be documented.
The whole documentatation is based doxygen tool.
All the public code (data structures, functions, macro, variables) must be
documented as precisely as possible. Additionnaly, new buiding blocks implementation
must create a group (with `\@defgroup`) and provide a detailed description of
the features it provides. Syntax for code documentation can be found
[here](http://www.doxygen.nl/manual/docblocks.html),
and most useful elements can be found in the example below.
```
/**
* \@defgroup aml_buidling_block_implementation "AML buidling block implemation"
*
* \@brief This is a short description of this group.
*
* The documentation encapsulated below
* including this long description of the building_block
* implementation will be create a section dedicated to this buidling block
* implementation. It will be possible to link to it in the main header
* documentation with "@ref" or "@see".
* \@{
**/
/**
* This is a default operation table implementing
* table defined in main header.
**/
extern struct aml_building_block_ops aml_building_block_ops;
/**
* This is the bb inner data declaration, to
* stuff with needed attributes.
**/
struct aml_building_block_data {};
/**
* This is the bb declaration
**/
struct aml_building_block{
struct aml_building_block_ops *ops;
struct aml_building_block_data *data;
};
/** This is the static buidling block declaration macro **/
#define AML_BUILDING_BLOCK_DECL(name) \
struct aml_building_block_data __ ##name## _inner_data; \
struct aml_building_block name = { \
&aml_building_block_ops, \
(struct aml_building_block_data *)&__ ## name ## _inner_data, \
}
/** Static declaration of the building block size **/
#define AML_BUILDING_BLOCK_ALLOCSIZE (sizeof(struct aml_building_block_data) + \
sizeof(struct aml_building_block))
/**
* Allocates and initializes a new building_block.
*
* \@param bb[out]: A pointer to store the new building block.
* \@param other[in]: Other parameters used as input.
* \@return AML_SUCCESS if successful; an error code otherwise.
**/
int aml_building_block_create(struct aml_building_block **bb, ...);
...
/**
* This is the end of the inclusion into building_block documentation group.
* \@}
**/
```
If the contribution is an implementation of a building block and header has
been placed in `include/aml/building_block` then its documentation will automatically added to
the project documentation. However, it is necessary to point to this particular group
with `@ref` or `@see` command in the [main aml header](\ref aml.h).
If the contribution creates new include directories, the latter have to be included
in `doc/aml.doxy` after the field `INPUT`.
......@@ -5,7 +5,12 @@ if ADD_BENCHMARKS
SUBDIRS += benchmarks
endif
if AML_DOXYGEN
SUBDIRS += doc
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = aml.pc
EXTRA_DIST = autogen.sh aml.pc README.markdown
......@@ -7,6 +7,30 @@ memory management policies for allocation and placement of data across devices.
This library is still in the prototyping phase. APIs might break often.
## Documentation
The latest documentation can be found
[online](https://argo-aml.readthedocs.io/en/latest/),
can be installed when installing a release or generated
from git clone before installing with
```
make -C doc doxygen
```
## Requirements:
* autoconf
* automake
* libnuma
## Installation
```
sh autogen.sh
./configure
make -j install
```
# General Architecture
The architecture of the library relies on two principles: type-specific
......
......@@ -69,6 +69,12 @@ AC_CHECK_HEADERS([numa.h],,[AC_MSG_ERROR([AML requires libnuma headers.])])
AC_CHECK_HEADERS([numaif.h],,[AC_MSG_ERROR([AML requires libnuma headers.])])
AC_CHECK_LIB(numa, mbind,,[AC_MSG_ERROR([AML requires libnuma.])])
# Doxygen
# See m4/ax_doxygen.m4
AC_CHECK_PROG(doxygen_happy, [doxygen], [yes], [no])
AM_CONDITIONAL([AML_DOXYGEN],[ test "x$doxygen_happy" = "xyes" ])
AC_CONFIG_HEADERS([include/config.h])
AC_CONFIG_FILES([Makefile
......@@ -80,6 +86,7 @@ AC_CONFIG_FILES([Makefile
src/utils/Makefile
include/Makefile
tests/Makefile
doc/Makefile
benchmarks/Makefile
aml.pc
include/aml/utils/version.h])
......
DATA_INSTALL_DIR=$(datadir)/aml
DOXYGEN_BUILD_DIR=./build-doxygen
SPHINX_BUILD_DIR=./build-sphinx
doxygen:
doxygen aml.doxy
create-doc-dir:
mkdir -p $(DATA_INSTALL_DIR)
install-doc-html:
if [ -d $(DOXYGEN_BUILD_DIR)/html ]; then \
cp -r $(DOXYGEN_BUILD_DIR)/html $(DATA_INSTALL_DIR); \
fi
install-data-local: create-doc-dir install-doc-html
uninstall-local:
rm -rf $(DATA_INSTALL_DIR)
clean-local:
rm -rf $(DOXYGEN_BUILD_DIR) $(SPHINX_BUILD_DIR)
dist-hook: doxygen
cp -r $(DOXYGEN_BUILD_DIR) $(distdir)
# Doxyfile 1.8.13
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a double hash (##) is considered a comment and is placed in
# front of the TAG it is preceding.
#
# All text after a single hash (#) is considered a comment and will be ignored.
# The format is:
# TAG = value [value, ...]
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
# for the list of possible encodings.
# The default value is: UTF-8.
DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
# double-quotes, unless you are using Doxywizard) that should identify the
# project for which the documentation is generated. This name is used in the
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = "AML"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = "0.1.0"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF =
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = "./build-doxygen"
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
# will distribute the generated files over these directories. Enabling this
# option can be useful when feeding doxygen a huge amount of source files, where
# putting all generated files in the same directory would otherwise causes
# performance problems for the file system.
# The default value is: NO.
CREATE_SUBDIRS = NO
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
# U+3044.
# The default value is: NO.
ALLOW_UNICODE_NAMES = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
# Ukrainian and Vietnamese.
# The default value is: English.
OUTPUT_LANGUAGE = English
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
# The default value is: YES.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
# description of a member or function before the detailed description
#
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
# The default value is: YES.
REPEAT_BRIEF = YES
# This tag implements a quasi-intelligent brief description abbreviator that is
# used to form the text in various listings. Each string in this list, if found
# as the leading text of the brief description, will be stripped from the text
# and the result, after processing the whole list, is used as the annotated
# text. Otherwise, the brief description is used as-is. If left blank, the
# following values are used ($name is automatically replaced with the name of
# the entity):The $name class, The $name widget, The $name file, is, provides,
# specifies, contains, represents, a, an and the.
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# doxygen will generate a detailed section even if there is only a brief
# description.
# The default value is: NO.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
# The default value is: NO.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
# before files name in the file list and in the header files. If set to NO the
# shortest path that makes the file name unique will be used
# The default value is: YES.
FULL_PATH_NAMES = YES
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
# Stripping is only done if one of the specified strings matches the left-hand
# part of the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the path to
# strip.
#
# Note that you can specify absolute paths here, but also relative paths, which
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
# header file to include in order to use a class. If left blank only the name of
# the header file containing the class definition is used. Otherwise one should
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
# support long names like on DOS, Mac, or CD-ROM.
# The default value is: NO.
SHORT_NAMES = NO
# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
# first line (until the first dot) of a Javadoc-style comment as the brief
# description. If set to NO, the Javadoc-style will behave just like regular Qt-
# style comments (thus requiring an explicit @brief command for a brief
# description.)
# The default value is: NO.
JAVADOC_AUTOBRIEF = NO
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
# requiring an explicit \brief command for a brief description.)
# The default value is: NO.
QT_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
# a brief description. This used to be the default behavior. The new default is
# to treat a multi-line C++ comment block as a detailed description. Set this
# tag to YES if you prefer the old behavior instead.
#
# Note that setting this tag to YES also means that rational rose comments are
# not recognized any more.
# The default value is: NO.
MULTILINE_CPP_IS_BRIEF = NO
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
# documentation from any documented member that it re-implements.
# The default value is: YES.
INHERIT_DOCS = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
# page for each member. If set to NO, the documentation of a member will be part
# of the file/class/namespace that contains it.
# The default value is: NO.
SEPARATE_MEMBER_PAGES = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
# uses this value to replace tabs by spaces in code fragments.
# Minimum value: 1, maximum value: 16, default value: 4.
TAB_SIZE = 4
# This tag can be used to specify a number of aliases that act as commands in
# the documentation. An alias has the form:
# name=value
# For example adding
# "sideeffect=@par Side Effects:\n"
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
# members will be omitted, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored
# for that language. For instance, namespaces will be presented as packages,
# qualified scopes will look different, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources. Doxygen will then generate output that is tailored for Fortran.
# The default value is: NO.
OPTIMIZE_FOR_FORTRAN = NO
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL