00001
00002
00003
00004 #ifdef POLARIS_GNU_PRAGMAS
00005 #pragma implementation
00006 #endif
00007
00008 #include "SimGraph.h"
00009 #include "UEdge.h"
00010 #include "utilities/access_util.h"
00011 #include "utilities/stmt_util.h"
00012 #include "Range/Relation.h"
00013 #include "Range/RangeAccessor.h"
00014 #include "UBiGraphIterator.h"
00015
00016
00017 SimGraph::SimGraph( ) {
00018 #ifdef CLASS_INSTANCE_REGISTRY
00019 register_instance(SIM_GRAPH, sizeof(SimGraph), this);
00020 #endif
00021
00022 _descr_exists = new Array< bool >;
00023 _ptrs = new Array< RefElement< AbstractAccess > >;
00024 _graph = new Array<Array<SimEdgeKernel> >;
00025 _nodes = 0;
00026 _range_acc = 0;
00027 }
00028
00029
00030
00031 SimGraph::SimGraph( List<AbstractAccess> & list )
00032 {
00033 #ifdef CLASS_INSTANCE_REGISTRY
00034 register_instance(SIM_GRAPH, sizeof(SimGraph), this);
00035 #endif
00036
00037
00038
00039 _nodes = list.entries();
00040
00041 if (_nodes < 2) {
00042 _range_acc = 0;
00043 _ptrs = 0;
00044 _descr_exists = 0;
00045 _graph = 0;
00046 return;
00047 }
00048
00049 _ptrs = new Array< RefElement< AbstractAccess > >;
00050 _graph = new Array<Array<SimEdgeKernel> >;
00051
00052 _ptrs->resize(_nodes);
00053 _graph->resize(_nodes);
00054
00055 _descr_exists = new Array< bool >;
00056 _descr_exists->resize( _nodes );
00057
00058
00059
00060 for (int i=0; i < _nodes; ++i) {
00061 (*_descr_exists)[i] = true;
00062 }
00063
00064 Iterator<AbstractAccess> iter = list;
00065 for (int i = 0; iter.valid(); ++iter,++i) {
00066
00067 (*_ptrs)[i] = iter.current();
00068 (*_graph)[i].resize(_nodes);
00069 }
00070
00071
00072
00073 for (int i=0; i<_nodes; ++i) {
00074 for (int j=0; j<_nodes; ++j) {
00075 (((*_graph)[i])[j]).type(SIM_UNKNOWN);
00076 }
00077 }
00078
00079 Statement * r_stmt = range_stmt(*(list[0]._summarized_to));
00080 String stmt_tag = r_stmt->tag();
00081 _range_acc = new RangeAccessor(list[0]._pgm_summarized_to->range_dict_guarded(),
00082 *r_stmt );
00083
00084
00085
00086 for (int i=0; i<_nodes; ++i) {
00087 if (!(*_descr_exists)[i]) continue;
00088 for (int j=i+1; j<_nodes; ++j) {
00089 if (!(*_descr_exists)[j]) continue;
00090 calc_similarity( i, j );
00091 }
00092 }
00093 }
00094
00095 void
00096 SimGraph::print_similarities( ) const
00097 {
00098 if (_ar_logging && _ar_logging % 5 == 0) {
00099 for (int i=0; i<_nodes; ++i) {
00100 if (!(*_descr_exists)[i]) continue;
00101 arlog << "[" << i << "]" ;
00102 AbstractAccess & aa = *((*_ptrs)[i]);
00103 int ndims1 = aa.number_of_dimensions();
00104 for (int j=0; j<_nodes; ++j) {
00105 if (!(*_descr_exists)[j]) continue;
00106 AbstractAccess & aa2 = *((*_ptrs)[j]);
00107 SimEdgeKernel & sek = ((*_graph)[i])[j];
00108 int ndims2 = aa2.number_of_dimensions();
00109 arlog << " " << sek.type_name() << "[" ;
00110 if ((i != j) && (ndims1 == ndims2) &&
00111 (sek.type() != SIM_NOT_SIMILAR)) {
00112 for (int k=0; k<aa.number_of_dimensions(); ++k) {
00113 arlog << (*(sek.stridematch()))[k] << ":" ;
00114 if ((*(sek.spanmatch()))[k]) {
00115 arlog << "T";
00116 } else {
00117 arlog << "F";
00118 }
00119 }
00120 }
00121 arlog << "]";
00122 }
00123 arlog << endl;
00124 }
00125 }
00126 }
00127
00128
00129
00130 void
00131 SimGraph::_add_corresp_edge_forward(SimilarityType type, int index_new, int index_mid, int index_old,
00132 Array<int> * stride_match_new_mid, Array<bool> * span_match_new_mid)
00133 {
00134
00135
00136 SimEdgeKernel & kernel_mid_old = ((*_graph)[index_mid])[index_old];
00137 Array<int> * stride_match_mid_old = kernel_mid_old.stridematch( );
00138 Array<bool> * span_match_mid_old = kernel_mid_old.spanmatch( );
00139
00140 int new_dims = ((*_ptrs)[index_new])->number_of_dimensions();
00141 Array<int> * stride_match_new_old = new Array<int>;
00142 (*stride_match_new_old).resize( new_dims );
00143 Array<bool> * span_match_new_old = new Array<bool>;
00144 (*span_match_new_old).resize( new_dims );
00145
00146 for (int i=0; i<new_dims; ++i) {
00147 if ( (*stride_match_new_mid)[i] == -1 ) {
00148 (*stride_match_new_old)[i] = -1;
00149 (*span_match_new_old)[i] = false;
00150 } else {
00151 (*stride_match_new_old)[i] = (*stride_match_mid_old)[ (*stride_match_new_mid)[i] ];
00152 (*span_match_new_old)[i] = (*span_match_new_mid)[i] &&
00153 (*span_match_mid_old)[ (*stride_match_new_mid)[i] ];
00154 }
00155 }
00156 SimEdgeKernel & kernel_new_old = ((*_graph)[index_new])[index_old];
00157 kernel_new_old.dump_in_match( type, stride_match_new_old, span_match_new_old );
00158 }
00159
00160
00161
00162 void
00163 SimGraph::_add_corresp_edge_backward(SimilarityType type,
00164 int index_old, int index_mid, int index_new,
00165 Array<int> * stride_match_mid_new, Array<bool> * span_match_mid_new)
00166 {
00167
00168
00169 SimEdgeKernel & kernel_old_mid = ((*_graph)[index_old])[index_mid];
00170 Array<int> * stride_match_old_mid = kernel_old_mid.stridematch( );
00171 Array<bool> * span_match_old_mid = kernel_old_mid.spanmatch( );
00172 int old_dims = ((*_ptrs)[index_old])->number_of_dimensions();
00173
00174 Array<int> * stride_match_old_new = new Array<int>;
00175 (*stride_match_old_new).resize( old_dims );
00176 Array<bool> * span_match_old_new = new Array<bool>;
00177 (*span_match_old_new).resize( old_dims );
00178
00179 for (int i=0; i<old_dims; ++i) {
00180 if ( (*stride_match_old_mid)[i] == -1 ) {
00181 (*stride_match_old_new)[i] = -1;
00182 (*span_match_old_new)[i] = false;
00183 } else {
00184 (*stride_match_old_new)[i] = (*stride_match_mid_new)[ (*stride_match_old_mid)[i] ];
00185 (*span_match_old_new)[i] = (*span_match_old_mid)[i] &&
00186 (*span_match_mid_new)[ (*stride_match_old_mid)[i] ];
00187 }
00188 }
00189 SimEdgeKernel & kernel_old_new = ((*_graph)[index_old])[index_new];
00190 kernel_old_new.dump_in_match( type, stride_match_old_new, span_match_old_new );
00191 }
00192
00193
00194
00195
00196 SimGraph::SimGraph( const SimGraph & other ) {
00197 #ifdef CLASS_INSTANCE_REGISTRY
00198 register_instance(SIM_GRAPH, sizeof(SimGraph), this);
00199 #endif
00200
00201 _nodes = other._nodes;
00202 _ptrs = new Array< RefElement< AbstractAccess > >;
00203 _descr_exists = new Array< bool >;
00204 _graph = new Array< Array< SimEdgeKernel > >;
00205
00206 _ptrs->resize(_nodes);
00207 _descr_exists->resize( _nodes );
00208 _graph->resize(_nodes);
00209
00210 for (int i = 0; i<_nodes; ++i) {
00211 (*_ptrs)[i] = (*(other._ptrs))[i];
00212 (*_descr_exists)[i] = (*_descr_exists)[i];
00213 (*_graph)[i].resize(_nodes);
00214 }
00215
00216 for (int i=0; i < _nodes; ++i) {
00217 for (int j=0; j < _nodes; ++j) {
00218 ((*_graph)[i])[j] = ((*(other._graph))[i])[j];
00219 }
00220 }
00221 }
00222
00223
00224
00225 int
00226 SimGraph::nodes( )
00227 {
00228 return _nodes;
00229 }
00230
00231 SimGraph::~SimGraph( )
00232 {
00233 #ifdef CLASS_INSTANCE_REGISTRY
00234 unregister_instance(SIM_GRAPH, this);
00235 #endif
00236
00237 if (_ptrs) {
00238 delete _ptrs;
00239 }
00240 if (_descr_exists) {
00241 delete _descr_exists;
00242 }
00243 if (_graph) {
00244 delete _graph;
00245 }
00246 if (_range_acc) {
00247 delete _range_acc;
00248 }
00249 }
00250
00251
00252
00253 void
00254 SimGraph::calc_similarity( int i, int j )
00255 {
00256
00257 AbstractAccess & descr1 = *((*_ptrs)[ i ]);
00258 int ndims1 = descr1.number_of_dimensions();
00259
00260 AbstractAccess & descr2 = *((*_ptrs)[ j ]);
00261 int ndims2 = descr2.number_of_dimensions();
00262
00263 SimEdgeKernel & kernelij = ((*_graph)[i])[j];
00264 SimEdgeKernel & kernelji = ((*_graph)[j])[i];
00265
00266 SimilarityType orig_ij_type = kernelij.type();
00267 SimilarityType calc_ij_type;
00268
00269
00270 if ((orig_ij_type != SIM_UNKNOWN ) &&
00271 (orig_ij_type != SIM_DIM_EQUIV_UP ) &&
00272 (orig_ij_type != SIM_STRIDE_EQUIV_UP )) return;
00273
00274 bool equal_dim_count;
00275
00276 if (ndims1 == ndims2) {
00277 equal_dim_count = true;
00278 } else {
00279 equal_dim_count = false;
00280 }
00281
00282 bool matchoff = false;
00283 bool matchstrides, matchspans;
00284
00285 Array<int> * stride_match1;
00286 Array<int> * stride_match2;
00287 Array<bool> * span_match1;
00288 Array<bool> * span_match2;
00289
00290
00291
00292 matchoff = ar_offsets_match(descr1, descr2);
00293
00294
00295
00296
00297
00298 if (orig_ij_type == SIM_DIM_EQUIV_UP) {
00299 if (matchoff) {
00300 calc_ij_type = SIM_EQUIV;
00301 } else {
00302 calc_ij_type = SIM_DIM_EQUIV;
00303 }
00304 kernelij.type(calc_ij_type);
00305 kernelji.type(calc_ij_type);
00306
00307 stride_match1 = kernelij.stridematch();
00308 span_match1 = kernelij.spanmatch();
00309 stride_match2 = kernelji.stridematch();
00310 span_match2 = kernelji.spanmatch();
00311
00312 } else {
00313
00314
00315
00316 stride_match1 = new Array<int>;
00317 stride_match1->resize(ndims1);
00318
00319 stride_match2 = new Array<int>;
00320 stride_match2->resize(ndims2);
00321
00322 span_match1 = new Array<bool>;
00323 span_match1->resize(ndims1);
00324
00325 span_match2 = new Array<bool>;
00326 span_match2->resize(ndims2);
00327
00328 if (orig_ij_type == SIM_STRIDE_EQUIV_UP) {
00329
00330
00331
00332 Array<int> * temp1 = kernelij.stridematch();
00333 for (int ii=0; ii<ndims1; ++ii) {
00334 (*stride_match1)[ii] = (*temp1)[ii];
00335 (*span_match1)[ii] = false;
00336 }
00337 Array<int> * temp2 = kernelji.stridematch();
00338 for (int ii=0; ii<ndims2; ++ii) {
00339 (*stride_match2)[ii] = (*temp2)[ii];
00340 (*span_match2)[ii] = false;
00341 }
00342
00343 } else {
00344
00345 calc_stride_span_match(descr1, descr2, *_range_acc,
00346 *stride_match1, *stride_match2,
00347 *span_match1, *span_match2);
00348 }
00349
00350
00351
00352 if (orig_ij_type == SIM_STRIDE_EQUIV_UP) {
00353 matchstrides = true;
00354 } else {
00355 matchstrides = true;
00356
00357
00358
00359
00360 int count1 = 0;
00361 for (int ii=0; ii<ndims1; ++ii) {
00362 if ((*stride_match1)[ii] != -1) {
00363 count1++;
00364 }
00365 }
00366 int count2 = 0;
00367 for (int ii=0; ii<ndims2; ++ii) {
00368 if ((*stride_match2)[ii] != -1) {
00369 count2++;
00370 }
00371 }
00372
00373 p_assert(count1 == count2, "Stride-match is not reflexive");
00374
00375 if ((count1 != ndims1) && (count1 != ndims2)) {
00376 matchstrides = false;
00377 }
00378 }
00379
00380 matchspans = true;
00381 for (int ii=0; ii<ndims1; ++ii) {
00382 if (((*stride_match1)[ii] != -1) && (! (*span_match1)[ii])) {
00383 matchspans = false;
00384 break;
00385 }
00386 }
00387
00388 if (matchoff && matchstrides && matchspans && equal_dim_count) {
00389 calc_ij_type = SIM_EQUIV;
00390 } else if (matchoff && matchstrides && matchspans) {
00391 calc_ij_type = SIM_EQUIV_SEMI;
00392 } else if (matchstrides && matchspans && equal_dim_count) {
00393 calc_ij_type = SIM_DIM_EQUIV;
00394 } else if (matchstrides && matchspans) {
00395 calc_ij_type = SIM_DIM_EQUIV_SEMI;
00396 } else if (matchstrides && equal_dim_count) {
00397 calc_ij_type = SIM_STRIDE_EQUIV;
00398 } else if (matchstrides) {
00399 calc_ij_type = SIM_STRIDE_EQUIV_SEMI;
00400 } else {
00401 calc_ij_type = SIM_NOT_SIMILAR;
00402 }
00403
00404 kernelij.dump_in_match( calc_ij_type, stride_match1, span_match1 );
00405 kernelji.dump_in_match( calc_ij_type, stride_match2, span_match2 );
00406 }
00407
00408 if (kernelij.type( ) == SIM_NOT_SIMILAR) return;
00409
00410
00411
00412
00413
00414 for (int k=0; k<_nodes; ++k) {
00415 if (!(*_descr_exists)[k]) continue;
00416 if (k == i) continue;
00417 if (k == j) continue;
00418
00419 SimilarityType ik_type = ((*_graph)[i])[k].type();
00420
00421 if ((ik_type != SIM_NOT_SIMILAR) &&
00422 (ik_type != SIM_UNKNOWN)) {
00423
00424 if (calc_ij_type == SIM_EQUIV) {
00425 _add_corresp_edge_forward ( ik_type, j, i, k, stride_match2, span_match2 );
00426 _add_corresp_edge_backward( ik_type, k, i, j, stride_match1, span_match1 );
00427
00428 } else if (ik_type == SIM_EQUIV) {
00429 _add_corresp_edge_forward ( calc_ij_type, j, i, k, stride_match2, span_match2 );
00430 _add_corresp_edge_backward( calc_ij_type, k, i, j, stride_match1, span_match1 );
00431
00432 } else if ((calc_ij_type == SIM_DIM_EQUIV) &&
00433 (ik_type == SIM_DIM_EQUIV)) {
00434 _add_corresp_edge_forward ( SIM_DIM_EQUIV_UP, j, i, k, stride_match2, span_match2 );
00435 _add_corresp_edge_backward( SIM_DIM_EQUIV_UP, k, i, j, stride_match1, span_match1 );
00436
00437 } else if ((calc_ij_type == SIM_STRIDE_EQUIV) &&
00438 (ik_type == SIM_STRIDE_EQUIV)) {
00439 _add_corresp_edge_forward ( SIM_STRIDE_EQUIV_UP, j, i, k, stride_match2, span_match2 );
00440 _add_corresp_edge_backward( SIM_STRIDE_EQUIV_UP, k, i, j, stride_match1, span_match1 );
00441
00442 } else if (((calc_ij_type == SIM_STRIDE_EQUIV) &&
00443 (ik_type == SIM_DIM_EQUIV)) ||
00444 ((calc_ij_type == SIM_DIM_EQUIV) &&
00445 (ik_type == SIM_STRIDE_EQUIV))) {
00446 _add_corresp_edge_forward ( SIM_STRIDE_EQUIV, j, i, k, stride_match2, span_match2 );
00447 _add_corresp_edge_backward( SIM_STRIDE_EQUIV, k, i, j, stride_match1, span_match1 );
00448
00449 } else if ((calc_ij_type == SIM_DIM_EQUIV) &&
00450 (ik_type == SIM_DIM_EQUIV_UP)) {
00451 _add_corresp_edge_forward ( SIM_DIM_EQUIV_UP, j, i, k, stride_match2, span_match2 );
00452 _add_corresp_edge_backward( SIM_DIM_EQUIV_UP, k, i, j, stride_match1, span_match1 );
00453
00454 } else if ((calc_ij_type == SIM_DIM_EQUIV) &&
00455 (ik_type == SIM_STRIDE_EQUIV_UP)) {
00456 _add_corresp_edge_forward ( SIM_STRIDE_EQUIV_UP, j, i, k, stride_match2, span_match2 );
00457 _add_corresp_edge_backward( SIM_STRIDE_EQUIV_UP, k, i, j, stride_match1, span_match1 );
00458
00459 } else if ((calc_ij_type == SIM_STRIDE_EQUIV) &&
00460 (ik_type == SIM_DIM_EQUIV_UP)) {
00461 _add_corresp_edge_forward ( SIM_STRIDE_EQUIV, j, i, k, stride_match2, span_match2 );
00462 _add_corresp_edge_backward( SIM_STRIDE_EQUIV, k, i, j, stride_match1, span_match1 );
00463
00464 } else if ((calc_ij_type == SIM_STRIDE_EQUIV) &&
00465 (ik_type == SIM_STRIDE_EQUIV_UP)) {
00466 _add_corresp_edge_forward ( SIM_STRIDE_EQUIV_UP, j, i, k, stride_match2, span_match2 );
00467 _add_corresp_edge_backward( SIM_STRIDE_EQUIV_UP, k, i, j, stride_match1, span_match1 );
00468
00469 } else {
00470 continue;
00471 }
00472 }
00473 }
00474 }
00475
00476
00477
00478
00479
00480 void
00481 SimGraph::redo_spanmatch( SimEdge & edge, int which_node, int which_dim )
00482 {
00483 for (int i=0; i<_nodes; ++i) {
00484 if (!(*_descr_exists)[i]) continue;
00485 if (i==which_node) continue;
00486 SimEdgeKernel & edgek = ((*_graph)[which_node])[i];
00487 if ((edgek.type() == SIM_DIM_EQUIV) ||
00488 (edgek.type() == SIM_DIM_EQUIV_UP)) {
00489 (*(edgek.spanmatch()))[which_dim] = false;
00490 SimEdgeKernel & edgek2 = ((*_graph)[i])[which_node];
00491 (*(edgek2.spanmatch()))[(*(edgek.stridematch()))[which_dim]] = false;
00492 }
00493 }
00494 }
00495
00496 void
00497 SimGraph::set_unknown( SimEdge & edge, int which_node)
00498 {
00499 for (int i=0; i<_nodes; ++i) {
00500 if (!(*_descr_exists)[i]) continue;
00501 if (i==which_node) continue;
00502 ((*_graph)[which_node])[i].type(SIM_UNKNOWN);
00503 ((*_graph)[i])[which_node].type(SIM_UNKNOWN);
00504 }
00505 }
00506
00507 RangeAccessor *
00508 SimGraph::range_acc( )
00509 {
00510 return _range_acc;
00511 }
00512
00513 SimGraph *
00514 SimGraph::clone() const
00515 {
00516 return new SimGraph( (SimGraph &)*this );
00517 }
00518
00519 Listable *
00520 SimGraph::listable_clone() const
00521 {
00522 return (Listable *) clone();
00523 }
00524
00525 void
00526 SimGraph::print(ostream & o) const
00527 {
00528 o << "{ Nodes: " << _nodes << "; Ptrs: " << *_ptrs << "; Graph: " << *_graph << "}";
00529 }
00530
00531 ostream &
00532 operator << (ostream & o, const SimGraph & graph)
00533 {
00534 graph.print(o);
00535 return o;
00536 }
00537
00538 SimEdgeKernel &
00539 SimGraph::kernel(int i, int j)
00540 {
00541 return ((*_graph)[i])[j];
00542 }
00543
00544 void
00545 SimGraph::set_ptr(int i, AbstractAccess & aa)
00546 {
00547 (*_ptrs)[i] = aa;
00548 }