Repository navigation
How to contribute
Rigth now there is not a well defined methodology in order to contribute.
If you want to add anything to the repo, please send me an email to oscar.amoros.huguet@upc.edu and we can discuss anything.
I'm friendly and preffer direct communication rather than protocols. I'll keep it that way as long as it is manageable. If at some point I can't handle the volume of messages and so on, I'll think of some mechanisms and protocols to allow contribution.
I'm not particularly good at deciding about coding style conventions. If you had a look at the code, you will find some mix of coding styles.
This is an attempt to decide on some very basic rules, that I will be applying for new code and old code if I'm modifying it. So do not expect that all the code will follow this rules right now, it will at some point. One contribution you can do, is to apply the following code style rules to all the existing code.
- Write all the function declaration in a single line, but do not exeed 110 characters.
- If you need to break the line, you can do it at any point before the funtcion name. Try to keep template definitions in a single line, decorators in a single line, and return type, which can get quite long when using std::enable_if_t, in a single line, if possible.
- If you need to break any comma separated line, make all the elements to start at the same column as the first element of the comma separated scope, in the previous line.
- Function names must start with lower case and be camel case. They can end with ´_helper´, for example
myFunc_helperwill be a helper function for the functionmyFunc.
The following example, is an extreme case, that could be done in fewer lines, but serves to ilustrate where to break lines, only if necessary.
template <int SIZE, typename T>
constexpr __forceinline__ __host__ __device__
std::enable_if_t<(SIZE> 0), bool>
someFunction(const int& var1,
const int& var2,
const std::array<T, SIZE>& var3) {
bool result{false};
for (int i=0; i < SIZE; ++i) {
result |= (var1 * var2) < var3[i];
}
return result;
}According to the 110 characters limitation, that particular example could be written like this:
template <int SIZE, typename T>
constexpr __forceinline__ __host__ __device__ std::enable_if_t<(SIZE> 0), bool>
someFunction(const int& var1, const int& var2, const std::array<T, SIZE>& var3) {
bool result{false};
for (int i=0; i < SIZE; ++i) {
result |= (var1 * var2) < var3[i];
}
return result;
}This allows me to more easily work with split screens, whithout having to scroll laterally, which I find very distracting.
In the previous examples, you can already see the formating of a for loop. But let's add to it.
- Always use braces. No
if (boolVar) return 0;allowed. Please useif (boolVar) { return 0; };. - The same applies to loops.
- Types must ALWAYS start with upper case, and ideally be camel case. They can end with a
_tto denote that you don't need to use the ::type alias. - Variables must ALWAYS start with lower case. They can end with
_vwhen they are a template constexpr variable, created to avoid using the ::value from a template struct with the same name (struct name starting with upper case). - Template non type variables, must generally at least start with upper case, and ideally be fully upper case.
- The same applies to enum values, except for the unnamed
enum {size=xxx;}inside some structs.
The final user may require more flexibility, so we will not ask him to do this things, but the implementation of this library must be as fast as possible. So here are the basic things we are doing to ensure both CPU and GPU runtime performance, and ask you to follow if you want to contribute.
- Make all parameters cons & if possible. We found that this helps the compiler with inlining.
- To help with the previous, try to not use any parameter to store results. Try to always return any result generated. Note it can not be applied to __global__ functions.
- Try to make all the functions constexpr inline or forceinline.
- Operation member functions must be static, since no Operation will be instantiated.
Of course, if the function calls another function that is not constexpr, or uses a pointer that is NOT an static array with known size in the scope, or an std::array, or an fk:Array, then don't use constexpr.
- Try to avoid runtime for loops, use std::index_sequence or std::integer_sequence with a helper funtion when possible. For simple codes the compiler can do the trick, but the more complex the code, the more chances some optimizations will be disabled.
- If not, at least try to have the variable that contains the number of iterations as a template parameter or a constexpr variable.
As a performance recomendation, try to always make all variables const. Specially on device code. Instead of reusing the same variable, create another one also const.