This commit is contained in:
Alejandro Saucedo 2021-02-28 16:02:37 +00:00
parent 75315db943
commit 63e220a8a4
26 changed files with 667 additions and 624 deletions

View file

@ -4,23 +4,25 @@
namespace kp { namespace kp {
Algorithm::Algorithm( Algorithm::Algorithm(std::shared_ptr<vk::Device> device,
std::shared_ptr<vk::Device> device, const std::vector<std::shared_ptr<Tensor>>& tensors,
const std::vector<std::shared_ptr<Tensor>>& tensors, const std::vector<uint32_t>& spirv,
const std::vector<uint32_t>& spirv, const Workgroup& workgroup,
const Workgroup& workgroup, const Constants& specializationConstants)
const Constants& specializationConstants)
{ {
KP_LOG_DEBUG("Kompute Algorithm Constructor with device"); KP_LOG_DEBUG("Kompute Algorithm Constructor with device");
this->mDevice = device; this->mDevice = device;
if (tensors.size() && spirv.size()) { if (tensors.size() && spirv.size()) {
KP_LOG_INFO("Kompute Algorithm initialising with tensor size: {} and spirv size: {}", tensors.size(), spirv.size()); KP_LOG_INFO("Kompute Algorithm initialising with tensor size: {} and "
"spirv size: {}",
tensors.size(),
spirv.size());
this->rebuild(tensors, spirv, workgroup, specializationConstants); this->rebuild(tensors, spirv, workgroup, specializationConstants);
} } else {
else { KP_LOG_INFO("Kompute Algorithm constructor with empty tensors and or "
KP_LOG_INFO("Kompute Algorithm constructor with empty tensors and or spirv so not rebuilding vulkan components"); "spirv so not rebuilding vulkan components");
} }
} }
@ -32,20 +34,21 @@ Algorithm::~Algorithm()
} }
void void
Algorithm::rebuild( Algorithm::rebuild(const std::vector<std::shared_ptr<Tensor>>& tensors,
const std::vector<std::shared_ptr<Tensor>>& tensors, const std::vector<uint32_t>& spirv,
const std::vector<uint32_t>& spirv, const Workgroup& workgroup,
const Workgroup& workgroup, const Constants& specializationConstants)
const Constants& specializationConstants)
{ {
KP_LOG_DEBUG("Kompute Algorithm rebuild started"); KP_LOG_DEBUG("Kompute Algorithm rebuild started");
this->mTensors = tensors; this->mTensors = tensors;
this->mSpirv = spirv; this->mSpirv = spirv;
this->mSpecializationConstants = specializationConstants; this->mSpecializationConstants = specializationConstants;
this->setWorkgroup(workgroup, this->mTensors.size() ? this->mTensors[0]->size() : 1); this->setWorkgroup(workgroup,
this->mTensors.size() ? this->mTensors[0]->size() : 1);
// Descriptor pool is created first so if available then destroy all before rebuild // Descriptor pool is created first so if available then destroy all before
// rebuild
if (this->isInit()) { if (this->isInit()) {
this->destroy(); this->destroy();
} }
@ -56,22 +59,20 @@ Algorithm::rebuild(
} }
bool bool
Algorithm::isInit() { Algorithm::isInit()
return this->mPipeline && {
this->mPipelineCache && return this->mPipeline && this->mPipelineCache && this->mPipelineLayout &&
this->mPipelineLayout && this->mDescriptorPool && this->mDescriptorSet &&
this->mDescriptorPool && this->mDescriptorSetLayout && this->mShaderModule;
this->mDescriptorSet &&
this->mDescriptorSetLayout &&
this->mShaderModule;
} }
void void
Algorithm::destroy() { Algorithm::destroy()
{
if (!this->mDevice) { if (!this->mDevice) {
KP_LOG_WARN( KP_LOG_WARN("Kompute Algorithm destroy function reached with null "
"Kompute Algorithm destroy function reached with null Device pointer"); "Device pointer");
return; return;
} }
@ -79,7 +80,7 @@ Algorithm::destroy() {
KP_LOG_DEBUG("Kompute Algorithm Destroying pipeline"); KP_LOG_DEBUG("Kompute Algorithm Destroying pipeline");
if (!this->mPipeline) { if (!this->mPipeline) {
KP_LOG_WARN("Kompute Algorithm Error requested to destroy " KP_LOG_WARN("Kompute Algorithm Error requested to destroy "
"pipeline but it is null"); "pipeline but it is null");
} }
this->mDevice->destroy( this->mDevice->destroy(
*this->mPipeline, *this->mPipeline,
@ -91,7 +92,7 @@ Algorithm::destroy() {
KP_LOG_DEBUG("Kompute Algorithm Destroying pipeline cache"); KP_LOG_DEBUG("Kompute Algorithm Destroying pipeline cache");
if (!this->mPipelineCache) { if (!this->mPipelineCache) {
KP_LOG_WARN("Kompute Algorithm Error requested to destroy " KP_LOG_WARN("Kompute Algorithm Error requested to destroy "
"pipeline cache but it is null"); "pipeline cache but it is null");
} }
this->mDevice->destroy( this->mDevice->destroy(
*this->mPipelineCache, *this->mPipelineCache,
@ -103,7 +104,7 @@ Algorithm::destroy() {
KP_LOG_DEBUG("Kompute Algorithm Destroying pipeline layout"); KP_LOG_DEBUG("Kompute Algorithm Destroying pipeline layout");
if (!this->mPipelineLayout) { if (!this->mPipelineLayout) {
KP_LOG_WARN("Kompute Algorithm Error requested to destroy " KP_LOG_WARN("Kompute Algorithm Error requested to destroy "
"pipeline layout but it is null"); "pipeline layout but it is null");
} }
this->mDevice->destroy( this->mDevice->destroy(
*this->mPipelineLayout, *this->mPipelineLayout,
@ -115,7 +116,7 @@ Algorithm::destroy() {
KP_LOG_DEBUG("Kompute Algorithm Destroying shader module"); KP_LOG_DEBUG("Kompute Algorithm Destroying shader module");
if (!this->mShaderModule) { if (!this->mShaderModule) {
KP_LOG_WARN("Kompute Algorithm Error requested to destroy shader " KP_LOG_WARN("Kompute Algorithm Error requested to destroy shader "
"module but it is null"); "module but it is null");
} }
this->mDevice->destroy( this->mDevice->destroy(
*this->mShaderModule, *this->mShaderModule,
@ -123,10 +124,10 @@ Algorithm::destroy() {
this->mShaderModule = nullptr; this->mShaderModule = nullptr;
} }
// We don't call freeDescriptorSet as the descriptor pool is not created with // We don't call freeDescriptorSet as the descriptor pool is not created
// VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT more at // with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT more at
// (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkFreeDescriptorSets-descriptorPool-00312)) // (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-vkFreeDescriptorSets-descriptorPool-00312))
//if (this->mFreeDescriptorSet && this->mDescriptorSet) { // if (this->mFreeDescriptorSet && this->mDescriptorSet) {
// KP_LOG_DEBUG("Kompute Algorithm Freeing Descriptor Set"); // KP_LOG_DEBUG("Kompute Algorithm Freeing Descriptor Set");
// if (!this->mDescriptorSet) { // if (!this->mDescriptorSet) {
// KP_LOG_WARN( // KP_LOG_WARN(
@ -141,7 +142,7 @@ Algorithm::destroy() {
KP_LOG_DEBUG("Kompute Algorithm Destroying Descriptor Set Layout"); KP_LOG_DEBUG("Kompute Algorithm Destroying Descriptor Set Layout");
if (!this->mDescriptorSetLayout) { if (!this->mDescriptorSetLayout) {
KP_LOG_WARN("Kompute Algorithm Error requested to destroy " KP_LOG_WARN("Kompute Algorithm Error requested to destroy "
"descriptor set layout but it is null"); "descriptor set layout but it is null");
} }
this->mDevice->destroy( this->mDevice->destroy(
*this->mDescriptorSetLayout, *this->mDescriptorSetLayout,
@ -153,7 +154,7 @@ Algorithm::destroy() {
KP_LOG_DEBUG("Kompute Algorithm Destroying Descriptor Pool"); KP_LOG_DEBUG("Kompute Algorithm Destroying Descriptor Pool");
if (!this->mDescriptorPool) { if (!this->mDescriptorPool) {
KP_LOG_WARN("Kompute Algorithm Error requested to destroy " KP_LOG_WARN("Kompute Algorithm Error requested to destroy "
"descriptor pool but it is null"); "descriptor pool but it is null");
} }
this->mDevice->destroy( this->mDevice->destroy(
*this->mDescriptorPool, *this->mDescriptorPool,
@ -246,10 +247,10 @@ Algorithm::createShaderModule()
{ {
KP_LOG_DEBUG("Kompute Algorithm createShaderModule started"); KP_LOG_DEBUG("Kompute Algorithm createShaderModule started");
vk::ShaderModuleCreateInfo shaderModuleInfo( vk::ShaderModuleCreateInfo shaderModuleInfo(vk::ShaderModuleCreateFlags(),
vk::ShaderModuleCreateFlags(), sizeof(uint32_t) *
sizeof(uint32_t) * this->mSpirv.size(), this->mSpirv.size(),
this->mSpirv.data()); this->mSpirv.data());
KP_LOG_DEBUG("Kompute Algorithm Creating shader module. ShaderFileSize: {}", KP_LOG_DEBUG("Kompute Algorithm Creating shader module. ShaderFileSize: {}",
this->mSpirv.size()); this->mSpirv.size());
@ -281,9 +282,9 @@ Algorithm::createPipeline()
for (uint32_t i = 0; i < this->mSpecializationConstants.size(); i++) { for (uint32_t i = 0; i < this->mSpecializationConstants.size(); i++) {
vk::SpecializationMapEntry specializationEntry( vk::SpecializationMapEntry specializationEntry(
static_cast<uint32_t>(i), static_cast<uint32_t>(i),
static_cast<uint32_t>(sizeof(float) * i), static_cast<uint32_t>(sizeof(float) * i),
sizeof(float)); sizeof(float));
specializationEntries.push_back(specializationEntry); specializationEntries.push_back(specializationEntry);
} }
@ -338,7 +339,8 @@ Algorithm::createPipeline()
// TODO: Update to consistent // TODO: Update to consistent
// this->mPipeline = std::make_shared<vk::Pipeline>(); // this->mPipeline = std::make_shared<vk::Pipeline>();
// this->mDevice->createComputePipelines( // this->mDevice->createComputePipelines(
// *this->mPipelineCache, 1, &pipelineInfo, nullptr, this->mPipeline.get()); // *this->mPipelineCache, 1, &pipelineInfo, nullptr,
// this->mPipeline.get());
KP_LOG_DEBUG("Kompute Algorithm Create Pipeline Success"); KP_LOG_DEBUG("Kompute Algorithm Create Pipeline Success");
} }
@ -349,29 +351,31 @@ Algorithm::bindCore(const vk::CommandBuffer& commandBuffer)
KP_LOG_DEBUG("Kompute Algorithm binding pipeline"); KP_LOG_DEBUG("Kompute Algorithm binding pipeline");
commandBuffer.bindPipeline(vk::PipelineBindPoint::eCompute, commandBuffer.bindPipeline(vk::PipelineBindPoint::eCompute,
*this->mPipeline); *this->mPipeline);
KP_LOG_DEBUG("Kompute Algorithm binding descriptor sets"); KP_LOG_DEBUG("Kompute Algorithm binding descriptor sets");
commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eCompute, commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eCompute,
*this->mPipelineLayout, *this->mPipelineLayout,
0, // First set 0, // First set
*this->mDescriptorSet, *this->mDescriptorSet,
nullptr // Dispatcher nullptr // Dispatcher
); );
} }
void void
Algorithm::bindPush(const vk::CommandBuffer& commandBuffer, const Constants& pushConstants) Algorithm::bindPush(const vk::CommandBuffer& commandBuffer,
const Constants& pushConstants)
{ {
if (pushConstants.size()) { if (pushConstants.size()) {
KP_LOG_DEBUG("Kompute Algorithm binding push constants size: {}", pushConstants.size()); KP_LOG_DEBUG("Kompute Algorithm binding push constants size: {}",
pushConstants.size());
commandBuffer.pushConstants(*this->mPipelineLayout, commandBuffer.pushConstants(*this->mPipelineLayout,
vk::ShaderStageFlagBits::eCompute, vk::ShaderStageFlagBits::eCompute,
0, 0,
pushConstants.size() * sizeof(float), pushConstants.size() * sizeof(float),
pushConstants.data()); pushConstants.data());
} }
} }
@ -380,11 +384,13 @@ Algorithm::recordDispatch(const vk::CommandBuffer& commandBuffer)
{ {
KP_LOG_DEBUG("Kompute Algorithm recording dispatch"); KP_LOG_DEBUG("Kompute Algorithm recording dispatch");
commandBuffer.dispatch(this->mWorkgroup[0], this->mWorkgroup[1], this->mWorkgroup[2]); commandBuffer.dispatch(
this->mWorkgroup[0], this->mWorkgroup[1], this->mWorkgroup[2]);
} }
void void
Algorithm::setWorkgroup(const Workgroup& workgroup, uint32_t minSize) { Algorithm::setWorkgroup(const Workgroup& workgroup, uint32_t minSize)
{
KP_LOG_INFO("Kompute OpAlgoCreate setting dispatch size"); KP_LOG_INFO("Kompute OpAlgoCreate setting dispatch size");
@ -393,11 +399,9 @@ Algorithm::setWorkgroup(const Workgroup& workgroup, uint32_t minSize) {
if (workgroup[0] > 0) { if (workgroup[0] > 0) {
// If at least the x value is provided we use mainly the parameters // If at least the x value is provided we use mainly the parameters
// provided // provided
this->mWorkgroup = { this->mWorkgroup = { workgroup[0],
workgroup[0], workgroup[1] > 0 ? workgroup[1] : 1,
workgroup[1] > 0 ? workgroup[1] : 1, workgroup[2] > 0 ? workgroup[2] : 1 };
workgroup[2] > 0 ? workgroup[2] : 1
};
} else { } else {
this->mWorkgroup = { minSize, 1, 1 }; this->mWorkgroup = { minSize, 1, 1 };
} }
@ -409,17 +413,20 @@ Algorithm::setWorkgroup(const Workgroup& workgroup, uint32_t minSize) {
} }
const Workgroup& const Workgroup&
Algorithm::getWorkgroup() { Algorithm::getWorkgroup()
{
return this->mWorkgroup; return this->mWorkgroup;
} }
const Constants& const Constants&
Algorithm::getSpecializationConstants() { Algorithm::getSpecializationConstants()
{
return this->mSpecializationConstants; return this->mSpecializationConstants;
} }
const std::vector<std::shared_ptr<Tensor>>& const std::vector<std::shared_ptr<Tensor>>&
Algorithm::getTensors() { Algorithm::getTensors()
{
return this->mTensors; return this->mTensors;
} }

View file

@ -55,7 +55,8 @@ Manager::~Manager()
} }
void void
Manager::destroy() { Manager::destroy()
{
KP_LOG_DEBUG("Kompute Manager destroy() started"); KP_LOG_DEBUG("Kompute Manager destroy() started");
@ -78,7 +79,8 @@ Manager::destroy() {
if (this->mManageResources && this->mManagedAlgorithms.size()) { if (this->mManageResources && this->mManagedAlgorithms.size()) {
KP_LOG_DEBUG("Kompute Manager explicitly freeing algorithms"); KP_LOG_DEBUG("Kompute Manager explicitly freeing algorithms");
for (const std::weak_ptr<Algorithm>& weakAlgorithm : this->mManagedAlgorithms) { for (const std::weak_ptr<Algorithm>& weakAlgorithm :
this->mManagedAlgorithms) {
if (std::shared_ptr<Algorithm> algorithm = weakAlgorithm.lock()) { if (std::shared_ptr<Algorithm> algorithm = weakAlgorithm.lock()) {
algorithm->destroy(); algorithm->destroy();
} }
@ -214,31 +216,31 @@ Manager::createInstance()
} }
void void
Manager::clear() { Manager::clear()
{
if (this->mManageResources) { if (this->mManageResources) {
this->mManagedTensors.erase( this->mManagedTensors.erase(
std::remove_if( std::remove_if(begin(this->mManagedTensors),
begin(this->mManagedTensors), end(this->mManagedTensors),
end(this->mManagedTensors), [](std::weak_ptr<Tensor> t) { return t.expired(); }),
[](std::weak_ptr<Tensor> t) {return t.expired();}), end(this->mManagedTensors));
end(this->mManagedTensors));
this->mManagedAlgorithms.erase( this->mManagedAlgorithms.erase(
std::remove_if( std::remove_if(
begin(this->mManagedAlgorithms), begin(this->mManagedAlgorithms),
end(this->mManagedAlgorithms), end(this->mManagedAlgorithms),
[](std::weak_ptr<Algorithm> t) {return t.expired();}), [](std::weak_ptr<Algorithm> t) { return t.expired(); }),
end(this->mManagedAlgorithms)); end(this->mManagedAlgorithms));
this->mManagedSequences.erase( this->mManagedSequences.erase(
std::remove_if( std::remove_if(begin(this->mManagedSequences),
begin(this->mManagedSequences), end(this->mManagedSequences),
end(this->mManagedSequences), [](std::weak_ptr<Sequence> t) { return t.expired(); }),
[](std::weak_ptr<Sequence> t) {return t.expired();}), end(this->mManagedSequences));
end(this->mManagedSequences));
} }
} }
void void
Manager::createDevice(const std::vector<uint32_t>& familyQueueIndices, uint32_t physicalDeviceIndex) Manager::createDevice(const std::vector<uint32_t>& familyQueueIndices,
uint32_t physicalDeviceIndex)
{ {
KP_LOG_DEBUG("Kompute Manager creating Device"); KP_LOG_DEBUG("Kompute Manager creating Device");
@ -256,8 +258,7 @@ Manager::createDevice(const std::vector<uint32_t>& familyQueueIndices, uint32_t
std::vector<vk::PhysicalDevice> physicalDevices = std::vector<vk::PhysicalDevice> physicalDevices =
this->mInstance->enumeratePhysicalDevices(); this->mInstance->enumeratePhysicalDevices();
vk::PhysicalDevice physicalDevice = vk::PhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex];
physicalDevices[physicalDeviceIndex];
this->mPhysicalDevice = this->mPhysicalDevice =
std::make_shared<vk::PhysicalDevice>(physicalDevice); std::make_shared<vk::PhysicalDevice>(physicalDevice);
@ -342,16 +343,14 @@ Manager::createDevice(const std::vector<uint32_t>& familyQueueIndices, uint32_t
} }
std::shared_ptr<Tensor> std::shared_ptr<Tensor>
Manager::tensor( Manager::tensor(const std::vector<float>& data, Tensor::TensorTypes tensorType)
const std::vector<float>& data,
Tensor::TensorTypes tensorType)
{ {
KP_LOG_DEBUG("Kompute Manager tensor creation triggered"); KP_LOG_DEBUG("Kompute Manager tensor creation triggered");
std::shared_ptr<Tensor> tensor{ std::shared_ptr<Tensor> tensor{ new kp::Tensor(
new kp::Tensor(this->mPhysicalDevice, this->mDevice, data, tensorType) }; this->mPhysicalDevice, this->mDevice, data, tensorType) };
if (this->mManageResources) { if (this->mManageResources) {
this->mManagedTensors.push_back(tensor); this->mManagedTensors.push_back(tensor);
} }
@ -359,23 +358,18 @@ Manager::tensor(
} }
std::shared_ptr<Algorithm> std::shared_ptr<Algorithm>
Manager::algorithm( Manager::algorithm(const std::vector<std::shared_ptr<Tensor>>& tensors,
const std::vector<std::shared_ptr<Tensor>>& tensors, const std::vector<uint32_t>& spirv,
const std::vector<uint32_t>& spirv, const Workgroup& workgroup,
const Workgroup& workgroup, const Constants& specializationConstants)
const Constants& specializationConstants) { {
KP_LOG_DEBUG("Kompute Manager algorithm creation triggered"); KP_LOG_DEBUG("Kompute Manager algorithm creation triggered");
std::shared_ptr<Algorithm> algorithm{ std::shared_ptr<Algorithm> algorithm{ new kp::Algorithm(
new kp::Algorithm( this->mDevice, tensors, spirv, workgroup, specializationConstants) };
this->mDevice,
tensors,
spirv,
workgroup,
specializationConstants)};
if (this->mManageResources) { if (this->mManageResources) {
this->mManagedAlgorithms.push_back(algorithm); this->mManagedAlgorithms.push_back(algorithm);
} }
@ -385,16 +379,15 @@ Manager::algorithm(
std::shared_ptr<Sequence> std::shared_ptr<Sequence>
Manager::sequence(uint32_t queueIndex) Manager::sequence(uint32_t queueIndex)
{ {
KP_LOG_DEBUG("Kompute Manager sequence() with queueIndex: {}", KP_LOG_DEBUG("Kompute Manager sequence() with queueIndex: {}", queueIndex);
queueIndex);
std::shared_ptr<Sequence> sq{ std::shared_ptr<Sequence> sq{ new kp::Sequence(
new kp::Sequence(this->mPhysicalDevice, this->mPhysicalDevice,
this->mDevice, this->mDevice,
this->mComputeQueues[queueIndex], this->mComputeQueues[queueIndex],
this->mComputeQueueFamilyIndices[queueIndex]) }; this->mComputeQueueFamilyIndices[queueIndex]) };
if (this->mManageResources) { if (this->mManageResources) {
this->mManagedSequences.push_back(sq); this->mManagedSequences.push_back(sq);
} }

View file

@ -5,7 +5,7 @@
namespace kp { namespace kp {
OpAlgoDispatch::OpAlgoDispatch(const std::shared_ptr<kp::Algorithm>& algorithm, OpAlgoDispatch::OpAlgoDispatch(const std::shared_ptr<kp::Algorithm>& algorithm,
const kp::Constants& pushConstants) const kp::Constants& pushConstants)
{ {
KP_LOG_DEBUG("Kompute OpAlgoDispatch constructor"); KP_LOG_DEBUG("Kompute OpAlgoDispatch constructor");
@ -24,7 +24,8 @@ OpAlgoDispatch::record(const vk::CommandBuffer& commandBuffer)
KP_LOG_DEBUG("Kompute OpAlgoDispatch record called"); KP_LOG_DEBUG("Kompute OpAlgoDispatch record called");
// Barrier to ensure the data is finished writing to buffer memory // Barrier to ensure the data is finished writing to buffer memory
for (const std::shared_ptr<Tensor>& tensor : this->mAlgorithm->getTensors()) { for (const std::shared_ptr<Tensor>& tensor :
this->mAlgorithm->getTensors()) {
tensor->recordBufferMemoryBarrier( tensor->recordBufferMemoryBarrier(
commandBuffer, commandBuffer,
vk::AccessFlagBits::eHostWrite, vk::AccessFlagBits::eHostWrite,

View file

@ -30,8 +30,8 @@ OpTensorSyncDevice::record(const vk::CommandBuffer& commandBuffer)
for (size_t i = 0; i < this->mTensors.size(); i++) { for (size_t i = 0; i < this->mTensors.size(); i++) {
if (this->mTensors[i]->tensorType() == Tensor::TensorTypes::eDevice) { if (this->mTensors[i]->tensorType() == Tensor::TensorTypes::eDevice) {
this->mTensors[i]->recordCopyFromStagingToDevice( this->mTensors[i]->recordCopyFromStagingToDevice(commandBuffer,
commandBuffer, false); false);
} }
} }
} }

View file

@ -30,8 +30,8 @@ OpTensorSyncLocal::record(const vk::CommandBuffer& commandBuffer)
for (size_t i = 0; i < this->mTensors.size(); i++) { for (size_t i = 0; i < this->mTensors.size(); i++) {
if (this->mTensors[i]->tensorType() == Tensor::TensorTypes::eDevice) { if (this->mTensors[i]->tensorType() == Tensor::TensorTypes::eDevice) {
this->mTensors[i]->recordCopyFromDeviceToStaging( this->mTensors[i]->recordCopyFromDeviceToStaging(commandBuffer,
commandBuffer, true); true);
} }
} }
} }

View file

@ -37,7 +37,8 @@ Sequence::begin()
} }
if (this->isRunning()) { if (this->isRunning()) {
throw std::runtime_error("Kompute Sequence begin called when sequence still running"); throw std::runtime_error(
"Kompute Sequence begin called when sequence still running");
} }
KP_LOG_INFO("Kompute Sequence command now started recording"); KP_LOG_INFO("Kompute Sequence command now started recording");
@ -53,8 +54,7 @@ Sequence::end()
if (!this->isRecording()) { if (!this->isRecording()) {
KP_LOG_WARN("Kompute Sequence end called when not recording"); KP_LOG_WARN("Kompute Sequence end called when not recording");
return; return;
} } else {
else {
KP_LOG_INFO("Kompute Sequence command recording END"); KP_LOG_INFO("Kompute Sequence command recording END");
this->mCommandBuffer->end(); this->mCommandBuffer->end();
this->mRecording = false; this->mRecording = false;
@ -62,7 +62,8 @@ Sequence::end()
} }
void void
Sequence::clear() { Sequence::clear()
{
KP_LOG_DEBUG("Kompute Sequence calling clear"); KP_LOG_DEBUG("Kompute Sequence calling clear");
this->end(); this->end();
} }
@ -76,7 +77,8 @@ Sequence::eval()
} }
std::shared_ptr<Sequence> std::shared_ptr<Sequence>
Sequence::eval(std::shared_ptr<OpBase> op) { Sequence::eval(std::shared_ptr<OpBase> op)
{
this->clear(); this->clear();
return this->record(op)->eval(); return this->record(op)->eval();
} }
@ -89,8 +91,9 @@ Sequence::evalAsync()
} }
if (this->mIsRunning) { if (this->mIsRunning) {
throw std::runtime_error("Kompute Sequence evalAsync called when an eval async was " throw std::runtime_error(
"called without successful wait"); "Kompute Sequence evalAsync called when an eval async was "
"called without successful wait");
} }
this->mIsRunning = true; this->mIsRunning = true;
@ -137,7 +140,8 @@ Sequence::evalAwait(uint64_t waitFor)
this->mIsRunning = false; this->mIsRunning = false;
if (result == vk::Result::eTimeout) { if (result == vk::Result::eTimeout) {
KP_LOG_WARN("Kompute Sequence evalAwait reached timeout of {}", waitFor); KP_LOG_WARN("Kompute Sequence evalAwait reached timeout of {}",
waitFor);
return shared_from_this(); return shared_from_this();
} }
@ -161,11 +165,10 @@ Sequence::isRecording()
} }
bool bool
Sequence::isInit() { Sequence::isInit()
return this->mDevice && {
this->mCommandPool && return this->mDevice && this->mCommandPool && this->mCommandBuffer &&
this->mCommandBuffer && this->mComputeQueue;
this->mComputeQueue;
} }
void void
@ -175,16 +178,15 @@ Sequence::destroy()
if (!this->mDevice) { if (!this->mDevice) {
KP_LOG_WARN("Kompute Sequence destroy called " KP_LOG_WARN("Kompute Sequence destroy called "
"with null Device pointer"); "with null Device pointer");
return; return;
} }
if (this->mFreeCommandBuffer) { if (this->mFreeCommandBuffer) {
KP_LOG_INFO("Freeing CommandBuffer"); KP_LOG_INFO("Freeing CommandBuffer");
if (!this->mCommandBuffer) { if (!this->mCommandBuffer) {
KP_LOG_WARN( KP_LOG_WARN("Kompute Sequence destroy called with null "
"Kompute Sequence destroy called with null " "CommandPool pointer");
"CommandPool pointer");
return; return;
} }
this->mDevice->freeCommandBuffers( this->mDevice->freeCommandBuffers(
@ -199,9 +201,8 @@ Sequence::destroy()
if (this->mFreeCommandPool) { if (this->mFreeCommandPool) {
KP_LOG_INFO("Destroying CommandPool"); KP_LOG_INFO("Destroying CommandPool");
if (this->mCommandPool == nullptr) { if (this->mCommandPool == nullptr) {
KP_LOG_WARN( KP_LOG_WARN("Kompute Sequence destroy called with null "
"Kompute Sequence destroy called with null " "CommandPool pointer");
"CommandPool pointer");
return; return;
} }
this->mDevice->destroy( this->mDevice->destroy(
@ -228,7 +229,6 @@ Sequence::destroy()
if (this->mComputeQueue) { if (this->mComputeQueue) {
this->mComputeQueue = nullptr; this->mComputeQueue = nullptr;
} }
} }
std::shared_ptr<Sequence> std::shared_ptr<Sequence>

View file

@ -5,11 +5,13 @@
namespace kp { namespace kp {
std::vector<uint32_t> std::vector<uint32_t>
Shader::compile_sources(const std::vector<std::string>& sources, Shader::compile_sources(
const std::vector<std::string>& files, const std::vector<std::string>& sources,
const std::string& entryPoint, const std::vector<std::string>& files,
std::vector<std::pair<std::string,std::string>> definitions, const std::string& entryPoint,
const TBuiltInResource& resources) { std::vector<std::pair<std::string, std::string>> definitions,
const TBuiltInResource& resources)
{
// Initialize glslang library. // Initialize glslang library.
glslang::InitializeProcess(); glslang::InitializeProcess();
@ -18,27 +20,32 @@ Shader::compile_sources(const std::vector<std::string>& sources,
const EShLanguage language = EShLangCompute; const EShLanguage language = EShLangCompute;
glslang::TShader shader(language); glslang::TShader shader(language);
std::vector<const char*> filesCStr(files.size()), sourcesCStr(sources.size()); std::vector<const char*> filesCStr(files.size()),
for (size_t i = 0; i < sources.size(); i++) sourcesCStr[i] = sources[i].c_str(); sourcesCStr(sources.size());
for (size_t i = 0; i < sources.size(); i++)
sourcesCStr[i] = sources[i].c_str();
if (files.size() > 1) { if (files.size() > 1) {
assert(files.size() == sources.size()); assert(files.size() == sources.size());
for (size_t i = 0; i < files.size(); i++) filesCStr[i] = files[i].c_str(); for (size_t i = 0; i < files.size(); i++)
shader.setStringsWithLengthsAndNames(sourcesCStr.data(), nullptr, filesCStr.data(), filesCStr.size()); filesCStr[i] = files[i].c_str();
} shader.setStringsWithLengthsAndNames(
else { sourcesCStr.data(), nullptr, filesCStr.data(), filesCStr.size());
filesCStr = {""}; } else {
shader.setStringsWithLengthsAndNames(sourcesCStr.data(), nullptr, filesCStr.data(), sourcesCStr.size()); filesCStr = { "" };
shader.setStringsWithLengthsAndNames(
sourcesCStr.data(), nullptr, filesCStr.data(), sourcesCStr.size());
} }
shader.setEntryPoint(entryPoint.c_str()); shader.setEntryPoint(entryPoint.c_str());
shader.setSourceEntryPoint(entryPoint.c_str()); shader.setSourceEntryPoint(entryPoint.c_str());
std::string info_log = ""; std::string info_log = "";
const EShMessages messages = static_cast<EShMessages>(EShMsgDefault | EShMsgVulkanRules | EShMsgSpvRules); const EShMessages messages = static_cast<EShMessages>(
if (!shader.parse(&resources, 100, false, messages)) EShMsgDefault | EShMsgVulkanRules | EShMsgSpvRules);
{ if (!shader.parse(&resources, 100, false, messages)) {
info_log = std::string(shader.getInfoLog()) + "\n" + std::string(shader.getInfoDebugLog()); info_log = std::string(shader.getInfoLog()) + "\n" +
std::string(shader.getInfoDebugLog());
KP_LOG_ERROR("Kompute Shader Error: {}", info_log); KP_LOG_ERROR("Kompute Shader Error: {}", info_log);
throw std::runtime_error(info_log); throw std::runtime_error(info_log);
} }
@ -47,24 +54,23 @@ Shader::compile_sources(const std::vector<std::string>& sources,
glslang::TProgram program; glslang::TProgram program;
program.addShader(&shader); program.addShader(&shader);
// Link program. // Link program.
if (!program.link(messages)) if (!program.link(messages)) {
{ info_log = std::string(program.getInfoLog()) + "\n" +
info_log = std::string(program.getInfoLog()) + "\n" + std::string(program.getInfoDebugLog()); std::string(program.getInfoDebugLog());
KP_LOG_ERROR("Kompute Shader Error: {}", info_log); KP_LOG_ERROR("Kompute Shader Error: {}", info_log);
throw std::runtime_error(info_log); throw std::runtime_error(info_log);
} }
// Save any info log that was generated. // Save any info log that was generated.
if (shader.getInfoLog()) if (shader.getInfoLog()) {
{ info_log += std::string(shader.getInfoLog()) + "\n" +
info_log += std::string(shader.getInfoLog()) + "\n" + std::string(shader.getInfoDebugLog()) + "\n"; std::string(shader.getInfoDebugLog()) + "\n";
KP_LOG_INFO("Kompute Shader Information: {}", info_log); KP_LOG_INFO("Kompute Shader Information: {}", info_log);
} }
glslang::TIntermediate *intermediate = program.getIntermediate(language); glslang::TIntermediate* intermediate = program.getIntermediate(language);
// Translate to SPIRV. // Translate to SPIRV.
if (!intermediate) if (!intermediate) {
{
info_log += "Failed to get shared intermediate code.\n"; info_log += "Failed to get shared intermediate code.\n";
KP_LOG_ERROR("Kompute Shader Error: {}", info_log); KP_LOG_ERROR("Kompute Shader Error: {}", info_log);
throw std::runtime_error(info_log); throw std::runtime_error(info_log);
@ -74,8 +80,7 @@ Shader::compile_sources(const std::vector<std::string>& sources,
std::vector<std::uint32_t> spirv; std::vector<std::uint32_t> spirv;
glslang::GlslangToSpv(*intermediate, spirv, &logger); glslang::GlslangToSpv(*intermediate, spirv, &logger);
if (shader.getInfoLog()) if (shader.getInfoLog()) {
{
info_log += logger.getAllMessages() + "\n"; info_log += logger.getAllMessages() + "\n";
KP_LOG_DEBUG("Kompute Shader all result messages: {}", info_log); KP_LOG_DEBUG("Kompute Shader all result messages: {}", info_log);
} }
@ -87,11 +92,17 @@ Shader::compile_sources(const std::vector<std::string>& sources,
} }
std::vector<uint32_t> std::vector<uint32_t>
Shader::compile_source(const std::string& source, Shader::compile_source(
const std::string& entryPoint, const std::string& source,
std::vector<std::pair<std::string,std::string>> definitions, const std::string& entryPoint,
const TBuiltInResource& resource) { std::vector<std::pair<std::string, std::string>> definitions,
return compile_sources({source}, std::vector<std::string>({}), entryPoint, definitions, resource); const TBuiltInResource& resource)
{
return compile_sources({ source },
std::vector<std::string>({}),
entryPoint,
definitions,
resource);
} }
} }

View file

@ -4,9 +4,9 @@
namespace kp { namespace kp {
Tensor::Tensor(std::shared_ptr<vk::PhysicalDevice> physicalDevice, Tensor::Tensor(std::shared_ptr<vk::PhysicalDevice> physicalDevice,
std::shared_ptr<vk::Device> device, std::shared_ptr<vk::Device> device,
const std::vector<float>& data, const std::vector<float>& data,
const TensorTypes& tensorType) const TensorTypes& tensorType)
{ {
KP_LOG_DEBUG("Kompute Tensor constructor data length: {}, and type: {}", KP_LOG_DEBUG("Kompute Tensor constructor data length: {}, and type: {}",
data.size(), data.size(),
@ -29,17 +29,16 @@ Tensor::~Tensor()
} }
void void
Tensor::rebuild(const std::vector<float>& data, Tensor::rebuild(const std::vector<float>& data, TensorTypes tensorType)
TensorTypes tensorType)
{ {
KP_LOG_DEBUG("Kompute Tensor rebuilding with size {}", KP_LOG_DEBUG("Kompute Tensor rebuilding with size {}", data.size());
data.size());
this->mData = data; this->mData = data;
this->mTensorType = tensorType; this->mTensorType = tensorType;
if (this->mPrimaryBuffer || this->mPrimaryMemory) { if (this->mPrimaryBuffer || this->mPrimaryMemory) {
KP_LOG_DEBUG("Kompute Tensor destroying existing resources before rebuild"); KP_LOG_DEBUG(
"Kompute Tensor destroying existing resources before rebuild");
this->destroy(); this->destroy();
} }
@ -77,10 +76,9 @@ Tensor::tensorType()
} }
bool bool
Tensor::isInit() { Tensor::isInit()
return this->mDevice && {
this->mPrimaryBuffer && return this->mDevice && this->mPrimaryBuffer && this->mPrimaryMemory;
this->mPrimaryMemory;
} }
void void
@ -105,17 +103,16 @@ Tensor::recordCopyFrom(const vk::CommandBuffer& commandBuffer,
KP_LOG_DEBUG("Kompute Tensor recordCopyFrom data size {}.", bufferSize); KP_LOG_DEBUG("Kompute Tensor recordCopyFrom data size {}.", bufferSize);
this->recordCopyBuffer(commandBuffer, this->recordCopyBuffer(commandBuffer,
copyFromTensor->mPrimaryBuffer, copyFromTensor->mPrimaryBuffer,
this->mPrimaryBuffer, this->mPrimaryBuffer,
bufferSize, bufferSize,
copyRegion, copyRegion,
createBarrier); createBarrier);
} }
void void
Tensor::recordCopyFromStagingToDevice( Tensor::recordCopyFromStagingToDevice(const vk::CommandBuffer& commandBuffer,
const vk::CommandBuffer& commandBuffer, bool createBarrier)
bool createBarrier)
{ {
vk::DeviceSize bufferSize(this->memorySize()); vk::DeviceSize bufferSize(this->memorySize());
vk::BufferCopy copyRegion(0, 0, bufferSize); vk::BufferCopy copyRegion(0, 0, bufferSize);
@ -123,17 +120,16 @@ Tensor::recordCopyFromStagingToDevice(
KP_LOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize); KP_LOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize);
this->recordCopyBuffer(commandBuffer, this->recordCopyBuffer(commandBuffer,
this->mStagingBuffer, this->mStagingBuffer,
this->mPrimaryBuffer, this->mPrimaryBuffer,
bufferSize, bufferSize,
copyRegion, copyRegion,
createBarrier); createBarrier);
} }
void void
Tensor::recordCopyFromDeviceToStaging( Tensor::recordCopyFromDeviceToStaging(const vk::CommandBuffer& commandBuffer,
const vk::CommandBuffer& commandBuffer, bool createBarrier)
bool createBarrier)
{ {
vk::DeviceSize bufferSize(this->memorySize()); vk::DeviceSize bufferSize(this->memorySize());
vk::BufferCopy copyRegion(0, 0, bufferSize); vk::BufferCopy copyRegion(0, 0, bufferSize);
@ -141,20 +137,20 @@ Tensor::recordCopyFromDeviceToStaging(
KP_LOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize); KP_LOG_DEBUG("Kompute Tensor copying data size {}.", bufferSize);
this->recordCopyBuffer(commandBuffer, this->recordCopyBuffer(commandBuffer,
this->mPrimaryBuffer, this->mPrimaryBuffer,
this->mStagingBuffer, this->mStagingBuffer,
bufferSize, bufferSize,
copyRegion, copyRegion,
createBarrier); createBarrier);
} }
void void
Tensor::recordCopyBuffer(const vk::CommandBuffer& commandBuffer, Tensor::recordCopyBuffer(const vk::CommandBuffer& commandBuffer,
std::shared_ptr<vk::Buffer> bufferFrom, std::shared_ptr<vk::Buffer> bufferFrom,
std::shared_ptr<vk::Buffer> bufferTo, std::shared_ptr<vk::Buffer> bufferTo,
vk::DeviceSize bufferSize, vk::DeviceSize bufferSize,
vk::BufferCopy copyRegion, vk::BufferCopy copyRegion,
bool createBarrier) bool createBarrier)
{ {
commandBuffer.copyBuffer(*bufferFrom, *bufferTo, copyRegion); commandBuffer.copyBuffer(*bufferFrom, *bufferTo, copyRegion);
@ -170,12 +166,11 @@ Tensor::recordCopyBuffer(const vk::CommandBuffer& commandBuffer,
} }
void void
Tensor::recordBufferMemoryBarrier( Tensor::recordBufferMemoryBarrier(const vk::CommandBuffer& commandBuffer,
const vk::CommandBuffer& commandBuffer, vk::AccessFlagBits srcAccessMask,
vk::AccessFlagBits srcAccessMask, vk::AccessFlagBits dstAccessMask,
vk::AccessFlagBits dstAccessMask, vk::PipelineStageFlagBits srcStageMask,
vk::PipelineStageFlagBits srcStageMask, vk::PipelineStageFlagBits dstStageMask)
vk::PipelineStageFlagBits dstStageMask)
{ {
KP_LOG_DEBUG("Kompute Tensor recording buffer memory barrier"); KP_LOG_DEBUG("Kompute Tensor recording buffer memory barrier");
@ -190,11 +185,11 @@ Tensor::recordBufferMemoryBarrier(
bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
commandBuffer.pipelineBarrier(srcStageMask, commandBuffer.pipelineBarrier(srcStageMask,
dstStageMask, dstStageMask,
vk::DependencyFlags(), vk::DependencyFlags(),
nullptr, nullptr,
bufferMemoryBarrier, bufferMemoryBarrier,
nullptr); nullptr);
} }
vk::DescriptorBufferInfo vk::DescriptorBufferInfo
@ -449,7 +444,7 @@ Tensor::destroy()
if (this->mFreePrimaryBuffer) { if (this->mFreePrimaryBuffer) {
if (!this->mPrimaryBuffer) { if (!this->mPrimaryBuffer) {
KP_LOG_WARN("Kompose Tensor expected to destroy primary buffer " KP_LOG_WARN("Kompose Tensor expected to destroy primary buffer "
"but got null buffer"); "but got null buffer");
} else { } else {
KP_LOG_DEBUG("Kompose Tensor destroying primary buffer"); KP_LOG_DEBUG("Kompose Tensor destroying primary buffer");
this->mDevice->destroy( this->mDevice->destroy(
@ -463,7 +458,7 @@ Tensor::destroy()
if (this->mFreeStagingBuffer) { if (this->mFreeStagingBuffer) {
if (!this->mStagingBuffer) { if (!this->mStagingBuffer) {
KP_LOG_WARN("Kompose Tensor expected to destroy staging buffer " KP_LOG_WARN("Kompose Tensor expected to destroy staging buffer "
"but got null buffer"); "but got null buffer");
} else { } else {
KP_LOG_DEBUG("Kompose Tensor destroying staging buffer"); KP_LOG_DEBUG("Kompose Tensor destroying staging buffer");
this->mDevice->destroy( this->mDevice->destroy(
@ -477,7 +472,7 @@ Tensor::destroy()
if (this->mFreePrimaryMemory) { if (this->mFreePrimaryMemory) {
if (!this->mPrimaryMemory) { if (!this->mPrimaryMemory) {
KP_LOG_WARN("Kompose Tensor expected to free primary memory but " KP_LOG_WARN("Kompose Tensor expected to free primary memory but "
"got null memory"); "got null memory");
} else { } else {
KP_LOG_DEBUG("Kompose Tensor freeing primary memory"); KP_LOG_DEBUG("Kompose Tensor freeing primary memory");
this->mDevice->freeMemory( this->mDevice->freeMemory(
@ -491,7 +486,7 @@ Tensor::destroy()
if (this->mFreeStagingMemory) { if (this->mFreeStagingMemory) {
if (!this->mStagingMemory) { if (!this->mStagingMemory) {
KP_LOG_WARN("Kompose Tensor expected to free staging memory but " KP_LOG_WARN("Kompose Tensor expected to free staging memory but "
"got null memory"); "got null memory");
} else { } else {
KP_LOG_DEBUG("Kompose Tensor freeing staging memory"); KP_LOG_DEBUG("Kompose Tensor freeing staging memory");
this->mDevice->freeMemory( this->mDevice->freeMemory(

View file

@ -12,8 +12,7 @@ namespace kp {
*/ */
class Algorithm class Algorithm
{ {
public: public:
/** /**
* Default constructor for Algorithm * Default constructor for Algorithm
* *
@ -21,12 +20,11 @@ public:
* @param commandBuffer The vulkan command buffer to bind the pipeline and * @param commandBuffer The vulkan command buffer to bind the pipeline and
* shaders * shaders
*/ */
Algorithm( Algorithm(std::shared_ptr<vk::Device> device,
std::shared_ptr<vk::Device> device, const std::vector<std::shared_ptr<Tensor>>& tensors = {},
const std::vector<std::shared_ptr<Tensor>>& tensors = {}, const std::vector<uint32_t>& spirv = {},
const std::vector<uint32_t>& spirv = {}, const Workgroup& workgroup = {},
const Workgroup& workgroup = {}, const Constants& specializationConstants = {});
const Constants& specializationConstants = {});
/** /**
* Initialiser for the shader data provided to the algorithm as well as * Initialiser for the shader data provided to the algorithm as well as
@ -34,14 +32,13 @@ public:
* *
* @param shaderFileData The bytes in spir-v format of the shader * @param shaderFileData The bytes in spir-v format of the shader
* @tensorParams The Tensors to be used in the Algorithm / shader for * @tensorParams The Tensors to be used in the Algorithm / shader for
* @specalizationInstalces The specialization parameters to pass to the function * @specalizationInstalces The specialization parameters to pass to the
* processing * function processing
*/ */
void rebuild( void rebuild(const std::vector<std::shared_ptr<Tensor>>& tensors = {},
const std::vector<std::shared_ptr<Tensor>>& tensors = {}, const std::vector<uint32_t>& spirv = {},
const std::vector<uint32_t>& spirv = {}, const Workgroup& workgroup = {},
const Workgroup& workgroup = {}, const Constants& specializationConstants = {});
const Constants& specializationConstants = {});
/** /**
* Destructor for Algorithm which is responsible for freeing and desroying * Destructor for Algorithm which is responsible for freeing and desroying
@ -61,7 +58,8 @@ public:
void bindCore(const vk::CommandBuffer& commandBuffer); void bindCore(const vk::CommandBuffer& commandBuffer);
void bindPush(const vk::CommandBuffer& commandBuffer, const Constants& pushConstants); void bindPush(const vk::CommandBuffer& commandBuffer,
const Constants& pushConstants);
bool isInit(); bool isInit();
@ -73,7 +71,7 @@ public:
void destroy(); void destroy();
private: private:
// -------------- NEVER OWNED RESOURCES // -------------- NEVER OWNED RESOURCES
std::shared_ptr<vk::Device> mDevice; std::shared_ptr<vk::Device> mDevice;
std::vector<std::shared_ptr<Tensor>> mTensors; std::vector<std::shared_ptr<Tensor>> mTensors;

View file

@ -60,12 +60,19 @@ extern py::object kp_debug, kp_info, kp_warning, kp_error;
#define KP_LOG_DEBUG(...) #define KP_LOG_DEBUG(...)
#else #else
#if defined(VK_USE_PLATFORM_ANDROID_KHR) #if defined(VK_USE_PLATFORM_ANDROID_KHR)
#define KP_LOG_DEBUG(...) \ #define KP_LOG_DEBUG(...) \
((void)__android_log_print(ANDROID_LOG_DEBUG, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__))) ((void)__android_log_print( \
ANDROID_LOG_DEBUG, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__)))
#elif defined(KOMPUTE_BUILD_PYTHON) #elif defined(KOMPUTE_BUILD_PYTHON)
#define KP_LOG_DEBUG(...) kp_debug(fmt::format(__VA_ARGS__)) #define KP_LOG_DEBUG(...) kp_debug(fmt::format(__VA_ARGS__))
#else #else
#define KP_LOG_DEBUG(...) fmt::print("[{} {}] [debug] [{}:{}] {}\n", __DATE__, __TIME__, __FILE__, __LINE__, fmt::format(__VA_ARGS__)) #define KP_LOG_DEBUG(...) \
fmt::print("[{} {}] [debug] [{}:{}] {}\n", \
__DATE__, \
__TIME__, \
__FILE__, \
__LINE__, \
fmt::format(__VA_ARGS__))
#endif // VK_USE_PLATFORM_ANDROID_KHR #endif // VK_USE_PLATFORM_ANDROID_KHR
#endif // SPDLOG_ACTIVE_LEVEL > 1 #endif // SPDLOG_ACTIVE_LEVEL > 1
@ -73,12 +80,19 @@ extern py::object kp_debug, kp_info, kp_warning, kp_error;
#define KP_LOG_INFO(...) #define KP_LOG_INFO(...)
#else #else
#if defined(VK_USE_PLATFORM_ANDROID_KHR) #if defined(VK_USE_PLATFORM_ANDROID_KHR)
#define KP_LOG_INFO(...) \ #define KP_LOG_INFO(...) \
((void)__android_log_print(ANDROID_LOG_INFO, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__))) ((void)__android_log_print( \
ANDROID_LOG_INFO, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__)))
#elif defined(KOMPUTE_BUILD_PYTHON) #elif defined(KOMPUTE_BUILD_PYTHON)
#define KP_LOG_INFO(...) kp_info(fmt::format(__VA_ARGS__)) #define KP_LOG_INFO(...) kp_info(fmt::format(__VA_ARGS__))
#else #else
#define KP_LOG_INFO(...) fmt::print("[{} {}] [debug] [{}:{}] {}\n", __DATE__, __TIME__, __FILE__, __LINE__, fmt::format(__VA_ARGS__)) #define KP_LOG_INFO(...) \
fmt::print("[{} {}] [debug] [{}:{}] {}\n", \
__DATE__, \
__TIME__, \
__FILE__, \
__LINE__, \
fmt::format(__VA_ARGS__))
#endif // VK_USE_PLATFORM_ANDROID_KHR #endif // VK_USE_PLATFORM_ANDROID_KHR
#endif // SPDLOG_ACTIVE_LEVEL > 2 #endif // SPDLOG_ACTIVE_LEVEL > 2
@ -86,12 +100,19 @@ extern py::object kp_debug, kp_info, kp_warning, kp_error;
#define KP_LOG_WARN(...) #define KP_LOG_WARN(...)
#else #else
#if defined(VK_USE_PLATFORM_ANDROID_KHR) #if defined(VK_USE_PLATFORM_ANDROID_KHR)
#define KP_LOG_WARN(...) \ #define KP_LOG_WARN(...) \
((void)__android_log_print(ANDROID_LOG_WARN, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__))) ((void)__android_log_print( \
ANDROID_LOG_WARN, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__)))
#elif defined(KOMPUTE_BUILD_PYTHON) #elif defined(KOMPUTE_BUILD_PYTHON)
#define KP_LOG_WARN(...) kp_warning(fmt::format(__VA_ARGS__)) #define KP_LOG_WARN(...) kp_warning(fmt::format(__VA_ARGS__))
#else #else
#define KP_LOG_WARN(...) fmt::print("[{} {}] [debug] [{}:{}] {}\n", __DATE__, __TIME__, __FILE__, __LINE__, fmt::format(__VA_ARGS__)) #define KP_LOG_WARN(...) \
fmt::print("[{} {}] [debug] [{}:{}] {}\n", \
__DATE__, \
__TIME__, \
__FILE__, \
__LINE__, \
fmt::format(__VA_ARGS__))
#endif // VK_USE_PLATFORM_ANDROID_KHR #endif // VK_USE_PLATFORM_ANDROID_KHR
#endif // SPDLOG_ACTIVE_LEVEL > 3 #endif // SPDLOG_ACTIVE_LEVEL > 3
@ -99,12 +120,19 @@ extern py::object kp_debug, kp_info, kp_warning, kp_error;
#define KP_LOG_ERROR(...) #define KP_LOG_ERROR(...)
#else #else
#if defined(VK_USE_PLATFORM_ANDROID_KHR) #if defined(VK_USE_PLATFORM_ANDROID_KHR)
#define KP_LOG_ERROR(...) \ #define KP_LOG_ERROR(...) \
((void)__android_log_print(ANDROID_LOG_ERROR, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__))) ((void)__android_log_print( \
ANDROID_LOG_ERROR, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__)))
#elif defined(KOMPUTE_BUILD_PYTHON) #elif defined(KOMPUTE_BUILD_PYTHON)
#define KP_LOG_ERROR(...) kp_error(fmt::format(__VA_ARGS__)) #define KP_LOG_ERROR(...) kp_error(fmt::format(__VA_ARGS__))
#else #else
#define KP_LOG_ERROR(...) fmt::print("[{} {}] [debug] [{}:{}] {}\n", __DATE__, __TIME__, __FILE__, __LINE__, fmt::format(__VA_ARGS__)) #define KP_LOG_ERROR(...) \
fmt::print("[{} {}] [debug] [{}:{}] {}\n", \
__DATE__, \
__TIME__, \
__FILE__, \
__LINE__, \
fmt::format(__VA_ARGS__))
#endif // VK_USE_PLATFORM_ANDROID_KHR #endif // VK_USE_PLATFORM_ANDROID_KHR
#endif // SPDLOG_ACTIVE_LEVEL > 4 #endif // SPDLOG_ACTIVE_LEVEL > 4
#endif // KOMPUTE_SPDLOG_ENABLED #endif // KOMPUTE_SPDLOG_ENABLED

View file

@ -84,10 +84,10 @@ class Manager
Tensor::TensorTypes tensorType = Tensor::TensorTypes::eDevice); Tensor::TensorTypes tensorType = Tensor::TensorTypes::eDevice);
std::shared_ptr<Algorithm> algorithm( std::shared_ptr<Algorithm> algorithm(
const std::vector<std::shared_ptr<Tensor>>& tensors = {}, const std::vector<std::shared_ptr<Tensor>>& tensors = {},
const std::vector<uint32_t>& spirv = {}, const std::vector<uint32_t>& spirv = {},
const Workgroup& workgroup = {}, const Workgroup& workgroup = {},
const Constants& specializationConstants = {}); const Constants& specializationConstants = {});
void destroy(); void destroy();
void clear(); void clear();
@ -119,7 +119,8 @@ class Manager
// Create functions // Create functions
void createInstance(); void createInstance();
void createDevice(const std::vector<uint32_t>& familyQueueIndices = {}, uint32_t hysicalDeviceIndex = 0); void createDevice(const std::vector<uint32_t>& familyQueueIndices = {},
uint32_t hysicalDeviceIndex = 0);
}; };
} // End namespace kp } // End namespace kp

View file

@ -9,7 +9,7 @@ namespace kp {
/** /**
* Container of operations that can be sent to GPU as batch * Container of operations that can be sent to GPU as batch
*/ */
class Sequence: public std::enable_shared_from_this<Sequence> class Sequence : public std::enable_shared_from_this<Sequence>
{ {
public: public:
/** /**
@ -46,8 +46,9 @@ class Sequence: public std::enable_shared_from_this<Sequence>
* which allows for extensible configurations on initialisation. * which allows for extensible configurations on initialisation.
*/ */
template<typename T, typename... TArgs> template<typename T, typename... TArgs>
std::shared_ptr<Sequence> std::shared_ptr<Sequence> record(
record(std::vector<std::shared_ptr<Tensor>> tensors, TArgs&&... params) std::vector<std::shared_ptr<Tensor>> tensors,
TArgs&&... params)
{ {
KP_LOG_DEBUG("Kompute Sequence record function started"); KP_LOG_DEBUG("Kompute Sequence record function started");
@ -56,14 +57,13 @@ class Sequence: public std::enable_shared_from_this<Sequence>
"OpBase derived classes"); "OpBase derived classes");
KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance"); KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance");
std::shared_ptr<T> op{ std::shared_ptr<T> op{ new T(tensors, std::forward<TArgs>(params)...) };
new T(tensors, std::forward<TArgs>(params)...) };
return this->record(op); return this->record(op);
} }
template<typename T, typename... TArgs> template<typename T, typename... TArgs>
std::shared_ptr<Sequence> std::shared_ptr<Sequence> record(std::shared_ptr<Algorithm> algorithm,
record(std::shared_ptr<Algorithm> algorithm, TArgs&&... params) TArgs&&... params)
{ {
KP_LOG_DEBUG("Kompute Sequence record function started"); KP_LOG_DEBUG("Kompute Sequence record function started");
@ -72,8 +72,8 @@ class Sequence: public std::enable_shared_from_this<Sequence>
"OpBase derived classes"); "OpBase derived classes");
KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance"); KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance");
std::shared_ptr<T> op{ std::shared_ptr<T> op{ new T(algorithm,
new T(algorithm, std::forward<TArgs>(params)...) }; std::forward<TArgs>(params)...) };
return this->record(op); return this->record(op);
} }
@ -96,8 +96,8 @@ class Sequence: public std::enable_shared_from_this<Sequence>
*/ */
// TODO: Aim to have only a single function with tensors/algorithm // TODO: Aim to have only a single function with tensors/algorithm
template<typename T, typename... TArgs> template<typename T, typename... TArgs>
std::shared_ptr<Sequence> std::shared_ptr<Sequence> eval(std::vector<std::shared_ptr<Tensor>> tensors,
eval(std::vector<std::shared_ptr<Tensor>> tensors, TArgs&&... params) TArgs&&... params)
{ {
KP_LOG_DEBUG("Kompute Sequence record function started"); KP_LOG_DEBUG("Kompute Sequence record function started");
@ -106,16 +106,16 @@ class Sequence: public std::enable_shared_from_this<Sequence>
"OpBase derived classes"); "OpBase derived classes");
KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance"); KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance");
std::shared_ptr<T> op{ std::shared_ptr<T> op{ new T(tensors, std::forward<TArgs>(params)...) };
new T(tensors, std::forward<TArgs>(params)...) };
// TODO: Aim to be able to handle errors when returning without throw except // TODO: Aim to be able to handle errors when returning without throw
// except
return this->eval(op); return this->eval(op);
} }
// Needded as otherise can't use initialiser list // Needded as otherise can't use initialiser list
template<typename T, typename... TArgs> template<typename T, typename... TArgs>
std::shared_ptr<Sequence> std::shared_ptr<Sequence> eval(std::shared_ptr<Algorithm> algorithm,
eval(std::shared_ptr<Algorithm> algorithm, TArgs&&... params) TArgs&&... params)
{ {
KP_LOG_DEBUG("Kompute Sequence record function started"); KP_LOG_DEBUG("Kompute Sequence record function started");
@ -124,8 +124,8 @@ class Sequence: public std::enable_shared_from_this<Sequence>
"OpBase derived classes"); "OpBase derived classes");
KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance"); KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance");
std::shared_ptr<T> op{ std::shared_ptr<T> op{ new T(algorithm,
new T(algorithm, std::forward<TArgs>(params)...) }; std::forward<TArgs>(params)...) };
return this->eval(op); return this->eval(op);
} }
@ -147,8 +147,9 @@ class Sequence: public std::enable_shared_from_this<Sequence>
* @return shared_ptr<Sequence> of the Sequence class itself * @return shared_ptr<Sequence> of the Sequence class itself
*/ */
template<typename T, typename... TArgs> template<typename T, typename... TArgs>
std::shared_ptr<Sequence> std::shared_ptr<Sequence> evalAsync(
evalAsync(std::vector<std::shared_ptr<Tensor>> tensors, TArgs&&... params) std::vector<std::shared_ptr<Tensor>> tensors,
TArgs&&... params)
{ {
KP_LOG_DEBUG("Kompute Sequence record function started"); KP_LOG_DEBUG("Kompute Sequence record function started");
@ -157,15 +158,14 @@ class Sequence: public std::enable_shared_from_this<Sequence>
"OpBase derived classes"); "OpBase derived classes");
KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance"); KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance");
std::shared_ptr<T> op{ std::shared_ptr<T> op{ new T(tensors, std::forward<TArgs>(params)...) };
new T(tensors, std::forward<TArgs>(params)...) };
return this->evalAsync(op); return this->evalAsync(op);
} }
// Needed as otherwise it's not possible to use initializer lists // Needed as otherwise it's not possible to use initializer lists
template<typename T, typename... TArgs> template<typename T, typename... TArgs>
std::shared_ptr<Sequence> std::shared_ptr<Sequence> evalAsync(std::shared_ptr<Algorithm> algorithm,
evalAsync(std::shared_ptr<Algorithm> algorithm, TArgs&&... params) TArgs&&... params)
{ {
KP_LOG_DEBUG("Kompute Sequence record function started"); KP_LOG_DEBUG("Kompute Sequence record function started");
@ -174,8 +174,8 @@ class Sequence: public std::enable_shared_from_this<Sequence>
"OpBase derived classes"); "OpBase derived classes");
KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance"); KP_LOG_DEBUG("Kompute Sequence creating OpBase derived class instance");
std::shared_ptr<T> op{ std::shared_ptr<T> op{ new T(algorithm,
new T(algorithm, std::forward<TArgs>(params)...) }; std::forward<TArgs>(params)...) };
return this->evalAsync(op); return this->evalAsync(op);
} }
@ -190,7 +190,8 @@ class Sequence: public std::enable_shared_from_this<Sequence>
std::shared_ptr<Sequence> evalAwait(uint64_t waitFor = UINT64_MAX); std::shared_ptr<Sequence> evalAwait(uint64_t waitFor = UINT64_MAX);
/** /**
* Clear function clears all operations currently recorded and starts recording again. * Clear function clears all operations currently recorded and starts
* recording again.
*/ */
void clear(); void clear();
@ -217,7 +218,6 @@ class Sequence: public std::enable_shared_from_this<Sequence>
*/ */
bool isRecording(); bool isRecording();
bool isInit(); bool isInit();
/** /**

View file

@ -4,9 +4,9 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <SPIRV/GlslangToSpv.h>
#include <glslang/Include/ResourceLimits.h> #include <glslang/Include/ResourceLimits.h>
#include <glslang/Public/ShaderLang.h> #include <glslang/Public/ShaderLang.h>
#include <SPIRV/GlslangToSpv.h>
#include "kompute/Core.hpp" #include "kompute/Core.hpp"
@ -16,117 +16,120 @@ namespace kp {
// Has been adobted by: // Has been adobted by:
// https://github.com/KhronosGroup/glslang/blob/master/StandAlone/ResourceLimits.cpp // https://github.com/KhronosGroup/glslang/blob/master/StandAlone/ResourceLimits.cpp
const TBuiltInResource defaultResource = { const TBuiltInResource defaultResource = {
/* .MaxLights = */ 0, /* .MaxLights = */ 0,
/* .MaxClipPlanes = */ 0, /* .MaxClipPlanes = */ 0,
/* .MaxTextureUnits = */ 0, /* .MaxTextureUnits = */ 0,
/* .MaxTextureCoords = */ 0, /* .MaxTextureCoords = */ 0,
/* .MaxVertexAttribs = */ 64, /* .MaxVertexAttribs = */ 64,
/* .MaxVertexUniformComponents = */ 4096, /* .MaxVertexUniformComponents = */ 4096,
/* .MaxVaryingFloats = */ 64, /* .MaxVaryingFloats = */ 64,
/* .MaxVertexTextureImageUnits = */ 0, /* .MaxVertexTextureImageUnits = */ 0,
/* .MaxCombinedTextureImageUnits = */ 0, /* .MaxCombinedTextureImageUnits = */ 0,
/* .MaxTextureImageUnits = */ 0, /* .MaxTextureImageUnits = */ 0,
/* .MaxFragmentUniformComponents = */ 0, /* .MaxFragmentUniformComponents = */ 0,
/* .MaxDrawBuffers = */ 0, /* .MaxDrawBuffers = */ 0,
/* .MaxVertexUniformVectors = */ 128, /* .MaxVertexUniformVectors = */ 128,
/* .MaxVaryingVectors = */ 8, /* .MaxVaryingVectors = */ 8,
/* .MaxFragmentUniformVectors = */ 0, /* .MaxFragmentUniformVectors = */ 0,
/* .MaxVertexOutputVectors = */ 16, /* .MaxVertexOutputVectors = */ 16,
/* .MaxFragmentInputVectors = */ 0, /* .MaxFragmentInputVectors = */ 0,
/* .MinProgramTexelOffset = */ -8, /* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7, /* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8, /* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535, /* .MaxComputeWorkGroupCountX = */ 65535,
/* .MaxComputeWorkGroupCountY = */ 65535, /* .MaxComputeWorkGroupCountY = */ 65535,
/* .MaxComputeWorkGroupCountZ = */ 65535, /* .MaxComputeWorkGroupCountZ = */ 65535,
/* .MaxComputeWorkGroupSizeX = */ 1024, /* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024, /* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64, /* .MaxComputeWorkGroupSizeZ = */ 64,
/* .MaxComputeUniformComponents = */ 1024, /* .MaxComputeUniformComponents = */ 1024,
/* .MaxComputeTextureImageUnits = */ 16, /* .MaxComputeTextureImageUnits = */ 16,
/* .MaxComputeImageUniforms = */ 8, /* .MaxComputeImageUniforms = */ 8,
/* .MaxComputeAtomicCounters = */ 8, /* .MaxComputeAtomicCounters = */ 8,
/* .MaxComputeAtomicCounterBuffers = */ 1, /* .MaxComputeAtomicCounterBuffers = */ 1,
/* .MaxVaryingComponents = */ 60, /* .MaxVaryingComponents = */ 60,
/* .MaxVertexOutputComponents = */ 64, /* .MaxVertexOutputComponents = */ 64,
/* .MaxGeometryInputComponents = */ 64, /* .MaxGeometryInputComponents = */ 64,
/* .MaxGeometryOutputComponents = */ 128, /* .MaxGeometryOutputComponents = */ 128,
/* .MaxFragmentInputComponents = */ 0, /* .MaxFragmentInputComponents = */ 0,
/* .MaxImageUnits = */ 0, /* .MaxImageUnits = */ 0,
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 0, /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 0,
/* .MaxCombinedShaderOutputResources = */ 8, /* .MaxCombinedShaderOutputResources = */ 8,
/* .MaxImageSamples = */ 0, /* .MaxImageSamples = */ 0,
/* .MaxVertexImageUniforms = */ 0, /* .MaxVertexImageUniforms = */ 0,
/* .MaxTessControlImageUniforms = */ 0, /* .MaxTessControlImageUniforms = */ 0,
/* .MaxTessEvaluationImageUniforms = */ 0, /* .MaxTessEvaluationImageUniforms = */ 0,
/* .MaxGeometryImageUniforms = */ 0, /* .MaxGeometryImageUniforms = */ 0,
/* .MaxFragmentImageUniforms = */ 0, /* .MaxFragmentImageUniforms = */ 0,
/* .MaxCombinedImageUniforms = */ 0, /* .MaxCombinedImageUniforms = */ 0,
/* .MaxGeometryTextureImageUnits = */ 0, /* .MaxGeometryTextureImageUnits = */ 0,
/* .MaxGeometryOutputVertices = */ 256, /* .MaxGeometryOutputVertices = */ 256,
/* .MaxGeometryTotalOutputComponents = */ 1024, /* .MaxGeometryTotalOutputComponents = */ 1024,
/* .MaxGeometryUniformComponents = */ 1024, /* .MaxGeometryUniformComponents = */ 1024,
/* .MaxGeometryVaryingComponents = */ 64, /* .MaxGeometryVaryingComponents = */ 64,
/* .MaxTessControlInputComponents = */ 128, /* .MaxTessControlInputComponents = */ 128,
/* .MaxTessControlOutputComponents = */ 128, /* .MaxTessControlOutputComponents = */ 128,
/* .MaxTessControlTextureImageUnits = */ 0, /* .MaxTessControlTextureImageUnits = */ 0,
/* .MaxTessControlUniformComponents = */ 1024, /* .MaxTessControlUniformComponents = */ 1024,
/* .MaxTessControlTotalOutputComponents = */ 4096, /* .MaxTessControlTotalOutputComponents = */ 4096,
/* .MaxTessEvaluationInputComponents = */ 128, /* .MaxTessEvaluationInputComponents = */ 128,
/* .MaxTessEvaluationOutputComponents = */ 128, /* .MaxTessEvaluationOutputComponents = */ 128,
/* .MaxTessEvaluationTextureImageUnits = */ 16, /* .MaxTessEvaluationTextureImageUnits = */ 16,
/* .MaxTessEvaluationUniformComponents = */ 1024, /* .MaxTessEvaluationUniformComponents = */ 1024,
/* .MaxTessPatchComponents = */ 120, /* .MaxTessPatchComponents = */ 120,
/* .MaxPatchVertices = */ 32, /* .MaxPatchVertices = */ 32,
/* .MaxTessGenLevel = */ 64, /* .MaxTessGenLevel = */ 64,
/* .MaxViewports = */ 16, /* .MaxViewports = */ 16,
/* .MaxVertexAtomicCounters = */ 0, /* .MaxVertexAtomicCounters = */ 0,
/* .MaxTessControlAtomicCounters = */ 0, /* .MaxTessControlAtomicCounters = */ 0,
/* .MaxTessEvaluationAtomicCounters = */ 0, /* .MaxTessEvaluationAtomicCounters = */ 0,
/* .MaxGeometryAtomicCounters = */ 0, /* .MaxGeometryAtomicCounters = */ 0,
/* .MaxFragmentAtomicCounters = */ 0, /* .MaxFragmentAtomicCounters = */ 0,
/* .MaxCombinedAtomicCounters = */ 8, /* .MaxCombinedAtomicCounters = */ 8,
/* .MaxAtomicCounterBindings = */ 1, /* .MaxAtomicCounterBindings = */ 1,
/* .MaxVertexAtomicCounterBuffers = */ 0, /* .MaxVertexAtomicCounterBuffers = */ 0,
/* .MaxTessControlAtomicCounterBuffers = */ 0, /* .MaxTessControlAtomicCounterBuffers = */ 0,
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0, /* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
/* .MaxGeometryAtomicCounterBuffers = */ 0, /* .MaxGeometryAtomicCounterBuffers = */ 0,
/* .MaxFragmentAtomicCounterBuffers = */ 0, /* .MaxFragmentAtomicCounterBuffers = */ 0,
/* .MaxCombinedAtomicCounterBuffers = */ 1, /* .MaxCombinedAtomicCounterBuffers = */ 1,
/* .MaxAtomicCounterBufferSize = */ 16384, /* .MaxAtomicCounterBufferSize = */ 16384,
/* .MaxTransformFeedbackBuffers = */ 4, /* .MaxTransformFeedbackBuffers = */ 4,
/* .MaxTransformFeedbackInterleavedComponents = */ 64, /* .MaxTransformFeedbackInterleavedComponents = */ 64,
/* .MaxCullDistances = */ 8, /* .MaxCullDistances = */ 8,
/* .MaxCombinedClipAndCullDistances = */ 8, /* .MaxCombinedClipAndCullDistances = */ 8,
/* .MaxSamples = */ 4, /* .MaxSamples = */ 4,
/* .maxMeshOutputVerticesNV = */ 256, /* .maxMeshOutputVerticesNV = */ 256,
/* .maxMeshOutputPrimitivesNV = */ 512, /* .maxMeshOutputPrimitivesNV = */ 512,
/* .maxMeshWorkGroupSizeX_NV = */ 32, /* .maxMeshWorkGroupSizeX_NV = */ 32,
/* .maxMeshWorkGroupSizeY_NV = */ 1, /* .maxMeshWorkGroupSizeY_NV = */ 1,
/* .maxMeshWorkGroupSizeZ_NV = */ 1, /* .maxMeshWorkGroupSizeZ_NV = */ 1,
/* .maxTaskWorkGroupSizeX_NV = */ 32, /* .maxTaskWorkGroupSizeX_NV = */ 32,
/* .maxTaskWorkGroupSizeY_NV = */ 1, /* .maxTaskWorkGroupSizeY_NV = */ 1,
/* .maxTaskWorkGroupSizeZ_NV = */ 1, /* .maxTaskWorkGroupSizeZ_NV = */ 1,
/* .maxMeshViewCountNV = */ 4, /* .maxMeshViewCountNV = */ 4,
/* .maxDualSourceDrawBuffersEXT = */ 1, /* .maxDualSourceDrawBuffersEXT = */ 1,
/* .limits = */ { /* .limits = */
/* .nonInductiveForLoops = */ 1, {
/* .whileLoops = */ 1, /* .nonInductiveForLoops = */ 1,
/* .doWhileLoops = */ 1, /* .whileLoops = */ 1,
/* .generalUniformIndexing = */ 1, /* .doWhileLoops = */ 1,
/* .generalAttributeMatrixVectorIndexing = */ 1, /* .generalUniformIndexing = */ 1,
/* .generalVaryingIndexing = */ 1, /* .generalAttributeMatrixVectorIndexing = */ 1,
/* .generalSamplerIndexing = */ 1, /* .generalVaryingIndexing = */ 1,
/* .generalVariableIndexing = */ 1, /* .generalSamplerIndexing = */ 1,
/* .generalConstantMatrixVectorIndexing = */ 1, /* .generalVariableIndexing = */ 1,
}}; /* .generalConstantMatrixVectorIndexing = */ 1,
}
};
/** /**
Shader utily class with functions to compile and process glsl files. Shader utily class with functions to compile and process glsl files.
*/ */
class Shader { class Shader
public: {
public:
/** /**
* Compile multiple sources with optional filenames. Currently this function * Compile multiple sources with optional filenames. Currently this function
* uses the glslang C++ interface which is not thread safe so this funciton * uses the glslang C++ interface which is not thread safe so this funciton
@ -138,39 +141,37 @@ public:
* @param files A list of file names respective to each of the sources * @param files A list of file names respective to each of the sources
* @param entryPoint The function name to use as entry point * @param entryPoint The function name to use as entry point
* @param definitions List of pairs containing key value definitions * @param definitions List of pairs containing key value definitions
* @param resourcesLimit A list that contains the resource limits for the GLSL compiler * @param resourcesLimit A list that contains the resource limits for the
* GLSL compiler
* @return The compiled SPIR-V binary in unsigned int32 format * @return The compiled SPIR-V binary in unsigned int32 format
*/ */
static std::vector<uint32_t> compile_sources( static std::vector<uint32_t> compile_sources(
const std::vector<std::string>& sources, const std::vector<std::string>& sources,
const std::vector<std::string>& files = {}, const std::vector<std::string>& files = {},
const std::string& entryPoint = "main", const std::string& entryPoint = "main",
std::vector<std::pair<std::string,std::string>> definitions = {}, std::vector<std::pair<std::string, std::string>> definitions = {},
const TBuiltInResource& resources = defaultResource); const TBuiltInResource& resources = defaultResource);
/** /**
* Compile a single glslang source from string value. Currently this function * Compile a single glslang source from string value. Currently this
* uses the glslang C++ interface which is not thread safe so this funciton * function uses the glslang C++ interface which is not thread safe so this
* should not be called from multiple threads concurrently. If you have a * funciton should not be called from multiple threads concurrently. If you
* online shader processing multithreading use-case that can't use offline * have a online shader processing multithreading use-case that can't use
* compilation please open an issue. * offline compilation please open an issue.
* *
* @param source An individual raw glsl shader in string format * @param source An individual raw glsl shader in string format
* @param entryPoint The function name to use as entry point * @param entryPoint The function name to use as entry point
* @param definitions List of pairs containing key value definitions * @param definitions List of pairs containing key value definitions
* @param resourcesLimit A list that contains the resource limits for the GLSL compiler * @param resourcesLimit A list that contains the resource limits for the
* GLSL compiler
* @return The compiled SPIR-V binary in unsigned int32 format * @return The compiled SPIR-V binary in unsigned int32 format
*/ */
static std::vector<uint32_t> compile_source( static std::vector<uint32_t> compile_source(
const std::string& source, const std::string& source,
const std::string& entryPoint = "main", const std::string& entryPoint = "main",
std::vector<std::pair<std::string,std::string>> definitions = {}, std::vector<std::pair<std::string, std::string>> definitions = {},
const TBuiltInResource& resources = defaultResource); const TBuiltInResource& resources = defaultResource);
}; };
} }
#endif // DKOMPUTE_DISABLE_SHADER_UTILS #endif // DKOMPUTE_DISABLE_SHADER_UTILS

View file

@ -54,7 +54,7 @@ class Tensor
* otherwise there is no need to copy from host memory. * otherwise there is no need to copy from host memory.
*/ */
void rebuild(const std::vector<float>& data, void rebuild(const std::vector<float>& data,
TensorTypes tensorType = TensorTypes::eDevice); TensorTypes tensorType = TensorTypes::eDevice);
/** /**
* Destroys and frees the GPU resources which include the buffer and memory. * Destroys and frees the GPU resources which include the buffer and memory.
@ -125,9 +125,8 @@ class Tensor
* @param createBarrier Whether to create a barrier that ensures the data is * @param createBarrier Whether to create a barrier that ensures the data is
* copied before further operations. Default is true. * copied before further operations. Default is true.
*/ */
void recordCopyFromStagingToDevice( void recordCopyFromStagingToDevice(const vk::CommandBuffer& commandBuffer,
const vk::CommandBuffer& commandBuffer, bool createBarrier);
bool createBarrier);
/** /**
* Records a copy from the internal device memory to the staging memory * Records a copy from the internal device memory to the staging memory
@ -138,9 +137,8 @@ class Tensor
* @param createBarrier Whether to create a barrier that ensures the data is * @param createBarrier Whether to create a barrier that ensures the data is
* copied before further operations. Default is true. * copied before further operations. Default is true.
*/ */
void recordCopyFromDeviceToStaging( void recordCopyFromDeviceToStaging(const vk::CommandBuffer& commandBuffer,
const vk::CommandBuffer& commandBuffer, bool createBarrier);
bool createBarrier);
/** /**
* Records the buffer memory barrier into the command buffer which * Records the buffer memory barrier into the command buffer which
@ -152,12 +150,11 @@ class Tensor
* @param scrStageMask Pipeline stage flags for source stage mask * @param scrStageMask Pipeline stage flags for source stage mask
* @param dstStageMask Pipeline stage flags for destination stage mask * @param dstStageMask Pipeline stage flags for destination stage mask
*/ */
void recordBufferMemoryBarrier( void recordBufferMemoryBarrier(const vk::CommandBuffer& commandBuffer,
const vk::CommandBuffer& commandBuffer, vk::AccessFlagBits srcAccessMask,
vk::AccessFlagBits srcAccessMask, vk::AccessFlagBits dstAccessMask,
vk::AccessFlagBits dstAccessMask, vk::PipelineStageFlagBits srcStageMask,
vk::PipelineStageFlagBits srcStageMask, vk::PipelineStageFlagBits dstStageMask);
vk::PipelineStageFlagBits dstStageMask);
/** /**
* Constructs a vulkan descriptor buffer info which can be used to specify * Constructs a vulkan descriptor buffer info which can be used to specify
@ -205,11 +202,11 @@ class Tensor
std::shared_ptr<vk::DeviceMemory> memory, std::shared_ptr<vk::DeviceMemory> memory,
vk::MemoryPropertyFlags memoryPropertyFlags); vk::MemoryPropertyFlags memoryPropertyFlags);
void recordCopyBuffer(const vk::CommandBuffer& commandBuffer, void recordCopyBuffer(const vk::CommandBuffer& commandBuffer,
std::shared_ptr<vk::Buffer> bufferFrom, std::shared_ptr<vk::Buffer> bufferFrom,
std::shared_ptr<vk::Buffer> bufferTo, std::shared_ptr<vk::Buffer> bufferTo,
vk::DeviceSize bufferSize, vk::DeviceSize bufferSize,
vk::BufferCopy copyRegion, vk::BufferCopy copyRegion,
bool createBarrier); bool createBarrier);
// Private util functions // Private util functions
vk::BufferUsageFlags getPrimaryBufferUsageFlags(); vk::BufferUsageFlags getPrimaryBufferUsageFlags();

View file

@ -84,7 +84,7 @@ TEST(TestAsyncOperations, TestManagerParallelExecution)
for (uint32_t i = 0; i < numParallel; i++) { for (uint32_t i = 0; i < numParallel; i++) {
inputsAsyncB.push_back(mgr.tensor(data)); inputsAsyncB.push_back(mgr.tensor(data));
algosAsync.push_back(mgr.algorithm({inputsAsyncB[i]}, spirv)); algosAsync.push_back(mgr.algorithm({ inputsAsyncB[i] }, spirv));
} }
std::vector<std::shared_ptr<kp::Sequence>> sqs; std::vector<std::shared_ptr<kp::Sequence>> sqs;
@ -160,8 +160,8 @@ TEST(TestAsyncOperations, TestManagerAsyncExecution)
sq1->eval<kp::OpTensorSyncLocal>({ tensorA, tensorB }); sq1->eval<kp::OpTensorSyncLocal>({ tensorA, tensorB });
std::shared_ptr<kp::Algorithm> algo1 = mgr.algorithm({tensorA}, spirv); std::shared_ptr<kp::Algorithm> algo1 = mgr.algorithm({ tensorA }, spirv);
std::shared_ptr<kp::Algorithm> algo2 = mgr.algorithm({tensorB}, spirv); std::shared_ptr<kp::Algorithm> algo2 = mgr.algorithm({ tensorB }, spirv);
sq1->evalAsync<kp::OpAlgoDispatch>(algo1); sq1->evalAsync<kp::OpAlgoDispatch>(algo1);
sq2->evalAsync<kp::OpAlgoDispatch>(algo2); sq2->evalAsync<kp::OpAlgoDispatch>(algo2);

View file

@ -27,12 +27,12 @@ TEST(TestDestroy, TestDestroyTensorSingle)
tensorA = mgr.tensor({ 0, 0, 0 }); tensorA = mgr.tensor({ 0, 0, 0 });
std::shared_ptr<kp::Algorithm> algo = std::shared_ptr<kp::Algorithm> algo =
mgr.algorithm({ tensorA }, spirv); mgr.algorithm({ tensorA }, spirv);
mgr.sequence() mgr.sequence()
->record<kp::OpAlgoDispatch>(algo) ->record<kp::OpAlgoDispatch>(algo)
->eval() ->eval()
->eval<kp::OpTensorSyncLocal>(algo->getTensors()); ->eval<kp::OpTensorSyncLocal>(algo->getTensors());
tensorA->destroy(); tensorA->destroy();
EXPECT_FALSE(tensorA->isInit()); EXPECT_FALSE(tensorA->isInit());
@ -69,13 +69,13 @@ TEST(TestDestroy, TestDestroyTensorVector)
tensorB = mgr.tensor({ 1, 1, 1 }); tensorB = mgr.tensor({ 1, 1, 1 });
std::shared_ptr<kp::Algorithm> algo = std::shared_ptr<kp::Algorithm> algo =
mgr.algorithm({tensorA, tensorB}, spirv); mgr.algorithm({ tensorA, tensorB }, spirv);
mgr.sequence() mgr.sequence()
->record<kp::OpTensorSyncDevice>(algo->getTensors()) ->record<kp::OpTensorSyncDevice>(algo->getTensors())
->record<kp::OpAlgoDispatch>(algo) ->record<kp::OpAlgoDispatch>(algo)
->record<kp::OpTensorSyncLocal>(algo->getTensors()) ->record<kp::OpTensorSyncLocal>(algo->getTensors())
->eval(); ->eval();
tensorA->destroy(); tensorA->destroy();
tensorB->destroy(); tensorB->destroy();
@ -109,12 +109,13 @@ TEST(TestDestroy, TestDestroySequenceSingle)
{ {
kp::Manager mgr; kp::Manager mgr;
tensorA = mgr.tensor({0, 0, 0}); tensorA = mgr.tensor({ 0, 0, 0 });
sq = mgr.sequence() sq =
->record<kp::OpTensorSyncDevice>({tensorA}) mgr.sequence()
->record<kp::OpAlgoDispatch>(mgr.algorithm({tensorA}, spirv)) ->record<kp::OpTensorSyncDevice>({ tensorA })
->record<kp::OpTensorSyncLocal>({tensorA}) ->record<kp::OpAlgoDispatch>(mgr.algorithm({ tensorA }, spirv))
->record<kp::OpTensorSyncLocal>({ tensorA })
->eval(); ->eval();
sq->destroy(); sq->destroy();
@ -124,4 +125,3 @@ TEST(TestDestroy, TestDestroySequenceSingle)
} }
EXPECT_EQ(tensorA->data(), std::vector<float>({ 1, 1, 1 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 1, 1, 1 }));
} }

View file

@ -29,24 +29,27 @@ TEST(TestLogisticRegression, TestMainLogisticRegression)
std::shared_ptr<kp::Tensor> lOut = mgr.tensor({ 0, 0, 0, 0, 0 }); std::shared_ptr<kp::Tensor> lOut = mgr.tensor({ 0, 0, 0, 0, 0 });
std::vector<std::shared_ptr<kp::Tensor>> params = { xI, xJ, y, std::vector<std::shared_ptr<kp::Tensor>> params = { xI, xJ, y,
wIn, wOutI, wOutJ, wIn, wOutI, wOutJ,
bIn, bOut, lOut }; bIn, bOut, lOut };
mgr.sequence()->eval<kp::OpTensorSyncDevice>(params); mgr.sequence()->eval<kp::OpTensorSyncDevice>(params);
std::vector<uint32_t> spirv = std::vector<uint32_t>( std::vector<uint32_t> spirv = std::vector<uint32_t>(
(uint32_t*)kp::shader_data::test_shaders_glsl_test_logistic_regression_comp_spv, (uint32_t*)kp::shader_data::
(uint32_t*)(kp::shader_data::test_shaders_glsl_test_logistic_regression_comp_spv + test_shaders_glsl_test_logistic_regression_comp_spv,
kp::shader_data::test_shaders_glsl_test_logistic_regression_comp_spv_len)); (uint32_t*)(kp::shader_data::
test_shaders_glsl_test_logistic_regression_comp_spv +
kp::shader_data::
test_shaders_glsl_test_logistic_regression_comp_spv_len));
std::shared_ptr<kp::Algorithm> algorithm = std::shared_ptr<kp::Algorithm> algorithm = mgr.algorithm(
mgr.algorithm(params, spirv, kp::Workgroup({5}), kp::Constants({5.0})); params, spirv, kp::Workgroup({ 5 }), kp::Constants({ 5.0 }));
std::shared_ptr<kp::Sequence> sq = std::shared_ptr<kp::Sequence> sq =
mgr.sequence() mgr.sequence()
->record<kp::OpTensorSyncDevice>({ wIn, bIn }) ->record<kp::OpTensorSyncDevice>({ wIn, bIn })
->record<kp::OpAlgoDispatch>(algorithm) ->record<kp::OpAlgoDispatch>(algorithm)
->record<kp::OpTensorSyncLocal>({ wOutI, wOutJ, bOut, lOut }); ->record<kp::OpTensorSyncLocal>({ wOutI, wOutJ, bOut, lOut });
// Iterate across all expected iterations // Iterate across all expected iterations
for (size_t i = 0; i < ITERATIONS; i++) { for (size_t i = 0; i < ITERATIONS; i++) {
@ -90,37 +93,38 @@ TEST(TestLogisticRegression, TestMainLogisticRegressionManualCopy)
std::shared_ptr<kp::Tensor> y = mgr.tensor({ 0, 0, 0, 1, 1 }); std::shared_ptr<kp::Tensor> y = mgr.tensor({ 0, 0, 0, 1, 1 });
std::shared_ptr<kp::Tensor> wIn = mgr.tensor( std::shared_ptr<kp::Tensor> wIn =
{ 0.001, 0.001 }, kp::Tensor::TensorTypes::eHost); mgr.tensor({ 0.001, 0.001 }, kp::Tensor::TensorTypes::eHost);
std::shared_ptr<kp::Tensor> wOutI = mgr.tensor({ 0, 0, 0, 0, 0 }); std::shared_ptr<kp::Tensor> wOutI = mgr.tensor({ 0, 0, 0, 0, 0 });
std::shared_ptr<kp::Tensor> wOutJ = mgr.tensor({ 0, 0, 0, 0, 0 }); std::shared_ptr<kp::Tensor> wOutJ = mgr.tensor({ 0, 0, 0, 0, 0 });
std::shared_ptr<kp::Tensor> bIn = mgr.tensor( std::shared_ptr<kp::Tensor> bIn =
{ 0 }, mgr.tensor({ 0 }, kp::Tensor::TensorTypes::eHost);
kp::Tensor::TensorTypes::eHost);
std::shared_ptr<kp::Tensor> bOut = mgr.tensor({ 0, 0, 0, 0, 0 }); std::shared_ptr<kp::Tensor> bOut = mgr.tensor({ 0, 0, 0, 0, 0 });
std::shared_ptr<kp::Tensor> lOut = mgr.tensor({ 0, 0, 0, 0, 0 }); std::shared_ptr<kp::Tensor> lOut = mgr.tensor({ 0, 0, 0, 0, 0 });
std::vector<std::shared_ptr<kp::Tensor>> params = { xI, xJ, y, std::vector<std::shared_ptr<kp::Tensor>> params = { xI, xJ, y,
wIn, wOutI, wOutJ, wIn, wOutI, wOutJ,
bIn, bOut, lOut }; bIn, bOut, lOut };
mgr.sequence()->record<kp::OpTensorSyncDevice>(params)->eval(); mgr.sequence()->record<kp::OpTensorSyncDevice>(params)->eval();
std::vector<uint32_t> spirv = std::vector<uint32_t>( std::vector<uint32_t> spirv = std::vector<uint32_t>(
(uint32_t*)kp::shader_data::shaders_glsl_logisticregression_comp_spv, (uint32_t*)kp::shader_data::shaders_glsl_logisticregression_comp_spv,
(uint32_t*)(kp::shader_data::shaders_glsl_logisticregression_comp_spv + (uint32_t*)(kp::shader_data::
kp::shader_data::shaders_glsl_logisticregression_comp_spv_len)); shaders_glsl_logisticregression_comp_spv +
kp::shader_data::
shaders_glsl_logisticregression_comp_spv_len));
std::shared_ptr<kp::Algorithm> algorithm = std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm(params, spirv, kp::Workgroup(), kp::Constants({5.0})); mgr.algorithm(params, spirv, kp::Workgroup(), kp::Constants({ 5.0 }));
std::shared_ptr<kp::Sequence> sq = std::shared_ptr<kp::Sequence> sq =
mgr.sequence() mgr.sequence()
->record<kp::OpTensorSyncDevice>({ wIn, bIn }) ->record<kp::OpTensorSyncDevice>({ wIn, bIn })
->record<kp::OpAlgoDispatch>(algorithm) ->record<kp::OpAlgoDispatch>(algorithm)
->record<kp::OpTensorSyncLocal>({ wOutI, wOutJ, bOut, lOut }); ->record<kp::OpTensorSyncLocal>({ wOutI, wOutJ, bOut, lOut });
// Iterate across all expected iterations // Iterate across all expected iterations
for (size_t i = 0; i < ITERATIONS; i++) { for (size_t i = 0; i < ITERATIONS; i++) {
@ -136,18 +140,18 @@ TEST(TestLogisticRegression, TestMainLogisticRegressionManualCopy)
bIn->mapDataIntoHostMemory(); bIn->mapDataIntoHostMemory();
} }
// Based on the inputs the outputs should be at least: // Based on the inputs the outputs should be at least:
// * wi < 0.01 // * wi < 0.01
// * wj > 1.0 // * wj > 1.0
// * b < 0 // * b < 0
// TODO: Add EXPECT_DOUBLE_EQ instead // TODO: Add EXPECT_DOUBLE_EQ instead
EXPECT_LT(wIn->data()[0], 0.01); EXPECT_LT(wIn->data()[0], 0.01);
EXPECT_GT(wIn->data()[1], 1.0); EXPECT_GT(wIn->data()[1], 1.0);
EXPECT_LT(bIn->data()[0], 0.0); EXPECT_LT(bIn->data()[0], 0.0);
KP_LOG_WARN("Result wIn i: {}, wIn j: {}, bIn: {}", KP_LOG_WARN("Result wIn i: {}, wIn j: {}, bIn: {}",
wIn->data()[0], wIn->data()[0],
wIn->data()[1], wIn->data()[1],
bIn->data()[0]); bIn->data()[0]);
} }
} }

View file

@ -11,13 +11,14 @@ TEST(TestManager, EndToEndOpMultEvalFlow)
std::shared_ptr<kp::Tensor> tensorRHS = mgr.tensor({ 2, 4, 6 }); std::shared_ptr<kp::Tensor> tensorRHS = mgr.tensor({ 2, 4, 6 });
std::shared_ptr<kp::Tensor> tensorOutput = mgr.tensor({ 0, 0, 0 }); std::shared_ptr<kp::Tensor> tensorOutput = mgr.tensor({ 0, 0, 0 });
std::vector<std::shared_ptr<kp::Tensor>> params = std::vector<std::shared_ptr<kp::Tensor>> params = { tensorLHS,
{ tensorLHS, tensorRHS, tensorOutput }; tensorRHS,
tensorOutput };
mgr.sequence() mgr.sequence()
->eval<kp::OpTensorSyncDevice>(params) ->eval<kp::OpTensorSyncDevice>(params)
->eval<kp::OpMult>(params, mgr.algorithm()) ->eval<kp::OpMult>(params, mgr.algorithm())
->eval<kp::OpTensorSyncLocal>(params); ->eval<kp::OpTensorSyncLocal>(params);
EXPECT_EQ(tensorOutput->data(), std::vector<float>({ 0, 4, 12 })); EXPECT_EQ(tensorOutput->data(), std::vector<float>({ 0, 4, 12 }));
} }
@ -30,14 +31,15 @@ TEST(TestManager, EndToEndOpMultSeqFlow)
std::shared_ptr<kp::Tensor> tensorRHS = mgr.tensor({ 2, 4, 6 }); std::shared_ptr<kp::Tensor> tensorRHS = mgr.tensor({ 2, 4, 6 });
std::shared_ptr<kp::Tensor> tensorOutput = mgr.tensor({ 0, 0, 0 }); std::shared_ptr<kp::Tensor> tensorOutput = mgr.tensor({ 0, 0, 0 });
std::vector<std::shared_ptr<kp::Tensor>> params = std::vector<std::shared_ptr<kp::Tensor>> params = { tensorLHS,
{ tensorLHS, tensorRHS, tensorOutput }; tensorRHS,
tensorOutput };
mgr.sequence() mgr.sequence()
->record<kp::OpTensorSyncDevice>(params) ->record<kp::OpTensorSyncDevice>(params)
->record<kp::OpMult>(params, mgr.algorithm()) ->record<kp::OpMult>(params, mgr.algorithm())
->record<kp::OpTensorSyncLocal>(params) ->record<kp::OpTensorSyncLocal>(params)
->eval(); ->eval();
EXPECT_EQ(tensorOutput->data(), std::vector<float>({ 0, 4, 12 })); EXPECT_EQ(tensorOutput->data(), std::vector<float>({ 0, 4, 12 }));
} }
@ -50,8 +52,9 @@ TEST(TestManager, TestMultipleSequences)
std::shared_ptr<kp::Tensor> tensorRHS = mgr.tensor({ 2, 4, 6 }); std::shared_ptr<kp::Tensor> tensorRHS = mgr.tensor({ 2, 4, 6 });
std::shared_ptr<kp::Tensor> tensorOutput = mgr.tensor({ 0, 0, 0 }); std::shared_ptr<kp::Tensor> tensorOutput = mgr.tensor({ 0, 0, 0 });
std::vector<std::shared_ptr<kp::Tensor>> params = std::vector<std::shared_ptr<kp::Tensor>> params = { tensorLHS,
{ tensorLHS, tensorRHS, tensorOutput }; tensorRHS,
tensorOutput };
mgr.sequence()->eval<kp::OpTensorSyncDevice>(params); mgr.sequence()->eval<kp::OpTensorSyncDevice>(params);
mgr.sequence()->eval<kp::OpMult>(params, mgr.algorithm()); mgr.sequence()->eval<kp::OpMult>(params, mgr.algorithm());
@ -59,4 +62,3 @@ TEST(TestManager, TestMultipleSequences)
EXPECT_EQ(tensorOutput->data(), std::vector<float>({ 0, 4, 12 })); EXPECT_EQ(tensorOutput->data(), std::vector<float>({ 0, 4, 12 }));
} }

View file

@ -3,7 +3,8 @@
#include "kompute/Kompute.hpp" #include "kompute/Kompute.hpp"
TEST(TestMultipleAlgoExecutions, TestEndToEndFunctionality) { TEST(TestMultipleAlgoExecutions, TestEndToEndFunctionality)
{
kp::Manager mgr; kp::Manager mgr;
@ -38,21 +39,24 @@ TEST(TestMultipleAlgoExecutions, TestEndToEndFunctionality) {
} }
)"); )");
std::vector<std::shared_ptr<kp::Tensor>> params = {tensorInA, tensorInB, tensorOutA, tensorOutB}; std::vector<std::shared_ptr<kp::Tensor>> params = {
tensorInA, tensorInB, tensorOutA, tensorOutB
};
kp::Workgroup workgroup({3, 1, 1}); kp::Workgroup workgroup({ 3, 1, 1 });
kp::Constants specConsts({ 2 }); kp::Constants specConsts({ 2 });
kp::Constants pushConstsA({ 2.0 }); kp::Constants pushConstsA({ 2.0 });
kp::Constants pushConstsB({ 3.0 }); kp::Constants pushConstsB({ 3.0 });
auto algorithm = mgr.algorithm(params, kp::Shader::compile_source(shader), workgroup, specConsts); auto algorithm = mgr.algorithm(
params, kp::Shader::compile_source(shader), workgroup, specConsts);
// 3. Run operation with string shader synchronously // 3. Run operation with string shader synchronously
mgr.sequence() mgr.sequence()
->record<kp::OpTensorSyncDevice>(params) ->record<kp::OpTensorSyncDevice>(params)
->record<kp::OpAlgoDispatch>(algorithm, pushConstsA) ->record<kp::OpAlgoDispatch>(algorithm, pushConstsA)
->record<kp::OpAlgoDispatch>(algorithm, pushConstsB) ->record<kp::OpAlgoDispatch>(algorithm, pushConstsB)
->eval(); ->eval();
auto sq = mgr.sequence(); auto sq = mgr.sequence();
sq->evalAsync<kp::OpTensorSyncLocal>(params); sq->evalAsync<kp::OpTensorSyncLocal>(params);
@ -83,12 +87,12 @@ TEST(TestMultipleAlgoExecutions, SingleSequenceRecord)
{ {
mgr.sequence() mgr.sequence()
->record<kp::OpTensorSyncDevice>({ tensorA }) ->record<kp::OpTensorSyncDevice>({ tensorA })
->record<kp::OpAlgoDispatch>(mgr.algorithm({tensorA}, spirv)) ->record<kp::OpAlgoDispatch>(mgr.algorithm({ tensorA }, spirv))
->record<kp::OpAlgoDispatch>(mgr.algorithm({tensorA}, spirv)) ->record<kp::OpAlgoDispatch>(mgr.algorithm({ tensorA }, spirv))
->record<kp::OpAlgoDispatch>(mgr.algorithm({tensorA}, spirv)) ->record<kp::OpAlgoDispatch>(mgr.algorithm({ tensorA }, spirv))
->record<kp::OpTensorSyncLocal>({ tensorA }) ->record<kp::OpTensorSyncLocal>({ tensorA })
->eval(); ->eval();
} }
EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 }));
@ -111,29 +115,20 @@ TEST(TestMultipleAlgoExecutions, MultipleCmdBufRecords)
std::vector<uint32_t> spirv = kp::Shader::compile_source(shader); std::vector<uint32_t> spirv = kp::Shader::compile_source(shader);
std::shared_ptr<kp::Algorithm> algorithm = mgr.algorithm({tensorA}, spirv); std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm({ tensorA }, spirv);
std::shared_ptr<kp::Sequence> sq = mgr.sequence(); std::shared_ptr<kp::Sequence> sq = mgr.sequence();
mgr.sequence() mgr.sequence()->record<kp::OpTensorSyncDevice>({ tensorA })->eval();
->record<kp::OpTensorSyncDevice>({ tensorA })
->eval();
mgr.sequence() mgr.sequence()->record<kp::OpAlgoDispatch>(algorithm)->eval();
->record<kp::OpAlgoDispatch>(algorithm)
->eval();
mgr.sequence() mgr.sequence()->record<kp::OpAlgoDispatch>(algorithm)->eval();
->record<kp::OpAlgoDispatch>(algorithm)
->eval();
mgr.sequence() mgr.sequence()->record<kp::OpAlgoDispatch>(algorithm)->eval();
->record<kp::OpAlgoDispatch>(algorithm)
->eval();
mgr.sequence() mgr.sequence()->record<kp::OpTensorSyncLocal>({ tensorA })->eval();
->record<kp::OpTensorSyncLocal>({ tensorA })
->eval();
EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 }));
} }
@ -156,23 +151,20 @@ TEST(TestMultipleAlgoExecutions, MultipleSequences)
std::vector<uint32_t> spirv = kp::Shader::compile_source(shader); std::vector<uint32_t> spirv = kp::Shader::compile_source(shader);
std::shared_ptr<kp::Algorithm> algorithm = mgr.algorithm({tensorA}, spirv); std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm({ tensorA }, spirv);
std::shared_ptr<kp::Sequence> sq = mgr.sequence(); std::shared_ptr<kp::Sequence> sq = mgr.sequence();
sq->record<kp::OpTensorSyncDevice>({ tensorA })->eval(); sq->record<kp::OpTensorSyncDevice>({ tensorA })->eval();
sq->record<kp::OpAlgoDispatch>(algorithm) sq->record<kp::OpAlgoDispatch>(algorithm)->eval();
->eval();
sq->record<kp::OpAlgoDispatch>(algorithm) sq->record<kp::OpAlgoDispatch>(algorithm)->eval();
->eval();
sq->record<kp::OpAlgoDispatch>(algorithm) sq->record<kp::OpAlgoDispatch>(algorithm)->eval();
->eval();
sq->record<kp::OpTensorSyncLocal>({ tensorA }) sq->record<kp::OpTensorSyncLocal>({ tensorA })->eval();
->eval();
EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 }));
} }
@ -194,24 +186,20 @@ TEST(TestMultipleAlgoExecutions, SingleRecordMultipleEval)
std::vector<uint32_t> spirv = kp::Shader::compile_source(shader); std::vector<uint32_t> spirv = kp::Shader::compile_source(shader);
std::shared_ptr<kp::Algorithm> algorithm = mgr.algorithm({tensorA}, spirv); std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm({ tensorA }, spirv);
std::shared_ptr<kp::Sequence> sq = mgr.sequence(); std::shared_ptr<kp::Sequence> sq = mgr.sequence();
sq->record<kp::OpTensorSyncDevice>({ tensorA })->eval(); sq->record<kp::OpTensorSyncDevice>({ tensorA })->eval();
sq->record<kp::OpAlgoDispatch>(algorithm) sq->record<kp::OpAlgoDispatch>(algorithm)->eval()->eval()->eval();
->eval()
->eval()
->eval();
sq->record<kp::OpTensorSyncLocal>({ tensorA }) sq->record<kp::OpTensorSyncLocal>({ tensorA })->eval();
->eval();
EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 }));
} }
TEST(TestMultipleAlgoExecutions, SequenceAlgoDestroyOutsideManagerScope) TEST(TestMultipleAlgoExecutions, SequenceAlgoDestroyOutsideManagerScope)
{ {
std::shared_ptr<kp::Tensor> tensorA = nullptr; std::shared_ptr<kp::Tensor> tensorA = nullptr;
@ -234,22 +222,18 @@ TEST(TestMultipleAlgoExecutions, SequenceAlgoDestroyOutsideManagerScope)
std::vector<uint32_t> spirv = kp::Shader::compile_source(shader); std::vector<uint32_t> spirv = kp::Shader::compile_source(shader);
std::shared_ptr<kp::Algorithm> algorithm = mgr.algorithm({tensorA}, spirv); std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm({ tensorA }, spirv);
sq = mgr.sequence(); sq = mgr.sequence();
sq->record<kp::OpTensorSyncDevice>({ tensorA })->eval(); sq->record<kp::OpTensorSyncDevice>({ tensorA })->eval();
sq->record<kp::OpAlgoDispatch>(algorithm) sq->record<kp::OpAlgoDispatch>(algorithm)->eval()->eval()->eval();
->eval()
->eval()
->eval();
sq->record<kp::OpTensorSyncLocal>({ tensorA }) sq->record<kp::OpTensorSyncLocal>({ tensorA })->eval();
->eval();
} }
} }
EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 3, 3, 3 }));
} }

View file

@ -32,10 +32,9 @@ TEST(TestOpAlgoCreate, ShaderRawDataFromConstructor)
std::vector<std::shared_ptr<kp::Tensor>> params = { tensorA, tensorB }; std::vector<std::shared_ptr<kp::Tensor>> params = { tensorA, tensorB };
mgr.sequence() mgr.sequence()
->eval<kp::OpTensorSyncDevice>(params) ->eval<kp::OpTensorSyncDevice>(params)
->eval<kp::OpAlgoDispatch>(mgr.algorithm(params, spirv)) ->eval<kp::OpAlgoDispatch>(mgr.algorithm(params, spirv))
->eval<kp::OpTensorSyncLocal>(params); ->eval<kp::OpTensorSyncLocal>(params);
EXPECT_EQ(tensorA->data(), std::vector<float>({ 0, 1, 2 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 0, 1, 2 }));
EXPECT_EQ(tensorB->data(), std::vector<float>({ 3, 4, 5 })); EXPECT_EQ(tensorB->data(), std::vector<float>({ 3, 4, 5 }));
@ -48,27 +47,27 @@ TEST(TestOpAlgoCreate, ShaderCompiledDataFromConstructor)
std::shared_ptr<kp::Tensor> tensorA = mgr.tensor({ 3, 4, 5 }); std::shared_ptr<kp::Tensor> tensorA = mgr.tensor({ 3, 4, 5 });
std::shared_ptr<kp::Tensor> tensorB = mgr.tensor({ 0, 0, 0 }); std::shared_ptr<kp::Tensor> tensorB = mgr.tensor({ 0, 0, 0 });
std::vector<uint32_t> spirv = std::vector<uint32_t> spirv = std::vector<uint32_t>(
std::vector<uint32_t>( (uint32_t*)
(uint32_t*)kp::shader_data::test_shaders_glsl_test_op_custom_shader_comp_spv, kp::shader_data::test_shaders_glsl_test_op_custom_shader_comp_spv,
(uint32_t*)(kp::shader_data::test_shaders_glsl_test_op_custom_shader_comp_spv + (uint32_t*)(kp::shader_data::
kp::shader_data:: test_shaders_glsl_test_op_custom_shader_comp_spv +
test_shaders_glsl_test_op_custom_shader_comp_spv_len)); kp::shader_data::
test_shaders_glsl_test_op_custom_shader_comp_spv_len));
std::vector<std::shared_ptr<kp::Tensor>> params = { tensorA, tensorB }; std::vector<std::shared_ptr<kp::Tensor>> params = { tensorA, tensorB };
mgr.sequence() mgr.sequence()
->eval<kp::OpTensorSyncDevice>(params) ->eval<kp::OpTensorSyncDevice>(params)
->eval<kp::OpAlgoDispatch>(mgr.algorithm(params, spirv)) ->eval<kp::OpAlgoDispatch>(mgr.algorithm(params, spirv))
->eval<kp::OpTensorSyncLocal>(params); ->eval<kp::OpTensorSyncLocal>(params);
EXPECT_EQ(tensorA->data(), std::vector<float>({ 0, 1, 2 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 0, 1, 2 }));
EXPECT_EQ(tensorB->data(), std::vector<float>({ 3, 4, 5 })); EXPECT_EQ(tensorB->data(), std::vector<float>({ 3, 4, 5 }));
} }
// TODO: Add support to read from file for shader // TODO: Add support to read from file for shader
//TEST(TestOpAlgoCreate, ShaderCompiledDataFromFile) // TEST(TestOpAlgoCreate, ShaderCompiledDataFromFile)
//{ //{
// kp::Manager mgr; // kp::Manager mgr;
// //
@ -77,7 +76,8 @@ TEST(TestOpAlgoCreate, ShaderCompiledDataFromConstructor)
// mgr.rebuild({ tensorA, tensorB }); // mgr.rebuild({ tensorA, tensorB });
// //
// mgr.evalOpDefault<kp::OpAlgoCreate>( // mgr.evalOpDefault<kp::OpAlgoCreate>(
// { tensorA, tensorB }, "test/shaders/glsl/test_op_custom_shader.comp.spv"); // { tensorA, tensorB },
// "test/shaders/glsl/test_op_custom_shader.comp.spv");
// //
// mgr.evalOpDefault<kp::OpTensorSyncLocal>({ tensorA, tensorB }); // mgr.evalOpDefault<kp::OpTensorSyncLocal>({ tensorA, tensorB });
// //

View file

@ -18,9 +18,9 @@ TEST(TestOpTensorCopy, CopyDeviceToDeviceTensor)
EXPECT_TRUE(tensorB->isInit()); EXPECT_TRUE(tensorB->isInit());
mgr.sequence() mgr.sequence()
->eval<kp::OpTensorSyncDevice>({ tensorA, tensorB }) ->eval<kp::OpTensorSyncDevice>({ tensorA, tensorB })
->eval<kp::OpTensorCopy>({ tensorA, tensorB }) ->eval<kp::OpTensorCopy>({ tensorA, tensorB })
->eval<kp::OpTensorSyncLocal>({ tensorA, tensorB }); ->eval<kp::OpTensorSyncLocal>({ tensorA, tensorB });
// Making sure the GPU holds the same data // Making sure the GPU holds the same data
EXPECT_EQ(tensorA->data(), tensorB->data()); EXPECT_EQ(tensorA->data(), tensorB->data());
@ -44,15 +44,14 @@ TEST(TestOpTensorCopy, CopyDeviceToDeviceTensorMulti)
EXPECT_TRUE(tensorC->isInit()); EXPECT_TRUE(tensorC->isInit());
mgr.sequence() mgr.sequence()
->eval<kp::OpTensorSyncLocal>({tensorA, tensorB, tensorC}) ->eval<kp::OpTensorSyncLocal>({ tensorA, tensorB, tensorC })
->eval<kp::OpTensorCopy>({tensorA, tensorB, tensorC }); ->eval<kp::OpTensorCopy>({ tensorA, tensorB, tensorC });
EXPECT_EQ(tensorA->data(), tensorB->data()); EXPECT_EQ(tensorA->data(), tensorB->data());
EXPECT_EQ(tensorA->data(), tensorC->data()); EXPECT_EQ(tensorA->data(), tensorC->data());
// Making sure the GPU holds the same data // Making sure the GPU holds the same data
mgr.sequence() mgr.sequence()->eval<kp::OpTensorSyncLocal>({ tensorB, tensorC });
->eval<kp::OpTensorSyncLocal>({ tensorB, tensorC });
EXPECT_EQ(tensorA->data(), tensorB->data()); EXPECT_EQ(tensorA->data(), tensorB->data());
EXPECT_EQ(tensorA->data(), tensorC->data()); EXPECT_EQ(tensorA->data(), tensorC->data());
@ -67,8 +66,8 @@ TEST(TestOpTensorCopy, CopyDeviceToHostTensor)
std::vector<float> testVecB{ 0, 0, 0 }; std::vector<float> testVecB{ 0, 0, 0 };
std::shared_ptr<kp::Tensor> tensorA = mgr.tensor(testVecA); std::shared_ptr<kp::Tensor> tensorA = mgr.tensor(testVecA);
std::shared_ptr<kp::Tensor> tensorB = mgr.tensor( std::shared_ptr<kp::Tensor> tensorB =
testVecB, kp::Tensor::TensorTypes::eHost); mgr.tensor(testVecB, kp::Tensor::TensorTypes::eHost);
// Only calling sync on device type tensor // Only calling sync on device type tensor
mgr.sequence()->eval<kp::OpTensorSyncDevice>({ tensorA }); mgr.sequence()->eval<kp::OpTensorSyncDevice>({ tensorA });
@ -93,8 +92,8 @@ TEST(TestOpTensorCopy, CopyHostToDeviceTensor)
std::vector<float> testVecA{ 4, 5, 6 }; std::vector<float> testVecA{ 4, 5, 6 };
std::vector<float> testVecB{ 0, 0, 0 }; std::vector<float> testVecB{ 0, 0, 0 };
std::shared_ptr<kp::Tensor> tensorA = mgr.tensor( std::shared_ptr<kp::Tensor> tensorA =
testVecA, kp::Tensor::TensorTypes::eHost); mgr.tensor(testVecA, kp::Tensor::TensorTypes::eHost);
std::shared_ptr<kp::Tensor> tensorB = mgr.tensor(testVecB); std::shared_ptr<kp::Tensor> tensorB = mgr.tensor(testVecB);
// Only calling sync on device type tensor // Only calling sync on device type tensor
@ -120,17 +119,17 @@ TEST(TestOpTensorCopy, CopyHostToHostTensor)
std::vector<float> testVecA{ 5, 6, 7 }; std::vector<float> testVecA{ 5, 6, 7 };
std::vector<float> testVecB{ 0, 0, 0 }; std::vector<float> testVecB{ 0, 0, 0 };
std::shared_ptr<kp::Tensor> tensorA = mgr.tensor( std::shared_ptr<kp::Tensor> tensorA =
testVecA, kp::Tensor::TensorTypes::eHost); mgr.tensor(testVecA, kp::Tensor::TensorTypes::eHost);
std::shared_ptr<kp::Tensor> tensorB = mgr.tensor( std::shared_ptr<kp::Tensor> tensorB =
testVecB, kp::Tensor::TensorTypes::eHost); mgr.tensor(testVecB, kp::Tensor::TensorTypes::eHost);
EXPECT_TRUE(tensorA->isInit()); EXPECT_TRUE(tensorA->isInit());
EXPECT_TRUE(tensorB->isInit()); EXPECT_TRUE(tensorB->isInit());
mgr.sequence() mgr.sequence()
->eval<kp::OpTensorSyncDevice>({ tensorA }) ->eval<kp::OpTensorSyncDevice>({ tensorA })
->eval<kp::OpTensorCopy>({ tensorA, tensorB }); ->eval<kp::OpTensorCopy>({ tensorA, tensorB });
EXPECT_EQ(tensorA->data(), tensorB->data()); EXPECT_EQ(tensorA->data(), tensorB->data());
@ -146,8 +145,8 @@ TEST(TestOpTensorCopy, SingleTensorShouldFail)
std::vector<float> testVecA{ 6, 7, 8 }; std::vector<float> testVecA{ 6, 7, 8 };
std::shared_ptr<kp::Tensor> tensorA = mgr.tensor( std::shared_ptr<kp::Tensor> tensorA =
testVecA, kp::Tensor::TensorTypes::eHost); mgr.tensor(testVecA, kp::Tensor::TensorTypes::eHost);
EXPECT_TRUE(tensorA->isInit()); EXPECT_TRUE(tensorA->isInit());

View file

@ -32,16 +32,18 @@ TEST(TestPushConstants, TestTwoConstants)
std::shared_ptr<kp::Tensor> tensor = mgr.tensor({ 0, 0, 0 }); std::shared_ptr<kp::Tensor> tensor = mgr.tensor({ 0, 0, 0 });
std::shared_ptr<kp::Algorithm> algo = std::shared_ptr<kp::Algorithm> algo =
mgr.algorithm({tensor}, spirv, kp::Workgroup({1})); mgr.algorithm({ tensor }, spirv, kp::Workgroup({ 1 }));
sq = mgr.sequence() sq = mgr.sequence()
->record<kp::OpTensorSyncDevice>({tensor}) ->record<kp::OpTensorSyncDevice>({ tensor })
->record<kp::OpAlgoDispatch>(algo, kp::Constants{0.1, 0.2, 0.3}) ->record<kp::OpAlgoDispatch>(algo,
->record<kp::OpAlgoDispatch>(algo, kp::Constants{0.3, 0.2, 0.1}) kp::Constants{ 0.1, 0.2, 0.3 })
->record<kp::OpTensorSyncLocal>({tensor}) ->record<kp::OpAlgoDispatch>(algo,
->eval(); kp::Constants{ 0.3, 0.2, 0.1 })
->record<kp::OpTensorSyncLocal>({ tensor })
->eval();
EXPECT_EQ(tensor->data(), kp::Constants({0.4, 0.4, 0.4})); EXPECT_EQ(tensor->data(), kp::Constants({ 0.4, 0.4, 0.4 }));
} }
} }
} }

View file

@ -17,4 +17,3 @@ TEST(TestSequence, SequenceDestructorViaManager)
EXPECT_FALSE(sq->isInit()); EXPECT_FALSE(sq->isInit());
} }

View file

@ -28,17 +28,19 @@ TEST(TestSpecializationConstants, TestTwoConstants)
std::shared_ptr<kp::Tensor> tensorA = mgr.tensor({ 0, 0, 0 }); std::shared_ptr<kp::Tensor> tensorA = mgr.tensor({ 0, 0, 0 });
std::shared_ptr<kp::Tensor> tensorB = mgr.tensor({ 0, 0, 0 }); std::shared_ptr<kp::Tensor> tensorB = mgr.tensor({ 0, 0, 0 });
std::vector<std::shared_ptr<kp::Tensor>> params = {tensorA, tensorB}; std::vector<std::shared_ptr<kp::Tensor>> params = { tensorA,
tensorB };
kp::Constants spec = kp::Constants({5.0, 0.3}); kp::Constants spec = kp::Constants({ 5.0, 0.3 });
std::shared_ptr<kp::Algorithm> algo = mgr.algorithm(params, spirv, {}, spec); std::shared_ptr<kp::Algorithm> algo =
mgr.algorithm(params, spirv, {}, spec);
sq = mgr.sequence() sq = mgr.sequence()
->record<kp::OpTensorSyncDevice>(params) ->record<kp::OpTensorSyncDevice>(params)
->record<kp::OpAlgoDispatch>(algo) ->record<kp::OpAlgoDispatch>(algo)
->record<kp::OpTensorSyncLocal>(params) ->record<kp::OpTensorSyncLocal>(params)
->eval(); ->eval();
EXPECT_EQ(tensorA->data(), std::vector<float>({ 5, 5, 5 })); EXPECT_EQ(tensorA->data(), std::vector<float>({ 5, 5, 5 }));
EXPECT_EQ(tensorB->data(), std::vector<float>({ 0.3, 0.3, 0.3 })); EXPECT_EQ(tensorB->data(), std::vector<float>({ 0.3, 0.3, 0.3 }));

View file

@ -11,4 +11,3 @@ TEST(TestTensor, ConstructorData)
EXPECT_EQ(tensor->size(), vec.size()); EXPECT_EQ(tensor->size(), vec.size());
EXPECT_EQ(tensor->data(), vec); EXPECT_EQ(tensor->data(), vec);
} }

View file

@ -18,16 +18,21 @@ TEST(TestWorkgroup, TestSimpleWorkgroup)
tensorA = mgr.tensor(std::vector<float>(16 * 8)); tensorA = mgr.tensor(std::vector<float>(16 * 8));
tensorB = mgr.tensor(std::vector<float>(16 * 8)); tensorB = mgr.tensor(std::vector<float>(16 * 8));
std::vector<std::shared_ptr<kp::Tensor>> params = {tensorA, tensorB}; std::vector<std::shared_ptr<kp::Tensor>> params = { tensorA,
tensorB };
std::vector<uint32_t> spirv( std::vector<uint32_t> spirv(
(uint32_t*)kp::shader_data::test_shaders_glsl_test_workgroup_comp_spv, (uint32_t*)
(uint32_t*)(kp::shader_data::test_shaders_glsl_test_workgroup_comp_spv + kp::shader_data::test_shaders_glsl_test_workgroup_comp_spv,
kp::shader_data::test_shaders_glsl_test_workgroup_comp_spv_len)); (uint32_t*)(kp::shader_data::
test_shaders_glsl_test_workgroup_comp_spv +
kp::shader_data::
test_shaders_glsl_test_workgroup_comp_spv_len));
kp::Workgroup workgroup = {16, 8, 1}; kp::Workgroup workgroup = { 16, 8, 1 };
std::shared_ptr<kp::Algorithm> algorithm = mgr.algorithm(params, spirv, workgroup); std::shared_ptr<kp::Algorithm> algorithm =
mgr.algorithm(params, spirv, workgroup);
sq = mgr.sequence(); sq = mgr.sequence();
sq->record<kp::OpTensorSyncDevice>(params); sq->record<kp::OpTensorSyncDevice>(params);
@ -37,11 +42,26 @@ TEST(TestWorkgroup, TestSimpleWorkgroup)
} }
} }
std::vector<float> expectedA = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15}; std::vector<float> expectedA = {
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15
};
std::vector<float> expectedB = { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 }; std::vector<float> expectedB = {
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5,
6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3,
4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1,
2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5,
6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7
};
EXPECT_EQ(tensorA->data(), expectedA); EXPECT_EQ(tensorA->data(), expectedA);
EXPECT_EQ(tensorB->data(), expectedB); EXPECT_EQ(tensorB->data(), expectedB);
} }