|
| 1 | +# Programs |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +Program is a class that let users define expressions on vector elements, and have ICICLE compile it for the backends for a fused implementation. This solves memory bottlenecks and also let users customize algorithms such as sumcheck. Program can create only element-wise lambda functions. |
| 6 | + |
| 7 | + |
| 8 | +## C++ API |
| 9 | + |
| 10 | +### Symbol |
| 11 | + |
| 12 | +Symbol is the basic (template) class that allow users to define their own program. The lambda function the user define will operate on symbols. |
| 13 | + |
| 14 | +### Defining lambda function |
| 15 | + |
| 16 | +To define a custom lambda function the user will use Symbol: |
| 17 | +```cpp |
| 18 | +void lambda_multi_result(std::vector<Symbol<scalar_t>>& vars) |
| 19 | +{ |
| 20 | + const Symbol<scalar_t>& A = vars[0]; |
| 21 | + const Symbol<scalar_t>& B = vars[1]; |
| 22 | + const Symbol<scalar_t>& C = vars[2]; |
| 23 | + const Symbol<scalar_t>& EQ = vars[3]; |
| 24 | + vars[4] = EQ * (A * B - C) + scalar_t::from(9); |
| 25 | + vars[5] = A * B - C.inverse(); |
| 26 | + vars[6] = vars[5]; |
| 27 | + vars[3] = 2 * (var[0] + var[1]) // all variables can be both inputs and outputs |
| 28 | +} |
| 29 | +``` |
| 30 | +
|
| 31 | +Each symbol element at the vector argument `var` represent an input or an output. The type of the symbol (`scalar_t` in this example) will be the type of the inputs and outputs. In this example we created a lambda function with four inputs and three outputs. |
| 32 | +
|
| 33 | +In this example there are four input variables and three three outputs. Inside the function the user can define custom expressions on them. |
| 34 | +
|
| 35 | +Program support few pre-defined programs. The user can use those pre-defined programs without creating a lambda function, as will be explained in the next section. |
| 36 | +
|
| 37 | +### Creating program |
| 38 | +
|
| 39 | +To execute the lambda function we just created we need to create a program from it. |
| 40 | +To create program from lambda function we can use the following constructor: |
| 41 | +
|
| 42 | +```cpp |
| 43 | +Program(std::function<void(std::vector<Symbol<S>>&)> program_func, const int nof_parameters) |
| 44 | +``` |
| 45 | + |
| 46 | +`program_func` is the lambda function (in the example above `lambda_multi_result`) and `nof_parameters` is the total number of parameter (inputs + outputs) for the lambda (seven in the above example). |
| 47 | + |
| 48 | +#### Pre-defined programs |
| 49 | + |
| 50 | +As mentioned before, there are few pre-defined programs the user can use without the need to create a lambda function first. The enum `PreDefinedPrograms` contains the pre-defined program. Using pre-defined function will lead to better performance compared to creating the equivalent lambda function. |
| 51 | +To create a pre-defined program a different constructor is bing used: |
| 52 | + |
| 53 | +```cpp |
| 54 | +Program(PreDefinedPrograms pre_def) |
| 55 | +``` |
| 56 | +
|
| 57 | +`pre_def` is the pre-defined program (from `PreDefinedPrograms`). |
| 58 | +
|
| 59 | +##### PreDefinedPrograms |
| 60 | +
|
| 61 | +```cpp |
| 62 | +enum PreDefinedPrograms { |
| 63 | + AB_MINUS_C = 0, |
| 64 | + EQ_X_AB_MINUS_C |
| 65 | +}; |
| 66 | +``` |
| 67 | + |
| 68 | +`AB_MINUS_C` - the pre-defined program `AB - C` for the input vectors `A`, `B` and `C` |
| 69 | + |
| 70 | +`EQ_X_AB_MINUS_C` - the pre-defined program `EQ(AB - C)` for the input vectors `A`, `B`, `C` and `EQ` |
| 71 | + |
| 72 | + |
| 73 | +### Executing program |
| 74 | + |
| 75 | +To execute the program the `execute_program` function from the vector operation API should be used. This operation is supported by the CPU and CUDA backends. |
| 76 | + |
| 77 | + |
| 78 | +```cpp |
| 79 | +template <typename T> |
| 80 | +eIcicleError |
| 81 | +execute_program(std::vector<T*>& data, const Program<T>& program, uint64_t size, const VecOpsConfig& config); |
| 82 | +``` |
| 83 | +
|
| 84 | +The `data` vector is a vector of pointers to the inputs and output vectors, `program` is the program to execute, `size` is the length of the vectors and `config` is the configuration of the operation. |
| 85 | +
|
| 86 | +For the configuration the field `is_a_on_device` determined whethere the data (*inputs and outputs*) is on device or not. After the execution `data` will reside in the same place as it did before (i.e. the field `is_result_on_device` is irrelevant.) |
| 87 | +
|
| 88 | +> **_NOTE:_** Using program for executing lambdas is recommended only while using the CUDA backend. Program's primary use is to let users to customize algorithms (such as sumcheck). |
0 commit comments