Merge pull request #235 from EthicalML/remove_glslang_as_core_dep

Removing GLSLang as core dependency
This commit is contained in:
Alejandro Saucedo 2021-07-21 20:45:03 +01:00 committed by GitHub
commit 70227ce7cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 192 additions and 588 deletions

1
.ccls
View file

@ -24,4 +24,5 @@
-I./single_include/ -I./single_include/
-I./vk_ndk_wrapper_include/ -I./vk_ndk_wrapper_include/
-I./test/compiled_shaders_include/ -I./test/compiled_shaders_include/
-I./test/utils/

View file

@ -10,7 +10,7 @@ jobs:
cpp-tests: cpp-tests:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
container: axsauze/kompute-builder:0.2 container: axsauze/kompute-builder:0.3
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View file

@ -10,7 +10,7 @@ jobs:
python-tests: python-tests:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
container: axsauze/kompute-builder:0.2 container: axsauze/kompute-builder:0.3
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

2
.gitignore vendored
View file

@ -186,5 +186,5 @@ release/
# Kompute # Kompute
swiftshader/ swiftshader/
vk_swiftshader_icd.json vk_swiftshader_icd.json
tmp_kp_shader.comp.spv

4
.gitmodules vendored
View file

@ -14,10 +14,6 @@
path = python/pybind11 path = python/pybind11
url = https://github.com/pybind/pybind11 url = https://github.com/pybind/pybind11
branch = v2.6.1 branch = v2.6.1
[submodule "external/glslang"]
path = external/glslang
url = https://github.com/KhronosGroup/glslang/
branch = 11.1.0
[submodule "external/fmt"] [submodule "external/fmt"]
path = external/fmt path = external/fmt
url = https://github.com/fmtlib/fmt url = https://github.com/fmtlib/fmt

View file

@ -34,7 +34,7 @@
**Closed issues:** **Closed issues:**
- Update memory barriers to align with tensor staging/primary memory revamp [\#181](https://github.com/EthicalML/vulkan-kompute/issues/181) - Update memory barriers to align with tensor staging/primary memory revamp [\#181](https://github.com/EthicalML/vulkan-kompute/issues/181)
- Move shader defaultResource inside kp::Shader class [\#175](https://github.com/EthicalML/vulkan-kompute/issues/175) - Move shader defaultResource inside kp_test_utils::Shader class [\#175](https://github.com/EthicalML/vulkan-kompute/issues/175)
- Reach at least 90% code coverage on tests [\#170](https://github.com/EthicalML/vulkan-kompute/issues/170) - Reach at least 90% code coverage on tests [\#170](https://github.com/EthicalML/vulkan-kompute/issues/170)
- Add functionality to re-record sequence as now it's possible to update the underlying algorithm [\#169](https://github.com/EthicalML/vulkan-kompute/issues/169) - Add functionality to re-record sequence as now it's possible to update the underlying algorithm [\#169](https://github.com/EthicalML/vulkan-kompute/issues/169)
- Use numpy arrays as default return value [\#166](https://github.com/EthicalML/vulkan-kompute/issues/166) - Use numpy arrays as default return value [\#166](https://github.com/EthicalML/vulkan-kompute/issues/166)

View file

@ -19,7 +19,6 @@ option(KOMPUTE_OPT_ENABLE_SPDLOG "Extra compile flags for Kompute, see docs for
option(KOMPUTE_OPT_REPO_SUBMODULE_BUILD "Use the submodule repos instead of external package manager" 0) option(KOMPUTE_OPT_REPO_SUBMODULE_BUILD "Use the submodule repos instead of external package manager" 0)
option(KOMPUTE_OPT_ANDROID_BUILD "Enable android compilation flags required" 0) option(KOMPUTE_OPT_ANDROID_BUILD "Enable android compilation flags required" 0)
option(KOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS "Explicitly disable debug layers even on debug" 0) option(KOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS "Explicitly disable debug layers even on debug" 0)
option(KOMPUTE_OPT_DISABLE_SHADER_UTILS "Remove shader util code and dependencies including glslang" 0)
option(KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS "Whether to use shared libraries for dependencies for install" 0) option(KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS "Whether to use shared libraries for dependencies for install" 0)
option(KOMPUTE_OPT_BUILD_AS_SHARED_LIB "Whether to build kompute as shared library" 0) option(KOMPUTE_OPT_BUILD_AS_SHARED_LIB "Whether to build kompute as shared library" 0)
# Build flags # Build flags
@ -55,19 +54,15 @@ if(KOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS)
set(KOMPUTE_EXTRA_CXX_FLAGS "${KOMPUTE_EXTRA_CXX_FLAGS} -DKOMPUTE_DISABLE_VK_DEBUG_LAYERS=1") set(KOMPUTE_EXTRA_CXX_FLAGS "${KOMPUTE_EXTRA_CXX_FLAGS} -DKOMPUTE_DISABLE_VK_DEBUG_LAYERS=1")
endif() endif()
if(NOT KOMPUTE_OPT_DISABLE_SHADER_UTILS) if(KOMPUTE_OPT_INSTALL)
if(KOMPUTE_OPT_INSTALL) # Enable install parameters for glslang (overrides parameters passed)
# Enable install parameters for glslang (overrides parameters passed) # When install is enabled the glslang libraries become shared
# When install is enabled the glslang libraries become shared set(ENABLE_GLSLANG_INSTALL ON CACHE BOOL "Enables install of glslang" FORCE)
set(ENABLE_GLSLANG_INSTALL ON CACHE BOOL "Enables install of glslang" FORCE)
# By default we enable shared library based installation # By default we enable shared library based installation
if(KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS) if(KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON CACHE BOOL "Enables build of shared libraries" FORCE) set(BUILD_SHARED_LIBS ON CACHE BOOL "Enables build of shared libraries" FORCE)
endif()
endif() endif()
else()
set(KOMPUTE_EXTRA_CXX_FLAGS "${KOMPUTE_EXTRA_CXX_FLAGS} -DKOMPUTE_DISABLE_SHADER_UTILS=1")
endif() endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1 ${KOMPUTE_EXTRA_CXX_FLAGS} -DUSE_DEBUG_EXTENTIONS") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1 ${KOMPUTE_EXTRA_CXX_FLAGS} -DUSE_DEBUG_EXTENTIONS")

View file

@ -194,7 +194,7 @@ build_single_header:
"single_include/kompute/Kompute.hpp" "single_include/kompute/Kompute.hpp"
win_build_xxd: win_build_xxd:
cd external/bin/ && gcc -o xxd.exe xxd.c -DCYGWIN cd external/bin/ && gcc.exe -o xxd.exe xxd.c -DCYGWIN
format: format:
$(CLANG_FORMAT_BIN) -i -style="{BasedOnStyle: mozilla, IndentWidth: 4}" src/*.cpp src/include/kompute/*.hpp test/*cpp $(CLANG_FORMAT_BIN) -i -style="{BasedOnStyle: mozilla, IndentWidth: 4}" src/*.cpp src/include/kompute/*.hpp test/*cpp

View file

@ -74,7 +74,8 @@ void kompute(const std::string& shader) {
kp::Constants pushConstsB({ 3.0 }); kp::Constants pushConstsB({ 3.0 });
auto algorithm = mgr.algorithm(params, auto algorithm = mgr.algorithm(params,
kp::Shader::compileSource(shader), // See documentation shader section for compileSource
compileSource(shader),
workgroup, workgroup,
specConsts, specConsts,
pushConstsA); pushConstsA);
@ -165,6 +166,7 @@ def kompute(shader):
push_consts_a = [2] push_consts_a = [2]
push_consts_b = [3] push_consts_b = [3]
# See documentation shader section for compile_source
spirv = kp.Shader.compile_source(shader) spirv = kp.Shader.compile_source(shader)
algo = mgr.algorithm(params, spirv, workgroup, spec_consts, push_consts_a) algo = mgr.algorithm(params, spirv, workgroup, spec_consts, push_consts_a)
@ -372,7 +374,7 @@ You can also access the <a href="https://github.com/EthicalML/vulkan-kompute/tre
### Simple examples ### Simple examples
* [Pass shader as raw string](https://kompute.cc/overview/advanced-examples.html#simple-shader-example) * [Simple multiplication example](https://kompute.cc/overview/advanced-examples.html#simple-shader-example)
* [Record batch commands with a Kompute Sequence](https://kompute.cc/overview/advanced-examples.html#record-batch-commands) * [Record batch commands with a Kompute Sequence](https://kompute.cc/overview/advanced-examples.html#record-batch-commands)
* [Run Asynchronous Operations](https://kompute.cc/overview/advanced-examples.html#asynchronous-operations) * [Run Asynchronous Operations](https://kompute.cc/overview/advanced-examples.html#asynchronous-operations)
* [Run Parallel Operations Across Multiple GPU Queues](https://kompute.cc/overview/advanced-examples.html#parallel-operations) * [Run Parallel Operations Across Multiple GPU Queues](https://kompute.cc/overview/advanced-examples.html#parallel-operations)

View file

@ -1,4 +1,4 @@
FROM ubuntu:18.04 FROM ubuntu:20.04
# Base packages from default ppa # Base packages from default ppa
RUN apt-get update -y RUN apt-get update -y
@ -26,9 +26,14 @@ RUN apt-get install -y libxext-dev
COPY --from=axsauze/swiftshader:0.1 /swiftshader/ /swiftshader/ COPY --from=axsauze/swiftshader:0.1 /swiftshader/ /swiftshader/
# GLSLANG tools for tests
RUN apt-get install -y glslang-tools
# Setup Python # Setup Python
RUN apt-get install -y python3-pip RUN apt-get install -y python3-pip
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 10
RUN mkdir builder RUN mkdir builder
WORKDIR /builder WORKDIR /builder

View file

@ -1,9 +1,9 @@
build_kompute_builder: build_kompute_builder:
docker build .. -f KomputeBuilder.Dockerfile -t axsauze/kompute-builder:0.2 docker build .. -f KomputeBuilder.Dockerfile -t axsauze/kompute-builder:0.3
push_kompute_builder: build_kompute_builder push_kompute_builder: build_kompute_builder
docker push axsauze/kompute-builder:0.2 docker push axsauze/kompute-builder:0.3
build_swiftshader: build_swiftshader:
docker build .. -f Swiftshader.Dockerfile -t axsauze/swiftshader:0.1 docker build .. -f Swiftshader.Dockerfile -t axsauze/swiftshader:0.1

View file

@ -55,7 +55,8 @@ The example below shows how you can enable the "VK_EXT_shader_atomic_float" exte
atomicAdd(pa[2], pcs.z); atomicAdd(pa[2], pcs.z);
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); // See shader documentation section for compileSource
std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;
@ -102,7 +103,8 @@ We also provide tools that allow you to `convert shaders into C++ headers <https
throw std::runtime_error("Kompute OpMult expected 3 tensors but got " + tensors.size()); throw std::runtime_error("Kompute OpMult expected 3 tensors but got " + tensors.size());
} }
std::vector<uint32_t> spirv = kp::Shader::compileSource(R"( // See shader documentation section for compileSource
std::vector<uint32_t> spirv = compileSource(R"(
#version 450 #version 450
layout(set = 0, binding = 0) buffer tensorLhs { layout(set = 0, binding = 0) buffer tensorLhs {
@ -215,7 +217,8 @@ In this case we create a shader that should take a couple of milliseconds to run
} }
)"); )");
auto algo = mgr.algorithm({tensor}, kp::Shader::compileSource(shader)); // See shader documentation section for compileSource
auto algo = mgr.algorithm({tensor}, compileSource(shader));
Now we are able to run the await function on the default sequence. Now we are able to run the await function on the default sequence.
@ -361,7 +364,8 @@ Similar to the asyncrhonous usecase above, we can still run synchronous commands
} }
)"); )");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); // See shader documentation section for compileSource
std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Algorithm> algo = mgr.algorithm({tensorA, tenssorB}, spirv); std::shared_ptr<kp::Algorithm> algo = mgr.algorithm({tensorA, tenssorB}, spirv);

View file

@ -69,8 +69,6 @@ Compile Flags
- Enable debug build including debug flags (enabled by cmake debug build) - Enable debug build including debug flags (enabled by cmake debug build)
* - -DKOMPUTE_DISABLE_VK_DEBUG_LAYERS * - -DKOMPUTE_DISABLE_VK_DEBUG_LAYERS
- Disable the debug Vulkan SDK Layers, mainly used for android builds - Disable the debug Vulkan SDK Layers, mainly used for android builds
* - -DKOMPUTE_DISABLE_SHADER_UTILS
- Disable the shader utils and skip adding glslang as dependency
Other CMake Flags Other CMake Flags
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

View file

@ -38,10 +38,7 @@ Running on the CPU
We use `Swiftshader <https://github.com/google/swiftshader>`_ to enable us to run the Kompute framework directly on the CPU for the CI tests. We use `Swiftshader <https://github.com/google/swiftshader>`_ to enable us to run the Kompute framework directly on the CPU for the CI tests.
Even though Swiftshader is optimized to function as a high-performance CPU backend for the Vulkan SDK, there are several limitations, the most notable in context of Kompute are: Even though Swiftshader is optimized to function as a high-performance CPU backend for the Vulkan SDK, there are several limitations, the most notable are limitations in extensions.
* Loading files (spirv or text) leads to segfault
* Loading raw text string shaders leads to segfault
This is one of the main reason why only a subset of the tests are run in the CI. This is one of the main reason why only a subset of the tests are run in the CI.

View file

@ -119,13 +119,4 @@ The :class:`kp::OpMemoryBarrier` is a tensor only operation which adds memory ba
.. doxygenclass:: kp::OpTensorSyncDevice .. doxygenclass:: kp::OpTensorSyncDevice
:members: :members:
Shader
--------
The :class:`kp::Shader` class contains a set of utilities to compile and process shaders.
.. doxygenclass:: kp::Shader
:members:

View file

@ -3,21 +3,29 @@
Processing Shaders with Kompute Processing Shaders with Kompute
===================== =====================
Kompute allows for two main ways of interacting with shaders - namely: Demo / testing function to compile shaders
----------------------------------
* Integration with [glslang](https://github.com/KhronosGroup/glslang) for online/runtime shader compilation GLSLANG was initially integrated as part of the framework but it now has been removed due to the license of the glslang pre-processor being under a custom NVIDIA license which explicitly excludes grant of any licenses to NVIDIA's patents in the preprocessor. This is covered in more detail here: https://github.com/EthicalML/vulkan-kompute/pull/235
* A CLI that coverts shaders into C++ header files
Processing Shaders Online via Kompute Shader Utils For users that are looking to quickly test the processors it is possible to use the function that is provided in the examples which provides a (non-thread-safe / non-robust) implementation that compiles a shader string into spirv bytes. It is not recommended to use in production but it does enable for faster iteration cycles during development.
---------------
Kompute provides a set of helper functions that expose the C++ functionality of the glslang Khronos framework to process shader sources online during runtime. .. code-block:: cpp
:linenos:
It's worth emphasising that the suggested approach is to process shaders offline, so the section below is suggested to convert shaders to either their respective SPV format, or convert them into C++ sources that would be embedded as part of the resulting binary. static std::vector<uint32_t>
compileSource(
The Shader utility function can be skipped on build time through compiler flags - for more information on this you should read the `build section <build-system.rst>`_. const std::string& source)
{
More details on the shader utils can be found in the :class:`kp::Shader` section of the `C++ reference page <reference.rst>`_. if (system(std::string("glslangValidator --stdin -S comp -V -o tmp_kp_shader.comp.spv << END
" + source + "
END").c_str()))
throw std::runtime_error("Error running glslangValidator command");
std::ifstream fileStream("tmp_kp_shader.comp.spv", std::ios::binary);
std::vector<char> buffer;
buffer.insert(buffer.begin(), std::istreambuf_iterator<char>(fileStream), {});
return {(uint32_t*)buffer.data(), (uint32_t*)(buffer.data() + buffer.size())};
}
Converting Shaders into C / C++ Header Files Converting Shaders into C / C++ Header Files
---------------------------------- ----------------------------------

View file

@ -5,6 +5,18 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
static std::vector<uint32_t>
compileSource(
const std::string& source)
{
if (system(std::string("glslangValidator --stdin -S comp -V -o tmp_kp_shader.comp.spv << END\n" + source + "\nEND").c_str()))
throw std::runtime_error("Error running glslangValidator command");
std::ifstream fileStream("tmp_kp_shader.comp.spv", std::ios::binary);
std::vector<char> buffer;
buffer.insert(buffer.begin(), std::istreambuf_iterator<char>(fileStream), {});
return {(uint32_t*)buffer.data(), (uint32_t*)(buffer.data() + buffer.size())};
}
int main() int main()
{ {
#if KOMPUTE_ENABLE_SPDLOG #if KOMPUTE_ENABLE_SPDLOG
@ -39,7 +51,7 @@ int main()
std::vector<std::shared_ptr<kp::Tensor>> params = { tensorInA, tensorInB, tensorOut }; std::vector<std::shared_ptr<kp::Tensor>> params = { tensorInA, tensorInB, tensorOut };
std::shared_ptr<kp::Algorithm> algo = mgr.algorithm(params, kp::Shader::compileSource(shader)); std::shared_ptr<kp::Algorithm> algo = mgr.algorithm(params, kp_test_utils::compileSource(shader));
mgr.sequence() mgr.sequence()
->record<kp::OpTensorSyncDevice>(params) ->record<kp::OpTensorSyncDevice>(params)

View file

@ -4,6 +4,18 @@
#include "KomputeSummatorNode.h" #include "KomputeSummatorNode.h"
static std::vector<uint32_t>
compileSource(
const std::string& source)
{
if (system(std::string("glslangValidator --stdin -S comp -V -o tmp_kp_shader.comp.spv << END\n" + source + "\nEND").c_str()))
throw std::runtime_error("Error running glslangValidator command");
std::ifstream fileStream("tmp_kp_shader.comp.spv", std::ios::binary);
std::vector<char> buffer;
buffer.insert(buffer.begin(), std::istreambuf_iterator<char>(fileStream), {});
return {(uint32_t*)buffer.data(), (uint32_t*)(buffer.data() + buffer.size())};
}
KomputeSummatorNode::KomputeSummatorNode() { KomputeSummatorNode::KomputeSummatorNode() {
this->_init(); this->_init();
} }
@ -52,9 +64,9 @@ void KomputeSummatorNode::_init() {
)"); )");
std::shared_ptr<kp::Algorithm> algo = std::shared_ptr<kp::Algorithm> algo =
mgr.algorithm( this->mManager.algorithm(
{ this->mPrimaryTensor, this->mSecondaryTensor }, { this->mPrimaryTensor, this->mSecondaryTensor },
kp::Shader::compileSource(shader)); compileSource(shader));
// First we ensure secondary tensor loads to GPU // First we ensure secondary tensor loads to GPU
@ -63,7 +75,7 @@ void KomputeSummatorNode::_init() {
{ this->mSecondaryTensor }); { this->mSecondaryTensor });
// Then we run the operation with both tensors // Then we run the operation with both tensors
sq->record<kp::OpAlgoDispatch>(algo) sq->record<kp::OpAlgoDispatch>(algo);
// We map the result back to local // We map the result back to local
sq->record<kp::OpTensorSyncLocal>( sq->record<kp::OpTensorSyncLocal>(

View file

@ -5,6 +5,18 @@
#include "KomputeSummator.hpp" #include "KomputeSummator.hpp"
static std::vector<uint32_t>
compileSource(
const std::string& source)
{
if (system(std::string("glslangValidator --stdin -S comp -V -o tmp_kp_shader.comp.spv << END\n" + source + "\nEND").c_str()))
throw std::runtime_error("Error running glslangValidator command");
std::ifstream fileStream("tmp_kp_shader.comp.spv", std::ios::binary);
std::vector<char> buffer;
buffer.insert(buffer.begin(), std::istreambuf_iterator<char>(fileStream), {});
return {(uint32_t*)buffer.data(), (uint32_t*)(buffer.data() + buffer.size())};
}
namespace godot { namespace godot {
KomputeSummator::KomputeSummator() { KomputeSummator::KomputeSummator() {
@ -58,7 +70,7 @@ void KomputeSummator::_init() {
// Then we run the operation with both tensors // Then we run the operation with both tensors
this->mSequence->record<kp::OpAlgoCreate>( this->mSequence->record<kp::OpAlgoCreate>(
{ this->mPrimaryTensor, this->mSecondaryTensor }, { this->mPrimaryTensor, this->mSecondaryTensor },
kp::Shader::compileSource(shader)); compileSource(shader));
// We map the result back to local // We map the result back to local
this->mSequence->record<kp::OpTensorSyncLocal>( this->mSequence->record<kp::OpTensorSyncLocal>(

View file

@ -1,8 +1,15 @@
import os
import kp import kp
def compile_source(source):
os.system("glslangValidator --stdin -S comp -V -o tmp_kp_shader.comp.spv << END\n" + source + "\nEND")
return open("tmp_kp_shader.comp.spv", "rb").read()
# This is the convolution & leakyrelu shader. # This is the convolution & leakyrelu shader.
global conv_shader global conv_shader
conv_shader = kp.Shader.compile_source(""" conv_shader = compile_source("""
#version 450 #version 450
layout (local_size_x = 8, local_size_y = 2) in; layout (local_size_x = 8, local_size_y = 2) in;

1
external/glslang vendored

@ -1 +0,0 @@
Subproject commit c594de23cdd790d64ad5f9c8b059baae0ee2941d

View file

@ -33,34 +33,6 @@ PYBIND11_MODULE(kp, m) {
.value("storage", kp::Tensor::TensorTypes::eStorage, DOC(kp, Tensor, TensorTypes, eStorage)) .value("storage", kp::Tensor::TensorTypes::eStorage, DOC(kp, Tensor, TensorTypes, eStorage))
.export_values(); .export_values();
#if !defined(KOMPUTE_DISABLE_SHADER_UTILS) || !KOMPUTE_DISABLE_SHADER_UTILS
py::class_<kp::Shader>(m, "Shader", "Shader class")
.def_static("compile_source", [](
const std::string& source,
const std::string& entryPoint,
const std::vector<std::pair<std::string,std::string>>& definitions) {
std::vector<uint32_t> spirv = kp::Shader::compileSource(source, entryPoint, definitions);
return py::bytes((const char*)spirv.data(), spirv.size() * sizeof(uint32_t));
},
DOC(kp, Shader, compileSource),
py::arg("source"),
py::arg("entryPoint") = "main",
py::arg("definitions") = std::vector<std::pair<std::string,std::string>>() )
.def_static("compile_sources", [](
const std::vector<std::string>& source,
const std::vector<std::string>& files,
const std::string& entryPoint,
const std::vector<std::pair<std::string,std::string>>& definitions) {
std::vector<uint32_t> spirv = kp::Shader::compileSources(source, files, entryPoint, definitions);
return py::bytes((const char*)spirv.data(), spirv.size() * sizeof(uint32_t));
},
DOC(kp, Shader, compileSources),
py::arg("sources"),
py::arg("files") = std::vector<std::string>(),
py::arg("entryPoint") = "main",
py::arg("definitions") = std::vector<std::pair<std::string,std::string>>() );
#endif // KOMPUTE_DISABLE_SHADER_UTILS
py::class_<kp::OpBase, std::shared_ptr<kp::OpBase>>(m, "OpBase", DOC(kp, OpBase)); py::class_<kp::OpBase, std::shared_ptr<kp::OpBase>>(m, "OpBase", DOC(kp, OpBase));
py::class_<kp::OpTensorSyncDevice, std::shared_ptr<kp::OpTensorSyncDevice>>( py::class_<kp::OpTensorSyncDevice, std::shared_ptr<kp::OpTensorSyncDevice>>(

0
python/test/__init__.py Normal file
View file

View file

@ -5,10 +5,13 @@ import numpy as np
import logging import logging
import pyshader as ps import pyshader as ps
from .utils import compile_source
DIRNAME = os.path.dirname(os.path.abspath(__file__)) DIRNAME = os.path.dirname(os.path.abspath(__file__))
kp_log = logging.getLogger("kp") kp_log = logging.getLogger("kp")
def test_end_to_end(): def test_end_to_end():
mgr = kp.Manager() mgr = kp.Manager()
@ -52,7 +55,7 @@ def test_end_to_end():
push_consts_a = [2] push_consts_a = [2]
push_consts_b = [3] push_consts_b = [3]
algo = mgr.algorithm(params, kp.Shader.compile_source(shader), workgroup, spec_consts, push_consts_a) algo = mgr.algorithm(params, compile_source(shader), workgroup, spec_consts, push_consts_a)
(mgr.sequence() (mgr.sequence()
.record(kp.OpTensorSyncDevice(params)) .record(kp.OpTensorSyncDevice(params))
@ -88,7 +91,7 @@ void main()
} }
""" """
spirv = kp.Shader.compile_source(shader) spirv = compile_source(shader)
mgr = kp.Manager() mgr = kp.Manager()
@ -108,6 +111,7 @@ void main()
assert tensor_out.data().tolist() == [2.0, 4.0, 6.0] assert tensor_out.data().tolist() == [2.0, 4.0, 6.0]
def test_sequence(): def test_sequence():
""" """
Test basic OpAlgoBase operation Test basic OpAlgoBase operation
@ -127,7 +131,7 @@ def test_sequence():
} }
""" """
spirv = kp.Shader.compile_source(shader) spirv = compile_source(shader)
mgr = kp.Manager(0) mgr = kp.Manager(0)
@ -164,9 +168,10 @@ def test_sequence():
assert tensor_in_b.is_init() == False assert tensor_in_b.is_init() == False
assert tensor_out.is_init() == False assert tensor_out.is_init() == False
def test_pushconsts(): def test_pushconsts():
spirv = kp.Shader.compile_source(""" spirv = compile_source("""
#version 450 #version 450
layout(push_constant) uniform PushConstants { layout(push_constant) uniform PushConstants {
float x; float x;
@ -197,6 +202,7 @@ def test_pushconsts():
assert np.all(tensor.data() == np.array([0.4, 0.4, 0.4], dtype=np.float32)) assert np.all(tensor.data() == np.array([0.4, 0.4, 0.4], dtype=np.float32))
def test_workgroup(): def test_workgroup():
mgr = kp.Manager(0) mgr = kp.Manager(0)
@ -227,6 +233,7 @@ def test_workgroup():
assert np.all(tensor_a.data() == np.stack([np.arange(16)]*8, axis=1).ravel()) assert np.all(tensor_a.data() == np.stack([np.arange(16)]*8, axis=1).ravel())
assert np.all(tensor_b.data() == np.stack([np.arange(8)]*16, axis=0).ravel()) assert np.all(tensor_b.data() == np.stack([np.arange(8)]*16, axis=0).ravel())
def test_mgr_utils(): def test_mgr_utils():
mgr = kp.Manager() mgr = kp.Manager()

View file

@ -1,9 +1,10 @@
import pyshader as ps
import os import os
import pytest import pytest
import kp import kp
import numpy as np import numpy as np
from .utils import compile_source
VK_ICD_FILENAMES = os.environ.get("VK_ICD_FILENAMES", "") VK_ICD_FILENAMES = os.environ.get("VK_ICD_FILENAMES", "")
def test_type_float(): def test_type_float():
@ -22,7 +23,7 @@ def test_type_float():
} }
""" """
spirv = kp.Shader.compile_source(shader) spirv = compile_source(shader)
arr_in_a = np.array([123., 153., 231.], dtype=np.float32) arr_in_a = np.array([123., 153., 231.], dtype=np.float32)
arr_in_b = np.array([9482, 1208, 1238], dtype=np.float32) arr_in_b = np.array([9482, 1208, 1238], dtype=np.float32)
@ -61,7 +62,7 @@ def test_type_float_double_incorrect():
} }
""" """
spirv = kp.Shader.compile_source(shader) spirv = compile_source(shader)
arr_in_a = np.array([123., 153., 231.], dtype=np.float32) arr_in_a = np.array([123., 153., 231.], dtype=np.float32)
arr_in_b = np.array([9482, 1208, 1238], dtype=np.uint32) arr_in_b = np.array([9482, 1208, 1238], dtype=np.uint32)
@ -103,7 +104,7 @@ def test_type_double():
} }
""" """
spirv = kp.Shader.compile_source(shader) spirv = compile_source(shader)
arr_in_a = np.array([123., 153., 231.], dtype=np.float64) arr_in_a = np.array([123., 153., 231.], dtype=np.float64)
arr_in_b = np.array([9482, 1208, 1238], dtype=np.float64) arr_in_b = np.array([9482, 1208, 1238], dtype=np.float64)
@ -143,7 +144,7 @@ def test_type_int():
} }
""" """
spirv = kp.Shader.compile_source(shader) spirv = compile_source(shader)
arr_in_a = np.array([123, 153, 231], dtype=np.int32) arr_in_a = np.array([123, 153, 231], dtype=np.int32)
arr_in_b = np.array([9482, 1208, 1238], dtype=np.int32) arr_in_b = np.array([9482, 1208, 1238], dtype=np.int32)
@ -183,7 +184,7 @@ def test_type_unsigned_int():
} }
""" """
spirv = kp.Shader.compile_source(shader) spirv = compile_source(shader)
arr_in_a = np.array([123, 153, 231], dtype=np.uint32) arr_in_a = np.array([123, 153, 231], dtype=np.uint32)
arr_in_b = np.array([9482, 1208, 1238], dtype=np.uint32) arr_in_b = np.array([9482, 1208, 1238], dtype=np.uint32)

7
python/test/utils.py Normal file
View file

@ -0,0 +1,7 @@
import os
def compile_source(source):
os.system("glslangValidator --stdin -S comp -V -o tmp_kp_shader.comp.spv << END\n" + source + "\nEND")
return open("tmp_kp_shader.comp.spv", "rb").read()

View file

@ -2,7 +2,6 @@
#include "kompute/shaders/shaderopmult.hpp" #include "kompute/shaders/shaderopmult.hpp"
#include "kompute/shaders/shaderlogisticregression.hpp" #include "kompute/shaders/shaderlogisticregression.hpp"
#include "kompute/Core.hpp" #include "kompute/Core.hpp"
#include "kompute/Shader.hpp"
#include "kompute/Tensor.hpp" #include "kompute/Tensor.hpp"
#include "kompute/Algorithm.hpp" #include "kompute/Algorithm.hpp"
#include "kompute/operations/OpBase.hpp" #include "kompute/operations/OpBase.hpp"

View file

@ -725,78 +725,6 @@ extern py::object kp_debug, kp_info, kp_warning, kp_error;
#endif // KOMPUTE_SPDLOG_ENABLED #endif // KOMPUTE_SPDLOG_ENABLED
#endif // KOMPUTE_LOG_OVERRIDE #endif // KOMPUTE_LOG_OVERRIDE
#if !defined(KOMPUTE_DISABLE_SHADER_UTILS) || !KOMPUTE_DISABLE_SHADER_UTILS
#include <iostream>
#include <vector>
#ifdef USE_EXTERNAL_GLSLANG
#include <SPIRV/GlslangToSpv.h>
#else
#include <glslang/SPIRV/GlslangToSpv.h>
#endif
#include <glslang/Include/ResourceLimits.h>
#include <glslang/Public/ShaderLang.h>
namespace kp {
/**
Shader utily class with functions to compile and process glsl files.
*/
class Shader
{
public:
// The default resource limit for the GLSL compiler, can be overwritten
// Has been adopted by:
// https://github.com/KhronosGroup/glslang/blob/master/StandAlone/ResourceLimits.cpp
const static TBuiltInResource defaultResource;
/**
* Compile multiple sources with optional filenames. Currently this function
* uses the glslang C++ interface which is not thread safe so this funciton
* should not be called from multiple threads concurrently. If you have a
* online shader processing multithreading use-case that can't use offline
* compilation please open an issue.
*
* @param sources A list of raw glsl shaders in string format
* @param files A list of file names respective to each of the sources
* @param entryPoint The function name to use as entry point
* @param definitions List of pairs containing key value definitions
* @param resourcesLimit A list that contains the resource limits for the
* GLSL compiler
* @return The compiled SPIR-V binary in unsigned int32 format
*/
static std::vector<uint32_t> compileSources(
const std::vector<std::string>& sources,
const std::vector<std::string>& files = {},
const std::string& entryPoint = "main",
std::vector<std::pair<std::string, std::string>> definitions = {},
const TBuiltInResource& resources = Shader::defaultResource);
/**
* Compile a single glslang source from string value. Currently this
* function uses the glslang C++ interface which is not thread safe so this
* funciton should not be called from multiple threads concurrently. If you
* have a online shader processing multithreading use-case that can't use
* offline compilation please open an issue.
*
* @param source An individual raw glsl shader in string format
* @param entryPoint The function name to use as entry point
* @param definitions List of pairs containing key value definitions
* @param resourcesLimit A list that contains the resource limits for the
* GLSL compiler
* @return The compiled SPIR-V binary in unsigned int32 format
*/
static std::vector<uint32_t> compileSource(
const std::string& source,
const std::string& entryPoint = "main",
std::vector<std::pair<std::string, std::string>> definitions = {},
const TBuiltInResource& resources = Shader::defaultResource);
};
}
#endif // DKOMPUTE_DISABLE_SHADER_UTILS
namespace kp { namespace kp {
/** /**

View file

@ -141,41 +141,6 @@ if(KOMPUTE_OPT_BUILD_SINGLE_HEADER)
build_single_header) build_single_header)
endif() endif()
#####################################################
#################### GLSLANG #######################
#####################################################
if(NOT KOMPUTE_OPT_DISABLE_SHADER_UTILS)
if(KOMPUTE_OPT_REPO_SUBMODULE_BUILD)
add_subdirectory(${PROJECT_SOURCE_DIR}/external/glslang
${CMAKE_CURRENT_BINARY_DIR}/kompute_glslang)
target_include_directories(
kompute PRIVATE
${PROJECT_SOURCE_DIR}/external/glslang)
target_link_libraries(kompute
# Not including hlsl support
# HLSL
# glslang includes OGLCompiler, OSDependent, MachineIndependent
glslang
SPIRV)
else()
find_package(glslang CONFIG REQUIRED)
target_include_directories(
kompute PRIVATE
${GLSLANG_GENERATED_INCLUDEDIR})
target_link_libraries(kompute
# Not including hlsl support
# glslang::HLSL
# Adding explicit dependencies to match above
glslang::glslang
glslang::SPIRV)
endif()
endif()
add_library(kompute::kompute ALIAS kompute) add_library(kompute::kompute ALIAS kompute)

View file

@ -1,218 +0,0 @@
#if !defined(KOMPUTE_DISABLE_SHADER_UTILS) || !KOMPUTE_DISABLE_SHADER_UTILS
#include "kompute/Shader.hpp"
namespace kp {
std::vector<uint32_t>
Shader::compileSources(
const std::vector<std::string>& sources,
const std::vector<std::string>& files,
const std::string& entryPoint,
std::vector<std::pair<std::string, std::string>> definitions,
const TBuiltInResource& resources)
{
// Initialize glslang library.
glslang::InitializeProcess();
// Currently we don't support other shader types nor plan to
const EShLanguage language = EShLangCompute;
glslang::TShader shader(language);
std::vector<const char*> filesCStr(files.size()),
sourcesCStr(sources.size());
for (size_t i = 0; i < sources.size(); i++)
sourcesCStr[i] = sources[i].c_str();
if (files.size() > 1) {
assert(files.size() == sources.size());
for (size_t i = 0; i < files.size(); i++)
filesCStr[i] = files[i].c_str();
shader.setStringsWithLengthsAndNames(
sourcesCStr.data(), nullptr, filesCStr.data(), filesCStr.size());
} else {
filesCStr = { "" };
shader.setStringsWithLengthsAndNames(
sourcesCStr.data(), nullptr, filesCStr.data(), sourcesCStr.size());
}
shader.setEntryPoint(entryPoint.c_str());
shader.setSourceEntryPoint(entryPoint.c_str());
std::string info_log = "";
const EShMessages messages = static_cast<EShMessages>(
EShMsgDefault | EShMsgVulkanRules | EShMsgSpvRules);
if (!shader.parse(&resources, 100, false, messages)) {
info_log = std::string(shader.getInfoLog()) + "\n" +
std::string(shader.getInfoDebugLog());
KP_LOG_ERROR("Kompute Shader Error: {}", info_log);
throw std::runtime_error(info_log);
}
// Add shader to new program object.
glslang::TProgram program;
program.addShader(&shader);
// Link program.
if (!program.link(messages)) {
info_log = std::string(program.getInfoLog()) + "\n" +
std::string(program.getInfoDebugLog());
KP_LOG_ERROR("Kompute Shader Error: {}", info_log);
throw std::runtime_error(info_log);
}
// Save any info log that was generated.
if (shader.getInfoLog()) {
info_log += std::string(shader.getInfoLog()) + "\n" +
std::string(shader.getInfoDebugLog()) + "\n";
KP_LOG_INFO("Kompute Shader Information: {}", info_log);
}
glslang::TIntermediate* intermediate = program.getIntermediate(language);
// Translate to SPIRV.
if (!intermediate) {
info_log += "Failed to get shared intermediate code.\n";
KP_LOG_ERROR("Kompute Shader Error: {}", info_log);
throw std::runtime_error(info_log);
}
spv::SpvBuildLogger logger;
std::vector<std::uint32_t> spirv;
glslang::GlslangToSpv(*intermediate, spirv, &logger);
if (shader.getInfoLog()) {
info_log += logger.getAllMessages() + "\n";
KP_LOG_DEBUG("Kompute Shader all result messages: {}", info_log);
}
// Shutdown glslang library.
glslang::FinalizeProcess();
return spirv;
}
std::vector<uint32_t>
Shader::compileSource(
const std::string& source,
const std::string& entryPoint,
std::vector<std::pair<std::string, std::string>> definitions,
const TBuiltInResource& resource)
{
return compileSources({ source },
std::vector<std::string>({}),
entryPoint,
definitions,
resource);
}
const TBuiltInResource Shader::defaultResource = {
/* .MaxLights = */ 0,
/* .MaxClipPlanes = */ 0,
/* .MaxTextureUnits = */ 0,
/* .MaxTextureCoords = */ 0,
/* .MaxVertexAttribs = */ 64,
/* .MaxVertexUniformComponents = */ 4096,
/* .MaxVaryingFloats = */ 64,
/* .MaxVertexTextureImageUnits = */ 0,
/* .MaxCombinedTextureImageUnits = */ 0,
/* .MaxTextureImageUnits = */ 0,
/* .MaxFragmentUniformComponents = */ 0,
/* .MaxDrawBuffers = */ 0,
/* .MaxVertexUniformVectors = */ 128,
/* .MaxVaryingVectors = */ 8,
/* .MaxFragmentUniformVectors = */ 0,
/* .MaxVertexOutputVectors = */ 16,
/* .MaxFragmentInputVectors = */ 0,
/* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535,
/* .MaxComputeWorkGroupCountY = */ 65535,
/* .MaxComputeWorkGroupCountZ = */ 65535,
/* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64,
/* .MaxComputeUniformComponents = */ 1024,
/* .MaxComputeTextureImageUnits = */ 16,
/* .MaxComputeImageUniforms = */ 8,
/* .MaxComputeAtomicCounters = */ 8,
/* .MaxComputeAtomicCounterBuffers = */ 1,
/* .MaxVaryingComponents = */ 60,
/* .MaxVertexOutputComponents = */ 64,
/* .MaxGeometryInputComponents = */ 64,
/* .MaxGeometryOutputComponents = */ 128,
/* .MaxFragmentInputComponents = */ 0,
/* .MaxImageUnits = */ 0,
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 0,
/* .MaxCombinedShaderOutputResources = */ 8,
/* .MaxImageSamples = */ 0,
/* .MaxVertexImageUniforms = */ 0,
/* .MaxTessControlImageUniforms = */ 0,
/* .MaxTessEvaluationImageUniforms = */ 0,
/* .MaxGeometryImageUniforms = */ 0,
/* .MaxFragmentImageUniforms = */ 0,
/* .MaxCombinedImageUniforms = */ 0,
/* .MaxGeometryTextureImageUnits = */ 0,
/* .MaxGeometryOutputVertices = */ 256,
/* .MaxGeometryTotalOutputComponents = */ 1024,
/* .MaxGeometryUniformComponents = */ 1024,
/* .MaxGeometryVaryingComponents = */ 64,
/* .MaxTessControlInputComponents = */ 128,
/* .MaxTessControlOutputComponents = */ 128,
/* .MaxTessControlTextureImageUnits = */ 0,
/* .MaxTessControlUniformComponents = */ 1024,
/* .MaxTessControlTotalOutputComponents = */ 4096,
/* .MaxTessEvaluationInputComponents = */ 128,
/* .MaxTessEvaluationOutputComponents = */ 128,
/* .MaxTessEvaluationTextureImageUnits = */ 16,
/* .MaxTessEvaluationUniformComponents = */ 1024,
/* .MaxTessPatchComponents = */ 120,
/* .MaxPatchVertices = */ 32,
/* .MaxTessGenLevel = */ 64,
/* .MaxViewports = */ 16,
/* .MaxVertexAtomicCounters = */ 0,
/* .MaxTessControlAtomicCounters = */ 0,
/* .MaxTessEvaluationAtomicCounters = */ 0,
/* .MaxGeometryAtomicCounters = */ 0,
/* .MaxFragmentAtomicCounters = */ 0,
/* .MaxCombinedAtomicCounters = */ 8,
/* .MaxAtomicCounterBindings = */ 1,
/* .MaxVertexAtomicCounterBuffers = */ 0,
/* .MaxTessControlAtomicCounterBuffers = */ 0,
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
/* .MaxGeometryAtomicCounterBuffers = */ 0,
/* .MaxFragmentAtomicCounterBuffers = */ 0,
/* .MaxCombinedAtomicCounterBuffers = */ 1,
/* .MaxAtomicCounterBufferSize = */ 16384,
/* .MaxTransformFeedbackBuffers = */ 4,
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
/* .MaxCullDistances = */ 8,
/* .MaxCombinedClipAndCullDistances = */ 8,
/* .MaxSamples = */ 4,
/* .maxMeshOutputVerticesNV = */ 256,
/* .maxMeshOutputPrimitivesNV = */ 512,
/* .maxMeshWorkGroupSizeX_NV = */ 32,
/* .maxMeshWorkGroupSizeY_NV = */ 1,
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
/* .maxTaskWorkGroupSizeX_NV = */ 32,
/* .maxTaskWorkGroupSizeY_NV = */ 1,
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
/* .maxMeshViewCountNV = */ 4,
/* .maxDualSourceDrawBuffersEXT = */ 1,
/* .limits = */
{
/* .nonInductiveForLoops = */ 1,
/* .whileLoops = */ 1,
/* .doWhileLoops = */ 1,
/* .generalUniformIndexing = */ 1,
/* .generalAttributeMatrixVectorIndexing = */ 1,
/* .generalVaryingIndexing = */ 1,
/* .generalSamplerIndexing = */ 1,
/* .generalVariableIndexing = */ 1,
/* .generalConstantMatrixVectorIndexing = */ 1,
}
};
}
#endif // DKOMPUTE_DISABLE_SHADER_UTILS

View file

@ -1,75 +0,0 @@
#pragma once
#if !defined(KOMPUTE_DISABLE_SHADER_UTILS) || !KOMPUTE_DISABLE_SHADER_UTILS
#include <iostream>
#include <vector>
#ifdef USE_EXTERNAL_GLSLANG
#include <SPIRV/GlslangToSpv.h>
#else
#include <glslang/SPIRV/GlslangToSpv.h>
#endif
#include <glslang/Include/ResourceLimits.h>
#include <glslang/Public/ShaderLang.h>
#include "kompute/Core.hpp"
namespace kp {
/**
Shader utily class with functions to compile and process glsl files.
*/
class Shader
{
public:
// The default resource limit for the GLSL compiler, can be overwritten
// Has been adopted by:
// https://github.com/KhronosGroup/glslang/blob/master/StandAlone/ResourceLimits.cpp
const static TBuiltInResource defaultResource;
/**
* Compile multiple sources with optional filenames. Currently this function
* uses the glslang C++ interface which is not thread safe so this funciton
* should not be called from multiple threads concurrently. If you have a
* online shader processing multithreading use-case that can't use offline
* compilation please open an issue.
*
* @param sources A list of raw glsl shaders in string format
* @param files A list of file names respective to each of the sources
* @param entryPoint The function name to use as entry point
* @param definitions List of pairs containing key value definitions
* @param resourcesLimit A list that contains the resource limits for the
* GLSL compiler
* @return The compiled SPIR-V binary in unsigned int32 format
*/
static std::vector<uint32_t> compileSources(
const std::vector<std::string>& sources,
const std::vector<std::string>& files = {},
const std::string& entryPoint = "main",
std::vector<std::pair<std::string, std::string>> definitions = {},
const TBuiltInResource& resources = Shader::defaultResource);
/**
* Compile a single glslang source from string value. Currently this
* function uses the glslang C++ interface which is not thread safe so this
* funciton should not be called from multiple threads concurrently. If you
* have a online shader processing multithreading use-case that can't use
* offline compilation please open an issue.
*
* @param source An individual raw glsl shader in string format
* @param entryPoint The function name to use as entry point
* @param definitions List of pairs containing key value definitions
* @param resourcesLimit A list that contains the resource limits for the
* GLSL compiler
* @return The compiled SPIR-V binary in unsigned int32 format
*/
static std::vector<uint32_t> compileSource(
const std::string& source,
const std::string& entryPoint = "main",
std::vector<std::pair<std::string, std::string>> definitions = {},
const TBuiltInResource& resources = Shader::defaultResource);
};
}
#endif // DKOMPUTE_DISABLE_SHADER_UTILS

View file

@ -20,6 +20,7 @@ target_include_directories(
test_kompute PUBLIC test_kompute PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/single_include> $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/single_include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/compiled_shaders_include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/compiled_shaders_include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/utils>
) )
if(KOMPUTE_OPT_REPO_SUBMODULE_BUILD) if(KOMPUTE_OPT_REPO_SUBMODULE_BUILD)
@ -27,17 +28,18 @@ if(KOMPUTE_OPT_REPO_SUBMODULE_BUILD)
test_kompute PRIVATE test_kompute PRIVATE
${gtest_SOURCE_DIR}/include) ${gtest_SOURCE_DIR}/include)
target_link_libraries(test_kompute PRIVATE target_link_libraries(test_kompute
gtest_main) gtest_main)
else() else()
target_link_libraries(test_kompute PRIVATE target_link_libraries(test_kompute
GTest::gtest) GTest::gtest)
endif() endif()
target_link_libraries(test_kompute PRIVATE kompute) target_link_libraries(test_kompute kompute)
add_test(NAME test_kompute COMMAND test_kompute) add_test(NAME test_kompute COMMAND test_kompute)
##################################################### #####################################################
#################### CODECOV ####################### #################### CODECOV #######################
##################################################### #####################################################

View file

@ -5,6 +5,8 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
#include "kompute_test/Shader.hpp"
TEST(TestAsyncOperations, TestManagerParallelExecution) TEST(TestAsyncOperations, TestManagerParallelExecution)
{ {
// This test is built for NVIDIA 1650. It assumes: // This test is built for NVIDIA 1650. It assumes:
@ -37,7 +39,7 @@ TEST(TestAsyncOperations, TestManagerParallelExecution)
} }
)"); )");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::vector<float> data(size, 0.0); std::vector<float> data(size, 0.0);
std::vector<float> resultSync(size, 100000000); std::vector<float> resultSync(size, 100000000);
@ -145,7 +147,7 @@ TEST(TestAsyncOperations, TestManagerAsyncExecution)
} }
)"); )");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::vector<float> data(size, 0.0); std::vector<float> data(size, 0.0);
std::vector<float> resultAsync(size, 100000000); std::vector<float> resultAsync(size, 100000000);

View file

@ -3,6 +3,8 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
#include "kompute_test/Shader.hpp"
TEST(TestDestroy, TestDestroyTensorSingle) TEST(TestDestroy, TestDestroyTensorSingle)
{ {
std::shared_ptr<kp::TensorT<float>> tensorA = nullptr; std::shared_ptr<kp::TensorT<float>> tensorA = nullptr;
@ -16,7 +18,7 @@ TEST(TestDestroy, TestDestroyTensorSingle)
pa[index] = pa[index] + 1; pa[index] = pa[index] + 1;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
{ {
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;
@ -58,7 +60,7 @@ TEST(TestDestroy, TestDestroyTensorVector)
pa[index] = pa[index] + 1; pa[index] = pa[index] + 1;
pb[index] = pb[index] + 2; pb[index] = pb[index] + 2;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
{ {
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;
@ -103,7 +105,7 @@ TEST(TestDestroy, TestDestroySequenceSingle)
pa[index] = pa[index] + 1; pa[index] = pa[index] + 1;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
{ {
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;

View file

@ -3,6 +3,8 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
#include "kompute_test/Shader.hpp"
TEST(TestMultipleAlgoExecutions, TestEndToEndFunctionality) TEST(TestMultipleAlgoExecutions, TestEndToEndFunctionality)
{ {
@ -51,7 +53,7 @@ TEST(TestMultipleAlgoExecutions, TestEndToEndFunctionality)
kp::Constants pushConstsB({ 3.0 }); kp::Constants pushConstsB({ 3.0 });
auto algorithm = mgr.algorithm(params, auto algorithm = mgr.algorithm(params,
kp::Shader::compileSource(shader), compileSource(shader),
workgroup, workgroup,
specConsts, specConsts,
pushConstsA); pushConstsA);
@ -89,7 +91,7 @@ TEST(TestMultipleAlgoExecutions, SingleSequenceRecord)
pa[index] = pa[index] + 1; pa[index] = pa[index] + 1;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
{ {
// A sharedMemoryBarrier is required as the shader is not thread-safe:w // A sharedMemoryBarrier is required as the shader is not thread-safe:w
@ -130,7 +132,7 @@ TEST(TestMultipleAlgoExecutions, MultipleCmdBufRecords)
pa[index] = pa[index] + 1; pa[index] = pa[index] + 1;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Algorithm> algorithm = std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm({ tensorA }, spirv); mgr.algorithm({ tensorA }, spirv);
@ -166,7 +168,7 @@ TEST(TestMultipleAlgoExecutions, MultipleSequences)
pa[index] = pa[index] + 1; pa[index] = pa[index] + 1;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Algorithm> algorithm = std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm({ tensorA }, spirv); mgr.algorithm({ tensorA }, spirv);
@ -201,7 +203,7 @@ TEST(TestMultipleAlgoExecutions, SingleRecordMultipleEval)
pa[index] = pa[index] + 1; pa[index] = pa[index] + 1;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Algorithm> algorithm = std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm({ tensorA }, spirv); mgr.algorithm({ tensorA }, spirv);

View file

@ -5,6 +5,8 @@
#include "kompute_test/shaders/shadertest_op_custom_shader.hpp" #include "kompute_test/shaders/shadertest_op_custom_shader.hpp"
#include "kompute_test/Shader.hpp"
TEST(TestOpAlgoCreate, ShaderRawDataFromConstructor) TEST(TestOpAlgoCreate, ShaderRawDataFromConstructor)
{ {
kp::Manager mgr; kp::Manager mgr;
@ -27,7 +29,7 @@ TEST(TestOpAlgoCreate, ShaderRawDataFromConstructor)
} }
)"); )");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::vector<std::shared_ptr<kp::Tensor>> params = { tensorA, tensorB }; std::vector<std::shared_ptr<kp::Tensor>> params = { tensorA, tensorB };

View file

@ -3,6 +3,8 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
#include "kompute_test/Shader.hpp"
TEST(TestOpTensorCopy, CopyDeviceToDeviceTensor) TEST(TestOpTensorCopy, CopyDeviceToDeviceTensor)
{ {

View file

@ -2,6 +2,8 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
#include "kompute_test/Shader.hpp"
#include "fmt/ranges.h" #include "fmt/ranges.h"
TEST(TestPushConstants, TestConstantsAlgoDispatchOverride) TEST(TestPushConstants, TestConstantsAlgoDispatchOverride)
@ -22,7 +24,7 @@ TEST(TestPushConstants, TestConstantsAlgoDispatchOverride)
pa[2] += pcs.z; pa[2] += pcs.z;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;
@ -67,7 +69,7 @@ TEST(TestPushConstants, TestConstantsAlgoDispatchNoOverride)
pa[2] += pcs.z; pa[2] += pcs.z;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;
@ -112,7 +114,7 @@ TEST(TestPushConstants, TestConstantsWrongSize)
pa[2] += pcs.z; pa[2] += pcs.z;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;

View file

@ -3,6 +3,8 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
#include "kompute_test/Shader.hpp"
TEST(TestSequence, SequenceDestructorViaManager) TEST(TestSequence, SequenceDestructorViaManager)
{ {
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;
@ -66,7 +68,7 @@ TEST(TestSequence, RerecordSequence)
sq->eval<kp::OpTensorSyncDevice>({ tensorA, tensorB, tensorOut }); sq->eval<kp::OpTensorSyncDevice>({ tensorA, tensorB, tensorOut });
std::vector<uint32_t> spirv = kp::Shader::compileSource(R"( std::vector<uint32_t> spirv = compileSource(R"(
#version 450 #version 450
layout (local_size_x = 1) in; layout (local_size_x = 1) in;
@ -116,7 +118,7 @@ TEST(TestSequence, SequenceTimestamps)
pa[index] = pa[index] + 1; pa[index] = pa[index] + 1;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
auto seq = mgr.sequence(0, 100); // 100 timestamps auto seq = mgr.sequence(0, 100); // 100 timestamps
seq->record<kp::OpTensorSyncDevice>({ tensorA }) seq->record<kp::OpTensorSyncDevice>({ tensorA })

View file

@ -1,66 +0,0 @@
#include "gtest/gtest.h"
#include "kompute/Kompute.hpp"
static const std::string shaderString = (R"(
#version 450
layout (local_size_x = 1) in;
// The input tensors bind index is relative to index in parameter passed
layout(set = 0, binding = 0) buffer bina { float tina[]; };
layout(set = 0, binding = 1) buffer binb { float tinb[]; };
layout(set = 0, binding = 2) buffer bout { float tout[]; };
void main() {
uint index = gl_GlobalInvocationID.x;
int i = 1;
while(i < 200) {
tout[index] += tina[index] * tinb[index];
i++;
}
}
)");
void
compileShaderWithGivenResources(const std::string shaderString,
const TBuiltInResource resources)
{
kp::Shader::compileSource(
shaderString,
std::string("main"),
std::vector<std::pair<std::string, std::string>>({}),
resources);
}
TEST(TestShaderResources, TestNoMaxLight)
{
TBuiltInResource noMaxLightResources = kp::Shader::defaultResource;
noMaxLightResources.maxLights = 0;
EXPECT_NO_THROW(
compileShaderWithGivenResources(shaderString, noMaxLightResources));
}
TEST(TestShaderResources, TestSmallComputeWorkGroupSizeX)
{
TBuiltInResource smallComputeWorkGroupSizeXResources =
kp::Shader::defaultResource;
smallComputeWorkGroupSizeXResources.maxComputeWorkGroupSizeX = 0;
ASSERT_THROW(compileShaderWithGivenResources(
shaderString, smallComputeWorkGroupSizeXResources),
std::runtime_error);
}
TEST(TestShaderResources, TestNoWhileLoopLimit)
{
TBuiltInResource noWhileLoopLimitResources = kp::Shader::defaultResource;
noWhileLoopLimitResources.limits.whileLoops = 0;
ASSERT_THROW(
compileShaderWithGivenResources(shaderString, noWhileLoopLimitResources),
std::runtime_error);
}

View file

@ -2,6 +2,8 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
#include "kompute_test/Shader.hpp"
TEST(TestSpecializationConstants, TestTwoConstants) TEST(TestSpecializationConstants, TestTwoConstants)
{ {
{ {
@ -18,7 +20,7 @@ TEST(TestSpecializationConstants, TestTwoConstants)
pb[index] = cTwo; pb[index] = cTwo;
})"); })");
std::vector<uint32_t> spirv = kp::Shader::compileSource(shader); std::vector<uint32_t> spirv = compileSource(shader);
std::shared_ptr<kp::Sequence> sq = nullptr; std::shared_ptr<kp::Sequence> sq = nullptr;

View file

@ -0,0 +1,27 @@
#pragma once
#include <iostream>
#include <vector>
#include <fstream>
/**
* Compile a single glslang source from string value. This is only meant
* to be used for testing as it's non threadsafe, and it had to be removed
* from the glslang dependency and now can only run the CLI directly due to
* license issues: see https://github.com/EthicalML/vulkan-kompute/pull/235
*
* @param source An individual raw glsl shader in string format
* @return The compiled SPIR-V binary in unsigned int32 format
*/
static
std::vector<uint32_t>
compileSource(
const std::string& source)
{
if (system(std::string("glslangValidator --stdin -S comp -V -o tmp_kp_shader.comp.spv << END\n" + source + "\nEND").c_str()))
throw std::runtime_error("Error running glslangValidator command");
std::ifstream fileStream("tmp_kp_shader.comp.spv", std::ios::binary);
std::vector<char> buffer;
buffer.insert(buffer.begin(), std::istreambuf_iterator<char>(fileStream), {});
return {(uint32_t*)buffer.data(), (uint32_t*)(buffer.data() + buffer.size())};
}