| 646 | } |
| 647 | |
| 648 | static void rope(float* buf, float* vec, int d, int head_dim, int pos, float theta) { |
| 649 | // For some reason, DeepSeek-V2 was trained using rope output |
| 650 | // layout transposed compared to the input. This means we need a buffer |
| 651 | // to hold intermediate results. |
| 652 | assert(d % 2 == 0); |
| 653 | for (int i = 0; i < d; i += 2) { |
| 654 | int j_head = i % head_dim; |
| 655 | float freq = 1.0f / powf(theta, (float)j_head / (float)head_dim); |
| 656 | float val = pos * freq; |
| 657 | float fcr = cosf(val); |
| 658 | float fci = sinf(val); |
| 659 | |
| 660 | float v0 = vec[i]; |
| 661 | float v1 = vec[i + 1]; |
| 662 | buf[i/2] = v0 * fcr - v1 * fci; |
| 663 | buf[i/2 + d/2] = v0 * fci + v1 * fcr; |
| 664 | } |
| 665 | for (int i = 0; i < d; i++) { |
| 666 | vec[i] = buf[i]; |
| 667 | } |
| 668 | } |
| 669 | |
| 670 | static void rope_v3(float* vec, int d, int head_dim, int pos, float theta) { |
| 671 | int rotary_dim = head_dim; |
no test coverage detected