xref: /libCEED/doc/sphinx/source/libCEEDdev.md (revision 30eee50603500b9e4d8e628cabfcfd4558c48377)
1bcb2dfaeSJed Brown# Developer Notes
2bcb2dfaeSJed Brown
3bcb2dfaeSJed Brown## Style Guide
4bcb2dfaeSJed Brown
5bcb2dfaeSJed BrownPlease check your code for style issues by running
6bcb2dfaeSJed Brown
7bcb2dfaeSJed Brown`make style`
8bcb2dfaeSJed Brown
9bcb2dfaeSJed BrownIn addition to those automatically enforced style rules, libCEED tends to follow the following code style conventions:
10bcb2dfaeSJed Brown
11bcb2dfaeSJed Brown- Variable names: `snake_case`
12bcb2dfaeSJed Brown- Strut members: `snake_case`
13bcb2dfaeSJed Brown- Function and method names: `PascalCase` or language specific style
14bcb2dfaeSJed Brown- Type names: `PascalCase` or language specific style
15bcb2dfaeSJed Brown- Constant names: `CAPS_SNAKE_CASE` or language specific style
16bcb2dfaeSJed Brown
17bcb2dfaeSJed BrownAlso, documentation files should have one sentence per line to help make git diffs clearer and less disruptive.
18bcb2dfaeSJed Brown
19bcb2dfaeSJed Brown## Clang-tidy
20bcb2dfaeSJed Brown
21bcb2dfaeSJed BrownPlease check your code for common issues by running
22bcb2dfaeSJed Brown
23bcb2dfaeSJed Brown`make tidy`
24bcb2dfaeSJed Brown
25bcb2dfaeSJed Brownwhich uses the `clang-tidy` utility included in recent releases of Clang.  This
26bcb2dfaeSJed Browntool is much slower than actual compilation (`make -j8` parallelism helps).  To
27bcb2dfaeSJed Brownrun on a single file, use
28bcb2dfaeSJed Brown
29bcb2dfaeSJed Brown`make interface/ceed.c.tidy`
30bcb2dfaeSJed Brown
31bcb2dfaeSJed Brownfor example.  All issues reported by `make tidy` should be fixed.
32bcb2dfaeSJed Brown
33bcb2dfaeSJed Brown## Header Files
34bcb2dfaeSJed Brown
35bcb2dfaeSJed BrownHeader inclusion for source files should follow the principal of 'include what you use' rather than relying upon transitive `#include` to define all symbols.
36bcb2dfaeSJed Brown
37*30eee506SJeremy L ThompsonEvery 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.
38*30eee506SJeremy L ThompsonPlease check your code by running the tool `include-what-you-use` to see recommendations for changes to your source.
39bcb2dfaeSJed BrownMost 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.
40bcb2dfaeSJed Brown
41bcb2dfaeSJed BrownHeader files should be listed in alphabetical order, with installed headers preceding local headers and `ceed` headers being listed first.
42bcb2dfaeSJed Brown
43bcb2dfaeSJed Brown```c
44bcb2dfaeSJed Brown#include <ceed.h>
45bcb2dfaeSJed Brown#include <ceed/backend.h>
46bcb2dfaeSJed Brown#include <stdbool.h>
47bcb2dfaeSJed Brown#include <string.h>
48bcb2dfaeSJed Brown#include "ceed-avx.h"
49bcb2dfaeSJed Brown```
50bcb2dfaeSJed Brown
51bcb2dfaeSJed Brown## Shape
52bcb2dfaeSJed Brown
53bcb2dfaeSJed BrownBackends often manipulate tensors of dimension greater than 2.  It is
54bcb2dfaeSJed Brownawkward to pass fully-specified multi-dimensional arrays using C99 and
55bcb2dfaeSJed Browncertain operations will flatten/reshape the tensors for computational
56bcb2dfaeSJed Brownconvenience.  We frequently use comments to document shapes using a
57bcb2dfaeSJed Brownlexicographic ordering.  For example, the comment
58bcb2dfaeSJed Brown
59bcb2dfaeSJed Brown```c
60bcb2dfaeSJed Brown// u has shape [dim, num_comp, Q, num_elem]
61bcb2dfaeSJed Brown```
62bcb2dfaeSJed Brown
63bcb2dfaeSJed Brownmeans that it can be traversed as
64bcb2dfaeSJed Brown
65bcb2dfaeSJed Brown```c
66bcb2dfaeSJed Brownfor (d=0; d<dim; d++)
67bcb2dfaeSJed Brown  for (c=0; c<num_comp; c++)
68bcb2dfaeSJed Brown    for (q=0; q<Q; q++)
69bcb2dfaeSJed Brown      for (e=0; e<num_elem; e++)
70d4805b58SJeremy L Thompson        u[((d*num_comp + c)*Q + q)*num_elem + e] = ...
71bcb2dfaeSJed Brown```
72bcb2dfaeSJed Brown
73bcb2dfaeSJed BrownThis ordering is sometimes referred to as row-major or C-style.  Note
74bcb2dfaeSJed Brownthat flattening such as
75bcb2dfaeSJed Brown
76bcb2dfaeSJed Brown```c
77bcb2dfaeSJed Brown// u has shape [dim, num_comp, Q*num_elem]
78bcb2dfaeSJed Brown```
79bcb2dfaeSJed Brown
80bcb2dfaeSJed Brownand
81bcb2dfaeSJed Brown
82bcb2dfaeSJed Brown```c
83bcb2dfaeSJed Brown// u has shape [dim*num_comp, Q, num_elem]
84bcb2dfaeSJed Brown```
85bcb2dfaeSJed Brown
86bcb2dfaeSJed Brownare purely implicit -- one just indexes the same array using the
87bcb2dfaeSJed Brownappropriate convention.
88bcb2dfaeSJed Brown
89ae718e2fSJed Brown## `restrict` semantics
90ae718e2fSJed Brown
91ae718e2fSJed BrownQFunction arguments can be assumed to have `restrict` semantics. That is, each input and output array must reside in distinct memory without overlap.
92ae718e2fSJed Brown
93bcb2dfaeSJed Brown## Internal Layouts
94bcb2dfaeSJed Brown
95bcb2dfaeSJed BrownCeed 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.
96bcb2dfaeSJed BrownThere are several common layouts for **L-vectors**, **E-vectors**, and **Q-vectors**, detailed below:
97bcb2dfaeSJed Brown
98bcb2dfaeSJed Brown- **L-vector** layouts
99bcb2dfaeSJed Brown
100bcb2dfaeSJed Brown  - **L-vectors** described by a {ref}`CeedElemRestriction` have a layout described by the `offsets` array and `comp_stride` parameter.
101bcb2dfaeSJed Brown    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`.
102bcb2dfaeSJed Brown  - **L-vectors** described by a strided {ref}`CeedElemRestriction` have a layout described by the `strides` array.
103bcb2dfaeSJed Brown    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]`.
104bcb2dfaeSJed Brown
105bcb2dfaeSJed Brown- **E-vector** layouts
106bcb2dfaeSJed Brown
107bcb2dfaeSJed Brown  - If possible, backends should use {c:func}`CeedElemRestrictionSetELayout()` to use the `t2**` tests.
108bcb2dfaeSJed Brown    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]`.
109bcb2dfaeSJed Brown  - 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.
110bcb2dfaeSJed Brown
111bcb2dfaeSJed Brown- **Q-vector** layouts
112bcb2dfaeSJed Brown
113bcb2dfaeSJed Brown  - 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`.
114bcb2dfaeSJed Brown    Backends are free to provide the quadrature points in any order.
115bcb2dfaeSJed Brown  - 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`.
116bcb2dfaeSJed Brown  - 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**.
117bcb2dfaeSJed Brown
118bcb2dfaeSJed Brown## Backend Inheritance
119bcb2dfaeSJed Brown
120bcb2dfaeSJed BrownThere are three mechanisms by which a Ceed backend can inherit implementation from another Ceed backend.
121bcb2dfaeSJed BrownThese options are set in the backend initialization routine.
122bcb2dfaeSJed Brown
123bcb2dfaeSJed Brown1. Delegation - Developers may use {c:func}`CeedSetDelegate()` to set a backend that will provide the implementation of any unimplemented Ceed objects.
124bcb2dfaeSJed Brown2. Object delegation  - Developers may use {c:func}`CeedSetObjectDelegate()` to set a backend that will provide the implementation of a specific unimplemented Ceed object.
125bcb2dfaeSJed Brown   Object delegation has higher precedence than delegation.
126bcb2dfaeSJed Brown3. Operator fallback - Developers may use {c:func}`CeedSetOperatorFallbackResource()` to set a {ref}`Ceed` resource that will provide the implementation of unimplemented {ref}`CeedOperator` methods.
127bcb2dfaeSJed Brown   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`.
128bcb2dfaeSJed Brown   In order to use the fallback mechanism, the parent {ref}`Ceed` and fallback resource must use compatible **E-vector** and **Q-vector** layouts.
129