diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2014-08-11 12:32:56 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2014-08-11 12:36:13 -0400 |
commit | 123cac6d078cfd19ded5ae0342b12dd15c1d2254 (patch) | |
tree | de4a6acca22f5008ea2806a0c2cf83dedbc5f0b2 | |
parent | cd028d1d0da2a352a7c5ebff551bbbc6f46c2cf8 (diff) |
API: Add pgm_is_child() and pgm_is_parent().
This patch adds two new APIs to PGM: pgm_is_child()
and pgm_is_parent() for convenience to the programmer.
These functions can already be supported by a combination
of other PGM API calls, but it is troublesome for such
a simple query.
-rw-r--r-- | include/pgm.h | 62 | ||||
-rw-r--r-- | src/pgm.cpp | 48 |
2 files changed, 102 insertions, 8 deletions
diff --git a/include/pgm.h b/include/pgm.h index 671bb9f..27cae67 100644 --- a/include/pgm.h +++ b/include/pgm.h | |||
@@ -177,7 +177,7 @@ int pgm_init_graph(graph_t* graph, const char* graph_name); | |||
177 | /* | 177 | /* |
178 | Prints the graph in dot format to the provided file descriptor. | 178 | Prints the graph in dot format to the provided file descriptor. |
179 | [in] graph: Graph | 179 | [in] graph: Graph |
180 | [in] file: File descriptor | 180 | [in] file: File descriptor |
181 | Return: 0 on success. -1 on error. | 181 | Return: 0 on success. -1 on error. |
182 | */ | 182 | */ |
183 | int pgm_print_graph(graph_t graph, FILE* out); | 183 | int pgm_print_graph(graph_t graph, FILE* out); |
@@ -411,16 +411,59 @@ int pgm_get_nr_consume(edge_t edge); | |||
411 | int pgm_get_nr_threshold(edge_t edge); | 411 | int pgm_get_nr_threshold(edge_t edge); |
412 | 412 | ||
413 | /* | 413 | /* |
414 | Query to see if 'query' is a child of 'node'. | ||
415 | [in] node: possible parent of 'query' | ||
416 | [in] query: possible child of 'node' | ||
417 | Return: | ||
418 | 1 if 'query' is a child of 'node'. | ||
419 | 0 if 'query' is NOT a child of 'node'. | ||
420 | -1 if 'query' or 'node' is an invalid node, or | ||
421 | if 'query' and 'node' are from different graphs | ||
422 | |||
423 | Note: Explicit backedges are ignored. | ||
424 | |||
425 | Note: Beware that pgm_is_child() returns -1 on error, | ||
426 | so the code "if(pgm_is_child(..))" may introduce bugs | ||
427 | since the logic test does not distinguish between the | ||
428 | positive case and the error case. | ||
429 | */ | ||
430 | int pgm_is_child(node_t node, node_t query); | ||
431 | |||
432 | /* | ||
433 | Query to see if 'query' is a parent of 'node'. | ||
434 | [in] node: possible child of 'query' | ||
435 | [in] query: possible parent of 'node' | ||
436 | Return: | ||
437 | 1 if 'query' is a parent of 'node'. | ||
438 | 0 if 'query' is NOT a parent of 'node'. | ||
439 | -1 if 'query' or 'node' is an invalid node, or | ||
440 | if 'query' and 'node' are from different graphs | ||
441 | |||
442 | Note: Explicit backedges are ignored. | ||
443 | |||
444 | Note: Beware that pgm_is_parent() returns -1 on error, | ||
445 | so the code "if(pgm_is_parent(..))" may introduce bugs | ||
446 | since the logic test does not distinguish between the | ||
447 | positive case and the error case. | ||
448 | */ | ||
449 | int pgm_is_parent(node_t node, node_t query); | ||
450 | |||
451 | /* | ||
414 | Query to see if 'query' is an ancestor of 'node'. | 452 | Query to see if 'query' is an ancestor of 'node'. |
415 | [in] node: possible decendent of 'query' | 453 | [in] node: possible decendent of 'query' |
416 | [in] query: possible ancestor of 'node' | 454 | [in] query: possible ancestor of 'node' |
417 | Return: | 455 | Return: |
418 | 1 if 'query' is an ancestor of 'node'. | 456 | 1 if 'query' is an ancestor of 'node'. |
419 | 0 if 'query' is NOT an ancestor of 'node'. | 457 | 0 if 'query' is NOT an ancestor of 'node'. |
420 | -1 if 'query' or 'node' is an invalid node, or | 458 | -1 if 'query' or 'node' is an invalid node, or |
421 | if 'query' and 'node' are from different graphs | 459 | if 'query' and 'node' are from different graphs |
422 | 460 | ||
423 | Note: pgm_is_ancestor(n, q) === pgm_is_descendant(q, n) | 461 | Note: Explicit backedges are ignored. |
462 | |||
463 | Note: Beware that pgm_is_ancestor() returns -1 on error, | ||
464 | so the code "if(pgm_is_ancestor(..))" may introduce bugs | ||
465 | since the logic test does not distinguish between the | ||
466 | positive case and the error case. | ||
424 | */ | 467 | */ |
425 | int pgm_is_ancestor(node_t node, node_t query); | 468 | int pgm_is_ancestor(node_t node, node_t query); |
426 | 469 | ||
@@ -431,18 +474,23 @@ int pgm_is_ancestor(node_t node, node_t query); | |||
431 | Return: | 474 | Return: |
432 | 1 if 'query' is an decendent of 'node'. | 475 | 1 if 'query' is an decendent of 'node'. |
433 | 0 if 'query' is NOT an decendent of 'node'. | 476 | 0 if 'query' is NOT an decendent of 'node'. |
434 | -1 if 'query' or 'node' is an invalid node, or | 477 | -1 if 'query' or 'node' is an invalid node, or |
435 | if 'query' and 'node' are from different graphs | 478 | if 'query' and 'node' are from different graphs |
436 | 479 | ||
437 | Note: pgm_is_ancestor(n, q) === pgm_is_descendant(q, n) | 480 | Note: Explicit backedges are ignored. |
481 | |||
482 | Note: Beware that pgm_is_descendant() returns -1 on error, | ||
483 | so the code "if(pgm_is_descendant(..))" may introduce bugs | ||
484 | since the logic test does not distinguish between the | ||
485 | positive case and the error case. | ||
438 | */ | 486 | */ |
439 | int pgm_is_descendant(node_t node, node_t query); | 487 | int pgm_is_descendant(node_t node, node_t query); |
440 | 488 | ||
441 | /* | 489 | /* |
442 | Check if a graph is a acyclic. | 490 | Check if a graph is a acyclic. |
443 | [in] graph: Graph descriptor | 491 | [in] graph: Graph descriptor |
444 | [in] ignore_explicit_backedges: Ignore edges that were added | 492 | [in] ignore_explicit_backedges: Ignore edges that were added |
445 | with pgm_init_backedge(). | 493 | with pgm_init_backedge(). |
446 | Return: 1 if graph is acyclic, 0 if it is not. | 494 | Return: 1 if graph is acyclic, 0 if it is not. |
447 | */ | 495 | */ |
448 | int pgm_is_dag(graph_t graph, int ignore_explicit_backedges = 1); | 496 | int pgm_is_dag(graph_t graph, int ignore_explicit_backedges = 1); |
diff --git a/src/pgm.cpp b/src/pgm.cpp index d66641f..122775e 100644 --- a/src/pgm.cpp +++ b/src/pgm.cpp | |||
@@ -2723,6 +2723,53 @@ out: | |||
2723 | return ret; | 2723 | return ret; |
2724 | } | 2724 | } |
2725 | 2725 | ||
2726 | int pgm_is_parent(node_t node, node_t query) | ||
2727 | { | ||
2728 | int ret = -1; | ||
2729 | struct pgm_graph* g; | ||
2730 | struct pgm_node* n; | ||
2731 | struct pgm_node* q; | ||
2732 | |||
2733 | if(node.graph != query.graph) | ||
2734 | goto out; | ||
2735 | if(!is_valid_graph(node.graph)) | ||
2736 | goto out; | ||
2737 | |||
2738 | ret = 0; | ||
2739 | if(node.node == query.node) | ||
2740 | { | ||
2741 | goto out; | ||
2742 | } | ||
2743 | |||
2744 | g = &gGraphs[node.graph]; | ||
2745 | n = &g->nodes[node.node]; | ||
2746 | q = &g->nodes[query.node]; | ||
2747 | |||
2748 | pthread_mutex_lock(&g->lock); | ||
2749 | for(int i = 0; i < n->nr_in; ++i) | ||
2750 | { | ||
2751 | if(g->edges[n->in[i]].is_backedge) | ||
2752 | { | ||
2753 | continue; // skip backedge | ||
2754 | } | ||
2755 | |||
2756 | if(q == &g->nodes[g->edges[n->in[i]].producer]) | ||
2757 | { | ||
2758 | ret = 1; | ||
2759 | break; | ||
2760 | } | ||
2761 | } | ||
2762 | pthread_mutex_unlock(&g->lock); | ||
2763 | |||
2764 | out: | ||
2765 | return ret; | ||
2766 | } | ||
2767 | |||
2768 | int pgm_is_child(node_t node, node_t query) | ||
2769 | { | ||
2770 | return pgm_is_parent(query, node); | ||
2771 | } | ||
2772 | |||
2726 | static int is_ancestor(const struct pgm_graph* g, | 2773 | static int is_ancestor(const struct pgm_graph* g, |
2727 | const struct pgm_node* n, const struct pgm_node* q, | 2774 | const struct pgm_node* n, const struct pgm_node* q, |
2728 | std::set<int>& visited) | 2775 | std::set<int>& visited) |
@@ -2785,7 +2832,6 @@ int pgm_is_ancestor(node_t node, node_t query) | |||
2785 | 2832 | ||
2786 | out: | 2833 | out: |
2787 | return ret; | 2834 | return ret; |
2788 | |||
2789 | } | 2835 | } |
2790 | 2836 | ||
2791 | int pgm_is_descendant(node_t n, node_t query) | 2837 | int pgm_is_descendant(node_t n, node_t query) |