| 2154 | for (int i = 0; i < graph->n_nodes; i++) { |
| 2155 | struct ggml_tensor * node = graph->nodes[i]; |
| 2156 | graph_copy_init_tensor(&hash_set, node_copies, node_init, node); |
| 2157 | } |
| 2158 | |
| 2159 | // build graph copy |
| 2160 | struct ggml_cgraph * graph_copy = ggml_new_graph_custom(ctx_allocated, graph->size, false); |
| 2161 | for (int i = 0; i < graph->n_nodes; i++) { |
| 2162 | struct ggml_tensor * node = graph->nodes[i]; |
| 2163 | struct ggml_tensor * node_copy = node_copies[ggml_hash_find(&hash_set, node)]; |
| 2164 | graph_copy->nodes[i] = node_copy; |
| 2165 | } |
| 2166 | graph_copy->n_nodes = graph->n_nodes; |
| 2167 | |
| 2168 | ggml_hash_set_free(&hash_set); |
| 2169 | free(node_copies); |
| 2170 | free(node_init); |
| 2171 | |
| 2172 | return { |
| 2173 | /* .buffer = */ buffer, |
| 2174 | /* .ctx_allocated = */ ctx_allocated, |
| 2175 | /* .ctx_unallocated = */ ctx_unallocated, |
| 2176 | /* .graph = */ graph_copy, |
| 2177 | }; |
| 2178 | } |
| 2179 | |
| 2180 | void ggml_backend_graph_copy_free(struct ggml_backend_graph_copy copy) { |
| 2181 | ggml_backend_buffer_free(copy.buffer); |
| 2182 | ggml_free(copy.ctx_allocated); |
| 2183 | ggml_free(copy.ctx_unallocated); |
| 2184 | } |
| 2185 | |
| 2186 | 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) { |
| 2187 | struct ggml_backend_graph_copy copy = ggml_backend_graph_copy(backend2, graph); |
| 2188 | if (copy.buffer == NULL) { |
| 2189 | return false; |
| 2190 | } |
| 2191 | |
| 2192 | struct ggml_cgraph * g1 = graph; |
| 2193 | struct ggml_cgraph * g2 = copy.graph; |
| 2194 | |
| 2195 | assert(g1->n_nodes == g2->n_nodes); |
| 2196 | |
| 2197 | if (num_test_nodes != 0) { |
| 2198 | GGML_ASSERT(test_nodes); |
| 2199 | // Compute the whole graph and only test the output for specific tensors |
| 2200 | ggml_backend_graph_compute(backend1, g1); |
| 2201 | ggml_backend_graph_compute(backend2, g2); |
| 2202 | |
| 2203 | bool verified = false; |
| 2204 | for (int i = 0; i < g1->n_nodes; i++) { |
| 2205 | for (size_t j = 0; j < num_test_nodes; ++j) { |
| 2206 | if (g1->nodes[i] == test_nodes[j]) { |
| 2207 | callback(i, g1->nodes[i], g2->nodes[i], user_data); |
| 2208 | verified = true; |
| 2209 | } |
| 2210 | } |
| 2211 | } |
| 2212 | GGML_ASSERT(verified); |