MCPcopy Create free account
hub / github.com/PABannier/sam3.cpp / test_rope

Function test_rope

tests/test_vit.cpp:123–223  ·  view source on GitHub ↗

Forward-declare the internal function (defined in sam3.cpp) We'll test it by replicating the computation here.

Source from the content-addressed store, hash-verified

121// Forward-declare the internal function (defined in sam3.cpp)
122// We'll test it by replicating the computation here.
123static bool test_rope(const std::string & ref_dir) {
124 fprintf(stderr, "\n=== Test: RoPE ===\n");
125
126 // Test window RoPE (24x24)
127 auto ref_window = load_ref(ref_dir + "/rope_window_real");
128 if (!ref_window.data.empty()) {
129 // ref is [576, 32, 2] — (cos, sin) pairs
130 // Our compute_axial_cis produces [N, head_dim] with interleaved (cos, sin)
131 // But the Python ref stores them as [N, half_head, 2] where [:,:,0]=cos, [:,:,1]=sin
132 const int N = 576;
133 const int half_head = 32;
134 const int dim = 64;
135 const float theta = 10000.0f;
136 const float scale_pos = 1.0f;
137
138 std::vector<float> our_rope(N * dim);
139
140 const int half_dim = dim / 4; // 16
141 std::vector<float> freqs(half_dim);
142 for (int i = 0; i < half_dim; ++i) {
143 freqs[i] = 1.0f / powf(theta, (float)(i * 4) / dim);
144 }
145
146 for (int idx = 0; idx < N; ++idx) {
147 float t_x = (float)(idx % 24) * scale_pos;
148 float t_y = (float)(idx / 24) * scale_pos;
149
150 for (int i = 0; i < half_dim; ++i) {
151 float angle_x = t_x * freqs[i];
152 our_rope[idx * dim + i * 2 + 0] = cosf(angle_x);
153 our_rope[idx * dim + i * 2 + 1] = sinf(angle_x);
154 }
155 for (int i = 0; i < half_dim; ++i) {
156 float angle_y = t_y * freqs[i];
157 our_rope[idx * dim + half_dim * 2 + i * 2 + 0] = cosf(angle_y);
158 our_rope[idx * dim + half_dim * 2 + i * 2 + 1] = sinf(angle_y);
159 }
160 }
161
162 // Compare: ref is [N, 32, 2] = [N, half_head, (cos,sin)]
163 // Our layout is [N, dim] = [N, 64] with pairs (cos_x, sin_x, cos_x, sin_x, ..., cos_y, sin_y, ...)
164 // Need to rearrange comparison:
165 // ref[idx, j, 0] = cos of freq j for position idx
166 // ref[idx, j, 1] = sin of freq j for position idx
167 // Python: freqs_cis = cat([freqs_cis_x, freqs_cis_y], dim=-1) → [N, 32]
168 // freqs_cis_x has 16 complex values, freqs_cis_y has 16 complex values → total 32
169 // view_as_real → [N, 32, 2] where [:,i,0]=cos, [:,i,1]=sin
170 // So ref[idx, j, 0] for j<16 = cos(t_x * freqs[j])
171 // ref[idx, j, 1] for j<16 = sin(t_x * freqs[j])
172 // ref[idx, j, 0] for j>=16 = cos(t_y * freqs[j-16])
173 // ref[idx, j, 1] for j>=16 = sin(t_y * freqs[j-16])
174
175 // Our layout: [idx * 64 + j*2+0] = cos, [idx * 64 + j*2+1] = sin
176 // For x: j = 0..15 → our[idx*64 + j*2], ref[idx*64 + j*2]
177 // For y: j = 16..31 → our[idx*64 + 32 + (j-16)*2], ref[idx*64 + (j)*2]
178
179 // Actually both are the same layout! ref is stored flat as [N*32*2] = [N*64]
180 // and our_rope is [N*64] with the same interleaving.

Callers 1

mainFunction · 0.70

Calls 2

load_refFunction · 0.70
compare_tensorsFunction · 0.70

Tested by

no test coverage detected