MCPcopy Create free account
hub / github.com/cactus-compute/cactus / kernel_softmax_f16_single

Function kernel_softmax_f16_single

cactus/kernel/kernel_nn.cpp:416–499  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

414}
415
416void kernel_softmax_f16_single(const __fp16* input, __fp16* output, size_t vocab_size) {
417
418 constexpr size_t SIMD_WIDTH = 8;
419 constexpr size_t UNROLL_FACTOR = 4;
420 constexpr size_t VECTORIZED_WIDTH = SIMD_WIDTH * UNROLL_FACTOR;
421 const size_t vocab_vectorized = (vocab_size / VECTORIZED_WIDTH) * VECTORIZED_WIDTH;
422
423 float32x4_t max_vec[UNROLL_FACTOR * 2];
424 for (size_t u = 0; u < UNROLL_FACTOR * 2; u++) {
425 max_vec[u] = vdupq_n_f32(-std::numeric_limits<float>::infinity());
426 }
427
428 for (size_t i = 0; i < vocab_vectorized; i += VECTORIZED_WIDTH) {
429 for (size_t u = 0; u < UNROLL_FACTOR; u++) {
430 float16x8_t x_vec_f16 = vld1q_f16(&input[i + u * SIMD_WIDTH]);
431 float32x4_t x_low = vcvt_f32_f16(vget_low_f16(x_vec_f16));
432 float32x4_t x_high = vcvt_f32_f16(vget_high_f16(x_vec_f16));
433 max_vec[u * 2] = vmaxq_f32(max_vec[u * 2], x_low);
434 max_vec[u * 2 + 1] = vmaxq_f32(max_vec[u * 2 + 1], x_high);
435 }
436 }
437
438 float32x4_t final_max = max_vec[0];
439 for (size_t u = 1; u < UNROLL_FACTOR * 2; u++) {
440 final_max = vmaxq_f32(final_max, max_vec[u]);
441 }
442
443 float max_val = vmaxvq_f32(final_max);
444 for (size_t i = vocab_vectorized; i < vocab_size; ++i) {
445 max_val = std::max(max_val, static_cast<float>(input[i]));
446 }
447
448 const float32x4_t max_broadcast = vdupq_n_f32(max_val);
449
450 float32x4_t sum_vec[UNROLL_FACTOR * 2];
451 for (size_t u = 0; u < UNROLL_FACTOR * 2; u++) {
452 sum_vec[u] = vdupq_n_f32(0.0f);
453 }
454
455 for (size_t i = 0; i < vocab_vectorized; i += VECTORIZED_WIDTH) {
456 for (size_t u = 0; u < UNROLL_FACTOR; u++) {
457 float16x8_t x_vec_f16 = vld1q_f16(&input[i + u * SIMD_WIDTH]);
458
459 float32x4_t x_low = vcvt_f32_f16(vget_low_f16(x_vec_f16));
460 float32x4_t x_high = vcvt_f32_f16(vget_high_f16(x_vec_f16));
461
462 float32x4_t exp_low = fast_exp_f32x4(vsubq_f32(x_low, max_broadcast));
463 float32x4_t exp_high = fast_exp_f32x4(vsubq_f32(x_high, max_broadcast));
464
465 float16x8_t exp_f16 = vcombine_f16(vcvt_f16_f32(exp_low), vcvt_f16_f32(exp_high));
466 vst1q_f16(&output[i + u * SIMD_WIDTH], exp_f16);
467
468 sum_vec[u * 2] = vaddq_f32(sum_vec[u * 2], exp_low);
469 sum_vec[u * 2 + 1] = vaddq_f32(sum_vec[u * 2 + 1], exp_high);
470 }
471 }
472
473 float32x4_t final_sum = sum_vec[0];

Callers 1

cactus_softmax_f16Function · 0.85

Calls 1

fast_exp_f32x4Function · 0.85

Tested by

no test coverage detected