diff --git a/README.md b/README.md index e91a317..5e3497a 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ make ``` This will compile the source files and generate an executable called `benchmark` in the `bin/` directory. +Similar to the STREAM benchmark´s Makefile, the vector sizes are defined by the preprocessor variable `VECTOR_SIZE` that can be set in the Makefile. ### Clean Up @@ -96,6 +97,63 @@ Available kernels are: - daxpy ``` +## Adding New Kernels + +To add a new kernel to the project, follow these steps: + +1. **Define the Kernel**: + - Open the `src/kernels.cpp` file and scroll to the section where new kernels are registered (around the `initialize_registry` function). + - Use the existing kernels (`stream_triad` and `daxpy`) as templates. Create a new kernel by adding a lambda to the `register_kernel` method. + + For example, to add a new **vector product** kernel, you can do the following: + + ``` + registry->register_kernel("vector_product", [&]() { + auto a = std::make_shared>(); + auto b = std::make_shared>(); + auto c = std::make_shared>(); + + auto prepare = [=]() { + a->resize(VECTOR_SIZE); + b->resize(VECTOR_SIZE); + c->resize(VECTOR_SIZE); + initialize_vector(*b); + initialize_vector(*c); + }; + + auto execute = [=](int kernel_start_idx, int kernel_end_idx, int n_tasks_or_threads) { + strategy::execute_strategy(strategy_name, kernel_start_idx, kernel_end_idx, n_tasks_or_threads, [&](int i) { + (*a)[i] = (*b)[i] * (*c)[i]; // Vector product operation + }); + }; + + return Kernel("vector_product", execute, prepare); + }); + ``` + + In this example: + - `a`, `b`, and `c` are the vectors used for the operation. + - `prepare` initializes these vectors and fills them with random values using the `initialize_vector` function. + - `execute` contains the vector product logic, where each element in vector `a` is computed as the product of corresponding elements in vectors `b` and `c`. + +2. **Register the Kernel**: + - The new kernel should be automatically registered when the `initialize_registry` function is called. This is done dynamically through the registry. + +3. **Use the Kernel**: + - Once you have added the kernel to the registry, you can run it just like the existing kernels using the `./bin/benchmark` command. For example: + + ``` + ./bin/benchmark vector_product omp 4 + ``` + +### Notes on Adding Kernels: + +- Kernels must be registered with a **name** (e.g., `"vector_product"`) and should include the corresponding **allocations and data initialization** (`prepare`) and **kernel logic** (`execute`). +- Kernels must consist out of an outer loop at least for now. +- The kernel’s execution should be parallelizable using all of the available strategies (`omp` (OpenMP) and `eventify` (Eventify) for now). You can add more strategies by extending the `strategy` namespace. +- The `VECTOR_SIZE` preprocessor variable defines the size of the input data and should be appropriate for the kernel you are implementing. + + ## Contributing Feel free to submit issues or pull requests to improve the project.