Initial assessment for gdnative shared script

This commit is contained in:
Alejandro Saucedo 2020-09-20 10:22:55 +01:00
parent adf5f748d7
commit 9483739d3c
8 changed files with 207 additions and 0 deletions

View file

@ -0,0 +1,2 @@
vulkan-kompute
lib

View file

@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.17.0)
project(kompute_linear_reg VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 14)
set(KOMPUTE_EXTRA_CXX_FLAGS "" CACHE STRING "Extra compile flags for Kompute, see docs for full list")
# It is necessary to pass the DEBUG or RELEASE flag accordingly to Kompute
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1 ${KOMPUTE_EXTRA_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DRELEASE=1 ${KOMPUTE_EXTRA_CXX_FLAGS}")
find_package(kompute REQUIRED)
find_package(Vulkan REQUIRED)
add_executable(kompute_linear_reg
src/*.cpp)
target_link_libraries(kompute_linear_reg
kompute::kompute
Vulkan::Vulkan
)
target_link_libraries(kompute_linear_reg
"lib/godot.windows.tools.64.lib"
)

View file

@ -0,0 +1,45 @@
# Vulkan Kompute Godot Example
## Set Up Dependencies
### Vulkan
You will need the Vulkan SDK, in this case we use version `1.2.148.1`, which you can get at the official site https://vulkan.lunarg.com/sdk/home#windows
This will have the following contents that will be required later on:
* The VulkanSDK static library `vulkan-1`
### Kompute
We will be using v0.3.1 of Kompute, and similar to above we will need the built static library, but in this case we will build it.
We can start by cloning the repository on the v0.3.1 branch:
```
git clone --branch v0.3.1 https://github.com/EthicalML/vulkan-kompute/
```
You will be able to use cmake to generate the build files for your platform.
```
cmake vulkan-kompute/. -Bvulkan-kompute/build
```
You need to make sure that the build is configured with the same flags required for godot, for example, in windows you will need:
* Release build
* Configuration type: static library
* Runtime lib: Multi-threaded / multi-threaded debug
Now you should see the library built under `build/src/Release`
## Building Godot
Now to build godot you will need to set up a couple of things for the Scons file to work - namely setting up the following:
* Copy the `vulkan-1` library from your vulkan sdk folder to `lib/vulkan-1.lib`
* Copy the `kompute.lib` library from the Kompute build to `lib/kompute.lib`
* Make sure the versions above match as we provide the headers in the `include` folder - if you used different versions make sure these match as well

View file

@ -0,0 +1,5 @@
def can_build(env, platform):
return True
def configure(env):
pass

View file

@ -0,0 +1,14 @@
/* register_types.cpp */
#include "register_types.h"
#include "core/class_db.h"
#include "summator.h"
void register_summator_types() {
ClassDB::register_class<Summator>();
}
void unregister_summator_types() {
// Nothing to do here in this example.
}

View file

@ -0,0 +1,6 @@
/* register_types.h */
#pragma once
void register_summator_types();
void unregister_summator_types();
/* yes, the word in the middle must be the same as the module folder name */

View file

@ -0,0 +1,77 @@
/* summator.cpp */
#include <vector>
#include "summator.h"
Summator::Summator() {
this->mPrimaryTensor = this->mManager.buildTensor({ 0.0 });
this->mSecondaryTensor = this->mManager.buildTensor({ 0.0 });
this->mSequence = this->mManager.getOrCreateManagedSequence("AdditionSeq");
// We now record the steps in the sequence
if (std::shared_ptr<kp::Sequence> sq = this->mSequence.lock())
{
std::string shader(R"(
#version 450
layout (local_size_x = 1) in;
layout(set = 0, binding = 0) buffer a { float pa[]; };
layout(set = 0, binding = 1) buffer b { float pb[]; };
void main() {
uint index = gl_GlobalInvocationID.x;
pa[index] = pb[index] + pa[index];
}
)");
sq->begin();
// First we ensure secondary tensor loads to GPU
// No need to sync the primary tensor as it should not be changed
sq->record<kp::OpTensorSyncDevice>(
{ this->mSecondaryTensor });
// Then we run the operation with both tensors
sq->record<kp::OpAlgoBase<>>(
{ this->mPrimaryTensor, this->mSecondaryTensor },
std::vector<char>(shader.begin(), shader.end()));
// We map the result back to local
sq->record<kp::OpTensorSyncLocal>(
{ this->mPrimaryTensor });
sq->end();
}
else {
throw std::runtime_error("Sequence pointer no longer available");
}
}
void Summator::add(float value) {
// Set the new data in the local device
this->mSecondaryTensor->setData({value});
// Execute recorded sequence
if (std::shared_ptr<kp::Sequence> sq = this->mSequence.lock()) {
sq->eval();
}
else {
throw std::runtime_error("Sequence pointer no longer available");
}
}
void Summator::reset() {
}
float Summator::get_total() const {
return this->mPrimaryTensor->data()[0];
}
void Summator::_bind_methods() {
ClassDB::bind_method(D_METHOD("add", "value"), &Summator::add);
ClassDB::bind_method(D_METHOD("reset"), &Summator::reset);
ClassDB::bind_method(D_METHOD("get_total"), &Summator::get_total);
}

View file

@ -0,0 +1,32 @@
/* summator.h */
#ifndef SUMMATOR_H
#define SUMMATOR_H
#include <memory>
#include "kompute/Kompute.hpp"
#include "scene/main/node.h"
class Summator : public Node {
GDCLASS(Summator, Node);
public:
Summator();
void add(float value);
void reset();
float get_total() const;
protected:
static void _bind_methods();
private:
kp::Manager mManager;
std::weak_ptr<kp::Sequence> mSequence;
std::shared_ptr<kp::Tensor> mPrimaryTensor;
std::shared_ptr<kp::Tensor> mSecondaryTensor;
};
#endif // SUMMATOR_H