Skip to content

Commit cc3c259

Browse files
committed
ggml-cpu: add F16 input to the FWHT
The CPU FWHT accepts F32 input only. This change makes the source type a template parameter. The CPU path now accepts F16 input and F32 input. The CPU MUL_MAT reference now converts an F16 src1 to F32. It does this when the caller sets the Hadamard hint. No backend has an F16 FWHT kernel yet. The test cases come with the backend changes that add one.
1 parent 434ddbb commit cc3c259

3 files changed

Lines changed: 38 additions & 10 deletions

File tree

ggml/src/ggml-cpu/ggml-cpu.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ UseGgmlGemm1:;
13291329
const size_t nbw3 = nbw2*ne12;
13301330

13311331
assert(params->wsize >= ne13*nbw3);
1332-
GGML_ASSERT(src1->type == GGML_TYPE_F32);
1332+
GGML_ASSERT(src1->type == GGML_TYPE_F32 || src1->type == GGML_TYPE_F16);
13331333

13341334
#if 0
13351335
for (int64_t i13 = 0; i13 < ne13; ++i13) {
@@ -1348,9 +1348,19 @@ UseGgmlGemm1:;
13481348
size_t bs = ggml_blck_size(vec_dot_type);
13491349
int64_t ne10_block_start = (ith * ne10/bs) / nth;
13501350
int64_t ne10_block_end = ((ith + 1) * ne10/bs) / nth;
1351-
from_float((float *)((char *) src1->data + i13*nb13 + i12*nb12 + i11*nb11 + ne10_block_start*bs*nb10),
1352-
(void *) (wdata + i13*nbw3 + i12*nbw2 + i11*nbw1 + ne10_block_start*nbw0),
1353-
(ne10_block_end - ne10_block_start) * bs);
1351+
const char * src1_block = (const char *) src1->data + i13*nb13 + i12*nb12 + i11*nb11 + ne10_block_start*bs*nb10;
1352+
char * dst_block = wdata + i13*nbw3 + i12*nbw2 + i11*nbw1 + ne10_block_start*nbw0;
1353+
const int64_t n_block = (ne10_block_end - ne10_block_start) * bs;
1354+
1355+
if (src1->type == GGML_TYPE_F32) {
1356+
from_float((const float *) src1_block, dst_block, n_block);
1357+
} else {
1358+
const ggml_fp16_t * src_f16 = (const ggml_fp16_t *) src1_block;
1359+
float * dst_f32 = (float *) dst_block;
1360+
for (int64_t i = 0; i < n_block; ++i) {
1361+
dst_f32[i] = GGML_CPU_FP16_TO_FP32(src_f16[i]);
1362+
}
1363+
}
13541364
}
13551365
}
13561366
}

ggml/src/ggml-cpu/ggml-cpu.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,10 @@ static bool ggml_backend_cpu_device_supports_op(ggml_backend_dev_t dev, const st
451451
op->type != GGML_TYPE_IQ1_S &&
452452
op->type != GGML_TYPE_IQ1_M; // missing type_traits.from_float
453453
case GGML_OP_MUL_MAT:
454+
if (ggml_get_op_params_i32(op, 1) == GGML_HINT_SRC0_IS_HADAMARD &&
455+
src0->type == GGML_TYPE_F32 && op->type == GGML_TYPE_F32) {
456+
return src1->type == GGML_TYPE_F32 || src1->type == GGML_TYPE_F16;
457+
}
454458
return src1->type == GGML_TYPE_F32 || src1->type == ggml_get_type_traits_cpu(src0->type)->vec_dot_type;
455459
case GGML_OP_SOFT_MAX_BACK: {
456460
if (op->src[0]->type != GGML_TYPE_F32 || op->src[1]->type != GGML_TYPE_F32) {

ggml/src/ggml-cpu/ops.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11987,11 +11987,20 @@ void ggml_compute_forward_opt_step_sgd(const ggml_compute_params * params, ggml_
1198711987
}
1198811988
}
1198911989

11990-
static void ggml_compute_forward_fwht_f32(const ggml_compute_params * params, ggml_tensor * dst) {
11990+
static inline float ggml_fwht_load(const float value) {
11991+
return value;
11992+
}
11993+
11994+
static inline float ggml_fwht_load(const ggml_fp16_t value) {
11995+
return ggml_fp16_to_fp32(value);
11996+
}
11997+
11998+
template<typename src_t>
11999+
static void ggml_compute_forward_fwht_impl(const ggml_compute_params * params, ggml_tensor * dst) {
1199112000
const ggml_tensor * src0 = dst->src[0];
1199212001
const ggml_tensor * src1 = dst->src[1];
1199312002

11994-
GGML_ASSERT(src1->type == GGML_TYPE_F32);
12003+
GGML_ASSERT(src1->type == (std::is_same_v<src_t, float> ? GGML_TYPE_F32 : GGML_TYPE_F16));
1199512004
GGML_ASSERT(dst->type == GGML_TYPE_F32);
1199612005

1199712006
GGML_TENSOR_BINARY_OP_LOCALS
@@ -12018,11 +12027,11 @@ static void ggml_compute_forward_fwht_f32(const ggml_compute_params * params, gg
1201812027
const int64_t i12 = (r - i13 * ne11 * ne12) / ne11;
1201912028
const int64_t i11 = r - i13 * ne11 * ne12 - i12 * ne11;
1202012029

12021-
const float * src_row = (const float *) ((const char *) src1->data + i11 * nb11 + i12 * nb12 + i13 * nb13);
12030+
const src_t * src_row = (const src_t *) ((const char *) src1->data + i11 * nb11 + i12 * nb12 + i13 * nb13);
1202212031
float * dst_row = (float *) ((char *) dst->data + i11 * nb1 + i12 * nb2 + i13 * nb3);
1202312032

1202412033
for (int64_t j = 0; j < n; j++) {
12025-
dst_row[j] = src_row[j] * scale;
12034+
dst_row[j] = ggml_fwht_load(src_row[j]) * scale;
1202612035
}
1202712036

1202812037
// Scalar passes
@@ -12069,12 +12078,17 @@ void ggml_compute_forward_fwht(const ggml_compute_params * params, ggml_tensor *
1206912078
switch (src1->type) {
1207012079
case GGML_TYPE_F32:
1207112080
{
12072-
ggml_compute_forward_fwht_f32(params, dst);
12081+
ggml_compute_forward_fwht_impl<float>(params, dst);
12082+
}
12083+
break;
12084+
case GGML_TYPE_F16:
12085+
{
12086+
ggml_compute_forward_fwht_impl<ggml_fp16_t>(params, dst);
1207312087
}
1207412088
break;
1207512089
default:
1207612090
{
12077-
GGML_ABORT("fatal error - fwht is F32 only");
12091+
GGML_ABORT("fatal error - fwht supports F32 and F16 input");
1207812092
}
1207912093
}
1208012094
}

0 commit comments

Comments
 (0)