diff --git a/examples/array_multiplication/CMakeLists.txt b/examples/array_multiplication/CMakeLists.txt new file mode 100644 index 000000000..4ddc8d1d2 --- /dev/null +++ b/examples/array_multiplication/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.17.0) +project(kompute_array_mult VERSION 0.1.0) + +set(CMAKE_CXX_STANDARD 17) + +option(KOMPUTE_OPT_ENABLE_SPDLOG "Extra compile flags for Kompute, see docs for full list" 0) +set(KOMPUTE_EXTRA_CXX_FLAGS "" CACHE STRING "Extra compile flags for Kompute, see docs for full list") + +if(KOMPUTE_OPT_ENABLE_SPDLOG) + set(KOMPUTE_EXTRA_CXX_FLAGS "${KOMPUTE_EXTRA_CXX_FLAGS} -DKOMPUTE_ENABLE_SPDLOG=1") +endif() + +# It is necessary to pass the DEBUG or RELEASE flag accordingly to Kompute +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1 ${KOMPUTE_EXTRA_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DRELEASE=1 ${KOMPUTE_EXTRA_CXX_FLAGS}") + +find_package(kompute REQUIRED) +find_package(Vulkan REQUIRED) + +if(KOMPUTE_OPT_ENABLE_SPDLOG) + find_package(spdlog REQUIRED) + find_package(fmt REQUIRED) +endif() + +add_executable(kompute_array_mult + src/Main.cpp) + +target_link_libraries(kompute_array_mult + kompute::kompute + Vulkan::Vulkan +) + +if(KOMPUTE_OPT_ENABLE_SPDLOG) + target_link_libraries(kompute_array_mult + kompute::kompute + fmt::fmt + spdlog::spdlog + ) +endif() + diff --git a/examples/array_multiplication/README.md b/examples/array_multiplication/README.md new file mode 100644 index 000000000..9838b7217 --- /dev/null +++ b/examples/array_multiplication/README.md @@ -0,0 +1,74 @@ +# Kompute Array Multiplication Example + +This folder contains an end to end Kompute Example that implements logistic regression. + +This example is structured such that you will be able to extend it for your project. + +It contains a cmake build configuration that can be used in your production applications. + +## Pre-requisites + +In order to run this example, you will need the following dependencies: + +* REQUIRED + + Vulkan Kompute library must be accessible + + The Vulkan SDK must be installed +* OPTIONAL + + SPDLOG - for logging + + FMT - for text formatting + +We will cover how you can install Vulkan Kompute in the next section. + +For the Vulkan SDK, the simplest way to install it is through [their website](https://vulkan.lunarg.com/sdk/home). You just have to follow the instructions for the relevant platform. + +For the other libraries, because they are optional you can just make sure you build and install Kompute with these disabled (this will be covered in more detail below). + +Alternatively you can use package managers such as vcpkg to help you install them, although to simplify things you can start without the dependencies first. + +## Set Up Vulkan Kompute Dependency + +You have multiple options to set up Vulkan Kompute. The easiest is to perform a local installation. + +For this, you will want to go to the main repo and run the following cmake command, which will configure it without SPDLOG by default. + +``` +cmake \ + -Bbuild +``` + +You can pass the following optional parameters based on your desired configuration: +* If you wish to install with spdlog support you just have to pass `-DKOMPUTE_ENABLE_SPDLOG=1`. +* If you wish to perform the installation on the local folder instead of in your system you can use `-DCMAKE_INSTALL_PREFIX="build/src/CMakeFiles/Export/"` which will basically ensure that the final files are created in the local directory. +* If you are using a package manager such as `vcpkg` make sure you pass the `-DCMAKE_TOOLCHAIN_FILE=` parameter + +Then you can proceed to run the installation: + +* For Windows / Visual Studio you just have to build `INSTALL.vcxproj` +* For Linux you can just run the `install` target via `make -C build install` + +You also have the option to build as `Release` or `Debug` - just make sure that you build your example with the same build/debug flags as required. + +## Building the example + +Now that you've set up the dependencies / installation of Vulkan Kompute you can build this example. + +You will notice that it's a standalone project, so you can re-use it for your application. + +To build you just need to run the cmake command in this folder as follows: + +``` +cmake \ + -Bbuild +``` + +Make sure to pass the required flags depending on the configuration above: +* If you built with Debug make sure you build your example with Debug as well +* If you installed in the local folder, make sure you pass the CMAKE_PREFIX_PATH pointing to the respective folder (e.g. `-DCMAKE_PREFIX_PATH=../../build/src/CMakeFiles/Export/lib/cmake/kompute/` if parent folder is main repo). +* If you built Vulkan Kompute with spdlog enabled, make sure to pass `-DKOMPUTE_OPT_ENABLE_SPDLOG=1` +* If you are using a package manager such as `vcpkg` make sure you pass the `-DCMAKE_TOOLCHAIN_FILE=` parameter + +Now you just have to build your application as above: + +* For Windows / Visual Studio you just have to build and run `kompute_array_mult.vcxproj` +* For Linux you can just run the `kompute_array_mult` target via `make -C build kompute_array_mult` + diff --git a/examples/array_multiplication/src/Main.cpp b/examples/array_multiplication/src/Main.cpp new file mode 100755 index 000000000..f3587cae8 --- /dev/null +++ b/examples/array_multiplication/src/Main.cpp @@ -0,0 +1,53 @@ + +#include +#include +#include + +#include "kompute/Kompute.hpp" + +int main() +{ +#if KOMPUTE_ENABLE_SPDLOG + spdlog::set_level( + static_cast(SPDLOG_ACTIVE_LEVEL)); +#endif + + kp::Manager mgr; + + auto tensorInA = mgr.buildTensor({ 2.0, 4.0, 6.0 }); + auto tensorInB = mgr.buildTensor({ 0.0, 1.0, 2.0 }); + auto tensorOut = mgr.buildTensor({ 0.0, 0.0, 0.0 }); + + std::string shader(R"( + // The version to use + #version 450 + + // The execution structure + layout (local_size_x = 1) in; + + // The buffers are provided via the tensors + layout(binding = 0) buffer bufA { float a[]; }; + layout(binding = 1) buffer bufB { float b[]; }; + layout(binding = 2) buffer bufOut { float o[]; }; + + void main() { + uint index = gl_GlobalInvocationID.x; + + o[index] = a[index] * b[index]; + } + )"); + + mgr.evalOpDefault>( + { tensorInA, tensorInB, tensorOut }, + std::vector(shader.begin(), shader.end())); + + mgr.evalOpDefault({tensorOut}); + + // prints "Output { 0 4 12 }" + std::cout<< "Output: { "; + for (const float& elem : tensorOut->data()) { + std::cout << elem << " "; + } + std::cout << "}" << std::endl; +} +