提交 6a397912 编写于 作者: 李寅

Support hexagon_nn version 2.1 in Hexagon SDK 3.4.0

上级 5f039212
...@@ -51,10 +51,9 @@ int HexagonControlWrapper::GetVersion() { ...@@ -51,10 +51,9 @@ int HexagonControlWrapper::GetVersion() {
bool HexagonControlWrapper::Config() { bool HexagonControlWrapper::Config() {
LOG(INFO) << "Hexagon config"; LOG(INFO) << "Hexagon config";
if (hexagon_nn_set_powersave_level(0) != 0) { MACE_CHECK(hexagon_nn_set_powersave_level(0) == 0, "hexagon power error");
return false; MACE_CHECK(hexagon_nn_config() == 0, "hexagon config error");
} return true;
return hexagon_nn_config() == 0;
} }
bool HexagonControlWrapper::Init() { bool HexagonControlWrapper::Init() {
...@@ -80,7 +79,10 @@ bool HexagonControlWrapper::SetupGraph(const NetDef &net_def, ...@@ -80,7 +79,10 @@ bool HexagonControlWrapper::SetupGraph(const NetDef &net_def,
int64_t t0 = NowMicros(); int64_t t0 = NowMicros();
// const node // const node
std::thread const_thread([&]() { #if defined(MACE_USE_NNLIB_CAF) || defined(MACE_USE_NNLIB_OLD)
std::thread const_thread([&]()
#endif
{
std::vector<hexagon_nn_const_node> const_node_list; std::vector<hexagon_nn_const_node> const_node_list;
for (const ConstTensor &const_tensor : net_def.tensors()) { for (const ConstTensor &const_tensor : net_def.tensors()) {
std::vector<int> tensor_shape(const_tensor.dims().begin(), std::vector<int> tensor_shape(const_tensor.dims().begin(),
...@@ -124,10 +126,16 @@ bool HexagonControlWrapper::SetupGraph(const NetDef &net_def, ...@@ -124,10 +126,16 @@ bool HexagonControlWrapper::SetupGraph(const NetDef &net_def,
"append const node error"); "append const node error");
} }
const_node_list.clear(); const_node_list.clear();
}); }
#if defined(MACE_USE_NNLIB_CAF) || defined(MACE_USE_NNLIB_OLD)
); // NOLINT
#endif
// op node // op node
std::thread op_thread([&]() { #if defined(MACE_USE_NNLIB_CAF) || defined(MACE_USE_NNLIB_OLD)
std::thread op_thread([&]()
#endif
{
OpMap op_map; OpMap op_map;
op_map.Init(); op_map.Init();
std::vector<hexagon_nn_op_node> op_node_list; std::vector<hexagon_nn_op_node> op_node_list;
...@@ -197,10 +205,12 @@ bool HexagonControlWrapper::SetupGraph(const NetDef &net_def, ...@@ -197,10 +205,12 @@ bool HexagonControlWrapper::SetupGraph(const NetDef &net_def,
op_node_list.clear(); op_node_list.clear();
cached_inputs.clear(); cached_inputs.clear();
cached_outputs.clear(); cached_outputs.clear();
}); }
#if defined(MACE_USE_NNLIB_CAF) || defined(MACE_USE_NNLIB_OLD)
); // NOLINT
const_thread.join(); const_thread.join();
op_thread.join(); op_thread.join();
#endif
// input info // input info
num_inputs_ = 0; num_inputs_ = 0;
......
...@@ -225,7 +225,152 @@ __QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_execute_new)( ...@@ -225,7 +225,152 @@ __QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_execute_new)(
} }
#endif #endif
#else // nnlib version #elif defined(MACE_USE_NNLIB_2_1) // nnlib version
#ifndef __QAIC_HEADER
#define __QAIC_HEADER(ff) ff
#endif //__QAIC_HEADER
#ifndef __QAIC_HEADER_EXPORT
#define __QAIC_HEADER_EXPORT
#endif // __QAIC_HEADER_EXPORT
#ifndef __QAIC_HEADER_ATTRIBUTE
#define __QAIC_HEADER_ATTRIBUTE
#endif // __QAIC_HEADER_ATTRIBUTE
#ifndef __QAIC_IMPL
#define __QAIC_IMPL(ff) ff
#endif //__QAIC_IMPL
#ifndef __QAIC_IMPL_EXPORT
#define __QAIC_IMPL_EXPORT
#endif // __QAIC_IMPL_EXPORT
#ifndef __QAIC_IMPL_ATTRIBUTE
#define __QAIC_IMPL_ATTRIBUTE
#endif // __QAIC_IMPL_ATTRIBUTE
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__)
#define __QAIC_STRING1_OBJECT_DEFINED__
#define __STRING1_OBJECT__
typedef struct _cstring1_s {
char* data;
int dataLen;
} _cstring1_t;
#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */
typedef struct hexagon_nn_input hexagon_nn_input;
struct hexagon_nn_input {
unsigned int src_id;
unsigned int output_idx;
};
typedef struct hexagon_nn_output hexagon_nn_output;
struct hexagon_nn_output {
unsigned int rank;
unsigned int max_sizes[8];
unsigned int elementsize;
int zero_offset;
float stepsize;
};
typedef struct hexagon_nn_perfinfo hexagon_nn_perfinfo;
struct hexagon_nn_perfinfo {
unsigned int node_id;
unsigned int node_type;
unsigned int executions;
unsigned int unused;
unsigned int counter_lo;
unsigned int counter_hi;
};
typedef int hexagon_nn_nn_id;
enum hexagon_nn_padding_type {
NN_PAD_NA,
NN_PAD_SAME,
NN_PAD_VALID,
NN_PAD_MIRROR_REFLECT,
NN_PAD_MIRROR_SYMMETRIC,
NN_PAD_SAME_CAFFE,
_32BIT_PLACEHOLDER_hexagon_nn_padding_type = 0x7fffffff
};
typedef enum hexagon_nn_padding_type hexagon_nn_padding_type;
enum hexagon_nn_corner_type {
NN_CORNER_RELEASE,
NN_CORNER_TURBO,
NN_CORNER_NOMPLUS,
NN_CORNER_NOMINAL,
NN_CORNER_SVSPLUS,
NN_CORNER_SVS,
NN_CORNER_SVS2,
_32BIT_PLACEHOLDER_hexagon_nn_corner_type = 0x7fffffff
};
typedef enum hexagon_nn_corner_type hexagon_nn_corner_type;
enum hexagon_nn_dcvs_type {
NN_DCVS_DEFAULT,
NN_DCVS_ENABLE,
NN_DCVS_DISABLE,
_32BIT_PLACEHOLDER_hexagon_nn_dcvs_type = 0x7fffffff
};
typedef enum hexagon_nn_dcvs_type hexagon_nn_dcvs_type;
typedef struct hexagon_nn_tensordef hexagon_nn_tensordef;
struct hexagon_nn_tensordef {
unsigned int batches;
unsigned int height;
unsigned int width;
unsigned int depth;
unsigned char* data;
int dataLen;
unsigned int data_valid_len;
unsigned int unused;
};
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_config)(void) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_get_dsp_offset)(unsigned int* libhexagon_addr, unsigned int* fastrpc_shell_addr) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_init)(hexagon_nn_nn_id* g) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_set_debug_level)(hexagon_nn_nn_id id, int level) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_snpprint)(hexagon_nn_nn_id id, unsigned char* buf, int bufLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_getlog)(hexagon_nn_nn_id id, unsigned char* buf, int bufLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_append_node)(hexagon_nn_nn_id id, unsigned int node_id, unsigned int operation, hexagon_nn_padding_type padding, const hexagon_nn_input* inputs, int inputsLen, const hexagon_nn_output* outputs, int outputsLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_append_const_node)(hexagon_nn_nn_id id, unsigned int node_id, unsigned int batches, unsigned int height, unsigned int width, unsigned int depth, const unsigned char* data, int dataLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_append_empty_const_node)(hexagon_nn_nn_id id, unsigned int node_id, unsigned int batches, unsigned int height, unsigned int width, unsigned int depth, unsigned int size) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_populate_const_node)(hexagon_nn_nn_id id, unsigned int node_id, const unsigned char* data, int dataLen, unsigned int target_offset) __QAIC_HEADER_ATTRIBUTE;
typedef struct hexagon_nn_op_node hexagon_nn_op_node;
struct hexagon_nn_op_node {
unsigned int node_id;
unsigned int operation;
hexagon_nn_padding_type padding;
hexagon_nn_input* inputs;
int inputsLen;
hexagon_nn_output* outputs;
int outputsLen;
};
typedef struct hexagon_nn_const_node hexagon_nn_const_node;
struct hexagon_nn_const_node {
unsigned int node_id;
hexagon_nn_tensordef tensor;
};
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_append_node_list)(hexagon_nn_nn_id id, const hexagon_nn_op_node* ops, int opsLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_append_const_node_list)(hexagon_nn_nn_id id, const hexagon_nn_const_node* consts, int constsLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_prepare)(hexagon_nn_nn_id id) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_execute)(hexagon_nn_nn_id id, unsigned int batches_in, unsigned int height_in, unsigned int width_in, unsigned int depth_in, const unsigned char* data_in, int data_inLen, unsigned int* batches_out, unsigned int* height_out, unsigned int* width_out, unsigned int* depth_out, unsigned char* data_out, int data_outLen, unsigned int* data_len_out) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_teardown)(hexagon_nn_nn_id id) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_set_powersave_level)(unsigned int level) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_set_powersave_details)(hexagon_nn_corner_type corner, hexagon_nn_dcvs_type dcvs, unsigned int latency) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_get_perfinfo)(hexagon_nn_nn_id id, hexagon_nn_perfinfo* info_out, int info_outLen, unsigned int* n_items) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_reset_perfinfo)(hexagon_nn_nn_id id, unsigned int event) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_last_execution_cycles)(hexagon_nn_nn_id id, unsigned int* cycles_lo, unsigned int* cycles_hi) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_version)(int* ver) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_op_name_to_id)(const char* name, unsigned int* node_id) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_op_id_to_name)(unsigned int node_id, char* name, int nameLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_disable_dcvs)(void) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_GetHexagonBinaryVersion)(int* ver) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_PrintLog)(const unsigned char* buf, int bufLen) __QAIC_HEADER_ATTRIBUTE;
__QAIC_HEADER_EXPORT int __QAIC_HEADER(hexagon_nn_execute_new)(hexagon_nn_nn_id id, const hexagon_nn_tensordef* inputs, int inputsLen, hexagon_nn_tensordef* outputs, int outputsLen) __QAIC_HEADER_ATTRIBUTE;
#ifdef __cplusplus
}
#endif
#else // nnlib version : MACE_USE_NNLIB_CAF
#ifndef __QAIC_HEADER #ifndef __QAIC_HEADER
#define __QAIC_HEADER(ff) ff #define __QAIC_HEADER(ff) ff
......
...@@ -218,7 +218,231 @@ DEF_OP(QuantizedBiasAdd_8p8to8) ...@@ -218,7 +218,231 @@ DEF_OP(QuantizedBiasAdd_8p8to8)
#undef DEF_OP_WREF #undef DEF_OP_WREF
#endif #endif
#else // nnlib version #elif defined(MACE_USE_NNLIB_2_1) // nnlib version
DEF_OP(INPUT)
DEF_OP(OUTPUT)
DEF_OP(Nop)
DEF_OP(Const)
DEF_OP(Check)
DEF_OP(Close_f)
DEF_OP(Close_quint8)
DEF_OP(Close_q_quint8)
DEF_OP(Close_int32)
DEF_OP(Close_qint32)
DEF_OP(PPrint_8)
DEF_OP(PPrint_32)
DEF_OP(PPrint_f)
DEF_OP(PreFree)
DEF_OP(Flatten)
#ifndef DEF_OP_WREF
#define DEF_OP_WREF(NAME) DEF_OP(NAME) DEF_OP(NAME##_ref)
#define __SELF_DEF_OP_WREF
#endif
DEF_OP_WREF(QuantizedConv2d_8x8to32)
DEF_OP_WREF(QuantizedMatMul_8x8to32)
DEF_OP_WREF(QuantizeDownAndShrinkRange_32to8)
DEF_OP_WREF(QuantizedRelu_8)
DEF_OP_WREF(QuantizedReluX_8)
DEF_OP_WREF(QuantizedMaxPool_8)
DEF_OP_WREF(QuantizedAvgPool_8)
DEF_OP_WREF(QuantizedL2Pool_8)
DEF_OP_WREF(QuantizedConcat_8)
DEF_OP_WREF(QuantizedBiasAdd_8p8to32)
DEF_OP_WREF(Min_f)
DEF_OP_WREF(Max_f)
DEF_OP_WREF(Quantize)
DEF_OP_WREF(Dequantize)
DEF_OP_WREF(Supernode_8x8p8to8)
DEF_OP(QuantizedFlatten)
DEF_OP(Softmax_f)
DEF_OP(Conv2d_f)
DEF_OP(MatMul_f)
DEF_OP(Relu_f)
DEF_OP(ReluX_f)
DEF_OP(AvgPool_f)
DEF_OP(L2Pool_f)
DEF_OP(MaxPool_f)
DEF_OP(Concat_f)
DEF_OP(BiasAdd_f)
DEF_OP(LRN_f)
DEF_OP(Variable)
DEF_OP(Assign)
DEF_OP(Reshape)
DEF_OP(QuantizedReshape)
DEF_OP(Tanh_f)
DEF_OP(Sigmoid_f)
DEF_OP(Slice_8)
DEF_OP(Slice_f)
DEF_OP(QuantizedSlice_8)
DEF_OP(Add_f)
DEF_OP(Mul_f)
DEF_OP(Minimum_f)
DEF_OP(Maximum_f)
DEF_OP_WREF(Requantize_32to8)
DEF_OP_WREF(RequantizationRange_32)
DEF_OP(Neg_f)
DEF_OP(Sub_f)
DEF_OP(AddN_f)
DEF_OP(Range_int32)
DEF_OP(Rank_int32)
DEF_OP(Transpose_int32)
DEF_OP(Transpose_f)
DEF_OP(InstanceNorm_f)
DEF_OP_WREF(QuantizedInstanceNorm_8)
DEF_OP(Sub_int32)
DEF_OP(Add_int32)
DEF_OP(Split_f)
DEF_OP(Dequantize_qint32_f)
DEF_OP(PRelu_f)
DEF_OP_WREF(QuantizedPRelu_8)
DEF_OP(Sum_f)
DEF_OP(Prod_f)
DEF_OP(Mul_int32)
DEF_OP(LogicalAnd_int32)
DEF_OP(LogicalOr_int32)
DEF_OP(LogicalXor_int32)
DEF_OP(Shape_int32)
DEF_OP(Pack_int32)
DEF_OP(MirrorPad_f)
DEF_OP(ResizeNearestNeighbor_f)
DEF_OP(StridedSlice_int32)
DEF_OP(StridedSlice_f)
DEF_OP(ExpandDims_int32)
DEF_OP(ExpandDims_f)
DEF_OP(LogSoftmax_f)
DEF_OP(Split_int32)
DEF_OP(QuantizedSplit_8)
DEF_OP(Deconv_f)
DEF_OP_WREF(QuantizedDeconv_8x8to32)
DEF_OP_WREF(QuantizedMul_8x8to32)
DEF_OP_WREF(QuantizedAdd_8p8to32)
DEF_OP_WREF(QuantizedSigmoid_8)
DEF_OP_WREF(QuantizedTanh_8)
DEF_OP_WREF(QuantizedSoftmax_8)
DEF_OP_WREF(QuantizedLRN_8)
DEF_OP_WREF(Quantizedpad2d_frame_8p)
DEF_OP_WREF(QuantizedSub_8p8to32)
DEF_OP_WREF(QuantizedMaximum_8)
DEF_OP_WREF(QuantizedMinimum_8)
DEF_OP(Pad_f)
DEF_OP(SpaceToBatchND_f)
DEF_OP(BatchToSpaceND_f)
DEF_OP(QuantizedPad_8)
DEF_OP(ResizeBilinear_f)
DEF_OP(ConcatV2_f)
DEF_OP(ConcatV2_int32)
DEF_OP(Prod_int32)
DEF_OP(Slice_int32)
DEF_OP(QuantizedAdd_8p8to8)
DEF_OP(QuantizedResizeBilinear_8)
DEF_OP(Supernode_8x8p8to8_d32)
DEF_OP(Convert_to_d32)
DEF_OP(Convert_from_d32)
DEF_OP_WREF(QuantizedMaxPool_8_d32)
DEF_OP_WREF(QuantizedConcat_8_d32)
DEF_OP_WREF(QuantizedAvgPool_8_d32)
DEF_OP(Sink)
DEF_OP_WREF(QuantizedPRelu_8_d32)
DEF_OP_WREF(AutoQuantize)
DEF_OP_WREF(QuantizedDepthwiseConv2d_8x8to32)
DEF_OP_WREF(DepthwiseConv2d_f)
DEF_OP(DepthwiseSupernode_8x8p8to8)
DEF_OP(DepthwiseSupernode_8x8p8to8_d32)
DEF_OP_WREF(QuantizedMul_8x8to8_d32)
DEF_OP(FullyConnected_u8)
#if 0
DEF_OP_WREF(QuantizedFC_8x8p8to8)
#endif
DEF_OP_WREF(QuantizedAdd_8p8to8_d32)
DEF_OP_WREF(QuantizedClamp_8)
DEF_OP(Clamp_f)
DEF_OP(QuantizeForTest_d32)
DEF_OP(Close_d32)
DEF_OP_WREF(QuantizedSub_8p8to8_d32)
DEF_OP(InputSupernode_8x8p8to8_outd32)
DEF_OP(QuantizedLRN_8_d32)
DEF_OP_WREF(QuantizedBiasAdd_32p32to32)
DEF_OP_WREF(Quantize_int32)
DEF_OP(Supernode_8x8p32to8)
DEF_OP(DepthwiseSupernode_8x8p32to8)
DEF_OP(Supernode_8x8p32to8_d32)
DEF_OP(DepthwiseSupernode_8x8p32to8_d32)
DEF_OP(InputSupernode_8x8p32to8_outd32)
DEF_OP(PPrint_8_d32)
DEF_OP(PPrintWithPadding_8_d32)
DEF_OP_WREF(AutoQuantize_d32)
DEF_OP_WREF(QuantizedTanh_8_d32)
DEF_OP_WREF(QuantizedSigmoid_8_d32)
DEF_OP_WREF(QuantizedSoftmax_8_d32)
DEF_OP_WREF(QuantizedL2Pool_8_d32)
DEF_OP(Gather_f)
DEF_OP(Gather_int32)
DEF_OP(Gather_8)
DEF_OP(Table_f)
DEF_OP(Table_int32)
DEF_OP(Table_8)
DEF_OP(FillPadding_8_d32)
DEF_OP(QuantizedResizeBilinear_8_d32)
DEF_OP(QuantizeINPUT_f_to_8)
DEF_OP_WREF(DeconvBias_8x8to32)
DEF_OP(SpaceToBatchND_8)
DEF_OP(BatchToSpaceND_8)
DEF_OP(SpaceToDepth_f)
DEF_OP(DepthToSpace_f)
DEF_OP(SpaceToDepth_8)
DEF_OP(DepthToSpace_8)
DEF_OP(DequantizeOUTPUT_8tof)
DEF_OP(QuantizedBatchNorm_8x8p8to8)
DEF_OP(QuantizedBatchNorm_8x8p32to8)
DEF_OP(QuantizedBatchNorm_8x8p8to8_d32)
DEF_OP(QuantizedBatchNorm_8x8p32to8_d32)
DEF_OP_WREF(QuantizedInstanceNorm_8_d32)
DEF_OP_WREF(QuantizedInstanceNormBG_8)
DEF_OP_WREF(QuantizedInstanceNormBG_8_d32)
DEF_OP(ChannelShuffle_f)
DEF_OP(ChannelShuffle_int32)
DEF_OP(QuantizedChannelShuffle_8)
#ifdef __SELF_DEF_OP_WREF
#undef __SELF_DEF_OP_WREF
#undef DEF_OP_WREF
#endif
#else // nnlib version : MACE_USE_NNLIB_CAF
DEF_OP(INPUT) DEF_OP(INPUT)
DEF_OP(OUTPUT) DEF_OP(OUTPUT)
......
...@@ -10,6 +10,7 @@ build --copt=-std=c++11 ...@@ -10,6 +10,7 @@ build --copt=-std=c++11
build --copt=-D_GLIBCXX_USE_C99_MATH_TR1 build --copt=-D_GLIBCXX_USE_C99_MATH_TR1
build --copt=-DMACE_OBFUSCATE_LITERALS build --copt=-DMACE_OBFUSCATE_LITERALS
build --copt=-DGEMMLOWP_USE_OPENMP build --copt=-DGEMMLOWP_USE_OPENMP
build --copt=-DMACE_USE_NNLIB_CAF
# Usage example: bazel build --config android # Usage example: bazel build --config android
build:android --crosstool_top=//external:android/crosstool build:android --crosstool_top=//external:android/crosstool
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册