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 33*db52d626SJeremy L Thompson## Include-What-You-Use 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 3730eee506SJeremy 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*db52d626SJeremy L ThompsonPlease 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. 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. 40*db52d626SJeremy L ThompsonIf you have `include-what-you-use` installed in a sibling directory to libCEED, then you can use the makefile target `make iwyu`. 41bcb2dfaeSJed Brown 42bcb2dfaeSJed BrownHeader files should be listed in alphabetical order, with installed headers preceding local headers and `ceed` headers being listed first. 43*db52d626SJeremy L ThompsonThe `ceed-f64.h` and `ceed-f32.h` headers should only be included in `ceed.h`. 44bcb2dfaeSJed Brown 45bcb2dfaeSJed Brown```c 46bcb2dfaeSJed Brown#include <ceed.h> 47bcb2dfaeSJed Brown#include <ceed/backend.h> 48bcb2dfaeSJed Brown#include <stdbool.h> 49bcb2dfaeSJed Brown#include <string.h> 50bcb2dfaeSJed Brown#include "ceed-avx.h" 51bcb2dfaeSJed Brown``` 52bcb2dfaeSJed Brown 53bcb2dfaeSJed Brown## Shape 54bcb2dfaeSJed Brown 55bcb2dfaeSJed BrownBackends often manipulate tensors of dimension greater than 2. It is 56bcb2dfaeSJed Brownawkward to pass fully-specified multi-dimensional arrays using C99 and 57bcb2dfaeSJed Browncertain operations will flatten/reshape the tensors for computational 58bcb2dfaeSJed Brownconvenience. We frequently use comments to document shapes using a 59bcb2dfaeSJed Brownlexicographic ordering. For example, the comment 60bcb2dfaeSJed Brown 61bcb2dfaeSJed Brown```c 62bcb2dfaeSJed Brown// u has shape [dim, num_comp, Q, num_elem] 63bcb2dfaeSJed Brown``` 64bcb2dfaeSJed Brown 65bcb2dfaeSJed Brownmeans that it can be traversed as 66bcb2dfaeSJed Brown 67bcb2dfaeSJed Brown```c 68bcb2dfaeSJed Brownfor (d=0; d<dim; d++) 69bcb2dfaeSJed Brown for (c=0; c<num_comp; c++) 70bcb2dfaeSJed Brown for (q=0; q<Q; q++) 71bcb2dfaeSJed Brown for (e=0; e<num_elem; e++) 72d4805b58SJeremy L Thompson u[((d*num_comp + c)*Q + q)*num_elem + e] = ... 73bcb2dfaeSJed Brown``` 74bcb2dfaeSJed Brown 75bcb2dfaeSJed BrownThis ordering is sometimes referred to as row-major or C-style. Note 76bcb2dfaeSJed Brownthat flattening such as 77bcb2dfaeSJed Brown 78bcb2dfaeSJed Brown```c 79bcb2dfaeSJed Brown// u has shape [dim, num_comp, Q*num_elem] 80bcb2dfaeSJed Brown``` 81bcb2dfaeSJed Brown 82bcb2dfaeSJed Brownand 83bcb2dfaeSJed Brown 84bcb2dfaeSJed Brown```c 85bcb2dfaeSJed Brown// u has shape [dim*num_comp, Q, num_elem] 86bcb2dfaeSJed Brown``` 87bcb2dfaeSJed Brown 88bcb2dfaeSJed Brownare purely implicit -- one just indexes the same array using the 89bcb2dfaeSJed Brownappropriate convention. 90bcb2dfaeSJed Brown 91ae718e2fSJed Brown## `restrict` semantics 92ae718e2fSJed Brown 93ae718e2fSJed BrownQFunction arguments can be assumed to have `restrict` semantics. That is, each input and output array must reside in distinct memory without overlap. 94ae718e2fSJed Brown 95bcb2dfaeSJed Brown## Internal Layouts 96bcb2dfaeSJed Brown 97bcb2dfaeSJed 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. 98bcb2dfaeSJed BrownThere are several common layouts for **L-vectors**, **E-vectors**, and **Q-vectors**, detailed below: 99bcb2dfaeSJed Brown 100bcb2dfaeSJed Brown- **L-vector** layouts 101bcb2dfaeSJed Brown 102bcb2dfaeSJed Brown - **L-vectors** described by a {ref}`CeedElemRestriction` have a layout described by the `offsets` array and `comp_stride` parameter. 103bcb2dfaeSJed 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`. 104bcb2dfaeSJed Brown - **L-vectors** described by a strided {ref}`CeedElemRestriction` have a layout described by the `strides` array. 105bcb2dfaeSJed 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]`. 106bcb2dfaeSJed Brown 107bcb2dfaeSJed Brown- **E-vector** layouts 108bcb2dfaeSJed Brown 109bcb2dfaeSJed Brown - If possible, backends should use {c:func}`CeedElemRestrictionSetELayout()` to use the `t2**` tests. 110bcb2dfaeSJed 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]`. 111bcb2dfaeSJed 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. 112bcb2dfaeSJed Brown 113bcb2dfaeSJed Brown- **Q-vector** layouts 114bcb2dfaeSJed Brown 115bcb2dfaeSJed 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`. 116bcb2dfaeSJed Brown Backends are free to provide the quadrature points in any order. 117bcb2dfaeSJed 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`. 118bcb2dfaeSJed 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**. 119bcb2dfaeSJed Brown 120bcb2dfaeSJed Brown## Backend Inheritance 121bcb2dfaeSJed Brown 122bcb2dfaeSJed BrownThere are three mechanisms by which a Ceed backend can inherit implementation from another Ceed backend. 123bcb2dfaeSJed BrownThese options are set in the backend initialization routine. 124bcb2dfaeSJed Brown 125bcb2dfaeSJed Brown1. Delegation - Developers may use {c:func}`CeedSetDelegate()` to set a backend that will provide the implementation of any unimplemented Ceed objects. 126bcb2dfaeSJed Brown2. Object delegation - Developers may use {c:func}`CeedSetObjectDelegate()` to set a backend that will provide the implementation of a specific unimplemented Ceed object. 127bcb2dfaeSJed Brown Object delegation has higher precedence than delegation. 128bcb2dfaeSJed 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. 129bcb2dfaeSJed 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`. 130bcb2dfaeSJed Brown In order to use the fallback mechanism, the parent {ref}`Ceed` and fallback resource must use compatible **E-vector** and **Q-vector** layouts. 131