xref: /libCEED/doc/sphinx/source/libCEEDdev.md (revision 3f21f6b10abeb5d85d3454ea5cd38498737dc88a)
1# Developer Notes
2
3## Style Guide
4
5Please check your code for style issues by running
6
7`make style`
8
9In addition to those automatically enforced style rules, libCEED tends to follow the following code style conventions:
10
11- Variable names: `snake_case`
12- Strut members: `snake_case`
13- Function and method names: `PascalCase` or language specific style
14- Type names: `PascalCase` or language specific style
15- Constant names: `CAPS_SNAKE_CASE` or language specific style
16
17Also, documentation files should have one sentence per line to help make git diffs clearer and less disruptive.
18
19## Clang-tidy
20
21Please check your code for common issues by running
22
23`make tidy`
24
25which uses the `clang-tidy` utility included in recent releases of Clang.  This
26tool is much slower than actual compilation (`make -j8` parallelism helps).  To
27run on a single file, use
28
29`make interface/ceed.c.tidy`
30
31for example.  All issues reported by `make tidy` should be fixed.
32
33## Include-What-You-Use
34
35Header inclusion for source files should follow the principal of 'include what you use' rather than relying upon transitive `#include` to define all symbols.
36
37Every symbol that is used in the source file `foo.c` should be defined in `foo.c`, `foo.h`, or in a header file `#include`d in one of these two locations.
38Please check your code by running the tool [`include-what-you-use`](https://include-what-you-use.org/) to see recommendations for changes to your source.
39Most issues reported by `include-what-you-use` should be fixed; however this rule is flexible to account for differences in header file organization in external libraries.
40If you have `include-what-you-use` installed in a sibling directory to libCEED or set the environment variable `IWYU_CC`, then you can use the makefile target `make iwyu`.
41
42Header files should be listed in alphabetical order, with installed headers preceding local headers and `ceed` headers being listed first.
43The `ceed-f64.h` and `ceed-f32.h` headers should only be included in `ceed.h`.
44
45```c
46#include <ceed.h>
47#include <ceed/backend.h>
48#include <stdbool.h>
49#include <string.h>
50#include "ceed-avx.h"
51```
52
53## Shape
54
55Backends often manipulate tensors of dimension greater than 2.  It is
56awkward to pass fully-specified multi-dimensional arrays using C99 and
57certain operations will flatten/reshape the tensors for computational
58convenience.  We frequently use comments to document shapes using a
59lexicographic ordering.  For example, the comment
60
61```c
62// u has shape [dim, num_comp, Q, num_elem]
63```
64
65means that it can be traversed as
66
67```c
68for (d=0; d<dim; d++)
69  for (c=0; c<num_comp; c++)
70    for (q=0; q<Q; q++)
71      for (e=0; e<num_elem; e++)
72        u[((d*num_comp + c)*Q + q)*num_elem + e] = ...
73```
74
75This ordering is sometimes referred to as row-major or C-style.  Note
76that flattening such as
77
78```c
79// u has shape [dim, num_comp, Q*num_elem]
80```
81
82and
83
84```c
85// u has shape [dim*num_comp, Q, num_elem]
86```
87
88are purely implicit -- one just indexes the same array using the
89appropriate convention.
90
91## `restrict` semantics
92
93QFunction arguments can be assumed to have `restrict` semantics. That is, each input and output array must reside in distinct memory without overlap.
94
95## Internal Layouts
96
97Ceed backends are free to use any **E-vector** and **Q-vector** data layout, to include never fully forming these vectors, so long as the backend passes the `t5**` series tests and all examples.
98There are several common layouts for **L-vectors**, **E-vectors**, and **Q-vectors**, detailed below:
99
100- **L-vector** layouts
101
102  - **L-vectors** described by a {ref}`CeedElemRestriction` have a layout described by the `offsets` array and `comp_stride` parameter.
103    Data for node `i`, component `j`, element `k` can be found in the **L-vector** at index `offsets[i + k*elem_size] + j*comp_stride`.
104  - **L-vectors** described by a strided {ref}`CeedElemRestriction` have a layout described by the `strides` array.
105    Data for node `i`, component `j`, element `k` can be found in the **L-vector** at index `i*strides[0] + j*strides[1] + k*strides[2]`.
106
107- **E-vector** layouts
108
109  - If possible, backends should use {c:func}`CeedElemRestrictionSetELayout()` to use the `t2**` tests.
110    If the backend uses a strided **E-vector** layout, then the data for node `i`, component `j`, element `k` in the **E-vector** is given by `i*layout[0] + j*layout[1] + k*layout[2]`.
111  - Backends may choose to use a non-strided **E-vector** layout; however, the `t2**` tests will not function correctly in this case and the tests will need to be whitelisted for the backend to pass the test suite.
112
113- **Q-vector** layouts
114
115  - When the size of a {ref}`CeedQFunction` field is greater than `1`, data for quadrature point `i` component `j` can be found in the **Q-vector** at index `i + Q*j`.
116    Backends are free to provide the quadrature points in any order.
117  - When the {ref}`CeedQFunction` field has `emode` `CEED_EVAL_GRAD`, data for quadrature point `i`, component `j`, derivative `k` can be found in the **Q-vector** at index `i + Q*j + Q*size*k`.
118  - Note that backend developers must take special care to ensure that the data in the **Q-vectors** for a field with `emode` `CEED_EVAL_NONE` is properly ordered when the backend uses different layouts for **E-vectors** and **Q-vectors**.
119
120## Backend Inheritance
121
122There are three mechanisms by which a Ceed backend can inherit implementation from another Ceed backend.
123These options are set in the backend initialization routine.
124
1251. Delegation - Developers may use {c:func}`CeedSetDelegate()` to set a backend that will provide the implementation of any unimplemented Ceed objects.
1262. Object delegation  - Developers may use {c:func}`CeedSetObjectDelegate()` to set a backend that will provide the implementation of a specific unimplemented Ceed object.
127   Object delegation has higher precedence than delegation.
1283. Operator fallback - Developers may use {c:func}`CeedSetOperatorFallbackResource()` to set a {ref}`Ceed` resource that will provide the implementation of unimplemented {ref}`CeedOperator` methods.
129   A fallback {ref}`Ceed` with this resource will only be instantiated if a method is called that is not implemented by the parent {ref}`Ceed`.
130   In order to use the fallback mechanism, the parent {ref}`Ceed` and fallback resource must use compatible **E-vector** and **Q-vector** layouts.
131