📄 c_testpath.c
字号:
/************************************************************************* This program is part of the OpenMP Source Code Repository http://www.pcg.ull.es/ompscr/ e-mail: ompscr@etsii.ull.es This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License (LICENSE file) along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA FILE: c_testPath.cVERSION: 1.0DATE:AUTHOR: Arturo Gonz醠ez-EscribanoCOMMENTS TO: arturo@infor.uva.esDESCRIPTION: Test if there exist a path between two given nodes in a directed graph.COMMENTS: Method: Parallel search synchronized by a workers-farm paradigm: Accessing to a shared task-pool in a critical regionREFERENCES: BASIC PRAGMAS: parallel, criticalUSAGE: ./c_testPath.par <source_node_num> <target_node_num> <graph_file>INPUT: A graph stored in a fileOUTPUT: True or False Compile with -DDEBUG to see more information about the push/pop operations of the threads.FILE FORMATS: Graph file should use .gph format This format is intended to store task graphs information. Each node may store a list of values which indicate resources consumption associated with the task (e.g. CPU time). ------------------------------------------------------------- FORMAT ------------------------------------------------------------- # <optional_comments> # <optional_comments> T: <number_of_nodes> R: <number_of_resources_per_task> t<i> <list_of_values> s<num_succesors>: <list_of_succ> t<i> <list_of_values> s<num_succesors>: <list_of_succ> t<i> <list_of_values> s<num_succesors>: <list_of_succ> ... ------------------------------------------------------------- EXAMPLES: ------------------------------------------------------------- # Small graph example T: 4 R: 0 t0: s2: 1 2 t1: s1: 3 t2: s1: 3 t3: s0: 0 / \ 1 2 \ / 3 ------------------------------------------------------------- # Another small example with two sources and two sinks # It uses 1 resource to store CPU time of each task T: 5 R: 1 t0: 0.4500 s1: 2 t1: 1.2340 s1: 2 t2: 0.8000 s2: 3 4 t3: 1.1000 s0: t4: 0.9086 s0: 0 1 \ / 2 / \ 3 4 -------------------------------------------------------------RESTRICTIONS: Only directed graphsREVISION HISTORY:**************************************************************************/#include<stdio.h>#include<stdlib.h>#include<OmpSCR.h>#include "AStack.h"#include "tg.h"/* PROTOYPES */void testPath(int, int, int, tg);/* MAIN: PROCESS PARAMETERS */int main(int argc, char *argv[]) {int nthreads, source, target;char *graphFileName;FILE *graphFile;tg graph;char *argNames[3] = { "source_node_num", "target_node_num", "graph_file" };char *defaultValues[3] = { "1", "29", "exampleGraph_01.gph" };char *timerNames[1] = { "EXE_TIME" };nthreads = omp_get_max_threads();OSCR_init( nthreads, "Check if there is a path on a directed graph.", NULL, 3, argNames, defaultValues, 1, 1, timerNames, argc, argv );/* 1. GET PARAMETERS */source = OSCR_getarg_int(1);target = OSCR_getarg_int(2);graphFileName = OSCR_getarg_string(3);/* 2. READ GRAPH */graphFile = fopen(graphFileName,"r");if (graphFile==NULL) { fprintf(stderr,"Imposible to open graph file: %s\n",graphFileName); exit(-1); }graph = tg_read(graphFile);fclose(graphFile);/* 3. CALL COMPUTATION */testPath(nthreads, source, target, graph);/* 4. REPORT */OSCR_report();return 0;}/*** Graph search. Test if exists a path from a source node to a target node** Parallelization method: Shared-Memory workers-farm**/void testPath(int nthreads, int source, int target, tg graph) {/* SHARED STRUCTURES */Bool *searched=NULL;Astack pool;Bool found = FALSE;int ind;/* ENDING CONTROL */int num_waiting=0;/* 1. ALLOCATE MEMORY FOR ANCILLARY STRUCTURES */pool = Ast_init();searched = OSCR_calloc(tg_nodes(graph), sizeof(Bool));for (ind=0; ind<tg_nodes(graph); ind++) { searched[ind]=FALSE; }/* 2. INIT "nodes to explore" POOL WITH THE source ID */Ast_push(pool, source);/* 3. START TIMER */OSCR_timer_start(0);/* 4. SPAWN WORKERS */#pragma omp parallel default(none) \ shared(nthreads,num_waiting,graph,searched,pool,target,found) {Bool waiting = FALSE;tg_task next=TG_NULLID;task_list succs;int num_succs;int ind;#ifdef DEBUGint numPops=0;int numNoPops=0;int thread = omp_get_thread_num();#endif/* WORKER WORKS UNTIL: * ALL WORKERS ARE WAITING (TARGET NOT FOUND) * OR SOMEONE FINDS THE TARGET */while ( num_waiting != nthreads && !found ) { /* 1. GET NEXT ELEMENT TO PROCESS (OR WAIT UNTIL MORE ELEMENTS) */ while( next == TG_NULLID && num_waiting != nthreads && !found) { /* ALL POOL OPERATIONS ARE MONITORIZED */ #pragma omp critical { /* 1.1. CHECK THE POOL */ if ( Ast_more(pool) ) { /* 1.1.1. ELEMENTS IN THE POOL: GET NEXT */ next = Ast_pop(pool);#ifdef DEBUGnumPops++;#endif /* 1.1.2. IF WAITING, CHANGE STATE */ if ( waiting ) { waiting = FALSE; num_waiting--; } } else { /* 1.1.3. EMPTY POOL: IF NOT WAITING, CHANGE STATE */#ifdef DEBUGnumNoPops++;#endif if ( !waiting ) { waiting = TRUE; num_waiting++; } } /* OMP END CRITICAL: MONITORIZED OPERATION */ } } /* END GET next ELEMENT FROM THE POOL */ /* 2. PROCESS next ELEMENT */ if ( next != TG_NULLID ) { /* 2.1. TARGET FOUND: END ALL */ if (next == target) { found = TRUE; } /* 2.2. NO SUCCESORS: END */ else if ( tg_succ_num(graph, next) == 0 ) { next = TG_NULLID; } /* 2.3. GET SUCCESORS LIST AND PUSH IT TO THE POOL */ else { /* 2.3.1. GET SUCCS LIST */ num_succs = tg_succ_num(graph, next); succs = tg_succ(graph, next); /* 2.3.2. PUSH SUCCS TO POOL: MONITORIZED OPERATION */ #pragma omp critical if ( num_succs > 0 ) { for(ind=0; ind<num_succs; ind++) { tg_task vp = succs[ind]; /* PUSH ONLY NON-EXPLORED NODES */ if ( ! searched[ vp ] ) { searched[ vp ] = TRUE; Ast_push(pool, vp); } } /* END OMP CRITICAL: MONITORIZED OPERATION */ } } /* 2.4. END PROCESSING ELEMENT */ next = TG_NULLID; } } /* END PROCESSING */#ifdef DEBUGprintf("#DEBUG Thread %d ENDING ----> Pops: %d, NoPops: %d\n",thread,numPops,numNoPops);#endif/* WORKERS END: PARALLEL REGION */}/* 5. STOP TIMER */OSCR_timer_stop(0);/* 6. WRITE RESULT */printf("\nPath(%d,%d) = %d\n\n", source, target, found);/* 7. END */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -