Pathfinder

From README:

PathFinder searches for “signatures” within graphs. Graphs being searched are directed and cyclic. Many, but not all nodes within the graph have labels. Any given node may have more than one label, and any label may be applied to more than one node. A signature is an orderd list of labels. PathFinder searches for paths between labels within the signature. PathFinder returns success if there is a path from a node with the first label in the signature that passes through nodes with each label in order, ultimately reaching a node with the last label in the signature. Labeled nodes need not be contiguous on any given path.


Problem Configuration

    ./PathFinder.x -x <data file>

Sample data sets are included in the generatedData and scaleData subdirectories. The scaleData files are intended for performance characterization.


Analysis


Build and Run Information

Compiler = 'clang 5.0.1'
Build_Flags = '-g -O3 -march=native -fopenmp -lgomp -lm'
Run_Parameters = '-x data/scaleData/4kx750.adj_list'

Scaling


Program Aggregate

Threads (Time)
Inst/Cycle per Core
L1 DC Miss %
L2 DC Miss %
L3 Miss %
L1 Loads/Cycle per Core
L2 B/W Used
L3 B/W Used
DRAM B/W Used
1 (100.0%) 1.6 6.1% 63.3% 0.0% 0.49 14.5% 12.3% 0.0%
72 (100.0%) 1.3 5.6% 61.9% 0.0% 0.42 22.4% 19.3% 0.0%

findNextLabel

Threads (Time)
Inst/Cycle per Core
L1 DC Miss %
L2 DC Miss %
L3 Miss %
L1 Loads/Cycle per Core
L2 B/W Used
L3 B/W Used
DRAM B/W Used
1 (69.9%) 1.6 5.5% 68.0% 0.0% 0.52 13.8% 12.5% 0.0%
72 (40.8%) 2.0 6.0% 66.6% 0.0% 0.63 37.6% 34.7% 0.0%
138 bool findNextLabel( Node *node, Signature labels, NodePtrVec *result, Bitfield *visited )
139 {
140     EdgeList *edge;
141     bool success = false;
142     NodePtrVec *nextLegResult = NULL;
143     /* NodePtrVec *nextLegVisited = NULL; */
144     Bitfield *nextLegVisited = NULL;
145 
146 
147     /* A little basic error checking */
148     if ( !node || !labels || !result|| !visited )
149     {
150         return( false );
151     }
152 
153     /* If this node is already in the vector, we have found a loop. return false. */
154 
155     if ( Bitfield_nodeVisited( visited, node ) )
156         return( false );
157 
158     /* put this node on the result vector to show that we've been here */
159     NodePtrVec_push( result, node );
160 
161     /* Check this node's edges to see if there's a match */
162     /* Note: We have a NodePtrVec holding the set of nodes with this label. It
163      *       may be more optimal to see if a given edge node is in that set
164      *       rather than doing a bunch of inefficient strcmp calls. Another approach
165      *       would be to have unique hash values for each label, and thereby be
166      *       able to compare those. However for the initial version of this code,
167      *       keeping things simple and straightforward, we're doing the string
168      *       compare.
169      */
170 
Threads (Time)
Inst/Cycle per Core
L1 DC Miss %
L2 DC Miss %
L3 Miss %
L1 Loads/Cycle per Core
L2 B/W Used
L3 B/W Used
DRAM B/W Used
1 (32.3%) 1.3 8.1% 68.0% 0.0% 0.40 17.3% 15.7% 0.0%
72 (18.0%) 1.6 8.7% 66.7% 0.0% 0.48 46.7% 43.2% 0.0%
171     for ( edge = node->edges; edge != NULL; edge = edge->nextEdge )
172     {
173 
174         // string based:
175         if ( edge->targetNode->label
                 && strcmp( edge->targetNode->label, labels[0] ) == 0 )
176         // index based: if ( edge->targetNode->labelIdx == labelIdxs[0] )
177         {
178             if ( labels[1] != NULL ) /* more steps in the signature */
179             {
180                 nextLegResult = NodePtrVec_new( 50 ); /* arbitrary size,
                                              malloc success checked in recursion */
181                 nextLegVisited = Bitfield_new(visited->bitsNeeded);
182 
183                 success = findNextLabel( edge->targetNode, &labels[1],
                                             nextLegResult, nextLegVisited );
184                 /* NodePtrVec_delete( nextLegVisited ); */
185                 Bitfield_delete( nextLegVisited );
186                 if ( success )
187                 {
188                     NodePtrVec_appendVectors( result, nextLegResult, true );
189                     NodePtrVec_delete( nextLegResult );
190                     return( true );
191                 }
192 
193             }
194             else /* We have exhausted the signature - ultimate victory! */
195             {
196                 /* Register this edge node as being the final node */
197                 NodePtrVec_push( result, edge->targetNode );
198                 return( true );
199             }
200         }
201     }
202 
203 
204     /* IF we made it here, we need to continue through the tree, seeing if any of our
205      * edge nodes have a connection to a labeled node.
206      */
207     for ( edge = node->edges; edge != NULL; edge = edge->nextEdge )
208     {
209         success = findNextLabel( edge->targetNode, labels, result, visited );
210         if ( success )
211             return( true ); /* this edge has a path to the ultimate signature path */
212     }
213 
214 
215     /* and, if we make it here, we have failed. */
216     NodePtrVec_pop( result ); /* take current node off the result vector */
217     return false;
218 }