hexagon: add CLAMP op (#25934)
This commit is contained in:
@@ -3476,6 +3476,7 @@ static htp_op_code op_remap_to_htp(const ggml_tensor * t) {
|
|||||||
case GGML_OP_RMS_NORM: return HTP_OP_RMS_NORM;
|
case GGML_OP_RMS_NORM: return HTP_OP_RMS_NORM;
|
||||||
case GGML_OP_CONCAT: return HTP_OP_CONCAT;
|
case GGML_OP_CONCAT: return HTP_OP_CONCAT;
|
||||||
case GGML_OP_SCALE: return HTP_OP_SCALE;
|
case GGML_OP_SCALE: return HTP_OP_SCALE;
|
||||||
|
case GGML_OP_CLAMP: return HTP_OP_CLAMP;
|
||||||
case GGML_OP_SQR: return HTP_OP_SQR;
|
case GGML_OP_SQR: return HTP_OP_SQR;
|
||||||
case GGML_OP_SQRT: return HTP_OP_SQRT;
|
case GGML_OP_SQRT: return HTP_OP_SQRT;
|
||||||
case GGML_OP_SOFT_MAX: return HTP_OP_SOFTMAX;
|
case GGML_OP_SOFT_MAX: return HTP_OP_SOFTMAX;
|
||||||
@@ -4126,6 +4127,7 @@ static bool ggml_backend_hexagon_device_supports_op(ggml_backend_dev_t dev, cons
|
|||||||
case GGML_OP_L2_NORM:
|
case GGML_OP_L2_NORM:
|
||||||
case GGML_OP_RMS_NORM:
|
case GGML_OP_RMS_NORM:
|
||||||
case GGML_OP_SCALE:
|
case GGML_OP_SCALE:
|
||||||
|
case GGML_OP_CLAMP:
|
||||||
supp = ggml_hexagon_supported_unary(sess, op);
|
supp = ggml_hexagon_supported_unary(sess, op);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ enum htp_op_code {
|
|||||||
HTP_OP_PAD,
|
HTP_OP_PAD,
|
||||||
HTP_OP_NORM,
|
HTP_OP_NORM,
|
||||||
HTP_OP_CONCAT,
|
HTP_OP_CONCAT,
|
||||||
|
HTP_OP_CLAMP,
|
||||||
|
|
||||||
HTP_OP_INVALID
|
HTP_OP_INVALID
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -718,6 +718,7 @@ static int execute_op(struct htp_ops_context * octx) {
|
|||||||
case HTP_OP_RMS_NORM:
|
case HTP_OP_RMS_NORM:
|
||||||
case HTP_OP_RMS_NORM_MUL:
|
case HTP_OP_RMS_NORM_MUL:
|
||||||
case HTP_OP_SCALE:
|
case HTP_OP_SCALE:
|
||||||
|
case HTP_OP_CLAMP:
|
||||||
case HTP_OP_SQR:
|
case HTP_OP_SQR:
|
||||||
case HTP_OP_SQRT:
|
case HTP_OP_SQRT:
|
||||||
case HTP_OP_UNARY_SOFTPLUS:
|
case HTP_OP_UNARY_SOFTPLUS:
|
||||||
|
|||||||
@@ -138,6 +138,24 @@ static void scale_f32(const float * restrict src,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clamp_f32(const float * restrict src,
|
||||||
|
float * restrict dst,
|
||||||
|
const uint32_t num_rows,
|
||||||
|
const struct htp_unary_context * uctx) {
|
||||||
|
htp_unary_op_preamble;
|
||||||
|
float min = 0.f;
|
||||||
|
float max = 0.f;
|
||||||
|
memcpy(&min, &op_params[0], sizeof(float));
|
||||||
|
memcpy(&max, &op_params[1], sizeof(float));
|
||||||
|
|
||||||
|
for (uint32_t ir = 0; ir < num_rows; ir++) {
|
||||||
|
const uint8_t * restrict src_local = (const uint8_t *)src + (ir * src0_row_size_aligned);
|
||||||
|
uint8_t * restrict dst_local = (uint8_t *)dst + (ir * dst_row_size_aligned);
|
||||||
|
|
||||||
|
hvx_clamp_scalar_f32(dst_local, src_local, min, max, ne0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void rms_norm_f32(const float * restrict src,
|
static void rms_norm_f32(const float * restrict src,
|
||||||
float * restrict dst,
|
float * restrict dst,
|
||||||
const uint32_t num_rows,
|
const uint32_t num_rows,
|
||||||
@@ -542,6 +560,7 @@ DEFINE_UNARY_TASK(norm, false, false, norm_f32(src0_vtcm, dst_vtcm, bl
|
|||||||
DEFINE_UNARY_TASK(rms_norm, false, false, rms_norm_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
DEFINE_UNARY_TASK(rms_norm, false, false, rms_norm_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
||||||
DEFINE_UNARY_TASK(rms_norm_mul, true, false, rms_norm_mul_f32(src0_vtcm, uctx->broadcast_weight ? (const float *) src1_vtcm_data : src1_vtcm, dst_vtcm, block_size, uctx))
|
DEFINE_UNARY_TASK(rms_norm_mul, true, false, rms_norm_mul_f32(src0_vtcm, uctx->broadcast_weight ? (const float *) src1_vtcm_data : src1_vtcm, dst_vtcm, block_size, uctx))
|
||||||
DEFINE_UNARY_TASK(scale, false, false, scale_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
DEFINE_UNARY_TASK(scale, false, false, scale_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
||||||
|
DEFINE_UNARY_TASK(clamp, false, false, clamp_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
||||||
DEFINE_UNARY_TASK(sqr, false, false, sqr_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
DEFINE_UNARY_TASK(sqr, false, false, sqr_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
||||||
DEFINE_UNARY_TASK(sqrt, false, false, sqrt_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
DEFINE_UNARY_TASK(sqrt, false, false, sqrt_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
||||||
DEFINE_UNARY_TASK(unary_neg, false, false, neg_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
DEFINE_UNARY_TASK(unary_neg, false, false, neg_f32(src0_vtcm, dst_vtcm, block_size, uctx))
|
||||||
@@ -681,6 +700,14 @@ static inline void tile_scale_f32(uint8_t * dst_vtcm, const uint8_t * src_vtcm,
|
|||||||
hvx_scale_offset_f32_aa(dst_vtcm, src_vtcm, tw, scale, bias);
|
hvx_scale_offset_f32_aa(dst_vtcm, src_vtcm, tw, scale, bias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void tile_clamp_f32(uint8_t * dst_vtcm, const uint8_t * src_vtcm, uint32_t tw, const int32_t * op_params) {
|
||||||
|
float min = 0.f;
|
||||||
|
float max = 0.f;
|
||||||
|
memcpy(&min, &op_params[0], sizeof(float));
|
||||||
|
memcpy(&max, &op_params[1], sizeof(float));
|
||||||
|
hvx_clamp_scalar_f32(dst_vtcm, src_vtcm, min, max, tw);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void tile_unary_softplus_f32(uint8_t * dst_vtcm, const uint8_t * src_vtcm, uint32_t tw) {
|
static inline void tile_unary_softplus_f32(uint8_t * dst_vtcm, const uint8_t * src_vtcm, uint32_t tw) {
|
||||||
const float * restrict sf = (const float *) src_vtcm;
|
const float * restrict sf = (const float *) src_vtcm;
|
||||||
float * restrict df = (float *) dst_vtcm;
|
float * restrict df = (float *) dst_vtcm;
|
||||||
@@ -765,6 +792,7 @@ static inline void tri_apply_tile_f32(const uint8_t * restrict src, uint8_t * re
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_UNARY_TILED_TASK(scale, false, tile_scale_f32(dst_vtcm, src_vtcm, tw, op_params))
|
DEFINE_UNARY_TILED_TASK(scale, false, tile_scale_f32(dst_vtcm, src_vtcm, tw, op_params))
|
||||||
|
DEFINE_UNARY_TILED_TASK(clamp, false, tile_clamp_f32(dst_vtcm, src_vtcm, tw, op_params))
|
||||||
DEFINE_UNARY_TILED_TASK(sqr, false, hvx_sqr_f32_aa(dst_vtcm, src_vtcm, tw))
|
DEFINE_UNARY_TILED_TASK(sqr, false, hvx_sqr_f32_aa(dst_vtcm, src_vtcm, tw))
|
||||||
DEFINE_UNARY_TILED_TASK(sqrt, false, hvx_sqrt_f32_aa(dst_vtcm, src_vtcm, tw))
|
DEFINE_UNARY_TILED_TASK(sqrt, false, hvx_sqrt_f32_aa(dst_vtcm, src_vtcm, tw))
|
||||||
DEFINE_UNARY_TILED_TASK(unary_neg, false, hvx_scale_f32_aa(dst_vtcm, src_vtcm, tw, -1.0f))
|
DEFINE_UNARY_TILED_TASK(unary_neg, false, hvx_scale_f32_aa(dst_vtcm, src_vtcm, tw, -1.0f))
|
||||||
@@ -787,6 +815,7 @@ static int execute_op_unary_f32(struct htp_ops_context * octx) {
|
|||||||
case HTP_OP_RMS_NORM: op_type = "rmsnorm-f32"; break;
|
case HTP_OP_RMS_NORM: op_type = "rmsnorm-f32"; break;
|
||||||
case HTP_OP_RMS_NORM_MUL: op_type = "rmsnorm-mul-f32"; break;
|
case HTP_OP_RMS_NORM_MUL: op_type = "rmsnorm-mul-f32"; break;
|
||||||
case HTP_OP_SCALE: op_type = "scale-f32"; break;
|
case HTP_OP_SCALE: op_type = "scale-f32"; break;
|
||||||
|
case HTP_OP_CLAMP: op_type = "clamp-f32"; break;
|
||||||
case HTP_OP_SQR: op_type = "sqr-f32"; break;
|
case HTP_OP_SQR: op_type = "sqr-f32"; break;
|
||||||
case HTP_OP_SQRT: op_type = "sqrt-f32"; break;
|
case HTP_OP_SQRT: op_type = "sqrt-f32"; break;
|
||||||
case HTP_OP_UNARY_NEG: op_type = "neg-f32"; break;
|
case HTP_OP_UNARY_NEG: op_type = "neg-f32"; break;
|
||||||
@@ -882,6 +911,7 @@ static int execute_op_unary_f32(struct htp_ops_context * octx) {
|
|||||||
if (col_tile) {
|
if (col_tile) {
|
||||||
switch (octx->op) {
|
switch (octx->op) {
|
||||||
case HTP_OP_SCALE: task_func = unary_task_f32_tiled_scale; break;
|
case HTP_OP_SCALE: task_func = unary_task_f32_tiled_scale; break;
|
||||||
|
case HTP_OP_CLAMP: task_func = unary_task_f32_tiled_clamp; break;
|
||||||
case HTP_OP_SQR: task_func = unary_task_f32_tiled_sqr; break;
|
case HTP_OP_SQR: task_func = unary_task_f32_tiled_sqr; break;
|
||||||
case HTP_OP_SQRT: task_func = unary_task_f32_tiled_sqrt; break;
|
case HTP_OP_SQRT: task_func = unary_task_f32_tiled_sqrt; break;
|
||||||
case HTP_OP_UNARY_NEG: task_func = unary_task_f32_tiled_unary_neg; break;
|
case HTP_OP_UNARY_NEG: task_func = unary_task_f32_tiled_unary_neg; break;
|
||||||
@@ -898,6 +928,7 @@ static int execute_op_unary_f32(struct htp_ops_context * octx) {
|
|||||||
case HTP_OP_RMS_NORM: task_func = unary_task_f32_rms_norm; break;
|
case HTP_OP_RMS_NORM: task_func = unary_task_f32_rms_norm; break;
|
||||||
case HTP_OP_RMS_NORM_MUL: task_func = unary_task_f32_rms_norm_mul; break;
|
case HTP_OP_RMS_NORM_MUL: task_func = unary_task_f32_rms_norm_mul; break;
|
||||||
case HTP_OP_SCALE: task_func = unary_task_f32_scale; break;
|
case HTP_OP_SCALE: task_func = unary_task_f32_scale; break;
|
||||||
|
case HTP_OP_CLAMP: task_func = unary_task_f32_clamp; break;
|
||||||
case HTP_OP_SQR: task_func = unary_task_f32_sqr; break;
|
case HTP_OP_SQR: task_func = unary_task_f32_sqr; break;
|
||||||
case HTP_OP_SQRT: task_func = unary_task_f32_sqrt; break;
|
case HTP_OP_SQRT: task_func = unary_task_f32_sqrt; break;
|
||||||
case HTP_OP_UNARY_NEG: task_func = unary_task_f32_unary_neg; break;
|
case HTP_OP_UNARY_NEG: task_func = unary_task_f32_unary_neg; break;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ _Static_assert(sizeof(struct htp_unary_kernel_params) <= 128, "htp_unary_kernel_
|
|||||||
|
|
||||||
static inline bool htp_op_is_unary(uint32_t opcode) {
|
static inline bool htp_op_is_unary(uint32_t opcode) {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
case HTP_OP_CLAMP:
|
||||||
case HTP_OP_NORM:
|
case HTP_OP_NORM:
|
||||||
case HTP_OP_RMS_NORM:
|
case HTP_OP_RMS_NORM:
|
||||||
case HTP_OP_RMS_NORM_MUL:
|
case HTP_OP_RMS_NORM_MUL:
|
||||||
|
|||||||
Reference in New Issue
Block a user