Updated logistic regression example

Signed-off-by: Fabian Sauter <sauter.fabian@mailbox.org>
This commit is contained in:
Fabian Sauter 2022-06-24 10:10:11 +02:00
parent 7d16b73d14
commit 4b9b6607d0
7 changed files with 142 additions and 124 deletions

View file

@ -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)

View file

@ -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.

View file

@ -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 $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)

View file

@ -52,5 +52,3 @@ void main() {
lout[idx] = calculateLoss(yHat, yCurr);
}

View file

@ -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)

View file

@ -1,72 +0,0 @@
#include <iostream>
#include <memory>
#include <vector>
#include "kompute/Kompute.hpp"
int
main()
{
#if KOMPUTE_ENABLE_SPDLOG
spdlog::set_level(
static_cast<spdlog::level::level_enum>(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<std::shared_ptr<kp::Tensor>> params = { xI, xJ, y,
wIn, wOutI, wOutJ,
bIn, bOut, lOut };
std::vector<uint32_t> 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<kp::Algorithm> algo = mgr.algorithm(
params, spirv, kp::Workgroup({ 5 }), std::vector<float>({ 5.0 }));
mgr.sequence()->eval<kp::OpTensorSyncDevice>(params);
std::shared_ptr<kp::Sequence> sq =
mgr.sequence()
->record<kp::OpTensorSyncDevice>({ wIn, bIn })
->record<kp::OpAlgoDispatch>(algo)
->record<kp::OpTensorSyncLocal>({ 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;
}

View file

@ -0,0 +1,66 @@
#include <iostream>
#include <memory>
#include <vector>
#include "kompute/Tensor.hpp"
#include "my_shader.hpp"
#include <kompute/Kompute.hpp>
int
main()
{
uint32_t ITERATIONS = 100;
float learningRate = 0.1;
kp::Manager mgr;
std::shared_ptr<kp::TensorT<float>> xI = mgr.tensor({ 0, 1, 1, 1, 1 });
std::shared_ptr<kp::TensorT<float>> xJ = mgr.tensor({ 0, 0, 0, 1, 1 });
std::shared_ptr<kp::TensorT<float>> y = mgr.tensor({ 0, 0, 0, 1, 1 });
std::shared_ptr<kp::TensorT<float>> wIn = mgr.tensor({ 0.001, 0.001 });
std::shared_ptr<kp::TensorT<float>> wOutI = mgr.tensor({ 0, 0, 0, 0, 0 });
std::shared_ptr<kp::TensorT<float>> wOutJ = mgr.tensor({ 0, 0, 0, 0, 0 });
std::shared_ptr<kp::TensorT<float>> bIn = mgr.tensor({ 0 });
std::shared_ptr<kp::TensorT<float>> bOut = mgr.tensor({ 0, 0, 0, 0, 0 });
std::shared_ptr<kp::TensorT<float>> lOut = mgr.tensor({ 0, 0, 0, 0, 0 });
const std::vector<std::shared_ptr<kp::Tensor>> params = {
xI, xJ, y, wIn, wOutI, wOutJ, bIn, bOut, lOut
};
const std::vector<uint32_t> shader = std::vector<uint32_t>(
shader::MY_SHADER_COMP_SPV.begin(), shader::MY_SHADER_COMP_SPV.end());
std::shared_ptr<kp::Algorithm> algo = mgr.algorithm(
params, shader, kp::Workgroup({ 5 }), std::vector<float>({ 5.0 }));
mgr.sequence()->eval<kp::OpTensorSyncDevice>(params);
std::shared_ptr<kp::Sequence> sq =
mgr.sequence()
->record<kp::OpTensorSyncDevice>({ wIn, bIn })
->record<kp::OpAlgoDispatch>(algo)
->record<kp::OpTensorSyncLocal>({ 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;
}