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