benchmark_name | cpp_code | accera_code |
---|---|---|
Accera_Naive |
src/reduction/accera_naive.cpp |
src/reduction/naive.py |
Note
The following shows the implementation of the {{benchmark_name}}
.
The full source code listing of the Accera code generator can be found in {{accera_code}} :fas fa-code: and the benchmark runner is found in {{cpp_code}} :fas fa-code: .
The pseudocode of the naive implementation is:
\begin{algorithm}
\begin{algorithmic}
\PROCEDURE{NaiveReduction}{$Input$}
\STATE sum = 0
\FOR{$i$ = 0 \TO N}
\STATE sum = sum + Input[$i$]
\ENDFOR
\RETURN sum
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
<------ N ------>
+--+--+--+ +--+
| | | |...| |
+--+--+--+ +--+
To start, we need to import the Accera package:
We then define the input size (Which is also the iteration domain) of the problem. We choose a sufficiently large size to be able to more accurately compare performance across implementation and hide system noise.
The inputs and output can then be defined based on the size Input
array which is of type float32
and is of shape (N,)
--- i.e. a vector of size Sum
which is also of type float32
but contains a single element --- i.e. a 1-dimensional vector of size 1.
The nest is then defined.
Since the iteration domain is between
Use use the get_indices
function to get the iteration variable used in the nest:
As described above, the reduction sums all inputs into a single variable; i.e., for any iteration Sum[0] += Input[i]
.
With that, we define the iteration logic function and add it to the nest:
We can then create a package and add the accum_nest
to our package.
Our nest takes Sum
and Input
and we set it's exported C-name to be called "naive"
.
We then export the package as a HAT
package called "naive"
.
The output of the above are two files:
- A
naive.hat
file which is a header file containing the declaration of the function. - A
naive.o
file swhich contains the definition of the function.
Users can use the exported file within their C code by first importing the naive.hat
file
#include "naive.hat"
And then using the exported function (passing the expected arguments):
static size_t N = 1 << 20; // declare the problem size
std::vector<float> Input(N, 1.0/N); // a vector where each element is 1/N
// (the sum is therefore equal to N)
float sum = 0; // declare the output
naive(&sum, Input.data()); // invoke the implementation
std::cout << "Sum = " << sum << "\n"; // print the sum