1 /* =============================================================================
5 * =============================================================================
7 * For the license of ssca2, please see ssca2/COPYRIGHT
9 * ------------------------------------------------------------------------
11 * Unless otherwise noted, the following license applies to STAMP files:
13 * Copyright (c) 2007, Stanford University
14 * All rights reserved.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions are
20 * * Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
23 * * Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
28 * * Neither the name of Stanford University nor the names of its
29 * contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
32 * THIS SOFTWARE IS PROVIDED BY STANFORD UNIVERSITY ``AS IS'' AND ANY
33 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
35 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE
36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
42 * THE POSSIBILITY OF SUCH DAMAGE.
44 * =============================================================================
47 public class GenScalData {
49 public int[] global_permV;
50 public int[] global_cliqueSizes;
51 public int global_totCliques;
52 public int[] global_firstVsInCliques;
53 public int[] global_lastVsInCliques;
54 public int[] global_i_edgeStartCounter;
55 public int[] global_i_edgeEndCounter;
56 public int global_edgeNum;
57 public int global_numStrWtEdges;
58 public int[] global_startVertex;
59 public int[] global_endVertex;
60 public int[] global_tempIndex;
65 public GenScalData() {
67 global_cliqueSizes = null;
68 global_totCliques = 0;
69 global_firstVsInCliques = null;
70 global_lastVsInCliques = null;
71 global_i_edgeStartCounter = null;
72 global_i_edgeEndCounter = null;
74 global_numStrWtEdges = 0;
75 global_startVertex = null;
76 global_endVertex = null;
77 global_tempIndex = null;
82 * =============================================================================
84 * =============================================================================
87 genScalData_seq (GraphSDG SDGdataPtr)
89 System.out.println("Call to genScalData_seq(), Unimplemented: TODO\n");
95 * =============================================================================
97 * =============================================================================
101 genScalData (int myId, int numThread, Globals glb, GraphSDG SDGdataPtr)
104 * STEP 0: Create the permutations required to randomize the vertices
107 Random randomPtr = new Random();
108 randomPtr = randomPtr.random_alloc();
109 randomPtr.random_seed(myId);
114 permV = new int[glb.TOT_VERTICES];
115 global_permV = permV;
118 Barrier.enterBarrier();
120 permV = global_permV;
122 LocalStartStop lss = new LocalStartStop();
123 CreatePartition cp = new CreatePartition();
124 cp.createPartition(0, glb.TOT_VERTICES, myId, numThread, lss);
126 /* Initialize the array */
127 for (int i = lss.i_start; i < lss.i_stop; i++) {
131 Barrier.enterBarrier();
133 for (int i = i_start; i < i_stop; i++) {
134 int t1 = randomPtr.random_generate();
135 int t = i + t1 % (glb.TOT_VERTICES - i);
146 * STEP 1: Create Cliques
151 int estTotCliques = (int)(Math.ceil(1.5d * glb.TOT_VERTICES / ((1+glb.MAX_CLIQUE_SIZE)/2)));
154 * Allocate mem for Clique array
155 * Estimate number of clique required and pad by 50%
158 cliqueSizes = new int[estTotCliques];
159 global_cliqueSizes = cliqueSizes;
162 Barrier.enterBarrier();
164 cliqueSizes = global_cliqueSizes;
166 cp.createPartition(0, estTotCliques, myId, numThread, lss);
168 /* Generate random clique sizes. */
169 for (int i = lss.i_start; i < lss.i_stop; i++) {
170 cliqueSizes[i] = 1 + (randomPtr.random_generate() % glb.MAX_CLIQUE_SIZE);
173 Barrier.enterBarrier();
178 * Allocate memory for cliqueList
181 int[] firstVsInCliques;
182 int[] firstVsInCliques;
185 lastVsInCliques = new int[estTotCliques];
186 global_lastVsInCliques = lastVsInCliques;
187 firstVsInCliques = new int[estTotCliques];
188 global_firstVsInCliques = firstVsInCliques;
191 * Sum up vertices in each clique to determine the lastVsInCliques array
194 lastVsInCliques[0] = cliqueSizes[0] - 1;
196 for (i = 1; i < estTotCliques; i++) {
197 lastVsInCliques[i] = cliqueSizes[i] + lastVsInCliques[i-1];
198 if (lastVsInCliques[i] >= glb.TOT_VERTICES-1) {
204 global_totCliques = totCliques;
207 * Fix the size of the last clique
209 cliqueSizes[(totCliques-1)] =
210 glb.TOT_VERTICES - lastVsInCliques[(totCliques-2)] - 1;
211 lastVsInCliques[totCliques-1] = glb.TOT_VERTICES - 1;
213 firstVsInCliques[0] = 0;
217 Barrier.enterBarrier();
219 lastVsInCliques = global_lastVsInCliques;
220 firstVsInCliques = global_firstVsInCliques;
221 totCliques = global_totCliques;
223 /* Compute start Vertices in cliques. */
224 cp.createPartition(1, totCliques, myId, numThread, lss);
225 for (int i = i_start; i < i_stop; i++) {
226 firstVsInCliques[i] = lastVsInCliques[i-1] + 1;
229 /* TODO : if required
231 #ifdef WRITE_RESULT_FILES
232 Barrier.enterBarrier();
234 // Write the generated cliques to file for comparison with Kernel 4
236 FILE* outfp = fopen("cliques.txt", "w");
237 fSystem.out.println(outfp, "No. of cliques - %lu\n", totCliques);
238 for (i = 0; i < totCliques; i++) {
239 fSystem.out.println(outfp, "Clq %lu - ", i);
241 for (j = firstVsInCliques[i]; j <= lastVsInCliques[i]; j++) {
242 fSystem.out.println(outfp, "%lu ", permV[j]);
244 fSystem.out.println(outfp, "\n");
249 Barrier.enterBarrier();
254 * STEP 2: Create the edges within the cliques
258 * Estimate number of edges - using an empirical measure
261 if (glb.SCALE >= 12) {
262 estTotEdges = (int) (Math.ceil(1.0d *((glb.MAX_CLIQUE_SIZE-1) * glb.TOT_VERTICES)));
264 estTotEdges = (int) (Math.ceil(1.2d * (((glb.MAX_CLIQUE_SIZE-1)*glb.TOT_VERTICES)
265 * ((1 + glb.MAX_PARAL_EDGES)/2) + glb.TOT_VERTICES*2)));
269 * Initialize edge counter
272 float p = glb.PROB_UNIDIRECTIONAL;
282 int numByte = 1.5 * (estTotEdges/numThread);
283 startV = new int[numByte];
284 endV = new int[numByte];
286 int numByte = (estTotEdges/numThread);
287 startV = new int[numByte];
288 endV = new int[numByte];
292 * Tmp array to keep track of the no. of parallel edges in each direction
294 int[][] tmpEdgeCounter = new int[glb.MAX_CLIQUE_SIZE][glb.MAX_CLIQUE_SIZE];
297 * Create edges in parallel
300 cp.createPartition(0, totCliques, myId, numThread, lss);
302 for (int i_clique = lss.i_start; i_clique < lss.i_stop; i_clique++) {
305 * Get current clique parameters
308 int i_cliqueSize = cliqueSizes[i_clique];
309 int i_firstVsInClique = firstVsInCliques[i_clique];
312 * First create at least one edge between two vetices in a clique
315 for (int i = 0; i < i_cliqueSize; i++) {
316 for (int j = 0; j < i; j++) {
317 float r = (float)(randomPtr.random_generate() % 1000) / (float)1000;
320 startV[i_edgePtr] = i + i_firstVsInClique;
321 endV[i_edgePtr] = j + i_firstVsInClique;
323 tmpEdgeCounter[i][j] = 1;
325 startV[i_edgePtr] = j + i_firstVsInClique;
326 endV[i_edgePtr] = i + i_firstVsInClique;
328 tmpEdgeCounter[j][i] = 1;
330 } else if (r >= 0.5) {
332 startV[i_edgePtr] = i + i_firstVsInClique;
333 endV[i_edgePtr] = j + i_firstVsInClique;
335 tmpEdgeCounter[i][j] = 1;
336 tmpEdgeCounter[j][i] = 0;
340 startV[i_edgePtr] = j + i_firstVsInClique;
341 endV[i_edgePtr] = i + i_firstVsInClique;
343 tmpEdgeCounter[j][i] = 1;
344 tmpEdgeCounter[i][j] = 0;
351 if (i_cliqueSize != 1) {
352 int randNumEdges = randomPtr.random_generate() % (2*i_cliqueSize*glb.MAX_PARAL_EDGES);
354 for (int i_paralEdge = 0; i_paralEdge < randNumEdges; i_paralEdge++) {
355 int i = (int) (randomPtr.random_generate() % i_cliqueSize);
356 int j = (int) (randomPtr.random_generate() % i_cliqueSize);
357 if ((i != j) && (tmpEdgeCounter[i][j] < glb.MAX_PARAL_EDGES)) {
358 float r = (float)(randomPtr.random_generate() % 1000) / (float)1000;
360 /* Copy to edge structure. */
361 startV[i_edgePtr] = i + i_firstVsInClique;
362 endV[i_edgePtr] = j + i_firstVsInClique;
364 tmpEdgeCounter[i][j]++;
372 tmpEdgeCounter = null;
375 * Merge partial edge lists
378 int[] i_edgeStartCounter;
379 int[] i_edgeEndCounter;
382 i_edgeStartCounter = new int[ numThread];
383 global_i_edgeStartCounter = i_edgeStartCounter;
384 i_edgeEndCounter = new int[numThread];
385 global_i_edgeEndCounter = i_edgeEndCounter;
388 Barrier.enterBarrier();
390 i_edgeStartCounter = global_i_edgeStartCounter;
391 i_edgeEndCounter = global_i_edgeEndCounter;
393 i_edgeEndCounter[myId] = i_edgePtr;
394 i_edgeStartCounter[myId] = 0;
396 Barrier.enterBarrier();
399 for (int i = 1; i < numThread; i++) {
400 i_edgeEndCounter[i] = i_edgeEndCounter[i-1] + i_edgeEndCounter[i];
401 i_edgeStartCounter[i] = i_edgeEndCounter[i-1];
406 global_edgeNum = global_edgeNum + i_edgePtr;
409 Barrier.enterBarrier();
411 int edgeNum = global_edgeNum;
414 * Initialize edge list arrays
421 if (glb.SCALE < 10) {
422 int numByte = 2 * edgeNum;
423 startVertex = new int[numByte];
424 endVertex = new int[numByte];
426 int numByte = (edgeNum + glb.MAX_PARAL_EDGES * glb.TOT_VERTICES);
427 startVertex = new int[numByte];
428 endVertex = new int[numByte];
430 global_startVertex = startVertex;
431 global_endVertex = endVertex;
434 Barrier.enterBarrier();
436 startVertex = global_startVertex;
437 endVertex = global_endVertex;
439 for (int i = i_edgeStartCounter[myId]; i < i_edgeEndCounter[myId]; i++) {
440 startVertex[i] = startV[i-i_edgeStartCounter[myId]];
441 endVertex[i] = endV[i-i_edgeStartCounter[myId]];
444 int numEdgesPlacedInCliques = edgeNum;
446 Barrier.enterBarrier();
449 * STEP 3: Connect the cliques
453 p = PROB_INTERCL_EDGES;
456 * Generating inter-clique edges as given in the specs
459 cp.createPartition(0, glb.TOT_VERTICES, myId, numThread, lss);
461 for (int i = lss.i_start; i < lss.i_stop; i++) {
467 int m = ((h + l) / 2);
468 if (tempVertex1 >= firstVsInCliques[m]) {
471 if ((tempVertex1 < firstVsInCliques[m]) && (m > 0)) {
472 if (tempVertex1 >= firstVsInCliques[m-1]) {
484 for (m = (l + 1); m < h; m++) {
485 if (tempVertex1<firstVsInCliques[m]) {
492 int t1 = firstVsInCliques[t];
495 for (int d = 1, p = glb.PROB_INTERCL_EDGES; d < glb.TOT_VERTICES; d *= 2, p /= 2) {
497 float r = (float)(randomPtr.random_generate() % 1000) / (float)1000;
501 int tempVertex2 = ((i+d) % glb.TOT_VERTICES);
507 int m = (((h + l) / 2);
508 if (tempVertex2 >= firstVsInCliques[m]) {
511 if ((tempVertex2 < firstVsInCliques[m]) && (m > 0)) {
512 if (firstVsInCliques[m-1] <= tempVertex2) {
525 for (m = (l + 1); m < h; m++) {
526 if (tempVertex2 < firstVsInCliques[m]) {
533 int t2 = firstVsInCliques[t];
537 randomPtr.random_generate() % glb.MAX_PARAL_EDGES + 1;
539 for (int j = 0; j < randNumEdges; j++) {
540 startV[i_edgePtr] = tempVertex1;
541 endV[i_edgePtr] = tempVertex2;
548 float r0 = (float)(randomPtr.random_generate() % 1000) / (float)1000;
550 if ((r0 <= p) && (i-d>=0)) {
551 int tempVertex2 = (i - d) % glb.TOT_VERTICES;
557 int m = ((h + l) / 2);
558 if (tempVertex2 >= firstVsInCliques[m]) {
561 if ((tempVertex2 < firstVsInCliques[m]) && (m > 0)) {
562 if (firstVsInCliques[m-1] <= tempVertex2) {
574 for (m = (l + 1); m < h; m++) {
575 if (tempVertex2 < firstVsInCliques[m]) {
582 int t2 = firstVsInCliques[t];
586 randomPtr.random_generate() % glb.MAX_PARAL_EDGES + 1;
587 for (int j = 0; j < randNumEdges; j++) {
588 startV[i_edgePtr] = tempVertex1;
589 endV[i_edgePtr] = tempVertex2;
594 } /* r0 <= p && (i-d) > 0 */
601 i_edgeEndCounter[myId] = i_edgePtr;
602 i_edgeStartCounter[myId] = 0;
608 Barrier.enterBarrier();
611 for (int i = 1; i < numThread; i++) {
612 i_edgeEndCounter[i] = i_edgeEndCounter[i-1] + i_edgeEndCounter[i];
613 i_edgeStartCounter[i] = i_edgeEndCounter[i-1];
618 global_edgeNum = global_edgeNum + i_edgePtr;
621 Barrier.enterBarrier();
623 edgeNum = global_edgeNum;
624 int numEdgesPlacedOutside = global_edgeNum;
626 for (int i = (i_edgeStartCounter[myId]; i < i_edgeEndCounter[myId]; i++) {
627 startVertex[i+numEdgesPlacedInCliques] = startV[i-i_edgeStartCounter[myId]];
628 endVertex[i+numEdgesPlacedInCliques] = endV[i-i_edgeStartCounter[myId]];
631 Barrier.enterBarrier();
633 int numEdgesPlaced = numEdgesPlacedInCliques + numEdgesPlacedOutside;
636 SDGdataPtr.numEdgesPlaced = numEdgesPlaced;
638 System.out.println("Finished generating edges");
639 System.out.println("No. of intra-clique edges - " + numEdgesPlacedInCliques);
640 System.out.println("No. of inter-clique edges - " + numEdgesPlacedOutside);
641 System.out.println("Total no. of edges - " + numEdgesPlaced);
644 Barrier.enterBarrier();
647 * STEP 4: Generate edge weights
651 SDGdataPtr.intWeight = new int[numEdgesPlaced];
654 Barrier.enterBarrier();
656 p = glb.PERC_INT_WEIGHTS;
657 int numStrWtEdges = 0;
659 cp.createPartition(0, numEdgesPlaced, myId, numThread, lss);
661 for (int i = lss.i_start; i < lss.i_stop; i++) {
662 float r = (float)(randomPtr.random_generate() % 1000) / (float)1000;
664 SDGdataPtr.intWeight[i] =
665 1 + (randomPtr.random_generate() % (MAX_INT_WEIGHT-1));
667 SDGdataPtr.intWeight[i] = -1;
672 Barrier.enterBarrier();
676 for (int i = 0; i < numEdgesPlaced; i++) {
677 if (SDGdataPtr.intWeight[i] < 0) {
678 SDGdataPtr.intWeight[i] = -t;
685 global_numStrWtEdges = global_numStrWtEdges + numStrWtEdges;
688 Barrier.enterBarrier();
690 numStrWtEdges = global_numStrWtEdges;
693 SDGdataPtr.strWeight = new char[numStrWtEdges * glb.MAX_STRLEN];
696 Barrier.enterBarrier();
698 cp.createPartition(0, numEdgesPlaced, myId, numThread, lss);
700 for (int i = lss.i_start; i < lss.i_stop; i++) {
701 if (SDGdataPtr.intWeight[i] <= 0) {
702 for (int j = 0; j < glb.MAX_STRLEN; j++) {
703 SDGdataPtr.strWeight[(-SDGdataPtr.intWeight[i])*glb.MAX_STRLEN+j] =
704 // (char) (1 + PRANDOM_GENERATE(stream) % 127);
706 (char) (1 + (randomPtr.random_generate() % 127));
712 * Choose SOUGHT STRING randomly if not assigned
717 if (SOUGHT_STRING.length != glb.MAX_STRLEN) {
718 glb.SOUGHT_STRING = new char[MAX_STRLEN];
721 int t = randomPtr.random_generate() % numStrWtEdges;
722 for (int j = 0; j < glb.MAX_STRLEN; j++) {
725 (char) (SDGdataPtr.strWeight[(t*glb.MAX_STRLEN+j)]);
730 Barrier.enterBarrier();
733 * STEP 5: Permute Vertices
736 for (int i = lss.i_start; i < lss.i_stop; i++) {
737 startVertex[i] = permV[(startVertex[i])];
738 endVertex[i] = permV[(endVertex[i])];
741 Barrier.enterBarrier();
744 * STEP 6: Sort Vertices
748 * Radix sort with StartVertex as primary key
752 int numByte = numEdgesPlaced;
753 SDGdataPtr.startVertex = new int[numByte];
754 SDGdataPtr.endVertex = new int[numByte];
757 Barrier.enterBarrier();
759 Alg_Radix_Smp.all_radixsort_node_aux_s3(numEdgesPlaced,
761 SDGdataPtr.startVertex,
763 SDGdataPtr.endVertex);
765 Barrier.enterBarrier();
767 if (glb.SCALE < 12) {
770 * Sort with endVertex as secondary key
779 while (i < numEdgesPlaced) {
781 for (i = i0; i < numEdgesPlaced; i++) {
782 if (SDGdataPtr.startVertex[i] !=
783 SDGdataPtr.startVertex[i1])
791 for (int j = i0; j < i1; j++) {
793 for (int k = j+1; k < i1; k++) {
794 if (SDGdataPtr.endVertex[k] <
795 SDGdataPtr.endVertex[j])
797 int t = SDGdataPtr.endVertex[j];
798 SDGdataPtr.endVertex[j] = SDGdataPtr.endVertex[k];
799 SDGdataPtr.endVertex[k] = t;
804 if (SDGdataPtr.startVertex[i0] != glb.TOT_VERTICES-1) {
808 for (int j=i0; j<numEdgesPlaced; j++) {
810 for (int k=j+1; k<numEdgesPlaced; k++) {
811 if (SDGdataPtr.endVertex[k] <
812 SDGdataPtr.endVertex[j])
814 int t = SDGdataPtr.endVertex[j];
815 SDGdataPtr.endVertex[j] = SDGdataPtr.endVertex[k];
816 SDGdataPtr.endVertex[k] = t;
822 } /* while i < numEdgesPlaced */
832 tempIndex = new int[glb.TOT_VERTICES + 1];
833 global_tempIndex = tempIndex;
836 * Update degree of each vertex
840 tempIndex[glb.TOT_VERTICES] = numEdgesPlaced;
843 for (int i=0; i < glb.TOT_VERTICES; i++) {
844 tempIndex[i+1] = tempIndex[i];
846 for (int j = i0; j < numEdgesPlaced; j++) {
847 if (SDGdataPtr.startVertex[j] !=
848 SDGdataPtr.startVertex[i0])
850 if (SDGdataPtr.startVertex[i0] == i) {
860 Barrier.enterBarrier();
862 tempIndex = global_tempIndex;
865 * Insertion sort for now, replace with something better later on
870 for (int i = 0; i < glb.TOT_VERTICES; i++) {
871 for (int j = tempIndex[i]; j < tempIndex[i+1]; j++) {
872 for (int k = (j + 1); k < tempIndex[i+1]; k++) {
873 if (SDGdataPtr.endVertex[k] <
874 SDGdataPtr.endVertex[j])
876 int t = SDGdataPtr.endVertex[j];
877 SDGdataPtr.endVertex[j] = SDGdataPtr.endVertex[k];
878 SDGdataPtr.endVertex[k] = t;
890 /* =============================================================================
892 * End of genScalData.java
894 * =============================================================================