Repository: pytorch
Issue: SIGSEGV at at::is_vulkan_available() invocation on Android
Labels: triaged,module: android

## 🐛 Bug

SIGSEGV error on Android with Vulkan backend at `at::is_vulkan_available()` invocation.

After investigation, I found that the problem code starts [here](https://github.com/pytorch/pytorch/blob/c371542efc31b1abfe6f388042aa3ab0cef935f2/aten/src/ATen/native/vulkan/api/Runtime.cpp#L104). More detailed problem description you can find at [stackoverflow](https://stackoverflow.com/questions/54841772/vkcreateinstance-throws-segmentation-fault).

For myself, I solved this problem by following changes in source file:
```
diff --git a/aten/src/ATen/native/vulkan/api/Runtime.cpp b/aten/src/ATen/native/vulkan/api/Runtime.cpp
index bad1be699e..99a13be2ff 100644
--- a/aten/src/ATen/native/vulkan/api/Runtime.cpp
+++ b/aten/src/ATen/native/vulkan/api/Runtime.cpp
@@ -45,90 +45,6 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debug_report_callback_fn(
   return VK_FALSE;
 }
 
-VkInstance create_instance(const Runtime::Type type) {
-  std::vector<const char*> enabled_instance_layers;
-  std::vector<const char*> enabled_instance_extensions;
-
-  if (Runtime::Type::Debug == type) {
-    uint32_t instance_layers_count = 0;
-    VK_CHECK(vkEnumerateInstanceLayerProperties(
-        &instance_layers_count, nullptr));
-
-    std::vector<VkLayerProperties> instance_layer_properties(
-        instance_layers_count);
-
-    VK_CHECK(vkEnumerateInstanceLayerProperties(
-        &instance_layers_count,
-        instance_layer_properties.data()));
-
-    constexpr const char* const requested_instance_layers[]{
-        // "VK_LAYER_LUNARG_api_dump",
-        "VK_LAYER_KHRONOS_validation",
-    };
-
-    for (const auto& requested_instance_layer : requested_instance_layers) {
-      for (const auto& layer : instance_layer_properties) {
-        if (strcmp(requested_instance_layer, layer.layerName) == 0) {
-          enabled_instance_layers.push_back(requested_instance_layer);
-          break;
-        }
-      }
-    }
-
-    uint32_t instance_extension_count = 0;
-    VK_CHECK(vkEnumerateInstanceExtensionProperties(
-        nullptr, &instance_extension_count, nullptr));
-
-    std::vector<VkExtensionProperties> instance_extension_properties(
-        instance_extension_count);
-
-    VK_CHECK(vkEnumerateInstanceExtensionProperties(
-        nullptr, &instance_extension_count, instance_extension_properties.data()));
-
-    constexpr const char* const requested_instance_extensions[]{
-    #ifdef VK_EXT_debug_report
-      VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
-    #endif
-    };
-
-    for (const auto& requested_instance_extension : requested_instance_extensions) {
-      for (const auto& extension : instance_extension_properties) {
-        if (strcmp(requested_instance_extension, extension.extensionName) == 0) {
-          enabled_instance_extensions.push_back(requested_instance_extension);
-          break;
-        }
-      }
-    }
-  }
-
-  constexpr VkApplicationInfo application_info{
-    VK_STRUCTURE_TYPE_APPLICATION_INFO,
-    nullptr,
-    "PyTorch",
-    0,
-    "PyTorch",
-    0,
-    VK_API_VERSION_1_0,
-  };
-
-  const VkInstanceCreateInfo instance_create_info{
-    VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
-    nullptr,
-    0u,
-    &application_info,
-    static_cast<uint32_t>(enabled_instance_layers.size()),
-    enabled_instance_layers.data(),
-    static_cast<uint32_t>(enabled_instance_extensions.size()),
-    enabled_instance_extensions.data(),
-  };
-
-  VkInstance instance{};
-  VK_CHECK(vkCreateInstance(&instance_create_info, nullptr, &instance));
-  TORCH_CHECK(instance, "Invalid Vulkan instance!");
-
-  return instance;
-}
-
 VkDebugReportCallbackEXT create_debug_report_callback(
     const VkInstance instance,
     const Runtime::Type type) {
@@ -252,6 +168,90 @@ uint32_t query_compute_queue_family_index(const VkPhysicalDevice physical_device
 
 } // namespace
 
+VkInstance&& Runtime::init_instance(const Runtime::Type type) {
+  std::vector<const char*> enabled_instance_layers;
+  std::vector<const char*> enabled_instance_extensions;
+
+  if (Runtime::Type::Debug == type) {
+    uint32_t instance_layers_count = 0;
+    VK_CHECK(vkEnumerateInstanceLayerProperties(
+        &instance_layers_count, nullptr));
+
+    std::vector<VkLayerProperties> instance_layer_properties(
+        instance_layers_count);
+
+    VK_CHECK(vkEnumerateInstanceLayerProperties(
+        &instance_layers_count,
+        instance_layer_properties.data()));
+
+    constexpr const char* const requested_instance_layers[]{
+        // "VK_LAYER_LUNARG_api_dump",
+        "VK_LAYER_KHRONOS_validation",
+    };
+
+    for (const auto& requested_instance_layer : requested_instance_layers) {
+      for (const auto& layer : instance_layer_properties) {
+        if (strcmp(requested_instance_layer, layer.layerName) == 0) {
+          enabled_instance_layers.push_back(requested_instance_layer);
+          break;
+        }
+      }
+    }
+
+    uint32_t instance_extension_count = 0;
+    VK_CHECK(vkEnumerateInstanceExtensionProperties(
+        nullptr, &instance_extension_count, nullptr));
+
+    std::vector<VkExtensionProperties> instance_extension_properties(
+        instance_extension_count);
+
+    VK_CHECK(vkEnumerateInstanceExtensionProperties(
+        nullptr, &instance_extension_count, instance_extension_properties.data()));
+
+    constexpr const char* const requested_instance_extensions[]{
+    #ifdef VK_EXT_debug_report
+      VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
+    #endif
+    };
+
+    for (const auto& requested_instance_extension : requested_instance_extensions) {
+      for (const auto& extension : instance_extension_properties) {
+        if (strcmp(requested_instance_extension, extension.extensionName) == 0) {
+          enabled_instance_extensions.push_back(requested_instance_extension);
+          break;
+        }
+      }
+    }
+  }
+
+  application_info_ = VkApplicationInfo {
+      VK_STRUCTURE_TYPE_APPLICATION_INFO,
+      nullptr,
+      "PyTorch",
+      0,
+      "PyTorch",
+      0,
+      VK_API_VERSION_1_0,
+  };
+
+  instance_create_info_ = VkInstanceCreateInfo {
+      VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+      nullptr,
+      0u,
+      &application_info_,
+      static_cast<uint32_t>(enabled_instance_layers.size()),
+      enabled_instance_layers.data(),
+      static_cast<uint32_t>(enabled_instance_extensions.size()),
+      enabled_instance_extensions.data(),
+  };
+
+  VkInstance instance{};
+  VK_CHECK(vkCreateInstance(&instance_create_info_, nullptr, &instance));
+  TORCH_CHECK(instance, "Invalid Vulkan instance!");
+
+  return std::move(instance);
+}
+
 Runtime::Debug::Debug(const VkInstance instance)
   : instance_(instance) {
     TORCH_INTERNAL_ASSERT_DEBUG_ONLY(
@@ -275,8 +275,8 @@ void Runtime::Debug::operator()(
   }
 }
 
-Runtime::Runtime(const Type type)
-    : instance_(create_instance(type), &VK_DELETER(Instance)),
+Runtime::Runtime(const Type type) 
+    : instance_(init_instance(type), &VK_DELETER(Instance)),
       debug_report_callback_(
           create_debug_report_callback(instance(), type),
           Debug(instance())) {
diff --git a/aten/src/ATen/native/vulkan/api/Runtime.h b/aten/src/ATen/native/vulkan/api/Runtime.h
index 55eae70f87..8c5012c345 100644
--- a/aten/src/ATen/native/vulkan/api/Runtime.h
+++ b/aten/src/ATen/native/vulkan/api/Runtime.h
@@ -38,6 +38,9 @@ class Runtime final {
   typedef std::function<bool (const Adapter&)> Selector;
   Adapter select(const Selector& selector);
 
+ private:
+  VkInstance&& init_instance(const Type type);
+
  private:
   class Debug final {
    public:
@@ -51,6 +54,8 @@ class Runtime final {
  private:
   // Construction and destruction order matters.  Do not move members around.
   Handle<VkInstance, decltype(&VK_DELETER(Instance))> instance_;
+  VkInstanceCreateInfo instance_create_info_;
+  VkApplicationInfo application_info_;
   Handle<VkDebugReportCallbackEXT, Debug> debug_report_callback_;
 };
```

## To Reproduce

Steps to reproduce the behavior:

Follow steps at https://pytorch.org/tutorials/prototype/vulkan_workflow.html#c-api

## Expected behavior

There must be no errors on this command.

## Environment

 - PyTorch Version 1.8.1
 - OS: Android 10
 - Installing from source
 - Arch: arm64-v8a
 - Build command: see #55296