Updated vulkan pipeline to support raw shaders
This commit is contained in:
parent
8841063e31
commit
13206a9d9b
5 changed files with 119 additions and 50 deletions
7
Makefile
7
Makefile
|
|
@ -10,6 +10,9 @@
|
|||
VCPKG_WIN_PATH ?= "C:\\Users\\axsau\\Programming\\lib\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake"
|
||||
VCPKG_UNIX_PATH ?= "/c/Users/axsau/Programming/lib/vcpkg/scripts/buildsystems/vcpkg.cmake"
|
||||
|
||||
# Regext to pass to catch2 to filter tests
|
||||
FILTER_TESTS ?= "*"
|
||||
|
||||
ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10...
|
||||
CMAKE_BIN ?= "C:\Program Files\CMake\bin\cmake.exe"
|
||||
SCMP_BIN="C:\\VulkanSDK\\1.2.141.2\\Bin32\\glslangValidator.exe"
|
||||
|
|
@ -62,7 +65,7 @@ mk_run_docs: mk_build_docs
|
|||
(cd build/docs/sphinx && python2.7 -m SimpleHTTPServer)
|
||||
|
||||
mk_run_tests: mk_build_tests
|
||||
./build/test/test_kompute
|
||||
./build/test/test_kompute $(FILTER_TESTS)
|
||||
|
||||
|
||||
####### Visual studio build shortcut commands #######
|
||||
|
|
@ -91,7 +94,7 @@ vs_run_docs: vs_build_docs
|
|||
(cd build/docs/sphinx && python2.7 -m SimpleHTTPServer)
|
||||
|
||||
vs_run_tests: vs_build_tests
|
||||
./build/test/Debug/test_kompute.exe
|
||||
./build/test/Debug/test_kompute.exe $(FILTER_TESTS)
|
||||
|
||||
####### Create release ######
|
||||
|
||||
|
|
|
|||
|
|
@ -838,12 +838,16 @@ class OpAlgoBase : public OpBase
|
|||
* @param device Vulkan logical device for passing to Algorithm
|
||||
* @param commandBuffer Vulkan Command Buffer to record commands into
|
||||
* @param tensors Tensors that are to be used in this operation
|
||||
* @param copyOutputData Whether to map device data for all output tensors back to their host data vectors
|
||||
* @param shaderFilePath Optional parameter to specify the shader to load (either in spirv or raw format)
|
||||
*/
|
||||
OpAlgoBase(std::shared_ptr<vk::PhysicalDevice> physicalDevice,
|
||||
std::shared_ptr<vk::Device> device,
|
||||
std::shared_ptr<vk::CommandBuffer> commandBuffer,
|
||||
std::vector<std::shared_ptr<Tensor>>& tensors,
|
||||
bool copyOutputData);
|
||||
bool copyOutputData = false,
|
||||
std::string shaderFilePath = "",
|
||||
const std::vector<char>& shaderDataRaw = {});
|
||||
|
||||
/**
|
||||
* Default destructor, which is in charge of destroying the algorithm
|
||||
|
|
@ -891,7 +895,8 @@ class OpAlgoBase : public OpBase
|
|||
uint32_t mY;
|
||||
uint32_t mZ;
|
||||
|
||||
std::string mOptSpirvBinPath; ///< Optional member variable which can be provided for the OpAlgoBase to find the data automatically and load for processing
|
||||
std::string mShaderFilePath; ///< Optional member variable which can be provided for the OpAlgoBase to find the data automatically and load for processing
|
||||
std::vector<char> mShaderDataRaw; ///< Optional member variable which can be provided to contain either the raw shader content or the spirv binary content
|
||||
|
||||
virtual std::vector<char> fetchSpirvBinaryData();
|
||||
};
|
||||
|
|
@ -915,12 +920,12 @@ OpAlgoBase<tX, tY, tZ>::OpAlgoBase(std::shared_ptr<vk::PhysicalDevice> physicalD
|
|||
std::shared_ptr<vk::Device> device,
|
||||
std::shared_ptr<vk::CommandBuffer> commandBuffer,
|
||||
std::vector<std::shared_ptr<Tensor>>& tensors,
|
||||
bool copyOutputData)
|
||||
bool copyOutputData,
|
||||
std::string shaderFilePath,
|
||||
const std::vector<char>& shaderDataRaw)
|
||||
: OpBase(physicalDevice, device, commandBuffer, tensors, false)
|
||||
{
|
||||
SPDLOG_DEBUG("Kompute OpAlgoBase constructor with params");
|
||||
|
||||
SPDLOG_DEBUG("Kompute OpAlgoBase configured for copy output data: {}", copyOutputData);
|
||||
SPDLOG_DEBUG("Kompute OpAlgoBase constructor with params numTensors: {} copyOutputData: {}, shaderFilePath: {}", tensors.size(), copyOutputData, shaderFilePath);
|
||||
|
||||
// The dispatch size is set up based on either explicitly provided template
|
||||
// parameters or by default it would take the shape and size of the tensors
|
||||
|
|
@ -942,7 +947,9 @@ OpAlgoBase<tX, tY, tZ>::OpAlgoBase(std::shared_ptr<vk::PhysicalDevice> physicalD
|
|||
this->mY,
|
||||
this->mZ);
|
||||
|
||||
this->mShaderFilePath = shaderFilePath;
|
||||
this->mCopyOutputData = copyOutputData;
|
||||
this->mShaderDataRaw = shaderDataRaw;
|
||||
|
||||
this->mAlgorithm = std::make_shared<Algorithm>(device, commandBuffer);
|
||||
}
|
||||
|
|
@ -1054,24 +1061,32 @@ std::vector<char> OpAlgoBase<tX, tY, tZ>::fetchSpirvBinaryData()
|
|||
SPDLOG_WARN(
|
||||
"Kompute OpAlgoBase Running shaders directly from spirv file");
|
||||
|
||||
std::ifstream fileStream(this->mOptSpirvBinPath,
|
||||
std::ios::binary | std::ios::in | std::ios::ate);
|
||||
if (this->mShaderFilePath.size()) {
|
||||
std::ifstream fileStream(this->mShaderFilePath,
|
||||
std::ios::binary | std::ios::in | std::ios::ate);
|
||||
|
||||
if (!fileStream.good()) {
|
||||
throw std::runtime_error("Error reading file: " + this->mOptSpirvBinPath);
|
||||
if (!fileStream.good()) {
|
||||
throw std::runtime_error("Error reading file: " + this->mShaderFilePath);
|
||||
}
|
||||
|
||||
size_t shaderFileSize = fileStream.tellg();
|
||||
fileStream.seekg(0, std::ios::beg);
|
||||
char* shaderDataRaw = new char[shaderFileSize];
|
||||
fileStream.read(shaderDataRaw, shaderFileSize);
|
||||
fileStream.close();
|
||||
|
||||
SPDLOG_WARN(
|
||||
"Kompute OpAlgoBase fetched {} bytes", shaderFileSize);
|
||||
|
||||
return std::vector<char>(shaderDataRaw,
|
||||
shaderDataRaw + shaderFileSize);
|
||||
}
|
||||
else if (this->mShaderDataRaw.size()) {
|
||||
return this->mShaderDataRaw;
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Kompute OpAlgoBase Error reached fetchSpirvBinaryData but neither filepath nor data provided");
|
||||
}
|
||||
|
||||
size_t shaderFileSize = fileStream.tellg();
|
||||
fileStream.seekg(0, std::ios::beg);
|
||||
char* shaderDataRaw = new char[shaderFileSize];
|
||||
fileStream.read(shaderDataRaw, shaderFileSize);
|
||||
fileStream.close();
|
||||
|
||||
SPDLOG_WARN(
|
||||
"Kompute OpAlgoBase fetched {} bytes", shaderFileSize);
|
||||
|
||||
return std::vector<char>(shaderDataRaw,
|
||||
shaderDataRaw + shaderFileSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1327,12 +1342,12 @@ class OpMult : public OpAlgoBase<tX, tY, tZ>
|
|||
std::shared_ptr<vk::Device> device,
|
||||
std::shared_ptr<vk::CommandBuffer> commandBuffer,
|
||||
std::vector<std::shared_ptr<Tensor>> tensors)
|
||||
: OpAlgoBase<tX, tY, tZ>(physicalDevice, device, commandBuffer, tensors, true)
|
||||
: OpAlgoBase<tX, tY, tZ>(physicalDevice, device, commandBuffer, tensors, true, "")
|
||||
{
|
||||
SPDLOG_DEBUG("Kompute OpMult constructor with params");
|
||||
|
||||
#ifndef RELEASE
|
||||
this->mOptSpirvBinPath = "shaders/glsl/opmult.comp";
|
||||
this->mShaderFilePath = "shaders/glsl/opmult.comp";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,12 +50,16 @@ class OpAlgoBase : public OpBase
|
|||
* @param device Vulkan logical device for passing to Algorithm
|
||||
* @param commandBuffer Vulkan Command Buffer to record commands into
|
||||
* @param tensors Tensors that are to be used in this operation
|
||||
* @param copyOutputData Whether to map device data for all output tensors back to their host data vectors
|
||||
* @param shaderFilePath Optional parameter to specify the shader to load (either in spirv or raw format)
|
||||
*/
|
||||
OpAlgoBase(std::shared_ptr<vk::PhysicalDevice> physicalDevice,
|
||||
std::shared_ptr<vk::Device> device,
|
||||
std::shared_ptr<vk::CommandBuffer> commandBuffer,
|
||||
std::vector<std::shared_ptr<Tensor>>& tensors,
|
||||
bool copyOutputData);
|
||||
bool copyOutputData = false,
|
||||
std::string shaderFilePath = "",
|
||||
const std::vector<char>& shaderDataRaw = {});
|
||||
|
||||
/**
|
||||
* Default destructor, which is in charge of destroying the algorithm
|
||||
|
|
@ -103,7 +107,8 @@ class OpAlgoBase : public OpBase
|
|||
uint32_t mY;
|
||||
uint32_t mZ;
|
||||
|
||||
std::string mOptSpirvBinPath; ///< Optional member variable which can be provided for the OpAlgoBase to find the data automatically and load for processing
|
||||
std::string mShaderFilePath; ///< Optional member variable which can be provided for the OpAlgoBase to find the data automatically and load for processing
|
||||
std::vector<char> mShaderDataRaw; ///< Optional member variable which can be provided to contain either the raw shader content or the spirv binary content
|
||||
|
||||
virtual std::vector<char> fetchSpirvBinaryData();
|
||||
};
|
||||
|
|
@ -127,12 +132,12 @@ OpAlgoBase<tX, tY, tZ>::OpAlgoBase(std::shared_ptr<vk::PhysicalDevice> physicalD
|
|||
std::shared_ptr<vk::Device> device,
|
||||
std::shared_ptr<vk::CommandBuffer> commandBuffer,
|
||||
std::vector<std::shared_ptr<Tensor>>& tensors,
|
||||
bool copyOutputData)
|
||||
bool copyOutputData,
|
||||
std::string shaderFilePath,
|
||||
const std::vector<char>& shaderDataRaw)
|
||||
: OpBase(physicalDevice, device, commandBuffer, tensors, false)
|
||||
{
|
||||
SPDLOG_DEBUG("Kompute OpAlgoBase constructor with params");
|
||||
|
||||
SPDLOG_DEBUG("Kompute OpAlgoBase configured for copy output data: {}", copyOutputData);
|
||||
SPDLOG_DEBUG("Kompute OpAlgoBase constructor with params numTensors: {} copyOutputData: {}, shaderFilePath: {}", tensors.size(), copyOutputData, shaderFilePath);
|
||||
|
||||
// The dispatch size is set up based on either explicitly provided template
|
||||
// parameters or by default it would take the shape and size of the tensors
|
||||
|
|
@ -154,7 +159,9 @@ OpAlgoBase<tX, tY, tZ>::OpAlgoBase(std::shared_ptr<vk::PhysicalDevice> physicalD
|
|||
this->mY,
|
||||
this->mZ);
|
||||
|
||||
this->mShaderFilePath = shaderFilePath;
|
||||
this->mCopyOutputData = copyOutputData;
|
||||
this->mShaderDataRaw = shaderDataRaw;
|
||||
|
||||
this->mAlgorithm = std::make_shared<Algorithm>(device, commandBuffer);
|
||||
}
|
||||
|
|
@ -266,24 +273,32 @@ std::vector<char> OpAlgoBase<tX, tY, tZ>::fetchSpirvBinaryData()
|
|||
SPDLOG_WARN(
|
||||
"Kompute OpAlgoBase Running shaders directly from spirv file");
|
||||
|
||||
std::ifstream fileStream(this->mOptSpirvBinPath,
|
||||
std::ios::binary | std::ios::in | std::ios::ate);
|
||||
if (this->mShaderFilePath.size()) {
|
||||
std::ifstream fileStream(this->mShaderFilePath,
|
||||
std::ios::binary | std::ios::in | std::ios::ate);
|
||||
|
||||
if (!fileStream.good()) {
|
||||
throw std::runtime_error("Error reading file: " + this->mOptSpirvBinPath);
|
||||
if (!fileStream.good()) {
|
||||
throw std::runtime_error("Error reading file: " + this->mShaderFilePath);
|
||||
}
|
||||
|
||||
size_t shaderFileSize = fileStream.tellg();
|
||||
fileStream.seekg(0, std::ios::beg);
|
||||
char* shaderDataRaw = new char[shaderFileSize];
|
||||
fileStream.read(shaderDataRaw, shaderFileSize);
|
||||
fileStream.close();
|
||||
|
||||
SPDLOG_WARN(
|
||||
"Kompute OpAlgoBase fetched {} bytes", shaderFileSize);
|
||||
|
||||
return std::vector<char>(shaderDataRaw,
|
||||
shaderDataRaw + shaderFileSize);
|
||||
}
|
||||
else if (this->mShaderDataRaw.size()) {
|
||||
return this->mShaderDataRaw;
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Kompute OpAlgoBase Error reached fetchSpirvBinaryData but neither filepath nor data provided");
|
||||
}
|
||||
|
||||
size_t shaderFileSize = fileStream.tellg();
|
||||
fileStream.seekg(0, std::ios::beg);
|
||||
char* shaderDataRaw = new char[shaderFileSize];
|
||||
fileStream.read(shaderDataRaw, shaderFileSize);
|
||||
fileStream.close();
|
||||
|
||||
SPDLOG_WARN(
|
||||
"Kompute OpAlgoBase fetched {} bytes", shaderFileSize);
|
||||
|
||||
return std::vector<char>(shaderDataRaw,
|
||||
shaderDataRaw + shaderFileSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ class OpMult : public OpAlgoBase<tX, tY, tZ>
|
|||
std::shared_ptr<vk::Device> device,
|
||||
std::shared_ptr<vk::CommandBuffer> commandBuffer,
|
||||
std::vector<std::shared_ptr<Tensor>> tensors)
|
||||
: OpAlgoBase<tX, tY, tZ>(physicalDevice, device, commandBuffer, tensors, true)
|
||||
: OpAlgoBase<tX, tY, tZ>(physicalDevice, device, commandBuffer, tensors, true, "")
|
||||
{
|
||||
SPDLOG_DEBUG("Kompute OpMult constructor with params");
|
||||
|
||||
#ifndef RELEASE
|
||||
this->mOptSpirvBinPath = "shaders/glsl/opmult.comp";
|
||||
this->mShaderFilePath = "shaders/glsl/opmult.comp";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
36
test/TestCustomOpRawShaders.cpp
Normal file
36
test/TestCustomOpRawShaders.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
#include "kompute/Kompute.hpp"
|
||||
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
TEST_CASE("op_custom_simple_raw_shader") {
|
||||
kp::Manager mgr;
|
||||
|
||||
std::shared_ptr<kp::Tensor> tensorA{ new kp::Tensor({ 3, 4, 5 })};
|
||||
std::shared_ptr<kp::Tensor> tensorB{ new kp::Tensor({ 0, 0, 0 })};
|
||||
mgr.evalOp<kp::OpCreateTensor>({ tensorA, tensorB });
|
||||
|
||||
std::string shader(
|
||||
"#version 450\n"
|
||||
"layout (local_size_x = 1) in;\n"
|
||||
"layout(set = 0, binding = 0) buffer a { uint pa[]; };\n"
|
||||
"layout(set = 0, binding = 1) buffer b { uint pb[]; };\n"
|
||||
"void main() {\n"
|
||||
" uint index = gl_GlobalInvocationID.x;\n"
|
||||
" pb[index] = pa[index];\n"
|
||||
" pa[index] = index;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
mgr.evalOp<kp::OpAlgoBase<>>(
|
||||
{ tensorA, tensorB },
|
||||
"DEFAULT",
|
||||
true,
|
||||
"",
|
||||
std::vector<char>(shader.begin(), shader.end()));
|
||||
|
||||
REQUIRE(tensorA->data() == std::vector<uint32_t>{0, 1, 2});
|
||||
REQUIRE(tensorB->data() == std::vector<uint32_t>{3, 4, 5});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue