From 7d16b73d14c098020ca7d1fe0afc58ced4422dd1 Mon Sep 17 00:00:00 2001 From: Fabian Sauter Date: Fri, 24 Jun 2022 09:56:37 +0200 Subject: [PATCH] Updated the array_multiplication example Signed-off-by: Fabian Sauter --- examples/array_multiplication/CMakeLists.txt | 55 ++++++------- examples/array_multiplication/README.md | 54 ++++++------- .../shader/CMakeLists.txt | 20 +++++ .../shader/my_shader.comp | 14 ++++ .../array_multiplication/src/CMakeLists.txt | 4 + examples/array_multiplication/src/Main.cpp | 79 ------------------- examples/array_multiplication/src/main.cpp | 41 ++++++++++ 7 files changed, 130 insertions(+), 137 deletions(-) create mode 100644 examples/array_multiplication/shader/CMakeLists.txt create mode 100644 examples/array_multiplication/shader/my_shader.comp create mode 100644 examples/array_multiplication/src/CMakeLists.txt delete mode 100644 examples/array_multiplication/src/Main.cpp create mode 100644 examples/array_multiplication/src/main.cpp diff --git a/examples/array_multiplication/CMakeLists.txt b/examples/array_multiplication/CMakeLists.txt index bfc4c1c79..b278d8126 100644 --- a/examples/array_multiplication/CMakeLists.txt +++ b/examples/array_multiplication/CMakeLists.txt @@ -1,40 +1,37 @@ -cmake_minimum_required(VERSION 3.4.1) -project(kompute_array_mult VERSION 0.1.0) +cmake_minimum_required(VERSION 3.15) +project(kompute_array_mult) set(CMAKE_CXX_STANDARD 14) -option(KOMPUTE_ARR_OPT_INSTALLED_KOMPUTE "Enable if you prefer to use your installed Kompute library" 0) -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") +# Set a default build type if none was specified +# Based on: https://github.com/openchemistry/tomviz/blob/master/cmake/BuildType.cmake +set(DEFAULT_BUILD_TYPE "Release") -if(KOMPUTE_OPT_ENABLE_SPDLOG) - set(KOMPUTE_EXTRA_CXX_FLAGS "${KOMPUTE_EXTRA_CXX_FLAGS} -DKOMPUTE_ENABLE_SPDLOG=1") +if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + set(DEFAULT_BUILD_TYPE "Debug") 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}") +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.") + set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE STRING "Choose the type of build." FORCE) -if(KOMPUTE_ARR_OPT_INSTALLED_KOMPUTE) - find_package(kompute REQUIRED) -else() - add_subdirectory(../../ ${CMAKE_CURRENT_BINARY_DIR}/kompute_build) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() -find_package(Vulkan REQUIRED) - -add_executable(kompute_array_mult - src/Main.cpp) - -target_link_libraries(kompute_array_mult - kompute::kompute - Vulkan::Vulkan) - -include_directories( - ../../single_include/) - -if(KOMPUTE_OPT_ENABLE_SPDLOG) - target_link_libraries(kompute_array_mult - spdlog::spdlog) +if(WIN32) # Install dlls in the same directory as the executable on Windows + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) endif() +include(FetchContent) +FetchContent_Declare(kompute GIT_REPOSITORY https://github.com/COM8/kompute.git + GIT_TAG 01a0485f461e3d080b277aeb43c06a3ede8bd75d) # The commit hash for a dev version before v0.9.0. Replace with the latest from: https://github.com/KomputeProject/kompute/releases +FetchContent_MakeAvailable(kompute) +include_directories(${kompute_SOURCE_DIR}/src/include) + +# Add to the list, so CMake can later find the code to compile shaders to header files +list(APPEND CMAKE_PREFIX_PATH "${kompute_SOURCE_DIR}/cmake") + +add_subdirectory(shader) +add_subdirectory(src) diff --git a/examples/array_multiplication/README.md b/examples/array_multiplication/README.md index bc6de129c..ba6f9cab5 100644 --- a/examples/array_multiplication/README.md +++ b/examples/array_multiplication/README.md @@ -1,30 +1,39 @@ # 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. +It contains a CMake build configuration that can be used in your production applications. ## Building the example You will notice that it's a standalone project, so you can re-use it for your application. +It uses CMake's [`fetch_content`](https://cmake.org/cmake/help/latest/module/FetchContent.html) to consume Kompute as a dependency. +To build you just need to run the CMake command in this folder as follows: -This project has the option to either import the Kompute dependency relative to the project or use your existing installation of Kompute. - -To build you just need to run the cmake command in this folder as follows: - -``` -cmake -Bbuild/ \ - -DCMAKE_BUILD_TYPE=Debug \ - -DKOMPUTE_OPT_INSTALL=0 \ - -DKOMPUTE_OPT_ENABLE_SPDLOG=1 +```bash +git clone https://github.com/KomputeProject/kompute.git +cd kompute/examples/array_multiplication +mkdir build +cd build +cmake .. +cmake --build . ``` -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_OPT_ENABLE_SPDLOG=1`. -* If you are using a package manager such as `vcpkg` make sure you pass the `-DCMAKE_TOOLCHAIN_FILE=` parameter -* If you wish to load shader from raw glsl string instead of spirv bytes you can use `-DKOMPUTE_ANDROID_SHADER_FROM_STRING` +## Executing + +Form inside the `build/` directory run: + +### Linux + +```bash +./kompute_array_mult +``` + +### Windows + +```bash +.\Debug\kompute_array_mult.exe +``` ## Pre-requisites @@ -32,18 +41,5 @@ In order to run this example, you will need the following dependencies: * REQUIRED + The Vulkan SDK must be installed -* OPTIONAL - + Kompute library must be accessible (by default it uses the source directory) - + SPDLOG - for logging - + FMT - for text formatting - -We will cover how you can install 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. - - - diff --git a/examples/array_multiplication/shader/CMakeLists.txt b/examples/array_multiplication/shader/CMakeLists.txt new file mode 100644 index 000000000..bb01a0059 --- /dev/null +++ b/examples/array_multiplication/shader/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.15) + +# To add more shaders simply copy the vulkan_compile_shader command and replace it with your new shader +vulkan_compile_shader(INFILE my_shader.comp + OUTFILE my_shader.hpp + NAMESPACE "shader" + RELATIVE_PATH "${kompute_SOURCE_DIR}/cmake") + +# vulkan_compile_shader(INFILE my_shader2.comp +# OUTFILE my_shader2.hpp +# NAMESPACE "shader" +# RELATIVE_PATH "${kompute_SOURCE_DIR}/cmake") + +# Then add it to the library, so you can access it later in your code +add_library(shader "${CMAKE_CURRENT_BINARY_DIR}/my_shader.hpp" +# "${CMAKE_CURRENT_BINARY_DIR}/my_shader2.hpp" +) + +set_target_properties(shader PROPERTIES LINKER_LANGUAGE CXX) +target_include_directories(shader PUBLIC $) diff --git a/examples/array_multiplication/shader/my_shader.comp b/examples/array_multiplication/shader/my_shader.comp new file mode 100644 index 000000000..d4cfe6990 --- /dev/null +++ b/examples/array_multiplication/shader/my_shader.comp @@ -0,0 +1,14 @@ +#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]; +} \ No newline at end of file diff --git a/examples/array_multiplication/src/CMakeLists.txt b/examples/array_multiplication/src/CMakeLists.txt new file mode 100644 index 000000000..3a912ec1d --- /dev/null +++ b/examples/array_multiplication/src/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.15) + +add_executable(kompute_array_mult main.cpp) +target_link_libraries(kompute_array_mult PRIVATE shader kompute::kompute) diff --git a/examples/array_multiplication/src/Main.cpp b/examples/array_multiplication/src/Main.cpp deleted file mode 100644 index 4ba17cef1..000000000 --- a/examples/array_multiplication/src/Main.cpp +++ /dev/null @@ -1,79 +0,0 @@ - -#include -#include -#include - -#include "kompute/Kompute.hpp" - -static std::vector -compileSource(const std::string& source) -{ - std::ofstream fileOut("tmp_kp_shader.comp"); - fileOut << source; - fileOut.close(); - if (system( - std::string( - "glslangValidator -V tmp_kp_shader.comp -o tmp_kp_shader.comp.spv") - .c_str())) - throw std::runtime_error("Error running glslangValidator command"); - std::ifstream fileStream("tmp_kp_shader.comp.spv", std::ios::binary); - std::vector buffer; - buffer.insert( - buffer.begin(), std::istreambuf_iterator(fileStream), {}); - return { (uint32_t*)buffer.data(), - (uint32_t*)(buffer.data() + buffer.size()) }; -} - -int -main() -{ -#if KOMPUTE_ENABLE_SPDLOG - spdlog::set_level( - static_cast(SPDLOG_ACTIVE_LEVEL)); -#endif - - kp::Manager mgr; - - auto tensorInA = mgr.tensor({ 2.0, 4.0, 6.0 }); - auto tensorInB = mgr.tensor({ 0.0, 1.0, 2.0 }); - auto tensorOut = mgr.tensor({ 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]; - } - )"); - - std::vector> params = { tensorInA, - tensorInB, - tensorOut }; - - std::shared_ptr algo = - mgr.algorithm(params, compileSource(shader)); - - mgr.sequence() - ->record(params) - ->record(algo) - ->record(params) - ->eval(); - - // prints "Output { 0 4 12 }" - std::cout << "Output: { "; - for (const float& elem : tensorOut->vector()) { - std::cout << elem << " "; - } - std::cout << "}" << std::endl; -} diff --git a/examples/array_multiplication/src/main.cpp b/examples/array_multiplication/src/main.cpp new file mode 100644 index 000000000..56e1c06d2 --- /dev/null +++ b/examples/array_multiplication/src/main.cpp @@ -0,0 +1,41 @@ + +#include +#include +#include + +#include "my_shader.hpp" +#include + +int +main() +{ + kp::Manager mgr; + + std::shared_ptr> tensorInA = + mgr.tensor({ 2.0, 4.0, 6.0 }); + std::shared_ptr> tensorInB = + mgr.tensor({ 0.0, 1.0, 2.0 }); + std::shared_ptr> tensorOut = + mgr.tensor({ 0.0, 0.0, 0.0 }); + + const std::vector> params = { tensorInA, + tensorInB, + tensorOut }; + + const std::vector shader = std::vector( + shader::MY_SHADER_COMP_SPV.begin(), shader::MY_SHADER_COMP_SPV.end()); + std::shared_ptr algo = mgr.algorithm(params, shader); + + mgr.sequence() + ->record(params) + ->record(algo) + ->record(params) + ->eval(); + + // prints "Output { 0 4 12 }" + std::cout << "Output: { "; + for (const float& elem : tensorOut->vector()) { + std::cout << elem << " "; + } + std::cout << "}" << std::endl; +}