Commit 84c8f3a9 by Alex Weaver Committed by Tianqi Chen

Added option to build android rpc app with vulkan support

parent 508d4993
...@@ -8,9 +8,19 @@ endif ...@@ -8,9 +8,19 @@ endif
include $(config) include $(config)
# We target every architecture except armeabi here, for two reasons:
# 1) armeabi is deprecated in NDK r16 and removed in r17
# 2) vulkan is not supported in armeabi
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 mips
APP_STL := c++_static APP_STL := c++_static
APP_CPPFLAGS += -DDMLC_LOG_STACK_TRACE=0 -DTVM4J_ANDROID=1 -std=c++11 -Oz -frtti APP_CPPFLAGS += -DDMLC_LOG_STACK_TRACE=0 -DTVM4J_ANDROID=1 -std=c++11 -Oz -frtti
ifeq ($(USE_OPENCL), 1) ifeq ($(USE_OPENCL), 1)
APP_CPPFLAGS += -DTVM_OPENCL_RUNTIME=1 APP_CPPFLAGS += -DTVM_OPENCL_RUNTIME=1
endif endif
ifeq ($(USE_VULKAN), 1)
APP_CPPFLAGS += -DTVM_VULKAN_RUNTIME=1
APP_LDFLAGS += -lvulkan
endif
...@@ -19,6 +19,14 @@ APP_PLATFORM = android-17 ...@@ -19,6 +19,14 @@ APP_PLATFORM = android-17
# whether enable OpenCL during compile # whether enable OpenCL during compile
USE_OPENCL = 0 USE_OPENCL = 0
# whether to enable Vulkan during compile
USE_VULKAN = 0
ifeq ($(USE_VULKAN), 1)
# Statically linking vulkan requires API Level 24 or higher
APP_PLATFORM = android-24
endif
# the additional include headers you want to add, e.g., SDK_PATH/adrenosdk/Development/Inc # the additional include headers you want to add, e.g., SDK_PATH/adrenosdk/Development/Inc
ADD_C_INCLUDES = ADD_C_INCLUDES =
......
...@@ -28,3 +28,8 @@ ...@@ -28,3 +28,8 @@
#include "../src/runtime/opencl/opencl_device_api.cc" #include "../src/runtime/opencl/opencl_device_api.cc"
#include "../src/runtime/opencl/opencl_module.cc" #include "../src/runtime/opencl/opencl_module.cc"
#endif #endif
#ifdef TVM_VULKAN_RUNTIME
#include "../src/runtime/vulkan/vulkan_device_api.cc"
#include "../src/runtime/vulkan/vulkan_module.cc"
#endif
...@@ -86,9 +86,9 @@ struct VulkanContext { ...@@ -86,9 +86,9 @@ struct VulkanContext {
/*! \brief The buffer object */ /*! \brief The buffer object */
struct VulkanBuffer { struct VulkanBuffer {
/*! \brief underlying buffer */ /*! \brief underlying buffer */
VkBuffer buffer{nullptr}; VkBuffer buffer{VK_NULL_HANDLE};
/*! \brief underlying buffer */ /*! \brief underlying buffer */
VkDeviceMemory memory{nullptr}; VkDeviceMemory memory{VK_NULL_HANDLE};
}; };
/*! \brief Buffer only used for stagging */ /*! \brief Buffer only used for stagging */
...@@ -96,9 +96,9 @@ struct VulkanStagingBuffer { ...@@ -96,9 +96,9 @@ struct VulkanStagingBuffer {
/*! \brief the corresponding device */ /*! \brief the corresponding device */
VkDevice device{nullptr}; VkDevice device{nullptr};
/*! \brief underlying buffer */ /*! \brief underlying buffer */
VkBuffer buffer{nullptr}; VkBuffer buffer{VK_NULL_HANDLE};
/*! \brief underlying buffer */ /*! \brief underlying buffer */
VkDeviceMemory memory{nullptr}; VkDeviceMemory memory{VK_NULL_HANDLE};
/*! \brief host address */ /*! \brief host address */
void* host_addr{nullptr}; void* host_addr{nullptr};
/*! \brief size of the memory */ /*! \brief size of the memory */
...@@ -150,18 +150,18 @@ class VulkanWorkspace final : public DeviceAPI { ...@@ -150,18 +150,18 @@ class VulkanWorkspace final : public DeviceAPI {
/*! \brief Helper command buffer resource */ /*! \brief Helper command buffer resource */
struct VulkanCommandBuffer { struct VulkanCommandBuffer {
/*! \brief fence to signal the resource is ready to use */ /*! \brief fence to signal the resource is ready to use */
VkFence fence{nullptr}; VkFence fence{VK_NULL_HANDLE};
/*! \brief The internal command buffer */ /*! \brief The internal command buffer */
VkCommandBuffer cmd_buffer{nullptr}; VkCommandBuffer cmd_buffer{nullptr};
/*! \brief Descriptor set used to bind arguments */ /*! \brief Descriptor set used to bind arguments */
VkDescriptorSet descriptor_set{nullptr}; VkDescriptorSet descriptor_set{VK_NULL_HANDLE};
/*! \brief Internal utilities for write command */ /*! \brief Internal utilities for write command */
VkWriteDescriptorSet write_descriptor_set; VkWriteDescriptorSet write_descriptor_set;
VulkanCommandBuffer() { VulkanCommandBuffer() {
write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write_descriptor_set.pNext = nullptr; write_descriptor_set.pNext = nullptr;
write_descriptor_set.dstSet = nullptr; write_descriptor_set.dstSet = VK_NULL_HANDLE;
write_descriptor_set.dstBinding = 0; write_descriptor_set.dstBinding = 0;
write_descriptor_set.dstArrayElement = 0; write_descriptor_set.dstArrayElement = 0;
write_descriptor_set.descriptorCount = 1; write_descriptor_set.descriptorCount = 1;
...@@ -230,9 +230,9 @@ class VulkanCommandPool { ...@@ -230,9 +230,9 @@ class VulkanCommandPool {
/*! \brief the corresponding device*/ /*! \brief the corresponding device*/
VkDevice device_{nullptr}; VkDevice device_{nullptr};
/*! \brief internal command buffer pool */ /*! \brief internal command buffer pool */
VkCommandPool cmd_pool_{nullptr}; VkCommandPool cmd_pool_{VK_NULL_HANDLE};
/*! \brief Descriptor pool */ /*! \brief Descriptor pool */
VkDescriptorPool descriptor_pool_{nullptr}; VkDescriptorPool descriptor_pool_{VK_NULL_HANDLE};
}; };
/*! \brief Thread local workspace */ /*! \brief Thread local workspace */
......
...@@ -349,7 +349,7 @@ VulkanCommandPool::~VulkanCommandPool() { ...@@ -349,7 +349,7 @@ VulkanCommandPool::~VulkanCommandPool() {
vkFreeCommandBuffers(device_, cmd_pool_, 1, &(ring_[i].cmd_buffer)); vkFreeCommandBuffers(device_, cmd_pool_, 1, &(ring_[i].cmd_buffer));
ring_[i].cmd_buffer = nullptr; ring_[i].cmd_buffer = nullptr;
} }
if (ring_[i].fence != nullptr) { if (ring_[i].fence != VK_NULL_HANDLE) {
vkDestroyFence(device_, ring_[i].fence, nullptr); vkDestroyFence(device_, ring_[i].fence, nullptr);
} }
} }
...@@ -376,10 +376,10 @@ VulkanCommandBuffer* VulkanCommandPool::Alloc( ...@@ -376,10 +376,10 @@ VulkanCommandBuffer* VulkanCommandPool::Alloc(
} }
VULKAN_CHECK_ERROR(res); VULKAN_CHECK_ERROR(res);
vkResetFences(device_, 1, (&e->fence)); vkResetFences(device_, 1, (&e->fence));
if (e->descriptor_set != nullptr) { if (e->descriptor_set != VK_NULL_HANDLE) {
VULKAN_CALL(vkFreeDescriptorSets( VULKAN_CALL(vkFreeDescriptorSets(
device_, descriptor_pool_, 1, &(e->descriptor_set))); device_, descriptor_pool_, 1, &(e->descriptor_set)));
e->descriptor_set = nullptr; e->descriptor_set = VK_NULL_HANDLE;
} }
if (dlayout != nullptr) { if (dlayout != nullptr) {
VkDescriptorSetAllocateInfo alloc_info; VkDescriptorSetAllocateInfo alloc_info;
...@@ -425,15 +425,15 @@ VulkanThreadEntry::StagingBuffer(int device_id, size_t size) { ...@@ -425,15 +425,15 @@ VulkanThreadEntry::StagingBuffer(int device_id, size_t size) {
if (buf.host_addr != nullptr) { if (buf.host_addr != nullptr) {
vkUnmapMemory(buf.device, buf.memory); vkUnmapMemory(buf.device, buf.memory);
} }
if (buf.memory != nullptr) { if (buf.memory != VK_NULL_HANDLE) {
vkFreeMemory(buf.device, buf.memory, nullptr); vkFreeMemory(buf.device, buf.memory, nullptr);
} }
if (buf.buffer != nullptr) { if (buf.buffer != VK_NULL_HANDLE) {
vkDestroyBuffer(buf.device, buf.buffer, nullptr); vkDestroyBuffer(buf.device, buf.buffer, nullptr);
} }
buf.host_addr = nullptr; buf.host_addr = nullptr;
buf.memory = nullptr; buf.memory = VK_NULL_HANDLE;
buf.buffer = nullptr; buf.buffer = VK_NULL_HANDLE;
} }
const VulkanContext& vctx = const VulkanContext& vctx =
VulkanWorkspace::Global()->context_[device_id]; VulkanWorkspace::Global()->context_[device_id];
...@@ -441,7 +441,7 @@ VulkanThreadEntry::StagingBuffer(int device_id, size_t size) { ...@@ -441,7 +441,7 @@ VulkanThreadEntry::StagingBuffer(int device_id, size_t size) {
if (buf.device == nullptr) { if (buf.device == nullptr) {
buf.device = vctx.device; buf.device = vctx.device;
} }
if (buf.memory == nullptr) { if (buf.memory == VK_NULL_HANDLE) {
// allocate the stagging buffer memory if necessary // allocate the stagging buffer memory if necessary
VkBufferCreateInfo info; VkBufferCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
...@@ -479,10 +479,10 @@ VulkanThreadEntry::~VulkanThreadEntry() { ...@@ -479,10 +479,10 @@ VulkanThreadEntry::~VulkanThreadEntry() {
if (buf.host_addr != nullptr) { if (buf.host_addr != nullptr) {
vkUnmapMemory(buf.device, buf.memory); vkUnmapMemory(buf.device, buf.memory);
} }
if (buf.memory != nullptr) { if (buf.memory != VK_NULL_HANDLE) {
vkFreeMemory(buf.device, buf.memory, nullptr); vkFreeMemory(buf.device, buf.memory, nullptr);
} }
if (buf.buffer != nullptr) { if (buf.buffer != VK_NULL_HANDLE) {
vkDestroyBuffer(buf.device, buf.buffer, nullptr); vkDestroyBuffer(buf.device, buf.buffer, nullptr);
} }
} }
......
...@@ -35,10 +35,10 @@ class VulkanModuleNode final :public runtime::ModuleNode { ...@@ -35,10 +35,10 @@ class VulkanModuleNode final :public runtime::ModuleNode {
public: public:
// Pipeline cache states // Pipeline cache states
struct PipelineEntry { struct PipelineEntry {
VkShaderModule shader{nullptr}; VkShaderModule shader{VK_NULL_HANDLE};
VkPipelineLayout pipeline_layout{nullptr}; VkPipelineLayout pipeline_layout{VK_NULL_HANDLE};
VkDescriptorSetLayout descriptor_layout{nullptr}; VkDescriptorSetLayout descriptor_layout{VK_NULL_HANDLE};
VkPipeline pipeline{nullptr}; VkPipeline pipeline{VK_NULL_HANDLE};
}; };
// constructor // constructor
explicit VulkanModuleNode(std::unordered_map<std::string, VulkanShader> smap, explicit VulkanModuleNode(std::unordered_map<std::string, VulkanShader> smap,
...@@ -193,10 +193,10 @@ class VulkanModuleNode final :public runtime::ModuleNode { ...@@ -193,10 +193,10 @@ class VulkanModuleNode final :public runtime::ModuleNode {
pipeline_cinfo.stage.pName = func_name.c_str(); pipeline_cinfo.stage.pName = func_name.c_str();
pipeline_cinfo.stage.pSpecializationInfo = nullptr; pipeline_cinfo.stage.pSpecializationInfo = nullptr;
pipeline_cinfo.layout = pe.pipeline_layout; pipeline_cinfo.layout = pe.pipeline_layout;
pipeline_cinfo.basePipelineHandle = nullptr; pipeline_cinfo.basePipelineHandle = VK_NULL_HANDLE;
pipeline_cinfo.basePipelineIndex = 0; pipeline_cinfo.basePipelineIndex = 0;
VULKAN_CALL(vkCreateComputePipelines( VULKAN_CALL(vkCreateComputePipelines(
e.device, nullptr, 1, &pipeline_cinfo, nullptr, &(pe.pipeline))); e.device, VK_NULL_HANDLE, 1, &pipeline_cinfo, nullptr, &(pe.pipeline)));
e.smap[func_name] = pe; e.smap[func_name] = pe;
return pe; return pe;
} }
...@@ -250,7 +250,7 @@ class VulkanWrappedFunc { ...@@ -250,7 +250,7 @@ class VulkanWrappedFunc {
CHECK_LT(device_id, kVulkanMaxNumDevice); CHECK_LT(device_id, kVulkanMaxNumDevice);
const vulkan::VulkanContext& vctx = w_->context_[device_id]; const vulkan::VulkanContext& vctx = w_->context_[device_id];
VulkanModuleNode::PipelineEntry& pe = scache_[device_id]; VulkanModuleNode::PipelineEntry& pe = scache_[device_id];
if (pe.pipeline == nullptr) { if (pe.pipeline == VK_NULL_HANDLE) {
pe = m_->GetPipeline(device_id, func_name_, num_pack_args_); pe = m_->GetPipeline(device_id, func_name_, num_pack_args_);
} }
ThreadWorkLoad wl = thread_axis_cfg_.Extract(args); ThreadWorkLoad wl = thread_axis_cfg_.Extract(args);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment