Adds ov::internal::exclusive_async_requests in ov::internal::supported_properties (#18746)
* Adds ov::internal::exclusive_async_requests into ov::internal::supported_properties * Update HETERO tests for ov::internal::exclusive_async_requests
This commit is contained in:
@@ -1026,6 +1026,16 @@ ov::AnyMap ov::CoreImpl::get_supported_property(const std::string& full_device_n
|
||||
} catch (ov::Exception&) {
|
||||
}
|
||||
|
||||
// try to search against internal supported_properties
|
||||
try {
|
||||
for (auto&& property : ICore::get_property(device_name, ov::internal::supported_properties, {})) {
|
||||
if (property.is_mutable()) {
|
||||
supported_config_keys.emplace_back(std::move(property));
|
||||
}
|
||||
}
|
||||
} catch (ov::Exception&) {
|
||||
}
|
||||
|
||||
// collect supported properties for HW device
|
||||
AnyMap supported_config;
|
||||
for (auto&& kvp : flattened_config) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "ie_plugin_config.hpp"
|
||||
#include "itt.hpp"
|
||||
#include "openvino/op/util/op_types.hpp"
|
||||
#include "openvino/runtime/internal_properties.hpp"
|
||||
#include "openvino/runtime/properties.hpp"
|
||||
#include "openvino/util/common_util.hpp"
|
||||
#include "plugin.hpp"
|
||||
@@ -410,7 +411,17 @@ ov::hetero::CompiledModel::CompiledModel(const std::shared_ptr<ov::Model>& model
|
||||
// disable caching for subgraphs, because the whole HETERO model is cached
|
||||
auto device_config = metaDevices[m_compiled_submodels[id].device];
|
||||
device_config[ov::cache_dir.name()] = "";
|
||||
|
||||
// set exclusive_async_requests in case when model is split
|
||||
if (orderedSubgraphs.size() > 1) {
|
||||
auto supported_internal_properties =
|
||||
plugin->get_core()->get_property(m_compiled_submodels[id].device, ov::internal::supported_properties);
|
||||
if (std::find(supported_internal_properties.begin(),
|
||||
supported_internal_properties.end(),
|
||||
ov::internal::exclusive_async_requests) != supported_internal_properties.end()) {
|
||||
// adds property if it is not set yet
|
||||
device_config.insert(ov::internal::exclusive_async_requests(true));
|
||||
}
|
||||
}
|
||||
m_compiled_submodels[id].compiled_model = plugin->get_core()->compile_model(m_compiled_submodels[id].model,
|
||||
m_compiled_submodels[id].device,
|
||||
device_config);
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
|
||||
using namespace ov::hetero;
|
||||
|
||||
Configuration::Configuration()
|
||||
: dump_graph(false),
|
||||
exclusive_async_requests(true),
|
||||
device_properties({ov::internal::exclusive_async_requests(exclusive_async_requests)}) {}
|
||||
Configuration::Configuration() : dump_graph(false) {}
|
||||
|
||||
Configuration::Configuration(const ov::AnyMap& config, const Configuration& defaultCfg, bool throwOnUnsupported) {
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
@@ -27,10 +24,6 @@ Configuration::Configuration(const ov::AnyMap& config, const Configuration& defa
|
||||
dump_graph = value.as<bool>();
|
||||
} else if ("TARGET_FALLBACK" == key || ov::device::priorities == key) {
|
||||
device_priorities = value.as<std::string>();
|
||||
} else if (ov::internal::exclusive_async_requests == key) {
|
||||
exclusive_async_requests = value.as<bool>();
|
||||
// property should be passed to underlying devices as part of `get_device_properties()`
|
||||
device_properties.emplace(key, value);
|
||||
} else {
|
||||
if (throwOnUnsupported)
|
||||
OPENVINO_THROW("Property was not found: ", key);
|
||||
@@ -46,8 +39,6 @@ ov::Any Configuration::get(const std::string& name) const {
|
||||
return {dump_graph};
|
||||
} else if (name == "TARGET_FALLBACK" || name == ov::device::priorities) {
|
||||
return {device_priorities};
|
||||
} else if (name == ov::internal::exclusive_async_requests) {
|
||||
return {exclusive_async_requests};
|
||||
} else {
|
||||
OPENVINO_THROW("Property was not found: ", name);
|
||||
}
|
||||
@@ -58,8 +49,7 @@ std::vector<ov::PropertyName> Configuration::get_supported() const {
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
static const std::vector<ov::PropertyName> names = {HETERO_CONFIG_KEY(DUMP_GRAPH_DOT),
|
||||
"TARGET_FALLBACK",
|
||||
ov::device::priorities,
|
||||
ov::internal::exclusive_async_requests};
|
||||
ov::device::priorities};
|
||||
return names;
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
@@ -68,8 +58,7 @@ ov::AnyMap Configuration::get_hetero_properties() const {
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
return {{HETERO_CONFIG_KEY(DUMP_GRAPH_DOT), dump_graph},
|
||||
{"TARGET_FALLBACK", device_priorities},
|
||||
{ov::device::priorities.name(), device_priorities},
|
||||
{ov::internal::exclusive_async_requests.name(), exclusive_async_requests}};
|
||||
{ov::device::priorities.name(), device_priorities}};
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ struct Configuration {
|
||||
ov::AnyMap get_device_properties() const;
|
||||
|
||||
bool dump_graph;
|
||||
bool exclusive_async_requests;
|
||||
std::string device_priorities;
|
||||
ov::AnyMap device_properties;
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//
|
||||
#include "hetero_tests.hpp"
|
||||
#include "openvino/runtime/exec_model_info.hpp"
|
||||
#include "openvino/runtime/internal_properties.hpp"
|
||||
#include "openvino/runtime/properties.hpp"
|
||||
|
||||
using namespace ov::hetero::tests;
|
||||
@@ -54,7 +55,7 @@ TEST_F(HeteroTests, compile_with_device_properties) {
|
||||
auto mock0_properties = device_properties.at("MOCK0.0").as<ov::AnyMap>();
|
||||
ASSERT_TRUE(mock0_properties.count(ov::num_streams.name()));
|
||||
ASSERT_TRUE(mock0_properties.count(ov::enable_profiling.name()));
|
||||
EXPECT_EQ(4, mock0_properties.at(ov::num_streams.name()).as<ov::streams::Num>());
|
||||
EXPECT_EQ(1, mock0_properties.at(ov::num_streams.name()).as<ov::streams::Num>());
|
||||
EXPECT_EQ(false, mock0_properties.at(ov::enable_profiling.name()).as<bool>());
|
||||
ASSERT_TRUE(device_properties.count("MOCK1.0"));
|
||||
auto mock1_properties = device_properties.at("MOCK1.0").as<ov::AnyMap>();
|
||||
@@ -64,6 +65,25 @@ TEST_F(HeteroTests, compile_with_device_properties) {
|
||||
EXPECT_EQ(true, mock1_properties.at(ov::enable_profiling.name()).as<bool>());
|
||||
}
|
||||
|
||||
TEST_F(HeteroTests, compile_with_device_properties_no_exclusive) {
|
||||
ov::AnyMap config = {ov::device::priorities("MOCK0,MOCK1"),
|
||||
ov::internal::exclusive_async_requests(false),
|
||||
ov::device::properties("MOCK0", ov::num_streams(4)),
|
||||
ov::device::properties("MOCK1", ov::num_streams(6))};
|
||||
auto model = create_model_with_subtract_reshape();
|
||||
auto compiled_model = core.compile_model(model, "HETERO", config);
|
||||
EXPECT_THROW(compiled_model.get_property(ov::num_streams), ov::Exception);
|
||||
auto device_properties = compiled_model.get_property(ov::device::properties.name()).as<ov::AnyMap>();
|
||||
ASSERT_TRUE(device_properties.count("MOCK0.0"));
|
||||
auto mock0_properties = device_properties.at("MOCK0.0").as<ov::AnyMap>();
|
||||
ASSERT_TRUE(mock0_properties.count(ov::num_streams.name()));
|
||||
EXPECT_EQ(4, mock0_properties.at(ov::num_streams.name()).as<ov::streams::Num>());
|
||||
ASSERT_TRUE(device_properties.count("MOCK1.0"));
|
||||
auto mock1_properties = device_properties.at("MOCK1.0").as<ov::AnyMap>();
|
||||
ASSERT_TRUE(mock1_properties.count(ov::num_streams.name()));
|
||||
EXPECT_EQ(6, mock1_properties.at(ov::num_streams.name()).as<ov::streams::Num>());
|
||||
}
|
||||
|
||||
TEST_F(HeteroTests, get_runtime_model) {
|
||||
ov::AnyMap config = {ov::device::priorities("MOCK0,MOCK1")};
|
||||
auto model = create_model_with_subtract_reshape();
|
||||
|
||||
@@ -206,6 +206,11 @@ public:
|
||||
ov::enable_profiling.name()};
|
||||
return decltype(ov::supported_properties)::value_type(supported_properties);
|
||||
} else if (name == ov::num_streams) {
|
||||
if (m_config.count(ov::internal::exclusive_async_requests.name())) {
|
||||
auto exclusive_async_requests = m_config.at(ov::internal::exclusive_async_requests.name()).as<bool>();
|
||||
if (exclusive_async_requests)
|
||||
return ov::streams::Num(1);
|
||||
}
|
||||
return m_config.count(ov::num_streams.name()) ? m_config.at(ov::num_streams.name()) : ov::streams::Num(1);
|
||||
} else if (name == ov::enable_profiling) {
|
||||
return m_config.count(ov::enable_profiling.name()) ? m_config.at(ov::enable_profiling.name()) : false;
|
||||
@@ -526,6 +531,8 @@ public:
|
||||
num_streams = it.second.as<int32_t>();
|
||||
else if (it.first == ov::enable_profiling.name())
|
||||
m_profiling = it.second.as<bool>();
|
||||
else if (it.first == ov::internal::exclusive_async_requests.name())
|
||||
exclusive_async_requests = it.second.as<bool>();
|
||||
else if (it.first == ov::device::id.name())
|
||||
continue;
|
||||
else
|
||||
@@ -561,7 +568,10 @@ public:
|
||||
return decltype(ov::supported_properties)::value_type(supportedProperties);
|
||||
} else if (name == ov::internal::supported_properties) {
|
||||
return decltype(ov::internal::supported_properties)::value_type(
|
||||
{ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO}});
|
||||
{ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO},
|
||||
ov::PropertyName{ov::internal::exclusive_async_requests.name(), ov::PropertyMutability::RW}});
|
||||
} else if (name == ov::internal::exclusive_async_requests) {
|
||||
return decltype(ov::internal::exclusive_async_requests)::value_type{exclusive_async_requests};
|
||||
} else if (name == ov::device::uuid) {
|
||||
ov::device::UUID uuid;
|
||||
for (size_t i = 0; i < uuid.MAX_UUID_SIZE; i++) {
|
||||
@@ -608,6 +618,7 @@ public:
|
||||
|
||||
private:
|
||||
int32_t num_streams{0};
|
||||
bool exclusive_async_requests = false;
|
||||
};
|
||||
|
||||
class MockPluginSubtract : public MockPluginBase {
|
||||
|
||||
@@ -40,8 +40,7 @@ TEST_F(HeteroTests, get_property_supported_metrics) {
|
||||
TEST_F(HeteroTests, get_property_supported_configs) {
|
||||
const std::vector<std::string> supported_configs = {"HETERO_DUMP_GRAPH_DOT",
|
||||
"TARGET_FALLBACK",
|
||||
ov::device::priorities.name(),
|
||||
"EXCLUSIVE_ASYNC_REQUESTS"};
|
||||
ov::device::priorities.name()};
|
||||
auto actual_supported_configs =
|
||||
core.get_property("HETERO", METRIC_KEY(SUPPORTED_CONFIG_KEYS)).as<std::vector<std::string>>();
|
||||
EXPECT_EQ(supported_configs.size(), actual_supported_configs.size());
|
||||
@@ -76,10 +75,4 @@ TEST_F(HeteroTests, set_property_device_priorities) {
|
||||
core.set_property("HETERO", {{"TARGET_FALLBACK", "MOCK1,MOCK0"}});
|
||||
EXPECT_EQ("MOCK1,MOCK0", core.get_property("HETERO", ov::device::priorities));
|
||||
EXPECT_EQ("MOCK1,MOCK0", core.get_property("HETERO", "TARGET_FALLBACK").as<std::string>());
|
||||
}
|
||||
|
||||
TEST_F(HeteroTests, set_property_exclusive_async_request) {
|
||||
EXPECT_EQ(true, core.get_property("HETERO", "EXCLUSIVE_ASYNC_REQUESTS").as<bool>());
|
||||
core.set_property("HETERO", {{"EXCLUSIVE_ASYNC_REQUESTS", "NO"}});
|
||||
EXPECT_EQ(false, core.get_property("HETERO", "EXCLUSIVE_ASYNC_REQUESTS").as<bool>());
|
||||
}
|
||||
}
|
||||
@@ -664,7 +664,8 @@ Parameter Engine::GetMetricLegacy(const std::string& name, const std::map<std::s
|
||||
IE_SET_METRIC_RETURN(IMPORT_EXPORT_SUPPORT, true);
|
||||
} else if (ov::internal::supported_properties == name) {
|
||||
return decltype(ov::internal::supported_properties)::value_type{
|
||||
ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO}};
|
||||
ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO},
|
||||
ov::PropertyName{ov::internal::exclusive_async_requests.name(), ov::PropertyMutability::RW}};
|
||||
} else if (name == ov::internal::caching_properties) {
|
||||
std::vector<ov::PropertyName> cachingProperties = { METRIC_KEY(FULL_DEVICE_NAME) };
|
||||
return decltype(ov::internal::caching_properties)::value_type(cachingProperties);
|
||||
@@ -717,7 +718,8 @@ Parameter Engine::GetMetric(const std::string& name, const std::map<std::string,
|
||||
return decltype(ov::supported_properties)::value_type(supportedProperties);
|
||||
} else if (ov::internal::supported_properties == name) {
|
||||
return decltype(ov::internal::supported_properties)::value_type{
|
||||
ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO}}; ;
|
||||
ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO},
|
||||
ov::PropertyName{ov::internal::exclusive_async_requests.name(), ov::PropertyMutability::RW}};
|
||||
} else if (name == ov::device::full_name) {
|
||||
return decltype(ov::device::full_name)::value_type(deviceFullName);
|
||||
} else if (name == ov::available_devices) {
|
||||
|
||||
@@ -159,13 +159,13 @@ void Config::UpdateFromMap(const std::map<std::string, std::string>& config) {
|
||||
} else {
|
||||
THROW_GNA_EXCEPTION << "GNA compact mode should be true/false (YES/NO), but not " << value;
|
||||
}
|
||||
} else if (key == CONFIG_KEY(EXCLUSIVE_ASYNC_REQUESTS)) {
|
||||
} else if (key == ov::internal::exclusive_async_requests) {
|
||||
if (value == PluginConfigParams::YES) {
|
||||
gnaFlags.exclusive_async_requests = true;
|
||||
} else if (value == PluginConfigParams::NO) {
|
||||
gnaFlags.exclusive_async_requests = false;
|
||||
} else {
|
||||
THROW_GNA_EXCEPTION << "EXCLUSIVE_ASYNC_REQUESTS should be YES/NO, but not" << value;
|
||||
THROW_GNA_EXCEPTION << "ov::internal::exclusive_async_requests should be YES/NO, but not" << value;
|
||||
}
|
||||
} else if (key == ov::hint::performance_mode) {
|
||||
performance_mode = ov::util::from_string(value, ov::hint::performance_mode);
|
||||
@@ -316,7 +316,7 @@ void Config::AdjustKeyMapValues() {
|
||||
keyConfigMap[GNA_CONFIG_KEY(COMPILE_TARGET)] = DeviceToString(target->get_user_set_compile_target());
|
||||
keyConfigMap[ov::intel_gna::memory_reuse.name()] =
|
||||
gnaFlags.compact_mode ? PluginConfigParams::YES : PluginConfigParams::NO;
|
||||
keyConfigMap[CONFIG_KEY(EXCLUSIVE_ASYNC_REQUESTS)] =
|
||||
keyConfigMap[ov::internal::exclusive_async_requests.name()] =
|
||||
gnaFlags.exclusive_async_requests ? PluginConfigParams::YES : PluginConfigParams::NO;
|
||||
keyConfigMap[ov::hint::performance_mode.name()] = ov::util::to_string(performance_mode);
|
||||
if (inference_precision != ov::element::undefined) {
|
||||
@@ -408,7 +408,8 @@ const Parameter Config::GetSupportedProperties(bool compiled) {
|
||||
|
||||
const Parameter Config::GetSupportedInternalProperties() {
|
||||
std::vector<ov::PropertyName> supported_internal_properties = {
|
||||
{ov::internal::caching_properties.name(), ov::PropertyMutability::RO}};
|
||||
{ov::internal::caching_properties.name(), ov::PropertyMutability::RO},
|
||||
{ov::internal::exclusive_async_requests.name(), ov::PropertyMutability::RW}};
|
||||
return supported_internal_properties;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ static constexpr Property<ImplForcingMap, PropertyMutability::RW> force_implemen
|
||||
static constexpr Property<std::string, PropertyMutability::RW> config_file{"CONFIG_FILE"};
|
||||
static constexpr Property<bool, PropertyMutability::RW> enable_lp_transformations{"LP_TRANSFORMS_MODE"};
|
||||
static constexpr Property<size_t, PropertyMutability::RW> max_dynamic_batch{"DYN_BATCH_LIMIT"};
|
||||
static constexpr Property<bool, PropertyMutability::RW> exclusive_async_requests{"EXCLUSIVE_ASYNC_REQUESTS"};
|
||||
static constexpr Property<bool, PropertyMutability::RW> nv12_two_inputs{"GPU_NV12_TWO_INPUTS"};
|
||||
static constexpr Property<float, PropertyMutability::RW> buffers_preallocation_ratio{"GPU_BUFFERS_PREALLOCATION_RATIO"};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ CompiledModel::CompiledModel(InferenceEngine::CNNNetwork &network,
|
||||
InferenceEngine::InputsDataMap* inputs,
|
||||
InferenceEngine::OutputsDataMap* outputs) :
|
||||
InferenceEngine::ExecutableNetworkThreadSafeDefault{[&]() -> InferenceEngine::ITaskExecutor::Ptr {
|
||||
if (config.get_property(ov::intel_gpu::exclusive_async_requests)) {
|
||||
if (config.get_property(ov::internal::exclusive_async_requests)) {
|
||||
//exclusiveAsyncRequests essentially disables the streams (and hence should be checked first) => aligned with the CPU behavior
|
||||
return executorManager()->getExecutor("GPU");
|
||||
} else if (config.get_property(ov::num_streams) > 1) {
|
||||
@@ -74,7 +74,7 @@ CompiledModel::CompiledModel(cldnn::BinaryInputBuffer& ib,
|
||||
InferenceEngine::InputsDataMap* inputs,
|
||||
InferenceEngine::OutputsDataMap* outputs) :
|
||||
InferenceEngine::ExecutableNetworkThreadSafeDefault{[&]() -> InferenceEngine::ITaskExecutor::Ptr {
|
||||
if (config.get_property(ov::intel_gpu::exclusive_async_requests)) {
|
||||
if (config.get_property(ov::internal::exclusive_async_requests)) {
|
||||
//exclusiveAsyncRequests essentially disables the streams (and hence should be checked first) => aligned with the CPU behavior
|
||||
return executorManager()->getExecutor("GPU");
|
||||
} else if (config.get_property(ov::num_streams) > 1) {
|
||||
|
||||
@@ -761,7 +761,8 @@ std::vector<ov::PropertyName> Plugin::get_supported_properties() const {
|
||||
std::vector<ov::PropertyName> Plugin::get_supported_internal_properties() const {
|
||||
static const std::vector<ov::PropertyName> supported_internal_properties = {
|
||||
ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO},
|
||||
ov::PropertyName{ov::internal::config_device_id.name(), ov::PropertyMutability::WO}};
|
||||
ov::PropertyName{ov::internal::config_device_id.name(), ov::PropertyMutability::WO},
|
||||
ov::PropertyName{ov::internal::exclusive_async_requests.name(), ov::PropertyMutability::RW}};
|
||||
return supported_internal_properties;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "intel_gpu/runtime/execution_config.hpp"
|
||||
#include "intel_gpu/runtime/debug_configuration.hpp"
|
||||
#include "openvino/runtime/internal_properties.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
@@ -52,9 +53,9 @@ void ExecutionConfig::set_default() {
|
||||
std::make_tuple(ov::intel_gpu::hint::queue_throttle, ov::intel_gpu::hint::ThrottleLevel::MEDIUM),
|
||||
std::make_tuple(ov::intel_gpu::hint::queue_priority, ov::hint::Priority::MEDIUM),
|
||||
std::make_tuple(ov::intel_gpu::enable_loop_unrolling, true),
|
||||
std::make_tuple(ov::internal::exclusive_async_requests, false),
|
||||
|
||||
// Legacy API properties
|
||||
std::make_tuple(ov::intel_gpu::exclusive_async_requests, false),
|
||||
std::make_tuple(ov::intel_gpu::nv12_two_inputs, false),
|
||||
std::make_tuple(ov::intel_gpu::config_file, ""),
|
||||
std::make_tuple(ov::intel_gpu::enable_lp_transformations, false));
|
||||
@@ -154,6 +155,10 @@ void ExecutionConfig::apply_performance_hints(const cldnn::device_info& info) {
|
||||
int32_t n_streams = std::max<int32_t>(info.num_ccs, 2);
|
||||
set_property(ov::num_streams(n_streams));
|
||||
}
|
||||
|
||||
if (get_property(ov::internal::exclusive_async_requests)) {
|
||||
set_property(ov::num_streams(1));
|
||||
}
|
||||
}
|
||||
|
||||
void ExecutionConfig::apply_priority_hints(const cldnn::device_info& info) {
|
||||
|
||||
@@ -234,7 +234,6 @@ ov::Any ov::template_plugin::Plugin::get_property(const std::string& name, const
|
||||
std::vector<ov::PropertyName> rw_properties{ov::device::id,
|
||||
ov::enable_profiling,
|
||||
ov::hint::performance_mode,
|
||||
ov::internal::exclusive_async_requests,
|
||||
ov::template_plugin::disable_transformations};
|
||||
return rw_properties;
|
||||
};
|
||||
@@ -274,7 +273,8 @@ ov::Any ov::template_plugin::Plugin::get_property(const std::string& name, const
|
||||
return decltype(ov::supported_properties)::value_type(supported_properties);
|
||||
} else if (ov::internal::supported_properties == name) {
|
||||
return decltype(ov::internal::supported_properties)::value_type{
|
||||
ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO}};
|
||||
ov::PropertyName{ov::internal::caching_properties.name(), ov::PropertyMutability::RO},
|
||||
ov::PropertyName{ov::internal::exclusive_async_requests.name(), ov::PropertyMutability::RW}};
|
||||
} else if (ov::available_devices == name) {
|
||||
// TODO: fill list of available devices
|
||||
std::vector<std::string> available_devices = {""};
|
||||
|
||||
Reference in New Issue
Block a user