Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions ggml/src/ggml-cpu/simd-mappings.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ extern "C" {
// simd mappings
//

// Force full unrolling of a loop with a compile-time constant trip count.
//
// The generic SIMD kernels below hold their vector operands and accumulators in
// small arrays indexed by the inner loop counter (`for (j = 0; j < GGML_F32_ARR; j++)`).
// Those arrays only stay in registers if the loop is unrolled: GCC does that at
// -O3, but not at -O2 (the level used by RelWithDebInfo builds), where the
// arrays are left in memory and every vector operation pays a load/store round
// trip to the stack. Unrolling explicitly makes the codegen independent of the
// optimization level.
#if (defined(__clang__) && __clang_major__ >= 9) || (!defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8)
#define GGML_DO_PRAGMA_(x) _Pragma(#x)
#define GGML_DO_PRAGMA(x) GGML_DO_PRAGMA_(x)
#define GGML_UNROLL(n) GGML_DO_PRAGMA(GCC unroll n)
#else
#define GGML_UNROLL(n)
#endif

// FP16 to FP32 conversion

// 16-bit float
Expand Down
2 changes: 2 additions & 0 deletions ggml/src/ggml-cpu/vec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ void ggml_vec_dot_f32(int n, float * GGML_RESTRICT s, size_t bs, const float * G
GGML_F32_VEC ay[GGML_F32_ARR];

for (int i = 0; i < np; i += GGML_F32_STEP) {
GGML_UNROLL(GGML_F32_ARR)
for (int j = 0; j < GGML_F32_ARR; j++) {
ax[j] = GGML_F32_VEC_LOAD(x + i + j*GGML_F32_EPR);
ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR);
Expand Down Expand Up @@ -350,6 +351,7 @@ void ggml_vec_dot_f16(int n, float * GGML_RESTRICT s, size_t bs, ggml_fp16_t * G
GGML_F16_VEC ay[GGML_F16_ARR];

for (int i = 0; i < np; i += GGML_F16_STEP) {
GGML_UNROLL(GGML_F16_ARR)
for (int j = 0; j < GGML_F16_ARR; j++) {
ax[j] = GGML_F16_VEC_LOAD(x + i + j*GGML_F16_EPR, j);
ay[j] = GGML_F16_VEC_LOAD(y + i + j*GGML_F16_EPR, j);
Expand Down
9 changes: 9 additions & 0 deletions ggml/src/ggml-cpu/vec.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,11 @@ inline static void ggml_vec_dot_f16_unroll(const int n, const int xs, float * GG
GGML_F16_VEC ay[GGML_F16_ARR];

for (int i = 0; i < np; i += GGML_F16_STEP) {
GGML_UNROLL(GGML_F16_ARR)
for (int j = 0; j < GGML_F16_ARR; j++) {
ay[j] = GGML_F16_VEC_LOAD(y + i + j*GGML_F16_EPR, j);

GGML_UNROLL(GGML_VEC_DOT_UNROLL)
for (int k = 0; k < GGML_VEC_DOT_UNROLL; ++k) {
ax[j] = GGML_F16_VEC_LOAD(x[k] + i + j*GGML_F16_EPR, j);

Expand Down Expand Up @@ -414,6 +416,7 @@ inline static void ggml_vec_mad_f32(const int n, float * GGML_RESTRICT y, const
GGML_F32_VEC ay[GGML_F32_ARR];

for (int i = 0; i < np; i += GGML_F32_STEP) {
GGML_UNROLL(GGML_F32_ARR)
for (int j = 0; j < GGML_F32_ARR; j++) {
ax[j] = GGML_F32_VEC_LOAD(x + i + j*GGML_F32_EPR);
ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR);
Expand Down Expand Up @@ -562,6 +565,7 @@ inline static void ggml_vec_mad_f16(const int n, ggml_fp16_t * GGML_RESTRICT y,
GGML_F16_VEC ay[GGML_F16_ARR];

for (int i = 0; i < np; i += GGML_F16_STEP) {
GGML_UNROLL(GGML_F16_ARR)
for (int j = 0; j < GGML_F16_ARR; j++) {
ax[j] = GGML_F16_VEC_LOAD(x + i + j*GGML_F16_EPR, j);
ay[j] = GGML_F16_VEC_LOAD(y + i + j*GGML_F16_EPR, j);
Expand Down Expand Up @@ -623,9 +627,11 @@ inline static void ggml_vec_mad_f32_unroll(const int n, const int xs, const int
GGML_F32_VEC ay[GGML_F32_ARR];

for (int i = 0; i < np; i += GGML_F32_STEP) {
GGML_UNROLL(GGML_F32_ARR)
for (int j = 0; j < GGML_F32_ARR; j++) {
ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR);

GGML_UNROLL(GGML_VEC_MAD_UNROLL)
for (int k = 0; k < GGML_VEC_MAD_UNROLL; ++k) {
ax[k][j] = GGML_F32_VEC_LOAD(x[k] + i + j*GGML_F32_EPR);
ay[j] = GGML_F32_VEC_FMA(ay[j], ax[k][j], vx[k]);
Expand Down Expand Up @@ -678,6 +684,7 @@ inline static void ggml_vec_mad1_f32(const int n, float * y, const float * x, co
GGML_F32_VEC ay[GGML_F32_ARR];

for (int i = 0; i < np; i += GGML_F32_STEP) {
GGML_UNROLL(GGML_F32_ARR)
for (int j = 0; j < GGML_F32_ARR; j++) {
ay[j] = GGML_F32_VEC_LOAD(x + i + j*GGML_F32_EPR);
ay[j] = GGML_F32_VEC_FMA(vb, ay[j], vs);
Expand Down Expand Up @@ -745,6 +752,7 @@ inline static void ggml_vec_scale_f32(const int n, float * y, const float v) {
GGML_F32_VEC ay[GGML_F32_ARR];

for (int i = 0; i < np; i += GGML_F32_STEP) {
GGML_UNROLL(GGML_F32_ARR)
for (int j = 0; j < GGML_F32_ARR; j++) {
ay[j] = GGML_F32_VEC_LOAD(y + i + j*GGML_F32_EPR);
ay[j] = GGML_F32_VEC_MUL(ay[j], vx);
Expand Down Expand Up @@ -838,6 +846,7 @@ inline static void ggml_vec_scale_f16(const int n, ggml_fp16_t * y, const float
GGML_F16_VEC ay[GGML_F16_ARR];

for (int i = 0; i < np; i += GGML_F16_STEP) {
GGML_UNROLL(GGML_F16_ARR)
for (int j = 0; j < GGML_F16_ARR; j++) {
ay[j] = GGML_F16_VEC_LOAD(y + i + j*GGML_F16_EPR, j);
ay[j] = GGML_F16_VEC_MUL(ay[j], vx);
Expand Down