Skip to content

Commit

Permalink
Add structure array multiplication example
Browse files Browse the repository at this point in the history
Signed-off-by: Brian Petkovsek <[email protected]>
  • Loading branch information
BrianPetkovsek committed Jun 29, 2023
1 parent 7da4c1c commit 87aa8a9
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 0 deletions.
45 changes: 45 additions & 0 deletions examples/structure_array_multiplication/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
cmake_minimum_required(VERSION 3.20)
project(kompute_array_mult)
include(CMakePrintHelpers)

set(CMAKE_CXX_STANDARD 14)

# Options
option(KOMPUTE_OPT_GIT_TAG "The tag of the repo to use for the example" "master")
option(KOMPUTE_OPT_FROM_SOURCE "Whether to build example from source or from git fetch repo" 0)
# 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(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(DEFAULT_BUILD_TYPE "Debug")
endif()

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)

# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

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

if(KOMPUTE_OPT_FROM_SOURCE)
add_subdirectory(../../ ${CMAKE_CURRENT_BINARY_DIR}/kompute_build)
else()
include(FetchContent)
FetchContent_Declare(kompute GIT_REPOSITORY https://github.com/KomputeProject/kompute.git
GIT_TAG ${KOMPUTE_OPT_GIT_TAG})
FetchContent_MakeAvailable(kompute)
include_directories(${kompute_SOURCE_DIR}/src/include)
endif()

# 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(src/shaders)
add_subdirectory(src)
43 changes: 43 additions & 0 deletions examples/structure_array_multiplication/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Kompute Structure Array Multiplication Example

This folder contains an Kompute Example demonstrating how to use structs between c++ and shaders.

## 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:

```bash
git clone https://github.com/KomputeProject/kompute.git
cd kompute/examples/structure_array_multiplication
mkdir build
cd build
cmake ..
cmake --build .
```

## Executing

Form inside the `build/` directory run:

### Linux

```bash
./kompute_array_mult
```

### Windows

```bash
.\Debug\kompute_array_mult.exe
```

## Pre-requisites

In order to run this example, you will need the following dependencies:

* REQUIRED
+ The Vulkan SDK must be installed

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.
4 changes: 4 additions & 0 deletions examples/structure_array_multiplication/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.20)

add_executable(kompute_array_mult main.cpp)
target_link_libraries(kompute_array_mult PRIVATE shaders kompute::kompute)
71 changes: 71 additions & 0 deletions examples/structure_array_multiplication/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@

#include <iostream>
#include <memory>
#include <vector>

#include "SHADER_Mult1.hpp"
#include <kompute/Kompute.hpp>
#include "shaders/structs/ExampleStructure2.hpp"

int main()
{
kp::Manager mgr;

ExampleStructure2 a{ 1,2,3,4,5,6,7,8,9,10, {11,12,13,14,15,16,17,18,19,20} };
ExampleStructure2 b{ 1,2,3,4,5,6,7,8,9,10, {11,12,13,14,15,16,17,18,19,20} };
ExampleStructure2 c{ 0 };

std::shared_ptr<kp::TensorT<ExampleStructure2>> tensorInA =
mgr.tensorT<ExampleStructure2>({ a, b });
std::shared_ptr<kp::TensorT<ExampleStructure2>> tensorInB =
mgr.tensorT<ExampleStructure2>({ b, a });
std::shared_ptr<kp::TensorT<ExampleStructure2>> tensorOut =
mgr.tensorT<ExampleStructure2>({ c, c });

const std::vector<std::shared_ptr<kp::Tensor>> params = { tensorInA,
tensorInB,
tensorOut };

const std::vector<uint32_t> shader = std::vector<uint32_t>(
shaders::SHADER_MULT1_COMP_SPV.begin(), shaders::SHADER_MULT1_COMP_SPV.end());
std::shared_ptr<kp::Algorithm> algo = mgr.algorithm(params, shader);

mgr.sequence()
->record<kp::OpTensorSyncDevice>(params)
->record<kp::OpAlgoDispatch>(algo)
->record<kp::OpTensorSyncLocal>(params)
->eval();

// prints "Output { 0 4 12 }"
std::cout << "Output: { " << std::endl;
int i = 0;
for (const ExampleStructure2& elem : tensorOut->vector()) {
std::cout << "Elm " << i++ << ": ";
std::cout << elem.a << " ";
std::cout << elem.b << " ";
std::cout << elem.c << " ";
std::cout << elem.d << " ";
std::cout << elem.e << " ";
std::cout << elem.f << " ";
std::cout << elem.g << " ";
std::cout << elem.h << " ";
std::cout << elem.i << " ";
std::cout << elem.j << " ";

std::cout << "{" << " ";

std::cout << elem.k.a << " ";
std::cout << elem.k.b << " ";
std::cout << elem.k.c << " ";
std::cout << elem.k.d << " ";
std::cout << elem.k.e << " ";
std::cout << elem.k.f << " ";
std::cout << elem.k.g << " ";
std::cout << elem.k.h << " ";
std::cout << elem.k.i << " ";
std::cout << elem.k.j << " ";

std::cout << "} " << std::endl;
}
std::cout << "}" << std::endl;
}
18 changes: 18 additions & 0 deletions examples/structure_array_multiplication/src/shaders/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.20)

file(GLOB SHADERS *.comp)
foreach(SHADER ${SHADERS})
get_filename_component(SHADER_NAME ${SHADER} NAME_WE)
set(OUTPUT_FILE_NO_EXT ${CMAKE_CURRENT_BINARY_DIR}/${SHADER_NAME})

vulkan_compile_shader(INFILE ${SHADER_NAME}.comp
OUTFILE ${SHADER_NAME}.hpp
NAMESPACE "shaders"
RELATIVE_PATH "${kompute_SOURCE_DIR}/cmake")


list(APPEND SHADER_OUTPUTS ${OUTPUT_FILE_NO_EXT}.hpp)
endforeach()

add_library(shaders INTERFACE ${SHADER_OUTPUTS})
target_include_directories(shaders INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#version 450
#extension GL_GOOGLE_include_directive : require
#include "structs/ExampleStructure2.hpp"

layout (local_size_x = 1) in;

layout (std430, binding = 0) buffer bufA {
ExampleStructure2 A[];
};

layout (std430, binding = 1) buffer bufB {
ExampleStructure2 B[];
};

layout (std430, binding = 2) buffer bufOut {
ExampleStructure2 Out[];
};

void main() {
uint id = gl_GlobalInvocationID.x;

//example structure2
Out[id].a = A[id].a * B[id].a;
Out[id].b = A[id].b * B[id].b;
Out[id].c = A[id].c * B[id].c;
Out[id].d = A[id].d * B[id].d;
Out[id].e = A[id].e * B[id].e;
Out[id].f = A[id].f * B[id].f;
Out[id].g = A[id].g * B[id].g;
Out[id].h = A[id].h * B[id].h;
Out[id].i = A[id].i * B[id].i;
Out[id].j = A[id].j * B[id].j;

//example structure1(nested struct)
Out[id].k.a = A[id].k.a * B[id].k.a;
Out[id].k.b = A[id].k.b * B[id].k.b;
Out[id].k.c = A[id].k.c * B[id].k.c;
Out[id].k.d = A[id].k.d * B[id].k.d;
Out[id].k.e = A[id].k.e * B[id].k.e;
Out[id].k.f = A[id].k.f * B[id].k.f;
Out[id].k.g = A[id].k.g * B[id].k.g;
Out[id].k.h = A[id].k.h * B[id].k.h;
Out[id].k.i = A[id].k.i * B[id].k.i;
Out[id].k.j = A[id].k.j * B[id].k.j;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef EXAMPLE_STRUCTURE_1_HPP
#define EXAMPLE_STRUCTURE_1_HPP

#if defined(__clang__) || defined(_MSC_VER) || defined(__ICC) || defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__GNUG__)
//c++ compiler
#else
//shader comipler
#extension GL_GOOGLE_include_directive : require
#endif

#include "StructTemplate.hpp"

struct ExampleStructure1
{
int8_t a;
int16_t b;
int32_t c;
int64_t d;

uint8_t e;
uint16_t f;
uint32_t g;
uint64_t h;

float32_t i;
float64_t j;
};
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef EXAMPLE_STRUCTURE_2_HPP
#define EXAMPLE_STRUCTURE_2_HPP

#if defined(__clang__) || defined(_MSC_VER) || defined(__ICC) || defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__GNUG__)
//c++ compiler
#else
//shader comipler
#extension GL_GOOGLE_include_directive : require
#endif

#include "StructTemplate.hpp"
#include "ExampleStructure1.hpp"

struct ExampleStructure2
{
int8_t a;
int16_t b;
int32_t c;
int64_t d;

uint8_t e;
uint16_t f;
uint32_t g;
uint64_t h;

float32_t i;
float64_t j;
ExampleStructure1 k;
};
#endif

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#if defined(__clang__) || defined(_MSC_VER) || defined(__ICC) || defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__GNUG__)
//c++ compiler
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;

typedef float float32_t;
typedef double float64_t;
#else
//shader comipler
#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require
#extension GL_EXT_shader_explicit_arithmetic_types_int32 : require
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require

#extension GL_EXT_shader_explicit_arithmetic_types_float32 : require
#extension GL_EXT_shader_explicit_arithmetic_types_float64 : require
#endif

0 comments on commit 87aa8a9

Please sign in to comment.