nx_f32_rope.nx
buildroot/runtime/nx_f32_rope.nx
about
nx_f32_rope.nx -- bits-up f32 RoPE (Rotary Position Embedding).
L7 composition brick. Composes L6 sin + cos + exp + L4 mul/add/
sub/div/cvt. No libm.
Reference (Su 2021, "RoFormer"):
For each adjacent dim-pair (x_{2i}, x_{2i+1}) at position m:
theta_i = base^(-2i/d)
[x'_{2i}, x'_{2i+1}] = R(m*theta_i) @ [x_{2i}, x_{2i+1}]
where R(phi) is the 2x2 rotation matrix [[cos,-sin],[sin,cos]].
Concretely:
x'_{2i} = x_{2i} * cos(m*theta_i) - x_{2i+1} * sin(m*theta_i)
x'_{2i+1} = x_{2i} * sin(m*theta_i) + x_{2i+1} * cos(m*theta_i)
base is typically 10000 (Llama-2) or 500000 (Llama-3 / Qwen2).
Caller passes log(base) as f32 so it's computed once across all
positions. log(10000) ~= 9.2103404 = 0x4113411D in f32 nearest.
genealogy_id: su_2021_rope + standard_rotation_compose
lineage_id: substrate_f32_rope_v1
dependencies 7 imports · 8 importers
imports: nx_syscalls.nxnx_tier.nxnx_f32.nxnx_f32_div.nxnx_f32_cvt.nxnx_f32_exp.nxnx_f32_sincos.nx
imported by: nx_f32_llama_block.nxnx_f32_llama_block_test.nxnx_f32_llama_block_v4.nxnx_f32_llama_block_v4_test.nxnx_f32_llama_v4b.nxnx_f32_llama_v4p.nxnx_f32_rope_test.nxnx_nofloat_qwen_rope_h2h_gate.nx
structs
| none |
consts
| 32 | const NX_F32_ROPE_OK: nx_int = 0 |
| 33 | const NX_F32_ROPE_ERR_BAD_DIM: nx_int = 1 |
| 34 | const NX_F32_ROPE_ERR_ODD_DIM: nx_int = 2 |
| 35 | const NX_F32_ROPE_N_VERDICTS: nx_int = 3 |
functions
| 37 | func nx_f32_rope_verdict_is_valid(v: nx_int) -> nx_int called by 1: main |
| 51 | func nx_f32_rope_apply_vector(x: *i64, head_dim: nx_int, called by 2: nx_f32_llama_block_forward_v3main calls 9: nx_i32_to_f32nx_f32_negnx_f32_divnx_f32_mulnx_f32_expnx_f32_cos+3 |
| 106 | func nx_f32_rope_build_cs(cs_out: *i64, head_dim: nx_int, |
| 130 | func nx_f32_rope_apply_cs_neox(x: *i64, head_dim: nx_int, cs: *i64) -> nx_int |
| 155 | func nx_f32_rope_apply_vector_neox(x: *i64, head_dim: nx_int, called by 2: _rope_taskmain calls 9: nx_i32_to_f32nx_f32_negnx_f32_divnx_f32_mulnx_f32_expnx_f32_cos+3 |