From 4b9b6607d08fc350d7ff387397be2ddea793dfd8 Mon Sep 17 00:00:00 2001 From: Fabian Sauter Date: Fri, 24 Jun 2022 10:10:11 +0200 Subject: [PATCH] Updated logistic regression example Signed-off-by: Fabian Sauter --- examples/logistic_regression/CMakeLists.txt | 56 +++++++-------- examples/logistic_regression/README.md | 46 ++++++------ .../logistic_regression/shader/CMakeLists.txt | 20 ++++++ .../my_shader.comp} | 2 - .../logistic_regression/src/CMakeLists.txt | 4 ++ examples/logistic_regression/src/Main.cpp | 72 ------------------- examples/logistic_regression/src/main.cpp | 66 +++++++++++++++++ 7 files changed, 142 insertions(+), 124 deletions(-) create mode 100644 examples/logistic_regression/shader/CMakeLists.txt rename examples/logistic_regression/{shaders/glsl/logistic_regression.comp => shader/my_shader.comp} (99%) create mode 100644 examples/logistic_regression/src/CMakeLists.txt delete mode 100644 examples/logistic_regression/src/Main.cpp create mode 100644 examples/logistic_regression/src/main.cpp diff --git a/examples/logistic_regression/CMakeLists.txt b/examples/logistic_regression/CMakeLists.txt index 8c8e0eb8f..aa48f4231 100644 --- a/examples/logistic_regression/CMakeLists.txt +++ b/examples/logistic_regression/CMakeLists.txt @@ -1,41 +1,37 @@ -cmake_minimum_required(VERSION 3.4.1) -project(kompute_linear_reg VERSION 0.1.0) +cmake_minimum_required(VERSION 3.15) +project(kompute_logistic_regression) 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_linear_reg - src/Main.cpp) - -target_link_libraries(kompute_linear_reg - kompute::kompute - Vulkan::Vulkan -) - -include_directories( - ../../single_include/) - -if(KOMPUTE_OPT_ENABLE_SPDLOG) - target_link_libraries(kompute_linear_reg - 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 528e80515918b314d51a8082220572d27e20d94d) # 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/logistic_regression/README.md b/examples/logistic_regression/README.md index f6be72e60..204180f0a 100644 --- a/examples/logistic_regression/README.md +++ b/examples/logistic_regression/README.md @@ -1,30 +1,39 @@ # Kompute Logistic Regression 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/logistic_regression +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_logistic_regression +``` + +### Windows + +```bash +.\Debug\kompute_logistic_regression.exe +``` ## Pre-requisites @@ -32,8 +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 +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. diff --git a/examples/logistic_regression/shader/CMakeLists.txt b/examples/logistic_regression/shader/CMakeLists.txt new file mode 100644 index 000000000..bb01a0059 --- /dev/null +++ b/examples/logistic_regression/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/logistic_regression/shaders/glsl/logistic_regression.comp b/examples/logistic_regression/shader/my_shader.comp similarity index 99% rename from examples/logistic_regression/shaders/glsl/logistic_regression.comp rename to examples/logistic_regression/shader/my_shader.comp index 9fd76619b..a7f75b0f3 100644 --- a/examples/logistic_regression/shaders/glsl/logistic_regression.comp +++ b/examples/logistic_regression/shader/my_shader.comp @@ -52,5 +52,3 @@ void main() { lout[idx] = calculateLoss(yHat, yCurr); } - - diff --git a/examples/logistic_regression/src/CMakeLists.txt b/examples/logistic_regression/src/CMakeLists.txt new file mode 100644 index 000000000..8a2dfe8c9 --- /dev/null +++ b/examples/logistic_regression/src/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.15) + +add_executable(kompute_logistic_regression main.cpp) +target_link_libraries(kompute_logistic_regression PRIVATE shader kompute::kompute) diff --git a/examples/logistic_regression/src/Main.cpp b/examples/logistic_regression/src/Main.cpp deleted file mode 100644 index 8feee258f..000000000 --- a/examples/logistic_regression/src/Main.cpp +++ /dev/null @@ -1,72 +0,0 @@ - -#include -#include -#include - -#include "kompute/Kompute.hpp" - -int -main() -{ -#if KOMPUTE_ENABLE_SPDLOG - spdlog::set_level( - static_cast(SPDLOG_ACTIVE_LEVEL)); -#endif - - uint32_t ITERATIONS = 100; - float learningRate = 0.1; - - kp::Manager mgr; - - auto xI = mgr.tensor({ 0, 1, 1, 1, 1 }); - auto xJ = mgr.tensor({ 0, 0, 0, 1, 1 }); - - auto y = mgr.tensor({ 0, 0, 0, 1, 1 }); - - auto wIn = mgr.tensor({ 0.001, 0.001 }); - auto wOutI = mgr.tensor({ 0, 0, 0, 0, 0 }); - auto wOutJ = mgr.tensor({ 0, 0, 0, 0, 0 }); - - auto bIn = mgr.tensor({ 0 }); - auto bOut = mgr.tensor({ 0, 0, 0, 0, 0 }); - - auto lOut = mgr.tensor({ 0, 0, 0, 0, 0 }); - - std::vector> params = { xI, xJ, y, - wIn, wOutI, wOutJ, - bIn, bOut, lOut }; - - std::vector spirv( - (uint32_t*)kp::shader_data::shaders_glsl_logisticregression_comp_spv, - (uint32_t*)(kp::shader_data::shaders_glsl_logisticregression_comp_spv + - kp::shader_data:: - shaders_glsl_logisticregression_comp_spv_len)); - - std::shared_ptr algo = mgr.algorithm( - params, spirv, kp::Workgroup({ 5 }), std::vector({ 5.0 })); - - mgr.sequence()->eval(params); - - std::shared_ptr sq = - mgr.sequence() - ->record({ wIn, bIn }) - ->record(algo) - ->record({ wOutI, wOutJ, bOut, lOut }); - - // Iterate across all expected iterations - for (size_t i = 0; i < ITERATIONS; i++) { - - sq->eval(); - - for (size_t j = 0; j < bOut->size(); j++) { - wIn->data()[0] -= learningRate * wOutI->data()[j]; - wIn->data()[1] -= learningRate * wOutJ->data()[j]; - bIn->data()[0] -= learningRate * bOut->data()[j]; - } - } - - std::cout << "RESULTS" << std::endl; - std::cout << "w1: " << wIn->data()[0] << std::endl; - std::cout << "w2: " << wIn->data()[1] << std::endl; - std::cout << "b: " << bIn->data()[0] << std::endl; -} diff --git a/examples/logistic_regression/src/main.cpp b/examples/logistic_regression/src/main.cpp new file mode 100644 index 000000000..bc249a36f --- /dev/null +++ b/examples/logistic_regression/src/main.cpp @@ -0,0 +1,66 @@ + +#include +#include +#include + +#include "kompute/Tensor.hpp" +#include "my_shader.hpp" +#include + +int +main() +{ + uint32_t ITERATIONS = 100; + float learningRate = 0.1; + + kp::Manager mgr; + + std::shared_ptr> xI = mgr.tensor({ 0, 1, 1, 1, 1 }); + std::shared_ptr> xJ = mgr.tensor({ 0, 0, 0, 1, 1 }); + + std::shared_ptr> y = mgr.tensor({ 0, 0, 0, 1, 1 }); + + std::shared_ptr> wIn = mgr.tensor({ 0.001, 0.001 }); + std::shared_ptr> wOutI = mgr.tensor({ 0, 0, 0, 0, 0 }); + std::shared_ptr> wOutJ = mgr.tensor({ 0, 0, 0, 0, 0 }); + + std::shared_ptr> bIn = mgr.tensor({ 0 }); + std::shared_ptr> bOut = mgr.tensor({ 0, 0, 0, 0, 0 }); + + std::shared_ptr> lOut = mgr.tensor({ 0, 0, 0, 0, 0 }); + + const std::vector> params = { + xI, xJ, y, wIn, wOutI, wOutJ, bIn, bOut, lOut + }; + + 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, kp::Workgroup({ 5 }), std::vector({ 5.0 })); + + mgr.sequence()->eval(params); + + std::shared_ptr sq = + mgr.sequence() + ->record({ wIn, bIn }) + ->record(algo) + ->record({ wOutI, wOutJ, bOut, lOut }); + + // Iterate across all expected iterations + for (size_t i = 0; i < ITERATIONS; i++) { + + sq->eval(); + + for (size_t j = 0; j < bOut->size(); j++) { + wIn->data()[0] -= learningRate * wOutI->data()[j]; + wIn->data()[1] -= learningRate * wOutJ->data()[j]; + bIn->data()[0] -= learningRate * bOut->data()[j]; + } + } + + std::cout << "RESULTS" << std::endl; + std::cout << "w1: " << wIn->data()[0] << std::endl; + std::cout << "w2: " << wIn->data()[1] << std::endl; + std::cout << "b: " << bIn->data()[0] << std::endl; +} \ No newline at end of file