|
#include "ggml/ggml.h" |
|
|
|
#include <math.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
|
|
bool is_close(float a, float b, float epsilon) { |
|
return fabs(a - b) < epsilon; |
|
} |
|
|
|
int main(int argc, char ** argv) { |
|
const int n_threads = 1; |
|
const int n_embd_head = 4; |
|
const int n_head = 1; |
|
const int N = 8; |
|
|
|
struct ggml_init_params params = { |
|
.mem_size = 16*1024*1024, |
|
.mem_buffer = NULL, |
|
}; |
|
|
|
|
|
struct ggml_context * ctx = ggml_init(params); |
|
|
|
struct ggml_tensor * Q = ggml_new_tensor_3d(ctx, GGML_TYPE_F32, n_embd_head, n_head, N); |
|
struct ggml_tensor * K = ggml_new_tensor_3d(ctx, GGML_TYPE_F32, n_embd_head, n_head, N); |
|
|
|
for (int i = 0; i < ggml_nelements(Q); i++) { |
|
((float*) Q->data)[i] = 2.0f; |
|
((float*) K->data)[i] = 2.0f; |
|
} |
|
|
|
struct ggml_tensor * KQ_pos = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, N); |
|
int * data = (int *) KQ_pos->data; |
|
for (int i = 0; i < N; ++i) { |
|
data[i] = 1 + i; |
|
} |
|
|
|
struct ggml_tensor * Qx = ggml_rope_xpos_inplace(ctx, Q, KQ_pos, n_embd_head, 512.0f, false); |
|
struct ggml_tensor * Kx = ggml_rope_xpos_inplace(ctx, K, KQ_pos, n_embd_head, 512.0f, true); |
|
|
|
struct ggml_cgraph gf = ggml_build_forward(Qx); |
|
ggml_build_forward_expand(&gf, Kx); |
|
ggml_graph_compute_with_ctx(ctx, &gf, n_threads); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ggml_nelements(Q); i++) { |
|
if (((float*) Qx->data)[i] > 0) printf(" "); |
|
printf("%.4f ", ((float*) Qx->data)[i]); |
|
if ((i+1) % n_embd_head == 0) printf("\n"); |
|
} |
|
printf("\n"); |
|
|
|
GGML_ASSERT(is_close(((float*) Qx->data)[7 * n_embd_head + 0], -2.2257f, 0.0001f)); |
|
GGML_ASSERT(is_close(((float*) Qx->data)[7 * n_embd_head + 1], 1.6550f, 0.0001f)); |
|
GGML_ASSERT(is_close(((float*) Qx->data)[7 * n_embd_head + 2], 1.8212f, 0.0001f)); |
|
GGML_ASSERT(is_close(((float*) Qx->data)[7 * n_embd_head + 3], 2.1386f, 0.0001f)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ggml_nelements(K); i++) { |
|
if (((float*) Kx->data)[i] > 0) printf(" "); |
|
printf("%.4f ", ((float*) Kx->data)[i]); |
|
if ((i+1) % n_embd_head == 0) printf("\n"); |
|
} |
|
printf("\n"); |
|
|
|
GGML_ASSERT(is_close(((float*) Kx->data)[7 * n_embd_head + 0], -2.3146f, 0.0001f)); |
|
GGML_ASSERT(is_close(((float*) Kx->data)[7 * n_embd_head + 1], 1.7211f, 0.0001f)); |
|
GGML_ASSERT(is_close(((float*) Kx->data)[7 * n_embd_head + 2], 1.8465f, 0.0001f)); |
|
GGML_ASSERT(is_close(((float*) Kx->data)[7 * n_embd_head + 3], 2.1684f, 0.0001f)); |
|
|
|
ggml_free(ctx); |
|
|
|
return 0; |
|
} |
|
|