mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-20 21:14:14 +08:00
[Vulkan]Fix build warnings-treated-as-error on Linux. (#52781)
Summary: Pull Request resolved: https://github.com/pytorch/pytorch/pull/52781 Test Plan: Imported from OSS Reviewed By: SS-JIA Differential Revision: D26669311 Pulled By: AshkanAliabadi fbshipit-source-id: 78b08d0b264d4d5cf8af964c589b9b7d0ddc7311
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f3190a77b2
commit
e5ecd1ddf8
@ -206,7 +206,7 @@ case "$image" in
|
||||
PROTOBUF=yes
|
||||
DB=yes
|
||||
VISION=yes
|
||||
VULKAN_SDK_VERSION=1.2.148.0
|
||||
VULKAN_SDK_VERSION=1.2.162.1
|
||||
SWIFTSHADER=yes
|
||||
;;
|
||||
pytorch-linux-bionic-py3.8-gcc9)
|
||||
|
@ -8,16 +8,17 @@ retry () {
|
||||
$* || (sleep 1 && $*) || (sleep 2 && $*) || (sleep 4 && $*) || (sleep 8 && $*)
|
||||
}
|
||||
|
||||
_https_amazon_aws=https://ossci-android.s3.amazonaws.com
|
||||
|
||||
_vulkansdk_dir=/var/lib/jenkins/vulkansdk
|
||||
mkdir -p $_vulkansdk_dir
|
||||
_tmp_vulkansdk_targz=/tmp/vulkansdk.tar.gz
|
||||
curl --silent --show-error --location --fail --retry 3 \
|
||||
--output "$_tmp_vulkansdk_targz" "$_https_amazon_aws/vulkansdk-linux-x86_64-${VULKAN_SDK_VERSION}.tar.gz"
|
||||
|
||||
tar -C "$_vulkansdk_dir" -xzf "$_tmp_vulkansdk_targz" --strip-components 1
|
||||
curl \
|
||||
--silent \
|
||||
--show-error \
|
||||
--location \
|
||||
--fail \
|
||||
--retry 3 \
|
||||
--output "${_tmp_vulkansdk_targz}" "https://ossci-android.s3.amazonaws.com/vulkansdk-linux-x86_64-${VULKAN_SDK_VERSION}.tar.gz"
|
||||
|
||||
export VULKAN_SDK="$_vulkansdk_dir/"
|
||||
|
||||
rm "$_tmp_vulkansdk_targz"
|
||||
mkdir -p "${_vulkansdk_dir}"
|
||||
tar -C "${_vulkansdk_dir}" -xzf "${_tmp_vulkansdk_targz}" --strip-components 1
|
||||
rm -rf "${_tmp_vulkansdk_targz}"
|
||||
|
@ -123,7 +123,7 @@ fi
|
||||
|
||||
if [[ "$BUILD_ENVIRONMENT" != *android* && "$BUILD_ENVIRONMENT" == *vulkan-linux* ]]; then
|
||||
export USE_VULKAN=1
|
||||
export VULKAN_SDK=/var/lib/jenkins/vulkansdk/
|
||||
source /var/lib/jenkins/vulkansdk/setup-env.sh
|
||||
fi
|
||||
|
||||
if [[ "$BUILD_ENVIRONMENT" == *rocm* ]]; then
|
||||
|
@ -264,10 +264,9 @@ if(NOT DEFINED USE_VULKAN)
|
||||
"ANDROID" OFF)
|
||||
endif()
|
||||
|
||||
option(USE_VULKAN_FP16_INFERENCE "Vulkan - Use fp16 inference even on fp32 tensors" OFF)
|
||||
option(USE_VULKAN_FP16_INFERENCE "Vulkan - Use fp16 inference" OFF)
|
||||
option(USE_VULKAN_RELAXED_PRECISION "Vulkan - Use relaxed precision math in the kernels (mediump)" OFF)
|
||||
option(USE_VULKAN_SHADERC_RUNTIME "Vulkan - Use runtime shader compilation (needs libshaderc)" OFF)
|
||||
option(USE_VULKAN_WRAPPER "Vulkan - Dynamically load Vulkan functions" ON)
|
||||
option(USE_VULKAN_SHADERC_RUNTIME "Vulkan - Use runtime shader compilation as opposed to build-time (needs libshaderc)" OFF)
|
||||
option(USE_XNNPACK "Use XNNPACK" ON)
|
||||
option(USE_ZMQ "Use ZMQ" OFF)
|
||||
option(USE_ZSTD "Use ZSTD" OFF)
|
||||
@ -633,10 +632,6 @@ if(USE_VULKAN)
|
||||
if(USE_VULKAN_SHADERC_RUNTIME)
|
||||
string(APPEND CMAKE_CXX_FLAGS " -DUSE_VULKAN_SHADERC_RUNTIME")
|
||||
endif()
|
||||
|
||||
if(USE_VULKAN_WRAPPER)
|
||||
string(APPEND CMAKE_CXX_FLAGS " -DUSE_VULKAN_WRAPPER")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(USE_PYTORCH_METAL)
|
||||
|
@ -180,7 +180,7 @@ Descriptor::Set& Descriptor::Set::bind(
|
||||
"This descriptor set is in an invalid state! "
|
||||
"Potential reason: This descriptor set is moved from.");
|
||||
|
||||
update({
|
||||
update(Item{
|
||||
binding,
|
||||
shader_layout_signature_[binding],
|
||||
{
|
||||
|
@ -72,7 +72,7 @@ struct Pipeline final {
|
||||
|
||||
typedef Layout::Descriptor Descriptor;
|
||||
typedef VK_DELETER(PipelineLayout) Deleter;
|
||||
typedef Handle<VkPipelineLayout, Deleter> Handle;
|
||||
typedef api::Handle<VkPipelineLayout, Deleter> Handle;
|
||||
|
||||
struct Hasher {
|
||||
size_t operator()(const Descriptor& descriptor) const;
|
||||
@ -131,7 +131,7 @@ struct Pipeline final {
|
||||
|
||||
typedef Pipeline::Descriptor Descriptor;
|
||||
typedef VK_DELETER(Pipeline) Deleter;
|
||||
typedef Handle<VkPipeline, Deleter> Handle;
|
||||
typedef api::Handle<VkPipeline, Deleter> Handle;
|
||||
|
||||
struct Hasher {
|
||||
size_t operator()(const Descriptor& descriptor) const;
|
||||
|
@ -168,7 +168,7 @@ struct Resource final {
|
||||
|
||||
typedef Sampler::Descriptor Descriptor;
|
||||
typedef VK_DELETER(Sampler) Deleter;
|
||||
typedef Handle<VkSampler, Deleter> Handle;
|
||||
typedef api::Handle<VkSampler, Deleter> Handle;
|
||||
|
||||
struct Hasher {
|
||||
size_t operator()(const Descriptor& descriptor) const;
|
||||
|
@ -65,7 +65,7 @@ struct Shader final {
|
||||
|
||||
typedef Layout::Descriptor Descriptor;
|
||||
typedef VK_DELETER(DescriptorSetLayout) Deleter;
|
||||
typedef Handle<VkDescriptorSetLayout, Deleter> Handle;
|
||||
typedef api::Handle<VkDescriptorSetLayout, Deleter> Handle;
|
||||
|
||||
struct Hasher {
|
||||
size_t operator()(const Descriptor& descriptor) const;
|
||||
@ -156,7 +156,7 @@ struct Shader final {
|
||||
|
||||
typedef Shader::Descriptor Descriptor;
|
||||
typedef VK_DELETER(ShaderModule) Deleter;
|
||||
typedef Handle<VkShaderModule, Deleter> Handle;
|
||||
typedef api::Handle<VkShaderModule, Deleter> Handle;
|
||||
|
||||
struct Hasher {
|
||||
size_t operator()(const Descriptor& descriptor) const;
|
||||
|
@ -9,6 +9,10 @@ namespace {
|
||||
|
||||
using namespace api::utils;
|
||||
|
||||
uvec3 image_extents(IntArrayRef);
|
||||
bool requires_image(IntArrayRef);
|
||||
bool requires_staging(const api::Adapter*);
|
||||
|
||||
VkFormat vk_format(const caffe2::TypeMeta dtype) {
|
||||
switch (c10::typeMetaToScalarType(dtype)) {
|
||||
case kFloat:
|
||||
@ -155,13 +159,7 @@ VkDeviceSize buffer_bytes(
|
||||
const caffe2::TypeMeta dtype) {
|
||||
VkDeviceSize size = c10::elementSize(c10::typeMetaToScalarType(dtype));
|
||||
|
||||
// Forward declaration
|
||||
bool requires_image(IntArrayRef);
|
||||
|
||||
if (requires_image(sizes)) {
|
||||
// Forward declaration
|
||||
uvec3 image_extents(IntArrayRef);
|
||||
|
||||
const uvec3 extents = image_extents(sizes);
|
||||
size *= extents.data[0u] * extents.data[1u] * (4u * extents.data[2u]);
|
||||
}
|
||||
@ -188,9 +186,6 @@ vTensor::Buffer allocate_buffer(
|
||||
TORCH_CHECK(!sizes.empty(), "Invalid Vulkan tensor size!");
|
||||
verify(options);
|
||||
|
||||
// Forward declaration
|
||||
bool requires_staging(const api::Adapter*);
|
||||
|
||||
const VkFlags usage =
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
||||
@ -1093,6 +1088,12 @@ vTensor::View::State::State(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VULKAN_TENSOR_DEBUG
|
||||
std::ostream& operator<<(
|
||||
std::ostream&,
|
||||
const vTensor::View::State::Bundle&);
|
||||
#endif /* VULKAN_TENSOR_DEBUG */
|
||||
|
||||
vTensor::View::State::Transition
|
||||
vTensor::View::State::transition(const Bundle bundle) {
|
||||
const Bundle from = bundle_;
|
||||
@ -1110,15 +1111,10 @@ vTensor::View::State::transition(const Bundle bundle) {
|
||||
to.image = bundle.image;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Forward declaration
|
||||
std::ostream& operator<<(
|
||||
std::ostream&,
|
||||
const View::State::Bundle&);
|
||||
|
||||
#ifdef VULKAN_TENSOR_DEBUG
|
||||
std::cout << "From:" << std::endl << from << std::endl;
|
||||
std::cout << "To:" << std::endl << to << std::endl;
|
||||
#endif /* DEBUG */
|
||||
#endif /* VULKAN_TENSOR_DEBUG */
|
||||
|
||||
return Transition{
|
||||
from,
|
||||
@ -1149,6 +1145,8 @@ void verify(const TensorOptions& options) {
|
||||
// Debug
|
||||
//
|
||||
|
||||
#ifdef VULKAN_TENSOR_DEBUG
|
||||
|
||||
namespace {
|
||||
|
||||
// Considering that VkAccessFlags is a weak typedef of a built-in data type, we
|
||||
@ -1310,6 +1308,8 @@ std::ostream& operator<<(
|
||||
return stream;
|
||||
}
|
||||
|
||||
#endif /* VULKAN_TENSOR_DEBUG */
|
||||
|
||||
} // namespace ops
|
||||
} // namespace vulkan
|
||||
} // namespace native
|
||||
|
@ -326,6 +326,11 @@ class vTensor final {
|
||||
Component::Flags available_;
|
||||
Component::Flags dirty_;
|
||||
Bundle bundle_;
|
||||
|
||||
private:
|
||||
#ifdef VULKAN_TENSOR_DEBUG
|
||||
friend class View;
|
||||
#endif /* VULKAN_TENSOR_DEBUG */
|
||||
};
|
||||
|
||||
typedef State::Component Component;
|
||||
@ -364,10 +369,12 @@ class vTensor final {
|
||||
c10::SmallVector<int64_t, 6u> strides_;
|
||||
|
||||
private:
|
||||
// Debug
|
||||
#ifdef VULKAN_TENSOR_DEBUG
|
||||
friend class vTensor;
|
||||
friend std::ostream& operator<<(
|
||||
std::ostream&,
|
||||
const View::State::Bundle&);
|
||||
#endif /* VULKAN_TENSOR_DEBUG */
|
||||
};
|
||||
|
||||
// Even at the cost of a heap allocation plus the resulting negative impact
|
||||
@ -391,10 +398,11 @@ class vTensor final {
|
||||
std::shared_ptr<View> view_;
|
||||
|
||||
private:
|
||||
// Debug
|
||||
#ifdef VULKAN_TENSOR_DEBUG
|
||||
friend std::ostream& operator<<(
|
||||
std::ostream&,
|
||||
const View::State::Bundle&);
|
||||
#endif /* VULKAN_TENSOR_DEBUG */
|
||||
};
|
||||
|
||||
const vTensor& convert(const Tensor& tensor);
|
||||
|
@ -554,11 +554,13 @@ endif()
|
||||
|
||||
# ---[ Vulkan deps
|
||||
if(USE_VULKAN)
|
||||
set(Vulkan_LIBS)
|
||||
set(Vulkan_DEFINES)
|
||||
set(Vulkan_INCLUDES)
|
||||
set(Vulkan_LIBS)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/VulkanDependencies.cmake)
|
||||
list(APPEND Caffe2_DEPENDENCY_LIBS ${Vulkan_LIBS})
|
||||
string(APPEND CMAKE_CXX_FLAGS ${Vulkan_DEFINES})
|
||||
include_directories(SYSTEM ${Vulkan_INCLUDES})
|
||||
list(APPEND Caffe2_DEPENDENCY_LIBS ${Vulkan_LIBS})
|
||||
endif()
|
||||
|
||||
# ---[ gflags
|
||||
|
@ -146,7 +146,6 @@ function(caffe2_print_configuration_summary)
|
||||
message(STATUS " USE_VULKAN_FP16_INFERENCE : ${USE_VULKAN_FP16_INFERENCE}")
|
||||
message(STATUS " USE_VULKAN_RELAXED_PRECISION : ${USE_VULKAN_RELAXED_PRECISION}")
|
||||
message(STATUS " USE_VULKAN_SHADERC_RUNTIME : ${USE_VULKAN_SHADERC_RUNTIME}")
|
||||
message(STATUS " USE_VULKAN_WRAPPER : ${USE_VULKAN_WRAPPER}")
|
||||
endif()
|
||||
message(STATUS " USE_PROF : ${USE_PROF}")
|
||||
message(STATUS " USE_QNNPACK : ${USE_QNNPACK}")
|
||||
|
@ -49,7 +49,7 @@ if(NOT USE_VULKAN_SHADERC_RUNTIME)
|
||||
|
||||
if(NOT GLSLC_PATH)
|
||||
message(FATAL_ERROR "USE_VULKAN glslc not found")
|
||||
endif(GLSLC_PATH)
|
||||
endif(NOT GLSLC_PATH)
|
||||
endif()
|
||||
|
||||
set(PYTHONPATH "$ENV{PYTHONPATH}")
|
||||
|
@ -4,11 +4,11 @@ endif()
|
||||
|
||||
if(ANDROID)
|
||||
if(NOT ANDROID_NDK)
|
||||
message(FATAL_ERROR "USE_VULKAN requires ANDROID_NDK set")
|
||||
message(FATAL_ERROR "USE_VULKAN requires ANDROID_NDK set.")
|
||||
endif()
|
||||
|
||||
# Vulkan from ANDROID_NDK
|
||||
set(VULKAN_INCLUDE_DIR "${ANDROID_NDK}/sources/third-party/vulkan/src/include")
|
||||
set(VULKAN_INCLUDE_DIR "${ANDROID_NDK}/sources/third_party/vulkan/src/include")
|
||||
message(STATUS "VULKAN_INCLUDE_DIR:${VULKAN_INCLUDE_DIR}")
|
||||
|
||||
set(VULKAN_ANDROID_NDK_WRAPPER_DIR "${ANDROID_NDK}/sources/third_party/vulkan/src/common")
|
||||
@ -23,9 +23,9 @@ if(ANDROID)
|
||||
|
||||
target_include_directories(VulkanWrapper PUBLIC .)
|
||||
target_include_directories(VulkanWrapper PUBLIC "${VULKAN_INCLUDE_DIR}")
|
||||
|
||||
target_link_libraries(VulkanWrapper ${CMAKE_DL_LIBS})
|
||||
|
||||
string(APPEND Vulkan_DEFINES " -DUSE_VULKAN_WRAPPER")
|
||||
list(APPEND Vulkan_INCLUDES ${VULKAN_WRAPPER_DIR})
|
||||
list(APPEND Vulkan_LIBS VulkanWrapper)
|
||||
|
||||
@ -65,7 +65,7 @@ if(ANDROID)
|
||||
RESULT_VARIABLE error_code)
|
||||
|
||||
if(error_code)
|
||||
message(FATAL_ERROR "Failed to build ANDROID_NDK shaderc error_code:${error_code}")
|
||||
message(FATAL_ERROR "Failed to build ANDROID_NDK Shaderc error_code:${error_code}")
|
||||
else()
|
||||
unset(GOOGLE_SHADERC_LIBRARIES CACHE)
|
||||
find_library(
|
||||
@ -76,79 +76,26 @@ if(ANDROID)
|
||||
endif(NOT GOOGLE_SHADERC_LIBRARIES)
|
||||
|
||||
if(GOOGLE_SHADERC_INCLUDE_DIRS AND GOOGLE_SHADERC_LIBRARIES)
|
||||
message(STATUS "shaderc FOUND include:${GOOGLE_SHADERC_INCLUDE_DIRS}")
|
||||
message(STATUS "shaderc FOUND libs:${GOOGLE_SHADERC_LIBRARIES}")
|
||||
set(Shaderc_FOUND TRUE)
|
||||
message(STATUS "Shaderc FOUND include:${GOOGLE_SHADERC_INCLUDE_DIRS}")
|
||||
message(STATUS "Shaderc FOUND libs:${GOOGLE_SHADERC_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
list(APPEND Vulkan_INCLUDES ${GOOGLE_SHADERC_INCLUDE_DIRS})
|
||||
list(APPEND Vulkan_LIBS ${GOOGLE_SHADERC_LIBRARIES})
|
||||
endif(USE_VULKAN_SHADERC_RUNTIME)
|
||||
else()
|
||||
if(DEFINED ENV{VULKAN_SDK})
|
||||
message(STATUS "VULKAN_SDK:$ENV{VULKAN_SDK}")
|
||||
find_package(Vulkan)
|
||||
|
||||
set(VULKAN_INCLUDE_DIR "$ENV{VULKAN_SDK}/source/Vulkan-Headers/include")
|
||||
message(STATUS "VULKAN_INCLUDE_DIR:${VULKAN_INCLUDE_DIR}")
|
||||
|
||||
if(USE_VULKAN_WRAPPER)
|
||||
# Vulkan wrapper from VULKAN_SDK
|
||||
set(VULKAN_SDK_WRAPPER_DIR "$ENV{VULKAN_SDK}/source/Vulkan-Tools/common")
|
||||
message(STATUS "Vulkan_SDK_WRAPPER_DIR:${VULKAN_SDK_WRAPPER_DIR}")
|
||||
set(VULKAN_WRAPPER_DIR "${VULKAN_SDK_WRAPPER_DIR}")
|
||||
|
||||
add_library(
|
||||
VulkanWrapper
|
||||
STATIC
|
||||
${VULKAN_WRAPPER_DIR}/vulkan_wrapper.h
|
||||
${VULKAN_WRAPPER_DIR}/vulkan_wrapper.cpp)
|
||||
|
||||
target_include_directories(VulkanWrapper PUBLIC .)
|
||||
target_include_directories(VulkanWrapper PUBLIC "${VULKAN_INCLUDE_DIR}")
|
||||
|
||||
target_link_libraries(VulkanWrapper ${CMAKE_DL_LIBS})
|
||||
|
||||
list(APPEND Vulkan_INCLUDES ${VULKAN_WRAPPER_DIR})
|
||||
list(APPEND Vulkan_LIBS VulkanWrapper)
|
||||
else(USE_VULKAN_WRAPPER)
|
||||
find_library(VULKAN_LIBRARY
|
||||
NAMES vulkan
|
||||
PATHS
|
||||
"$ENV{VULKAN_SDK}/${CMAKE_HOST_SYSTEM_PROCESSOR}/lib")
|
||||
|
||||
if(NOT VULKAN_LIBRARY)
|
||||
message(FATAL_ERROR "USE_VULKAN: Vulkan library not found")
|
||||
endif()
|
||||
|
||||
message(STATUS "VULKAN_LIBRARY:${VULKAN_LIBRARY}")
|
||||
message(STATUS "VULKAN_INCLUDE_DIR:${VULKAN_INCLUDE_DIR}")
|
||||
|
||||
list(APPEND Vulkan_INCLUDES ${VULKAN_INCLUDE_DIR})
|
||||
list(APPEND Vulkan_LIBS ${VULKAN_LIBRARY})
|
||||
endif(USE_VULKAN_WRAPPER)
|
||||
|
||||
set(GOOGLE_SHADERC_INCLUDE_SEARCH_PATH $ENV{VULKAN_SDK}/${CMAKE_HOST_SYSTEM_PROCESSOR}/include)
|
||||
set(GOOGLE_SHADERC_LIBRARY_SEARCH_PATH $ENV{VULKAN_SDK}/${CMAKE_HOST_SYSTEM_PROCESSOR}/lib)
|
||||
|
||||
else()
|
||||
# Try looking in system path as a last resort.
|
||||
find_package(Vulkan)
|
||||
if(NOT Vulkan_FOUND)
|
||||
message(FATAL_ERROR "USE_VULKAN requires either Vulkan installed on system path or environment var VULKAN_SDK set")
|
||||
endif()
|
||||
|
||||
list(APPEND Vulkan_INCLUDES ${Vulkan_INCLUDE_DIRS})
|
||||
list(APPEND Vulkan_LIBS ${Vulkan_LIBRARIES})
|
||||
|
||||
if(USE_VULKAN_WRAPPER)
|
||||
message(STATUS "USE_VULKAN_WRAPPER is unsupported when environment var VULKAN_SDK not set")
|
||||
caffe2_update_option(USE_VULKAN_WRAPPER OFF)
|
||||
endif()
|
||||
|
||||
set(GOOGLE_SHADERC_INCLUDE_SEARCH_PATH ${Vulkan_INCLUDE_DIR})
|
||||
set(GOOGLE_SHADERC_LIBRARY_SEARCH_PATH ${Vulkan_LIBRARY})
|
||||
if(NOT Vulkan_FOUND)
|
||||
message(FATAL_ERROR "USE_VULKAN requires either Vulkan installed on system path or environment var VULKAN_SDK set.")
|
||||
endif()
|
||||
|
||||
list(APPEND Vulkan_INCLUDES ${Vulkan_INCLUDE_DIRS})
|
||||
list(APPEND Vulkan_LIBS ${Vulkan_LIBRARIES})
|
||||
|
||||
set(GOOGLE_SHADERC_INCLUDE_SEARCH_PATH ${Vulkan_INCLUDE_DIR})
|
||||
set(GOOGLE_SHADERC_LIBRARY_SEARCH_PATH ${Vulkan_LIBRARY})
|
||||
|
||||
if(USE_VULKAN_SHADERC_RUNTIME)
|
||||
find_path(
|
||||
GOOGLE_SHADERC_INCLUDE_DIRS
|
||||
@ -165,14 +112,15 @@ else()
|
||||
DEFAULT_MSG
|
||||
GOOGLE_SHADERC_INCLUDE_DIRS
|
||||
GOOGLE_SHADERC_LIBRARIES)
|
||||
|
||||
if(NOT Shaderc_FOUND)
|
||||
message(FATAL_ERROR "USE_VULKAN: Shaderc not found in VULKAN_SDK")
|
||||
else()
|
||||
message(STATUS "shaderc FOUND include:${GOOGLE_SHADERC_INCLUDE_DIRS}")
|
||||
message(STATUS "shaderc FOUND libs:${GOOGLE_SHADERC_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
list(APPEND Vulkan_INCLUDES ${GOOGLE_SHADERC_INCLUDE_DIRS})
|
||||
list(APPEND Vulkan_LIBS ${GOOGLE_SHADERC_LIBRARIES})
|
||||
endif(USE_VULKAN_SHADERC_RUNTIME)
|
||||
endif()
|
||||
|
||||
|
Reference in New Issue
Block a user