Fully working end to end flow

This commit is contained in:
Alejandro Saucedo 2020-08-22 20:13:30 +01:00
parent 622b8c4bc7
commit 9f74679dd5
10 changed files with 57 additions and 41 deletions

View file

@ -88,33 +88,6 @@ int main() {
}
```
Use equations to group operations on memory and execution step
```c++
int main() {
kp::Manager kManager(); // Chooses device 0
kp::Sequence sq;
kManager.createSequence(&sq);
sq.begin();
kp::Tensor inputOne;
sq.record<kp::OpCreateTensor>(&inputOne, {0, 1, 2, 3}); // Mounts to device and binds to 0
kp::Tensor inputTwo;
sq.record<kp::OpCreateTensor>(&inputTwo, {0, 1, 2, 3}); // Mounts to device and binds to 1
kp::Tensor output;
sq.record<kp::OpMult>(&inputOne, &inputTwo, &output);
sq.end();
sq.eval();
std::cout << output << std::endl;
}
```
## Development

View file

@ -22,6 +22,8 @@ void main()
//valuesOutput[index] = valuesLhs[index] * valuesRhs[index];
// FOR TESTING
valuesOutput[index] = valuesLhs[index] + valuesRhs[index];
valuesLhs[index] = 100 + index;
valuesRhs[index] = 100 + index;
}

Binary file not shown.

View file

@ -103,13 +103,25 @@ Algorithm::createParameters(std::vector<std::shared_ptr<Tensor>>& tensorParams)
this->mDevice->allocateDescriptorSets(&descriptorSetAllocateInfo,
this->mDescriptorSet.get());
std::vector<vk::DescriptorBufferInfo> descriptorBufferInfos;
for (size_t i = 0; i < tensorParams.size(); i++) {
descriptorBufferInfos.push_back(tensorParams[i]->constructDescriptorBufferInfo());
}
////std::vector<vk::DescriptorBufferInfo> descriptorBufferInfos;
////for (size_t i = 0; i < tensorParams.size(); i++) {
//// descriptorBufferInfos.push_back(tensorParams[i]->constructDescriptorBufferInfo());
////}
////std::vector<vk::WriteDescriptorSet> computeWriteDescriptorSets;
////computeWriteDescriptorSets.push_back(
//// vk::WriteDescriptorSet(*this->mDescriptorSet,
//// 0, // Destination binding
//// 0, // Destination array element
//// 1, // Descriptor count
//// vk::DescriptorType::eStorageBuffer,
//// nullptr, // Descriptor image info
//// descriptorBufferInfos.data()
//// ));
// TODO: Explore design exposing the destination array element
std::vector<vk::WriteDescriptorSet> computeWriteDescriptorSets;
for (size_t i = 0; i < tensorParams.size(); i++) {
std::vector<vk::WriteDescriptorSet> computeWriteDescriptorSets;
vk::DescriptorBufferInfo descriptorBufferInfo =
tensorParams[i]->constructDescriptorBufferInfo();
@ -123,10 +135,12 @@ Algorithm::createParameters(std::vector<std::shared_ptr<Tensor>>& tensorParams)
vk::DescriptorType::eStorageBuffer,
nullptr, // Descriptor image info
&descriptorBufferInfo));
this->mDevice->updateDescriptorSets(computeWriteDescriptorSets, nullptr);
}
SPDLOG_DEBUG("Kompute Algorithm updating descriptor sets");
this->mDevice->updateDescriptorSets(computeWriteDescriptorSets, nullptr);
//this->mDevice->updateDescriptorSets(computeWriteDescriptorSets, nullptr);
SPDLOG_DEBUG("Kompue Algorithm successfully run init");
}

View file

@ -65,6 +65,12 @@ Manager::~Manager()
}
}
Sequence
Manager::constructSequence() {
SPDLOG_DEBUG("Kompute Manager creating Sequence object");
return Sequence(this->mPhysicalDevice, this->mDevice, this->mComputeQueue, this->mComputeQueueFamilyIndex);
}
void
Manager::createInstance()
{

View file

@ -26,7 +26,8 @@ class Manager
~Manager();
// Evaluate actions
Sequence constructSequence();
template<typename T, typename... TArgs>
void evalOp(std::vector<std::shared_ptr<Tensor>> tensors)
{

View file

@ -123,6 +123,11 @@ OpMult<tX, tY, tZ>::record()
this->mAlgorithm->recordDispatch(this->mX, this->mY, this->mZ);
// Barrier to ensure the shader code is executed before buffer read
this->mTensorLHS->recordBufferMemoryBarrier(
vk::AccessFlagBits::eShaderWrite,
vk::AccessFlagBits::eTransferRead,
vk::PipelineStageFlagBits::eComputeShader,
vk::PipelineStageFlagBits::eTransfer);
this->mTensorOutput->recordBufferMemoryBarrier(
vk::AccessFlagBits::eShaderWrite,
vk::AccessFlagBits::eTransferRead,
@ -132,6 +137,11 @@ OpMult<tX, tY, tZ>::record()
this->mTensorOutputStaging->recordCopyFrom(this->mTensorOutput);
// Buffer to ensure wait until data is copied to staging buffer
this->mTensorLHS->recordBufferMemoryBarrier(
vk::AccessFlagBits::eTransferWrite,
vk::AccessFlagBits::eHostRead,
vk::PipelineStageFlagBits::eTransfer,
vk::PipelineStageFlagBits::eHost);
this->mTensorOutput->recordBufferMemoryBarrier(
vk::AccessFlagBits::eTransferWrite,
vk::AccessFlagBits::eHostRead,
@ -143,7 +153,7 @@ template<uint32_t tX, uint32_t tY, uint32_t tZ>
void
OpMult<tX, tY, tZ>::postSubmit()
{
SPDLOG_DEBUG("Kompute OpCreateTensor postSubmit called");
SPDLOG_DEBUG("Kompute OpMult postSubmit called");
this->mTensorOutputStaging->mapDataFromHostMemory();

View file

@ -31,7 +31,7 @@ class Sequence
// TODO: Explore design without template using just top level class
template<typename T, typename... TArgs>
void record(TArgs&&... args)
void record(std::vector<std::shared_ptr<Tensor>> tensors)
{
static_assert(std::is_base_of<OpBase, T>::value,
"Template only valid with OpBase derived classes");
@ -46,7 +46,7 @@ class Sequence
std::unique_ptr<OpBase> baseOpPtr{ baseOp };
SPDLOG_DEBUG("Kompute Sequence running init on OpBase derived class instance");
baseOpPtr->init(std::forward<TArgs>(args)...);
baseOpPtr->init(tensors);
SPDLOG_DEBUG("Kompute Sequence running record on OpBase derived class instance");
baseOpPtr->record();

View file

@ -211,6 +211,10 @@ Tensor::mapDataIntoHostMemory()
void* mapped = this->mDevice->mapMemory(
*this->mMemory, 0, bufferSize, vk::MemoryMapFlags());
memcpy(mapped, this->mData.data(), bufferSize);
this->mDevice->unmapMemory(*this->mMemory);
mapped = this->mDevice->mapMemory(
*this->mMemory, 0, bufferSize, vk::MemoryMapFlags());
vk::MappedMemoryRange mappedRange(*this->mMemory, 0, bufferSize);
this->mDevice->flushMappedMemoryRanges(1, &mappedRange);
this->mDevice->unmapMemory(*this->mMemory);

View file

@ -623,22 +623,25 @@ main()
spdlog::info("Creating manager");
kp::Manager mgr;
kp::Sequence sq = mgr.constructSequence();
sq.begin();
spdlog::info("Creating first tensor");
std::shared_ptr<kp::Tensor> tensorLHS{ new kp::Tensor(
{ 0.0, 1.0, 2.0 }) };
mgr.evalOp<kp::OpCreateTensor>({ tensorLHS });
spdlog::info("Creating second tensor");
std::shared_ptr<kp::Tensor> tensorRHS{ new kp::Tensor(
{ 2.0, 4.0, 6.0 }) };
mgr.evalOp<kp::OpCreateTensor>({ tensorRHS });
// TODO: Add capabilities for just output tensor types
spdlog::info("Creating output tensor");
std::shared_ptr<kp::Tensor> tensorOutput{ new kp::Tensor(
{ 0.0, 0.0, 0.0 }) };
mgr.evalOp<kp::OpCreateTensor>({ tensorOutput });
sq.record<kp::OpCreateTensor>({ tensorLHS });
sq.record<kp::OpCreateTensor>({ tensorRHS });
sq.record<kp::OpCreateTensor>({ tensorOutput });
spdlog::info("OpCreateTensor success for tensors");
spdlog::info("Tensor one: {}", tensorLHS->data());
@ -646,7 +649,10 @@ main()
spdlog::info("Tensor output: {}", tensorOutput->data());
spdlog::info("Calling op mult");
mgr.evalOp<kp::OpMult<>>({ tensorLHS, tensorRHS, tensorOutput });
sq.record<kp::OpMult<>>({ tensorLHS, tensorRHS, tensorOutput });
sq.end();
sq.eval();
spdlog::info("OpMult call success");
spdlog::info("Tensor output: {}", tensorOutput->data());