Adding tests for actual lib

This commit is contained in:
Alejandro Saucedo 2020-10-03 10:54:04 +01:00
parent 6c41ceb0b2
commit ec2ca803d3
4 changed files with 201 additions and 161 deletions

View file

@ -6,12 +6,12 @@ def ndkDir = properties.getProperty('ndk.dir')
def valLayerBinDir = "${ndkDir}/sources/third_party/vulkan/src/build-android/jniLibs"
android {
compileSdkVersion 24
compileSdkVersion 26
defaultConfig {
applicationId "com.ethicalml.kompute.examples.android"
minSdkVersion 24
targetSdkVersion 24
minSdkVersion 26
targetSdkVersion 26
versionCode = 1
versionName = "0.0.1"
externalNativeBuild {

View file

@ -13,20 +13,20 @@ add_library(app-glue STATIC
# build vulkan app
add_library(kompute_android SHARED
TutorialValLayer.cpp
main.cpp
${VK_ANDROID_COMMON_DIR}/vulkan_wrapper.cpp)
include_directories(
${VK_ANDROID_COMMON_DIR}
${VK_ANDROID_INCLUDE_DIR})
${VK_ANDROID_INCLUDE_DIR}
../../../../../../../single_include/)
# TODO: Explore:
# * -DVK_NO_PROTOTYPES
# * -DUSE_DEBUG_EXTENTIONS
# * -Wno-unused-variable
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Werror \
-DVK_USE_PLATFORM_ANDROID_KHR -DVK_NO_PROTOTYPES")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 \
-DVK_USE_PLATFORM_ANDROID_KHR -DUSE_DEBUG_EXTENTIONS")
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
@ -35,4 +35,5 @@ target_link_libraries(kompute_android
kompute
app-glue
log
"libvulkan.so"
android)

View file

@ -12,9 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "TutorialValLayer.hpp"
#include "vulkan/vulkan.h"
#include <android/log.h>
#include <cassert>
// Android log function wrappers
static const char* kTAG = "Vulkan-Tutorial02";
#define LOGI(...) \

View file

@ -12,15 +12,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#undef DEBUG
#define RELEASE 1
#include <android/log.h>
#include <android_native_app_glue.h>
#include <cassert>
#include <memory>
#include <vector>
#include "TutorialValLayer.hpp"
#include "vulkan_wrapper.h"
#include <unistd.h>
//#include "TutorialValLayer.hpp"
//#include "vulkan_wrapper.h"
#include "kompute/Kompute.hpp"
// Android log function wrappers
static const char* kTAG = "Vulkan-Tutorial02";
static const char* kTAG = "Vulkan-Tutorial01";
#define LOGI(...) \
((void)__android_log_print(ANDROID_LOG_INFO, kTAG, __VA_ARGS__))
#define LOGW(...) \
@ -55,181 +64,208 @@ void handle_cmd(android_app* app, int32_t cmd);
// typical Android NativeActivity entry function
void android_main(struct android_app* app) {
app->onAppCmd = handle_cmd;
app->onAppCmd = handle_cmd;
int events;
android_poll_source* source;
do {
if (ALooper_pollAll(initialized_ ? 1 : 0, nullptr, &events,
(void**)&source) >= 0) {
if (source != NULL) source->process(app, source);
}
} while (app->destroyRequested == 0);
int events;
android_poll_source* source;
do {
if (ALooper_pollAll(initialized_ ? 1 : 0, nullptr, &events,
(void**)&source) >= 0) {
if (source != NULL) source->process(app, source);
}
} while (app->destroyRequested == 0);
}
bool initialize(android_app* app) {
// Load Android vulkan and retrieve vulkan API function pointers
if (!InitVulkan()) {
LOGE("Vulkan is unavailable, install vulkan and re-start");
return false;
}
// // Load Android vulkan and retrieve vulkan API function pointers
// if (!InitVulkan()) {
// LOGE("Vulkan is unavailable, install vulkan and re-start");
// return false;
// }
VkApplicationInfo appInfo = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = nullptr,
.apiVersion = VK_MAKE_VERSION(1, 0, 0),
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
.pApplicationName = "tutorial02_prebuilt_layers",
.pEngineName = "tutorial",
};
LOGI("Starting");
sleep(1);
VkApplicationInfo appInfo = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = nullptr,
.apiVersion = VK_MAKE_VERSION(1, 0, 0),
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
.pApplicationName = "tutorial01_load_vulkan",
.pEngineName = "tutorial",
};
LOGI("Created");
sleep(1);
// prepare debug and layer objects
LayerAndExtensions layerAndExt;
layerAndExt.AddInstanceExt(layerAndExt.GetDbgExtName());
// prepare necessary extensions: Vulkan on Android need these to function
std::vector<const char *> instanceExt, deviceExt;
instanceExt.push_back("VK_KHR_surface");
instanceExt.push_back("VK_KHR_android_surface");
deviceExt.push_back("VK_KHR_swapchain");
// Create Vulkan instance, requesting all enabled layers / extensions
// available on the system
VkInstanceCreateInfo instanceCreateInfo{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr,
.pApplicationInfo = &appInfo,
.enabledExtensionCount = layerAndExt.InstExtCount(),
.ppEnabledExtensionNames =
static_cast<const char* const*>(layerAndExt.InstExtNames()),
.enabledLayerCount = layerAndExt.InstLayerCount(),
.ppEnabledLayerNames =
static_cast<const char* const*>(layerAndExt.InstLayerNames()),
};
CALL_VK(vkCreateInstance(&instanceCreateInfo, nullptr, &tutorialInstance));
LOGI("Creating instance");
sleep(1);
// Create the Vulkan instance
VkInstanceCreateInfo instanceCreateInfo{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr,
.pApplicationInfo = &appInfo,
.enabledExtensionCount = static_cast<uint32_t>(instanceExt.size()),
.ppEnabledExtensionNames = instanceExt.data(),
.enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr,
};
CALL_VK(vkCreateInstance(&instanceCreateInfo, nullptr, &tutorialInstance));
// Create debug callback obj and connect to vulkan instance
layerAndExt.HookDbgReportExt(tutorialInstance);
LOGI("Creating createinfo");
sleep(1);
// if we create a surface, we need the surface extension
VkAndroidSurfaceCreateInfoKHR createInfo{
.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
.pNext = nullptr,
.flags = 0,
.window = app->window};
CALL_VK(vkCreateAndroidSurfaceKHR(tutorialInstance, &createInfo, nullptr,
&tutorialSurface));
// Find one GPU to use:
// On Android, every GPU device is equal -- supporting
// graphics/compute/present
// for this sample, we use the very first GPU device found on the system
uint32_t gpuCount = 0;
CALL_VK(vkEnumeratePhysicalDevices(tutorialInstance, &gpuCount, nullptr));
VkPhysicalDevice tmpGpus[gpuCount];
CALL_VK(vkEnumeratePhysicalDevices(tutorialInstance, &gpuCount, tmpGpus));
tutorialGpu = tmpGpus[0]; // Pick up the first GPU Device
// Find one GPU to use:
// On Android, every GPU device is equal -- supporting
// graphics/compute/present
// for this sample, we use the very first GPU device found on the system
uint32_t gpuCount = 0;
CALL_VK(vkEnumeratePhysicalDevices(tutorialInstance, &gpuCount, nullptr));
VkPhysicalDevice tmpGpus[gpuCount];
CALL_VK(vkEnumeratePhysicalDevices(tutorialInstance, &gpuCount, tmpGpus));
tutorialGpu = tmpGpus[0]; // Pick up the first GPU Device
// Enumerate available device validation layers & extensions
layerAndExt.InitDevLayersAndExt(tutorialGpu);
// check for vulkan info on this GPU device
VkPhysicalDeviceProperties gpuProperties;
vkGetPhysicalDeviceProperties(tutorialGpu, &gpuProperties);
LOGI("Vulkan Physical Device Name: %s", gpuProperties.deviceName);
LOGI("Vulkan Physical Device Info: apiVersion: %x \n\t driverVersion: %x",
gpuProperties.apiVersion, gpuProperties.driverVersion);
LOGI("API Version Supported: %d.%d.%d",
VK_VERSION_MAJOR(gpuProperties.apiVersion),
VK_VERSION_MINOR(gpuProperties.apiVersion),
VK_VERSION_PATCH(gpuProperties.apiVersion));
// check for vulkan info on this GPU device
VkPhysicalDeviceProperties gpuProperties;
vkGetPhysicalDeviceProperties(tutorialGpu, &gpuProperties);
LOGI("Vulkan Physical Device Name: %s", gpuProperties.deviceName);
LOGI("Vulkan Physical Device Info: apiVersion: %x \n\t driverVersion: %x",
gpuProperties.apiVersion, gpuProperties.driverVersion);
LOGI("API Version Supported: %d.%d.%d",
VK_VERSION_MAJOR(gpuProperties.apiVersion),
VK_VERSION_MINOR(gpuProperties.apiVersion),
VK_VERSION_PATCH(gpuProperties.apiVersion));
VkSurfaceCapabilitiesKHR surfaceCapabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(tutorialGpu, tutorialSurface,
&surfaceCapabilities);
VkAndroidSurfaceCreateInfoKHR createInfo{
.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
.pNext = nullptr,
.flags = 0,
.window = app->window};
CALL_VK(vkCreateAndroidSurfaceKHR(tutorialInstance, &createInfo, nullptr,
&tutorialSurface));
LOGI("Vulkan Surface Capabilities:\n");
LOGI("\timage count: %u - %u\n", surfaceCapabilities.minImageCount,
surfaceCapabilities.maxImageCount);
LOGI("\tarray layers: %u\n", surfaceCapabilities.maxImageArrayLayers);
LOGI("\timage size (now): %dx%d\n", surfaceCapabilities.currentExtent.width,
surfaceCapabilities.currentExtent.height);
LOGI("\timage size (extent): %dx%d - %dx%d\n",
surfaceCapabilities.minImageExtent.width,
surfaceCapabilities.minImageExtent.height,
surfaceCapabilities.maxImageExtent.width,
surfaceCapabilities.maxImageExtent.height);
LOGI("\tusage: %x\n", surfaceCapabilities.supportedUsageFlags);
LOGI("\tcurrent transform: %u\n", surfaceCapabilities.currentTransform);
LOGI("\tallowed transforms: %x\n", surfaceCapabilities.supportedTransforms);
LOGI("\tcomposite alpha flags: %u\n", surfaceCapabilities.currentTransform);
VkSurfaceCapabilitiesKHR surfaceCapabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(tutorialGpu, tutorialSurface,
&surfaceCapabilities);
// Find a GFX queue family
uint32_t queueFamilyCount;
vkGetPhysicalDeviceQueueFamilyProperties(tutorialGpu, &queueFamilyCount, nullptr);
assert(queueFamilyCount);
std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(tutorialGpu, &queueFamilyCount,
queueFamilyProperties.data());
LOGI("Vulkan Surface Capabilities:\n");
LOGI("\timage count: %u - %u\n", surfaceCapabilities.minImageCount,
surfaceCapabilities.maxImageCount);
LOGI("\tarray layers: %u\n", surfaceCapabilities.maxImageArrayLayers);
LOGI("\timage size (now): %dx%d\n", surfaceCapabilities.currentExtent.width,
surfaceCapabilities.currentExtent.height);
LOGI("\timage size (extent): %dx%d - %dx%d\n",
surfaceCapabilities.minImageExtent.width,
surfaceCapabilities.minImageExtent.height,
surfaceCapabilities.maxImageExtent.width,
surfaceCapabilities.maxImageExtent.height);
LOGI("\tusage: %x\n", surfaceCapabilities.supportedUsageFlags);
LOGI("\tcurrent transform: %u\n", surfaceCapabilities.currentTransform);
LOGI("\tallowed transforms: %x\n", surfaceCapabilities.supportedTransforms);
LOGI("\tcomposite alpha flags: %u\n", surfaceCapabilities.currentTransform);
// Find a GFX queue family
uint32_t queueFamilyCount;
vkGetPhysicalDeviceQueueFamilyProperties(tutorialGpu, &queueFamilyCount, nullptr);
assert(queueFamilyCount);
std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(tutorialGpu, &queueFamilyCount,
queueFamilyProperties.data());
uint32_t queueFamilyIndex;
for (queueFamilyIndex=0; queueFamilyIndex < queueFamilyCount;
queueFamilyIndex++) {
if (queueFamilyProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
break;
uint32_t queueFamilyIndex;
for (queueFamilyIndex=0; queueFamilyIndex < queueFamilyCount;
queueFamilyIndex++) {
if (queueFamilyProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
break;
}
}
}
assert(queueFamilyIndex < queueFamilyCount);
assert(queueFamilyIndex < queueFamilyCount);
// Create a logical device from GPU we picked
float priorities[] = {
1.0f,
};
VkDeviceQueueCreateInfo queueCreateInfo{
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.queueCount = 1,
.queueFamilyIndex = queueFamilyIndex,
// Send nullptr for queue priority so debug extension could
// catch the bug and call back app's debug function
.pQueuePriorities = nullptr, // priorities,
};
// Create a logical device from GPU we picked
float priorities[] = {
1.0f,
};
VkDeviceQueueCreateInfo queueCreateInfo{
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.queueCount = 1,
.queueFamilyIndex = queueFamilyIndex,
.pQueuePriorities = priorities,
};
VkDeviceCreateInfo deviceCreateInfo{
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = nullptr,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &queueCreateInfo,
.enabledLayerCount = layerAndExt.DevLayerCount(),
.ppEnabledLayerNames =
static_cast<const char* const*>(layerAndExt.DevLayerNames()),
.enabledExtensionCount = layerAndExt.DevExtCount(),
.ppEnabledExtensionNames =
static_cast<const char* const*>(layerAndExt.DevExtNames()),
.pEnabledFeatures = nullptr,
};
VkDeviceCreateInfo deviceCreateInfo{
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = nullptr,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &queueCreateInfo,
.enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr,
.enabledExtensionCount = static_cast<uint32_t>(deviceExt.size()),
.ppEnabledExtensionNames = deviceExt.data(),
.pEnabledFeatures = nullptr,
};
CALL_VK(
vkCreateDevice(tutorialGpu, &deviceCreateInfo, nullptr, &tutorialDevice));
initialized_ = true;
return true;
CALL_VK(
vkCreateDevice(tutorialGpu, &deviceCreateInfo, nullptr, &tutorialDevice));
VkInstance tutorialInstance;
VkPhysicalDevice tutorialGpu;
VkDevice tutorialDevice;
std::shared_ptr<vk::Instance> tutorialInstanceHpp = std::make_shared<vk::Instance>(tutorialInstance);
std::shared_ptr<vk::PhysicalDevice> tutorialGpuHpp = std::make_shared<vk::PhysicalDevice>(tutorialGpu);
std::shared_ptr<vk::Device> tutorialDeviceHpp = std::make_shared<vk::Device>(tutorialDevice);
//
// kp::Manager mgr(tutorialInstanceHpp, tutorialGpuHpp, tutorialDeviceHpp, 0);
LOGI("BEFORE RUNNING");
// kp::Manager mgr;
// auto tensorA = mgr.buildTensor({0,1,2});
// auto tensorB = mgr.buildTensor({0,1,2});
// auto tensorC = mgr.buildTensor({0,0,0});
// mgr.evalOpDefault<kp::OpMult<>>({tensorA, tensorB, tensorC});
// mgr.evalOpDefault<kp::OpTensorSyncLocal>({tensorC});
//
// LOGI("HERE IS THE INFORMATION:");
//
// for(const float & i : tensorC->data()) {
// LOGI("%u ", i);
// }
initialized_ = true;
return 0;
}
void terminate(void) {
vkDestroySurfaceKHR(tutorialInstance, tutorialSurface, nullptr);
vkDestroyDevice(tutorialDevice, nullptr);
vkDestroyInstance(tutorialInstance, nullptr);
// vkDestroySurfaceKHR(tutorialInstance, tutorialSurface, nullptr);
// vkDestroyDevice(tutorialDevice, nullptr);
// vkDestroyInstance(tutorialInstance, nullptr);
initialized_ = false;
initialized_ = false;
}
// Process the next main command.
void handle_cmd(android_app* app, int32_t cmd) {
switch (cmd) {
case APP_CMD_INIT_WINDOW:
// The window is being shown, get it ready.
initialize(app);
break;
case APP_CMD_TERM_WINDOW:
// The window is being hidden or closed, clean it up.
terminate();
break;
default:
LOGI("event not handled: %d", cmd);
}
switch (cmd) {
case APP_CMD_INIT_WINDOW:
// The window is being shown, get it ready.
initialize(app);
break;
case APP_CMD_TERM_WINDOW:
// The window is being hidden or closed, clean it up.
terminate();
break;
default:
LOGI("event not handled: %d", cmd);
}
}