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