提升网站建设,无投入网站推广,宁波网络优化seo,怎样查公司注册信息查询1、前言
继续学习NCNN。本次学习binaryop和eltwise。
2、学习内容
2.1、binaryop
binaryop是用来二元计算的op#xff0c;先来看binaryop.h的中关于二元计算的定义#xff0c;其中二元计算定义了如下操作。
enum OperationType
{Operation_ADD 0,Operation_SUB 1,Oper…1、前言
继续学习NCNN。本次学习binaryop和eltwise。
2、学习内容
2.1、binaryop
binaryop是用来二元计算的op先来看binaryop.h的中关于二元计算的定义其中二元计算定义了如下操作。
enum OperationType
{Operation_ADD 0,Operation_SUB 1,Operation_MUL 2,Operation_DIV 3,Operation_MAX 4,Operation_MIN 5,Operation_POW 6,Operation_RSUB 7,Operation_RDIV 8,Operation_RPOW 9,Operation_ATAN2 10,Operation_RATAN2 11
};在binaryop.cpp中实际调用了二元计算函数。
templatetypename Op
static void binary_op_broadcast(const Mat a, const Mat b, Mat c, const Option opt){...
}static void binary_op_broadcast(const Mat a, const Mat b, Mat c, int op_type, const Option opt)
{if (op_type BinaryOp::Operation_ADD) return binary_op_broadcastbinary_op_add(a, b, c, opt);if (op_type BinaryOp::Operation_SUB) return binary_op_broadcastbinary_op_sub(a, b, c, opt);if (op_type BinaryOp::Operation_MUL) return binary_op_broadcastbinary_op_mul(a, b, c, opt);if (op_type BinaryOp::Operation_DIV) return binary_op_broadcastbinary_op_div(a, b, c, opt);if (op_type BinaryOp::Operation_MAX) return binary_op_broadcastbinary_op_max(a, b, c, opt);if (op_type BinaryOp::Operation_MIN) return binary_op_broadcastbinary_op_min(a, b, c, opt);if (op_type BinaryOp::Operation_POW) return binary_op_broadcastbinary_op_pow(a, b, c, opt);if (op_type BinaryOp::Operation_RSUB) return binary_op_broadcastbinary_op_sub(b, a, c, opt);if (op_type BinaryOp::Operation_RDIV) return binary_op_broadcastbinary_op_div(b, a, c, opt);if (op_type BinaryOp::Operation_RPOW) return binary_op_broadcastbinary_op_pow(b, a, c, opt);if (op_type BinaryOp::Operation_ATAN2) return binary_op_broadcastbinary_op_atan2(a, b, c, opt);if (op_type BinaryOp::Operation_RATAN2) return binary_op_broadcastbinary_op_atan2(b, a, c, opt);
}可以看出二元操作是通过函数模板实现的。在binaryop_arm.cpp中实现了具体的二元操作的例子。
templatetypename Op
static void binary_op_vector_no_broadcast(const float* ptr, const float* ptr1, float* outptr, int size)
{const Op op;int i 0;
#if __ARM_NEONfor (; i 3 size; i 4){float32x4_t _p vld1q_f32(ptr);float32x4_t _b vld1q_f32(ptr1);float32x4_t _outp op(_p, _b); // 通过op来确定最终的操作vst1q_f32(outptr, _outp);ptr 4;ptr1 4;outptr 4;}
#endif // __ARM_NEONfor (; i size; i){*outptr op(*ptr, *ptr1);ptr 1;ptr1 1;outptr 1;}
}2.2、eltwise
elwise 主要用于两个Mat类型的数据逐元素之间的操作。在eltwise.h 中定义了三种三种计算方式
enum OperationType
{Operation_PROD 0,Operation_SUM 1,Operation_MAX 2
};eltwise_arm.h 继承于 eltwise.h在eltwise_arm.cpp中实现了三种操作在arm上的实现方式。
int Eltwise_arm::forward(const std::vectorMat bottom_blobs, std::vectorMat top_blobs, const Option opt) const
{// first blobconst Mat bottom_blob bottom_blobs[0]; int w bottom_blob.w;int h bottom_blob.h;int d bottom_blob.d;int channels bottom_blob.c;int elempack bottom_blob.elempack;int size w * h * d * elempack;// 逐元素相乘if (op_type Operation_PROD){ // second blobconst Mat bottom_blob1 bottom_blobs[1]; // out bottom_blobs[0] .* bottom_blobs[1];for (int q 0; q channels; q){ // 每个channel计算const float* ptr bottom_blob.channel(q); // 0const float* ptr1 bottom_blob1.channel(q); // 1float* outptr top_blob.channel(q); // 0// 计算8的整数倍的数据for (; i 7 size; i 8){}// 计算4的整数倍的数据for (; i 3 size; i 4){}} // out out .* bottom_blobs[i]for (size_t b 2; b bottom_blobs.size(); b){}}// 逐元素相加if (op_type Operation_SUM){}// 逐元素计算最大值if (op_type Operation_SUM){}}3、总结
本次学习了NCNN中的binaryop、eltwise操作学会了两个向量之间的操作还能用模板实现省去了不少的代码量。