| 2154 | } |
| 2155 | |
| 2156 | bool ggml_backend_compare_graph_backend(ggml_backend_t backend1, ggml_backend_t backend2, struct ggml_cgraph * graph, ggml_backend_eval_callback callback, void * user_data, struct ggml_tensor const * const * test_nodes, size_t num_test_nodes) { |
| 2157 | struct ggml_backend_graph_copy copy = ggml_backend_graph_copy(backend2, graph); |
| 2158 | if (copy.buffer == NULL) { |
| 2159 | return false; |
| 2160 | } |
| 2161 | |
| 2162 | struct ggml_cgraph * g1 = graph; |
| 2163 | struct ggml_cgraph * g2 = copy.graph; |
| 2164 | |
| 2165 | assert(g1->n_nodes == g2->n_nodes); |
| 2166 | |
| 2167 | if (num_test_nodes != 0) { |
| 2168 | GGML_ASSERT(test_nodes); |
| 2169 | // Compute the whole graph and only test the output for specific tensors |
| 2170 | ggml_backend_graph_compute(backend1, g1); |
| 2171 | ggml_backend_graph_compute(backend2, g2); |
| 2172 | |
| 2173 | bool verified = false; |
| 2174 | for (int i = 0; i < g1->n_nodes; i++) { |
| 2175 | for (size_t j = 0; j < num_test_nodes; ++j) { |
| 2176 | if (g1->nodes[i] == test_nodes[j]) { |
| 2177 | callback(i, g1->nodes[i], g2->nodes[i], user_data); |
| 2178 | verified = true; |
| 2179 | } |
| 2180 | } |
| 2181 | } |
| 2182 | GGML_ASSERT(verified); |
| 2183 | } else { |
| 2184 | for (int i = 0; i < g1->n_nodes; i++) { |
| 2185 | struct ggml_tensor * t1 = g1->nodes[i]; |
| 2186 | struct ggml_tensor * t2 = g2->nodes[i]; |
| 2187 | |
| 2188 | assert(t1->op == t2->op && ggml_are_same_layout(t1, t2)); |
| 2189 | |
| 2190 | struct ggml_cgraph g1v = ggml_graph_view(g1, i, i + 1); |
| 2191 | struct ggml_cgraph g2v = ggml_graph_view(g2, i, i + 1); |
| 2192 | |
| 2193 | ggml_backend_graph_compute(backend1, &g1v); |
| 2194 | ggml_backend_graph_compute(backend2, &g2v); |
| 2195 | |
| 2196 | if (ggml_is_view_op(t1->op)) { |
| 2197 | continue; |
| 2198 | } |
| 2199 | |
| 2200 | // compare results, calculate rms etc |
| 2201 | if (!callback(i, t1, t2, user_data)) { |
| 2202 | break; |
| 2203 | } |
| 2204 | } |
| 2205 | } |
| 2206 | ggml_backend_graph_copy_free(copy); |
| 2207 | |
| 2208 | return true; |
| 2209 | } |
| 2210 | |
| 2211 | // CPU backend - buffer |
| 2212 | |