/********************************************************************* * interface.c * * Jorge Luis Vittes * * auxilary functions, and extra data structures for the tree-contraction * *********************************************************************/ #include #include #include #include #include "Globals.h" #include "Interface.h" #include "Contract.h" #include "BinCluster.h" #include "UnaryCluster.h" #include "Data.h" #include "Application.h" #include "Tree.h" #define SEED_FILE "seed" int seed; // this is used for debugging #define MILLION 1000000 Queue *cQueue; tree_t* cTree; ///////////////////////////////////////////////////////////////////// // Set the global tree and queue to tree and q respectively ///////////////////////////////////////////////////////////////////// void setTreeAndQueue(tree_t* tree, Queue* q) { cQueue = q; cTree = tree; } ////////////////////////////////////////////////////////////////////// // Structural Changes: link and cut ////////////////////////////////////////////////////////////////////// int link(node* thisNode, node* otherNode, int w, tree_t* tree, Queue* q) { int isLeaf1, isLeaf2; isLeaf1 = isLeaf(thisNode); isLeaf2 = isLeaf(otherNode); bin_data data = makeEdgeData (thisNode->nId, otherNode->nId, w); deprintf("Adding edge with weight %d from %d to %d\n",w,thisNode->nId,otherNode->nId); if (addEdge(thisNode,otherNode,data,tree)) { // Queue neighbors if leaf status changes if (isLeaf1) { insertQueue (GET_NEIGHBOR(thisNode->scars[thisNode->left].backscar),q); insertQueue (GET_NEIGHBOR(thisNode->scars[thisNode->right].backscar),q); } if (isLeaf2) { insertQueue (GET_NEIGHBOR(otherNode->scars[otherNode->left].backscar),q); insertQueue (GET_NEIGHBOR(otherNode->scars[otherNode->right].backscar),q); } insertQueue (thisNode,q); insertQueue (otherNode,q); assert (verifyTree(tree)); return 1; } deprintf("Insertion FAILED\n"); // Insertion failed. return 0; } ////////////////////////////////////////////////////////////////////// // add an edge between vertices of id n1 and n2 of weight w to // the cached tree. ////////////////////////////////////////////////////////////////////// int linkEdge(int n1, int n2, int w) { node* u = cTree->vertexArray+n1; node* v = cTree->vertexArray+n2; return link(u,v,w,cTree,cQueue); } ////////////////////////////////////////////////////////////////////// // cut the edge between v1, and v2 ////////////////////////////////////////////////////////////////////// void cut(node* v1, node* v2, tree_t* tree, Queue* q) { int deg; deprintf("deleting edge from %d to %d\n",v1->nId,v2->nId); if(deleteEdge(v1,v2,tree)) { deg = v1->degree; if(deg == 1) insertQueue(GET_NEIGHBOR(v1->scars[v1->left].backscar),q); deg = v2->degree; if(deg == 1) insertQueue(GET_NEIGHBOR(v2->scars[v2->left].backscar),q); insertQueue(v1,q); insertQueue(v2,q); } else { printf("ERROR NO SUCH EDGE\n");exit(-9); } } ////////////////////////////////////////////////////////////////// // cut and edge between vertices of id n1 and n2 in the cached // tree ////////////////////////////////////////////////////////////////// void cutEdge(int n1, int n2) { node* v1 = cTree->vertexArray + n1; node* v2 = cTree->vertexArray + n2; cut(v1,v2,cTree,cQueue); } /////////////////////////////////////////////////////////////////// // return true (1) if there is an edge between veritices of id n1 // and n2 in the cached tree, otherwise, false (0) /////////////////////////////////////////////////////////////////// int isEdge(int n1,int n2) { node* v1 = cTree->vertexArray + n1; node* v2 = cTree->vertexArray + n2; int i; for(i=0;iscars[i].backscar)) == v2) return 1; } return 0; } void changeDataOnVertex(int i, void (*f)(unary_data* )) { } ////////////////////////////////////////////////////////////////////// // Application-Specific Data Changes: changeVertexData and changeEdgeData // The function f must be supplied by the application ////////////////////////////////////////////////////////////////////// void changeVertexData (node* v, Queue* q, clusterList* cList, void (*f)(unary_data* )) { unary_cluster* ucl = (unary_cluster*) v->data; (*f)(&(ucl->data)); deprintf("changing data on %d\n",v->nId); deprintf("inserting into pq %p\n",cList); insertCluster(v->data,cList); } void changeEdgeData (node* v, node* u, Queue* q, clusterList* cList, void (*f)(bin_data*)) { bin_cluster* c = findEdgeCluster (v,u); deprintf("changing edge from %d to %d \n",v->nId, u->nId); assert (c); (*f)(&(c->data)); deprintf("inserting into pq %p\n",cList); insertCluster(c,cList); } ////////////////////////////////////////////////////////////////////// // Compute the value for the root cluster ////////////////////////////////////////////////////////////////////// // A util function for updating the tag of a cluster void updateCluster(cluster* cl) { PURIFY(&cl); cl -> synchronize (); cl -> affected = NOT_AFFECTED; } ////////////////////////////////////////////////////////////////////// // Propagate changes in the priority queue ////////////////////////////////////////////////////////////////////// cluster* propagate(clusterList* cList) { cluster* cl; cluster *root; while(cList->head) { cl = removeCluster(cList); cl = cl->parent; while (cl) { root = cl; updateCluster(cl); cl = cl->parent; } } return root; } cluster* update(Queue *q,tree_t* tree) { assert (! isEmpty (q)); cluster* root = rerun (q,tree,1); //synchronize (root); return root; } void contract() { rerun(cQueue,cTree,1); } ////////////////////////////////////////////////////////////////////// // Some functions for testing ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // Initializes the random number generator // with the seed in file SEED ////////////////////////////////////////////////////////////////////// void initTest () { FILE *file; // Initialize the random number generator with seed. file = fopen(SEED_FILE,"r"); if (!file) {printf ("Application must have a seed file"); exit (-1);} fscanf(file,"%i\n",&seed); srand(seed); fclose(file); } ////////////////////////////////////////////////////////////////////// // Write a new seed to the file SEED file ////////////////////////////////////////////////////////////////////// void finishTest () { // Write seed to the FILE *file; file = fopen(SEED_FILE,"w"); fprintf(file,"%d\n",rand()); fclose(file); } // Run tree contraction from scratch on the original tree, otree. final_data makeRegularRun(tree_t* otree) { Queue* q = initQueue (); tree_t *coTree = initTree(otree->n); cTree = coTree; copyTree(otree,coTree); // Do a tree contraction, from scratch initTreeContraction (q,coTree); cluster* root = initialrun(q,coTree); //synchronize (root); final_data result = ((final_cluster*)root)->data; destructTree(coTree); destructQueue (q); return result; } ////////////////////////////////////////////////////////////////////// // syncnAndCheck_ // // Does an update and if NDEBUG is not set (in the debugging mode, // it verifies the update. It will exit when incorrect. ////////////////////////////////////////////////////////////////////// final_data syncAndCheck_(tree_t *tree, Queue* Q) { cluster *root1; final_data data1, data2; deprintf("Rennuning\n\n"); drun(assert (verifyContractionTree(tree))); deprintf ("--------------------------------------------------\n"); drun(data2 = makeRegularRun(tree)); deprintf("\n **************\nRegular run done \n\n"); drun(assert (verifyContractionTree(tree))); root1 = update(Q,tree); deprintf("done with sync\n"); drun(assert (verifyContractionTree(tree))); data1 = ((final_cluster*)root1)->data; deprintf("root1's data is = ");drun(data1.print()); deprintf("root2's data is = ");drun(data2.print()); drun( if(!isEqual2(data1,data2)) { printf("\n CHECK HERE Seed is %d!!! \n\n", seed); debug=1; deprintf("root1's data is = ");data1.print(); deprintf("root2's data is = ");data2.print(); CRASH;exit(0); } ); deprintf("\n **************\nRerun done \n\n"); deprintf("done\n"); return data1; } void printTimePerOp (clock_t start, clock_t finish, int nOps) { double total = ((double) (finish - start)) * (MILLION*1.0) / CLOCKS_PER_SEC; printf("\nTime taken is %.5f microseconds/operation \n", total/(double) nOps); } ////////////////////////////////////////////////////////////////////// // propagateAndCheck // // Does and update and if NDEBUG is not set (in the debugging mode, // it verifies the update. It exit when incorrect and print correct // when so. ////////////////////////////////////////////////////////////////////// final_data propagateAndCheck (tree_t* tree, Queue* Q, clusterList* cList) { cluster *root1; final_data data1, data2; deprintf("Rennuning\n\n"); drun(assert (verifyContractionTree(tree))); deprintf ("--------------------------------------------------\n"); drun(data2= makeRegularRun(tree)); deprintf("\n **************\nRegular run done \n\n"); drun(assert (verifyContractionTree(tree))); root1 = propagate(cList); deprintf("Done with propagate\n"); drun(assert (verifyContractionTree(tree))); data1 = ((final_cluster *)root1)->data; //debug = 1; deprintf("root1's data is = "); data1.print(); deprintf("root2's data is = "); data2.print(); //debug = 0; drun( if(!isEqual2(data1,data2)) { printf("\n CHECK HERE Seed is %d!!! \n\n", seed); exit(0); } else deprintf("\nCorrect!!!\n"); ); deprintf("\n **************\nRerun done \n\n"); deprintf("done\n"); return data1; } ////////////////////////////////////////////////////////////////////// // set goRandom to some positive number to do the random cut&linkHHHs. // there will be goRandom number of cut&links. // if goRandom is zero, then it will follow the trace, fName. ////////////////////////////////////////////////////////////////////// void testSynchronize (char* treeName, int goRandom, char* fName) { cluster* root; clock_t start,finish; int n,n1,n2; int nOps; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtree(treeName); n = tree->n; node* vertexArray = tree->vertexArray; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); cTree = tree; cQueue = Q; root = initialrun(Q,tree); deprintf("done with the initial run\n"); // Do goRandom number of random cut&links (same edge). if (goRandom) { nOps = goRandom; start = clock (); deprintf("going random, %d\n", goRandom); deprintf ("."); fflush (stdout); while (goRandom > 0) { //debug =1; deprintf ("."); fflush (stdout); // Randomly select edges and cut/link n = tree->n; n1 = (rand() % n)+1; //choose a random node; node* v = tree->vertexArray + n1; if(v->degree !=0) { node* u = GET_NEIGHBOR(v->scars[v->left].backscar); // Cut and link the same age. cut (u,v,tree,Q); syncAndCheck_(tree,Q); goRandom -= 1; link(u,v,rand()%MILLION,tree,Q); // Syncronize syncAndCheck_(tree,Q); goRandom -= 1; } } finish = clock (); } else { FILE *trace; char str[200]; trace = fopen(fName,"r"); if (!trace) {printf ("Can't open trace file %s\n", fName); exit (-1);} start = clock(); nOps=0; while((fscanf(trace,"%s\n",str) != EOF)) { int w; deprintf ("."); if(strcasecmp(str,"L") == 0) { fscanf(trace,"%i %i %i\n",&n1,&n2,&w); link(vertexArray+n1, vertexArray+n2, rand()%10, tree, Q); //printf("Link %d, %d, with weight %d\n",n1,n2,w); syncAndCheck_(tree,Q); nOps++; } else if(strcasecmp(str,"C") == 0) { fscanf(trace,"%i %i\n",&n1,&n2); cut(vertexArray+n1,vertexArray+n2,tree,Q); deprintf("Cut %d, %d\n",n1,n2); syncAndCheck_(tree,Q); nOps++; } } finish = clock(); } printTimePerOp (start,finish,nOps); finishTest (); } ////////////////////////////////////////////////////////////////////// // set goRandom to some positive number to do the random cut&linkHHHs. // there will be goRandom number of cut&links. // if goRandom is zero, then it will follow the trace, fName. ////////////////////////////////////////////////////////////////////// void testNCutsWithLC(char* treeName, int nCuts, char* fName) { cluster* root; clock_t start,finish; int n; int nOps; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtreeAndEdges(treeName); n = tree->n; node* vertexArray = tree->vertexArray; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); cTree = tree; cQueue = Q; root = initialrun(Q,tree); deprintf("done with the initial run\n"); if(fName) { FILE *trace; char str[200]; int n1,n2; trace = fopen(fName,"r"); if (!trace) {printf ("Can't open trace file %s\n", fName); exit (-1);} start = clock(); nOps = 1; while((fscanf(trace,"%s\n",str) != EOF)) { int w; deprintf ("."); if(strcasecmp(str,"L") == 0) { fscanf(trace,"%i %i %i\n",&n1,&n2,&w); link(vertexArray+n1, vertexArray+n2, w, tree, Q); rerun(Q,tree,0); } else if(strcasecmp(str,"C") == 0) { fscanf(trace,"%i %i\n",&n1,&n2); cut(vertexArray+n1,vertexArray+n2,tree,Q); deprintf("Cut %d, %d\n",n1,n2); rerun(Q,tree,0); } } } else { nOps = 1; start = clock (); int i; for(i = 0;iedgeArray[i].eps[0]; node* v = vertexArray+tree->edgeArray[i].eps[1]; // Cut and link the same age. cut (u,v,tree,Q); rerun(Q,tree,0); } } finish = clock (); printTimePerOp (start,finish,nOps); finishTest (); } ////////////////////////////////////////////////////////////////////// // set goRandom to some positive number to do the random cut&linkHHHs. // there will be goRandom number of cut&links. // if goRandom is zero, then it will follow the trace, fName. ////////////////////////////////////////////////////////////////////// void testNCutsLC(char* treeName, int nCuts, char* fName) { cluster* root; clock_t start,finish; int n; int nOps; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtreeAndEdges(treeName); n = tree->n; node* vertexArray = tree->vertexArray; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); cTree = tree; cQueue = Q; root = initialrun(Q,tree); deprintf("done with the initial run\n"); if(fName) { FILE *trace; char str[200]; int n1,n2; trace = fopen(fName,"r"); if (!trace) {printf ("Can't open trace file %s\n", fName); exit (-1);} start = clock(); nOps = 1; while((fscanf(trace,"%s\n",str) != EOF)) { int w; deprintf ("."); if(strcasecmp(str,"L") == 0) { fscanf(trace,"%i %i %i\n",&n1,&n2,&w); link(vertexArray+n1, vertexArray+n2, w, tree, Q); } else if(strcasecmp(str,"C") == 0) { fscanf(trace,"%i %i\n",&n1,&n2); cut(vertexArray+n1,vertexArray+n2,tree,Q); deprintf("Cut %d, %d\n",n1,n2); } } rerun(Q,tree,0); } else { nOps = 1; start = clock (); int i; for(i = 0;iedgeArray[i].eps[0]; node* v = vertexArray+tree->edgeArray[i].eps[1]; // Cut and link the same age. cut (u,v,tree,Q); } rerun(Q,tree,0); } finish = clock (); printTimePerOp (start,finish,nOps); finishTest (); } ////////////////////////////////////////////////////////////////////// // set goRandom to some positive number to do the random cut&links. // there will be goRandom number of cut&links. // if goRandom is zero, then it will follow the trace, fName. ////////////////////////////////////////////////////////////////////// void testNCutsAndSync(char* treeName, int nCuts, char* fName) { cluster* root; clock_t start,finish; int n; int nOps; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtreeAndEdges(treeName); n = tree->n; node* vertexArray = tree->vertexArray; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); cTree = tree; cQueue = Q; root = initialrun(Q,tree); deprintf("done with the initial run\n"); if(fName) { FILE *trace; char str[200]; int n1,n2; trace = fopen(fName,"r"); if (!trace) {printf ("Can't open trace file %s\n", fName); exit (-1);} start = clock(); nOps = 1; while((fscanf(trace,"%s\n",str) != EOF)) { int w; deprintf ("."); if(strcasecmp(str,"L") == 0) { fscanf(trace,"%i %i %i\n",&n1,&n2,&w); link(vertexArray+n1, vertexArray+n2, w, tree, Q); } else if(strcasecmp(str,"C") == 0) { fscanf(trace,"%i %i\n",&n1,&n2); cut(vertexArray+n1,vertexArray+n2,tree,Q); deprintf("Cut %d, %d\n",n1,n2); } } syncAndCheck_(tree,Q); finish = clock (); } else { nOps = 1; start = clock (); int i; //debug =1; for(i = 0;iedgeArray[i].eps[0]; node* v = vertexArray+tree->edgeArray[i].eps[1]; // Cut and link the same age. cut (u,v,tree,Q); deprintf("cut %d done between %d and %d\n",i,tree->edgeArray[i].eps[0],tree->edgeArray[i].eps[1]); } syncAndCheck_(tree,Q); finish = clock (); } printTimePerOp (start,finish,nOps); finishTest (); } ////////////////////////////////////////////////////////////////////// // set goRandom to some positive number to do the random cut&links. // there will be goRandom number of cut&links. // if goRandom is zero, then it will follow the trace, fName. ////////////////////////////////////////////////////////////////////// void testNCutsWithSync(char* treeName, int nCuts, char* fName) { cluster* root; clock_t start,finish; int n; int nOps; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtreeAndEdges(treeName); n = tree->n; node* vertexArray = tree->vertexArray; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); cTree = tree; cQueue = Q; root = initialrun(Q,tree); deprintf("done with the initial run\n"); if(fName) { FILE *trace; char str[200]; int n1,n2; trace = fopen(fName,"r"); if (!trace) {printf ("Can't open trace file %s\n", fName); exit (-1);} start = clock(); nOps = 1; while((fscanf(trace,"%s\n",str) != EOF)) { int w; deprintf ("."); if(strcasecmp(str,"L") == 0) { fscanf(trace,"%i %i %i\n",&n1,&n2,&w); link(vertexArray+n1, vertexArray+n2, w, tree, Q); syncAndCheck_(tree,Q); } else if(strcasecmp(str,"C") == 0) { fscanf(trace,"%i %i\n",&n1,&n2); cut(vertexArray+n1,vertexArray+n2,tree,Q); deprintf("Cut %d, %d\n",n1,n2); syncAndCheck_(tree,Q); } } } else { nOps = 1; start = clock (); int i; //debug =1; for(i = 0;iedgeArray[i].eps[0]; node* v = vertexArray+tree->edgeArray[i].eps[1]; // Cut and link the same age. cut (u,v,tree,Q); deprintf("cut %d done between %d and %d\n",i,tree->edgeArray[i].eps[0],tree->edgeArray[i].eps[1]); syncAndCheck_(tree,Q); } } finish = clock (); printTimePerOp (start,finish,nOps); finishTest (); } void testSynchronizeWithQuery (char* treeName, int goRandom, char* fName,void (*query)(tree_t*)) { cluster* root; clock_t start,finish; int n,n1,n2; int nOps; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtree(treeName); n = tree->n; node* vertexArray = tree->vertexArray; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); cTree = tree; cQueue = Q; root = initialrun(Q,tree); deprintf("done with the initial run\n"); // Do goRandom number of random cut&links (same edge). if (goRandom) { nOps = goRandom; start = clock (); deprintf("going random, %d\n", goRandom); while (goRandom > 0) { // Randomly select edges and cut/link n = tree->n; n1 = (rand() % n)+1; //choose a random node; node* v = tree->vertexArray + n1; node* u = GET_NEIGHBOR(v->scars[v->left].backscar); // Cut and link the same age. cut (u,v,tree,Q); link(u,v,rand()%10,tree,Q); // Syncronize syncAndCheck_(tree,Q); // do a query (*query)(tree); goRandom -= 1; } finish = clock (); } else { FILE *trace; char str[200]; trace = fopen(fName,"r"); if (!trace) {printf ("Can't open trace file %s\n", fName); exit (-1);} start = clock(); nOps=0; while((fscanf(trace,"%s\n",str) != EOF)) { int w; deprintf ("."); if(strcasecmp(str,"L") == 0) { fscanf(trace,"%i %i %i\n",&n1,&n2,&w); link(vertexArray+n1, vertexArray+n2, rand()%10, tree, Q); //printf("Link %d, %d, with weight %d\n",n1,n2,w); syncAndCheck_(tree,Q); (*query)(tree); nOps++; } else if(strcasecmp(str,"C") == 0) { fscanf(trace,"%i %i\n",&n1,&n2); cut(vertexArray+n1,vertexArray+n2,tree,Q); deprintf("Cut %d, %d\n",n1,n2); } } finish = clock(); } printTimePerOp (start,finish,nOps); finishTest (); } void testSynchronizeWithQueryTrace (char* treeName, int goRandom, char* fName,void (*query)(tree_t*,FILE*)) { cluster* root; clock_t start,finish; int n,n1,n2; int nOps; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtree(treeName); n = tree->n; node* vertexArray = tree->vertexArray; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); cTree = tree; cQueue = Q; root = initialrun(Q,tree); deprintf("done with the initial run\n"); // Do goRandom number of random cut&links (same edge). if (goRandom) { nOps = goRandom; start = clock (); deprintf("going random, %d\n", goRandom); while (goRandom > 0) { // Randomly select edges and cut/link n = tree->n; n1 = (rand() % n)+1; //choose a random node; node* v = tree->vertexArray + n1; node* u = GET_NEIGHBOR(v->scars[v->left].backscar); // Cut and link the same age. cut (u,v,tree,Q); if(goRandom != nOps) link(u,v,rand()%10,tree,Q); // Syncronize syncAndCheck_(tree,Q); // do a query (*query)(tree,NULL); goRandom -= 1; } finish = clock (); } else { FILE *trace; char str[200]; trace = fopen(fName,"r"); if (!trace) {printf ("Can't open trace file %s\n", fName); exit (-1);} start = clock(); nOps=0; while((fscanf(trace,"%s\n",str) != EOF)) { int w; deprintf ("."); if(strcasecmp(str,"L") == 0) { fscanf(trace,"%i %i %i\n",&n1,&n2,&w); link(vertexArray+n1, vertexArray+n2, w, tree, Q); //printf("Link %d, %d, with weight %d\n",n1,n2,w); syncAndCheck_(tree,Q); (*query)(tree,trace); nOps++; } else if(strcasecmp(str,"C") == 0) { fscanf(trace,"%i %i\n",&n1,&n2); cut(vertexArray+n1,vertexArray+n2,tree,Q); deprintf("Cut %d, %d\n",n1,n2); } } finish = clock(); } printTimePerOp (start,finish,nOps); finishTest (); } ////////////////////////////////////////////////////////////////////// // set goRandom to some positive number to do the random cut&links. // there will be goRandom number of cut&links. // if goRandom is zero, then it will follow the trace, fName. ////////////////////////////////////////////////////////////////////// void testLinkCut (char* treeName, int goRandom, char* fName) { cluster* root; clock_t start,finish; int n,n1,n2; int nOps; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtree(treeName); n = tree->n; node* vertexArray = tree->vertexArray; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); cTree = tree; cQueue = Q; root = initialrun(Q,tree); deprintf("done with the initial run\n"); // Do goRandom number of random cut&links (same edge). if (goRandom) { nOps = goRandom; start = clock (); deprintf("going random, %d\n", goRandom); while (goRandom > 0) { // Randomly select edges and cut/link n = tree->n; n1 = (rand() % n)+1; //choose a random node; node* v = tree->vertexArray + n1; node* u = GET_NEIGHBOR(v->scars[v->left].backscar); // Cut and link the same age. cut (u,v,tree,Q); rerun(Q,tree,0); goRandom -= 1; link(u,v,rand()%10,tree,Q); // propagate rerun(Q,tree,0); //no synch goRandom -= 1; } finish = clock (); } else { FILE *trace; char str[200]; trace = fopen(fName,"r"); if (!trace) {printf ("Can't open trace file %s\n", fName); exit (-1);} start = clock(); nOps=0; while((fscanf(trace,"%s\n",str) != EOF)) { int w; deprintf ("."); if(strcasecmp(str,"L") == 0) { fscanf(trace,"%i %i %i\n",&n1,&n2,&w); link(vertexArray+n1, vertexArray+n2, rand()%MILLION, tree, Q); // propagate rerun (Q,tree,0); //no synch nOps++; } else if(strcasecmp(str,"C") == 0) { fscanf(trace,"%i %i\n",&n1,&n2); cut(vertexArray+n1,vertexArray+n2,tree,Q); deprintf("Cut %d, %d\n",n1,n2); } } finish = clock(); } printTimePerOp (start,finish,nOps); finishTest (); } void testLinkCutChain (char* treeName, int goRandom) { cluster* root; clock_t start,finish; int n,n1; int nOps; node *endp1, *endp2; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtree(treeName); n = tree->n; node* vertexArray = tree->vertexArray; cTree = tree; cQueue = Q; // Initial end points are always 1 and 2. endp1 = vertexArray+1; endp2 = vertexArray+2; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); root = initialrun(Q,tree); deprintf("done with the initial run\n"); // Do goRandom number of random cut&links (same edge). if (goRandom) { nOps = goRandom; start = clock (); deprintf("going random, %d\n", goRandom); while (--goRandom) { // Randomly select edges and cut/link n = tree->n; n1 = (rand() % n)+1; //choose a random node; node* v = tree->vertexArray + n1; node* u = GET_NEIGHBOR(v->scars[v->left].backscar); // Cut and link the same age. cut (u,v,tree,Q); link (endp1,endp2,rand()%MILLION,tree,Q); // propagate rerun(Q,tree,0); endp1 = u; endp2 = v; } finish = clock (); } printTimePerOp (start,finish,nOps); finishTest (); } void testLinkCutMSTChain (char* treeName, int goRandom,void (*query)(tree_t*)) { cluster* root; clock_t start,finish; int n,n1; int nOps; node *endp1, *endp2; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtree(treeName); n = tree->n; node* vertexArray = tree->vertexArray; cTree = tree; cQueue = Q; // Initial end points are always 1 and 2. endp1 = vertexArray+1; endp2 = vertexArray+2; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); root = initialrun(Q,tree); deprintf("done with the initial run\n"); // Do goRandom number of random cut&links (same edge). if (goRandom) { nOps = goRandom; start = clock (); deprintf("going random, %d\n", goRandom); while (--goRandom) { // Randomly select edges and cut/link n = tree->n; n1 = (rand() % n)+1; //choose a random node; node* v = tree->vertexArray + n1; node* u = GET_NEIGHBOR(v->scars[v->left].backscar); // Cut and link the same age. cut (u,v,tree,Q); link (endp1,endp2,rand()%MILLION,tree,Q); syncAndCheck_(tree,Q); (*query)(tree); endp1 = u; endp2 = v; } finish = clock (); } printTimePerOp (start,finish,nOps); finishTest (); } void testLinkCutSyncChain (char* treeName, int goRandom) { cluster* root; clock_t start,finish; int n,n1; int nOps; node *endp1, *endp2; initTest (); // Initialize the queues Queue* Q = initQueue(); // Do a tree contraction tree_t* tree = loadtree(treeName); n = tree->n; node* vertexArray = tree->vertexArray; cTree = tree; cQueue = Q; // Initial end points are always 1 and 2. endp1 = vertexArray+1; endp2 = vertexArray+2; initTreeContraction (Q,tree); deprintf("done with loadtree\n"); root = initialrun(Q,tree); deprintf("done with the initial run\n"); // Do goRandom number of random cut&links (same edge). if (goRandom) { nOps = goRandom; start = clock (); deprintf("going random, %d\n", goRandom); while (--goRandom) { // Randomly select edges and cut/link n = tree->n; n1 = (rand() % n)+1; //choose a random node; node* v = tree->vertexArray + n1; node* u = GET_NEIGHBOR(v->scars[v->left].backscar); // Cut and link the same age. cut (u,v,tree,Q); link (endp1,endp2,rand()%MILLION,tree,Q); syncAndCheck_(tree,Q); endp1 = u; endp2 = v; } finish = clock (); } printTimePerOp (start,finish,nOps); finishTest (); } ////////////////////////////////////////////////////////////////////// // test the edge data and do random update m times ////////////////////////////////////////////////////////////////////// void testEdgeData(char* treeFile, int rounds, void (*updateWeight)(bin_data*)) { final_data edge; node *v, *u; initTest (); Queue* Q = initQueue(); clusterList changedClusters; //changeClusters.head = NULL; deprintf("done with mem_init\n"); deprintf ("Loading the tree\n"); tree_t* tree = loadtree(treeFile); deprintf ("Loaded the tree\n"); cTree = tree; cQueue = Q; initTreeContraction (Q,tree); deprintf ("Done with inittreecontract\n"); deprintf("done with loadtree\n"); cluster* root = initialrun(Q,tree); edge = ((final_cluster*)root)->data; int n = tree->n; totalqueued=0; clock_t start = clock(); int i = 0; while(i++ < rounds) { int n1 = (rand() % n)+1; //choose a random node; v = tree->vertexArray + n1; u = GET_NEIGHBOR(v->scars[v->left].backscar); changeEdgeData(v,u,Q,&changedClusters,updateWeight); edge = propagateAndCheck(tree,Q,&changedClusters); } clock_t finish = clock(); finishTest (); printTimePerOp (start,finish,rounds); } void testVertexData(char* treeFile, int rounds, void (*updateWeight)(unary_data*)) { final_data edge; node *v; initTest (); Queue* Q = initQueue(); clusterList changedClusters; deprintf("done with mem_init\n"); deprintf ("Loading the tree\n"); tree_t* tree = loadtree(treeFile); deprintf ("Loaded the tree\n"); cTree = tree; cQueue = Q; initTreeContraction (Q,tree); deprintf ("Done with inittreecontract\n"); deprintf("done with loadtree\n"); cluster* root = initialrun(Q,tree); edge = ((final_cluster*)root)->data; int n = tree->n; totalqueued=0; clock_t start = clock(); int i = 0; while(i++ < rounds) { int n1 = (rand() % n)+1; //choose a random node; v = tree->vertexArray + n1; changeVertexData(v,Q,&changedClusters,updateWeight); propagateAndCheck(tree,Q,&changedClusters); } clock_t finish = clock(); printTimePerOp (start,finish,rounds); finishTest (); } void testVertexDataQuery(char* treeFile, int rounds, int opsPerRound, void (*changeMark)(unary_data*), unary_data (*readVertexData)(FILE*)) { unary_data edge; node *v; initTest (); Queue* Q = initQueue(); clusterList changedClusters; deprintf("done with mem_init\n"); deprintf ("Loading the tree\n"); tree_t* tree = loadtree_param_vertex(treeFile,readVertexData); deprintf ("Loaded the tree\n"); cTree = tree; cQueue = Q; initTreeContraction (Q,tree); deprintf ("Done with inittreecontract\n"); deprintf("done with loadtree\n"); cluster* root = initialrun(Q,tree); edge = ((unary_cluster*)root)->data; int n = tree->n; int nd = (rand() % n)+1; //choose a random node; v = tree->vertexArray + nd; changeVertexData(v,Q,&changedClusters,changeMark); propagateAndCheck(tree,Q,&changedClusters); totalqueued=0; clock_t start = clock(); int i = 0; while(i++ < rounds) { changeVertexData(v,Q,&changedClusters,changeMark); //unmark old node int n1 = (rand() % n)+1; //choose a random node; v = tree->vertexArray + n1; changeVertexData(v,Q,&changedClusters,changeMark); propagateAndCheck(tree,Q,&changedClusters); } clock_t finish = clock(); rounds = rounds*opsPerRound; printTimePerOp (start,finish,rounds); finishTest (); } //////////////////////////////////////////////////////////////////// // test the function query by running it rounds number of times // on the tree defined by treeFile //////////////////////////////////////////////////////////////////// void testQuery(char* treeFile, int rounds, void (*query)(tree_t*)) { unary_data edge; initTest (); Queue* Q = initQueue(); deprintf("done with mem_init\n"); deprintf ("Loading the tree\n"); tree_t* tree = loadtree(treeFile); cTree = tree; cQueue = Q; deprintf ("Loaded the tree\n"); initTreeContraction (Q,tree); deprintf ("Done with inittreecontract\n"); deprintf("done with loadtree\n"); cluster* root = initialrun(Q,tree); edge = ((unary_cluster*)root)->data; totalqueued=0; clock_t start = clock(); int i = 0; while(i++ < rounds) { (*query)(tree); } clock_t finish = clock(); printTimePerOp (start,finish,rounds); finishTest (); } ///////////////////////////////////////////////////////////////////////// // This is to test query functions that take the root of support trees ///////////////////////////////////////////////////////////////////////// void testQuery_root (char* treeFile, int rounds, void (*query)(cluster *)) { initTest (); Queue* Q = initQueue(); deprintf("done with mem_init\n"); deprintf ("Loading the tree\n"); tree_t* tree = loadtree(treeFile); deprintf ("Loaded the tree\n"); cTree = tree; cQueue = Q; initTreeContraction (Q,tree); deprintf ("Done with inittreecontract\n"); deprintf("done with loadtree\n"); cluster* root = initialrun(Q,tree); totalqueued=0; clock_t start = clock(); int i = 0; while(i++ < rounds) { (*query)(root); } clock_t finish = clock(); printTimePerOp (start,finish,rounds); finishTest (); }