1 // =============================================================================
2 // === GPUQREngine/Source/GPUQREngine_GraphVisHelper.cpp =======================
3 // =============================================================================
4 // === This is used for development and debugging only. ========================
5 // =============================================================================
6 //
7 // This file contains logic to render the current state of the BucketList data
8 // structure, including the current arrangement of row tiles into column
9 // buckets and bundles. The output language is DOT for use with either
10 // GraphViz's dot or sfdp package.
11 //
12 // Bundles are colored by task type:
13 // Apply : Yellow
14 // Factorize : Red
15 // ApplyFactorize: Orange
16 //
17 // =============================================================================
18
19 #include "GPUQREngine_Internal.hpp"
20
21 #ifdef GPUQRENGINE_RENDER
22
23 #include "GPUQREngine_BucketList.hpp"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 void GraphVizHelper_ComputeBundleLabel
29 (
30 LLBundle& bundle, // C++ Reference to the bundle
31 char *label // (output) The label to use for the bundle
32 );
33
34 static int DotSID = 1;
35
GPUQREngine_RenderBuckets(BucketList * buckets)36 void GPUQREngine_RenderBuckets(BucketList *buckets)
37 {
38 // if(!RENDER_DENSE_FACTORIZATION) return;
39
40 LLBundle *bundles = buckets->Bundles;
41
42 int numBundles = buckets->numBundles;
43 char bundleNames[numBundles][64];
44 char bundleLabel[numBundles][64];
45
46 Int *head = buckets->head;
47 Int *next = buckets->next;
48
49 char filename[64];
50 sprintf(filename, "out_%d.dot", DotSID++);
51
52 FILE *output = fopen(filename, "w");
53
54 bool RenderOutline = false;
55 bool UseFancyRendering = false;
56
57 /* If we want to render the outline, do it first. */
58 if (RenderOutline)
59 {
60 fprintf(output, "graph O\n");
61 fprintf(output, "{\n");
62 fprintf(output, "node [shape=circle, style=filled, color=black];\n");
63 for (int colBucket = 0; colBucket < buckets->numBuckets; colBucket++)
64 {
65 /* Shade the point depending on the region. */
66 const char *fillColor = "gray";
67 if (colBucket < buckets->Wavefront) fillColor = "green";
68 else if (colBucket <= buckets->LastBucket) fillColor = "red";
69 fprintf(output, "O_%d [fillcolor=%s];\n", colBucket, fillColor);
70 }
71 fprintf(output, "}\n");
72 }
73
74 fprintf(output, "digraph D\n");
75 fprintf(output, "{\n");
76 fprintf(output, "node [shape=record, style=filled];\n");
77
78 int start = (UseFancyRendering ? MAX(0, buckets->Wavefront - 1) : 0);
79 int end = (UseFancyRendering ?
80 MIN(buckets->numBuckets, buckets->LastBucket + 1)
81 : buckets->numBuckets);
82
83 for (int colBucket = start; colBucket < end; colBucket++)
84 {
85 // const char *colBucketName = "CB_" + colBucket;
86 // const char *colBucketLabel = "ColBucket" + colBucket;
87 // +" (" + buckets->bundleCount[colBucket] + " bundles)";
88 // const char *colBucketEmptyName = "CBE_" + colBucket;
89 // const char *colBucketEmptyLabel = "Empty";
90 const char *wavefrontColor = (colBucket < buckets->Wavefront ?
91 "green" : "gray");
92
93 fprintf(output, "CB_%d [label=\"ColBucket%d\", fillcolor=%s];\n",
94 colBucket, colBucket, wavefrontColor);
95 fprintf(output, "CBE_%d [label=\"Empty\"];\n", colBucket);
96
97 /* Render the idle tiles. */
98 int node;
99 char lastTile[32]; strcpy(lastTile, "");
100 if ((node = head[colBucket]) != EMPTY)
101 {
102 sprintf(lastTile, "IdleTile_%d", node);
103
104 const char *nodeShape = (buckets->triu[node] ?
105 "triangle" : "ellipse");
106 fprintf(output,
107 "IdleTile_%d [shape=%s, fillcolor=%s, label=\"%d\"];\n",
108 node, nodeShape, wavefrontColor, node);
109 fprintf(output, "CB_%d -> IdleTile_%d;\n", colBucket, node);
110 int last = node;
111 while ((node = next[node]) != EMPTY)
112 {
113 sprintf(lastTile, "IdleTile_%d", node);
114
115 nodeShape = (buckets->triu[node] ? "triangle" : "ellipse");
116 fprintf(output, "IdleTile_%d [shape=%s, label=\"%d\"];\n",
117 node, nodeShape, node);
118 fprintf(output, "IdleTile_%d -> IdleTile_%d;\n", last, node);
119 last = node;
120 }
121 }
122
123 /* Now render the bundles native to this bucket. */
124
125 /* Write the nodes */
126 int bbc = 0;
127 for(int i=0; i<numBundles; i++)
128 {
129 strcpy(bundleNames[i], "");
130 strcpy(bundleLabel[i], "");
131 }
132 for(int i=0; i<numBundles; i++)
133 {
134 LLBundle& bundle = bundles[i];
135 if (bundle.NativeBucket == colBucket)
136 {
137 sprintf(bundleNames[bbc], "CB_%d_HB_%d", colBucket, bbc);
138
139 const char *taskColor = "white";
140 bool isApply = (bundle.CurrentTask == TASKTYPE_GenericApply);
141 bool isFactorize =
142 (bundle.CurrentTask == TASKTYPE_GenericFactorize);
143 taskColor =
144 (isApply ? "yellow" : isFactorize ? "red" : "orange");
145
146 GraphVizHelper_ComputeBundleLabel(bundle, bundleLabel[bbc]);
147 fprintf(output, "%s [fillcolor=\"%s\", label=\"%s\"];\n",
148 bundleNames[bbc], taskColor, bundleLabel[bbc]);
149 bbc++;
150 }
151 }
152
153 /* Print connectivity. */
154 if (bbc > 0)
155 {
156 if(!strcmp(lastTile, ""))
157 {
158 fprintf(output, "CB_%d -> %s;\n", colBucket, bundleNames[0]);
159 }
160 else
161 {
162 fprintf(output, "%s -> %s;\n", lastTile, bundleNames[0]);
163 }
164
165 for (int i = 1; i < bbc; i++)
166 {
167 fprintf(output, "%s -> %s;\n",
168 bundleNames[i-1], bundleNames[i]);
169 }
170 fprintf(output, "%s -> CBE_%d;\n", bundleNames[bbc-1], colBucket);
171 }
172 else if (head[colBucket] != EMPTY)
173 {
174 fprintf(output, "%s -> CBE_%d;\n", lastTile, colBucket);
175 }
176 else
177 {
178 fprintf(output, "CB_%d -> CBE_%d;\n", colBucket, colBucket);
179 }
180 }
181
182 fprintf(output, "}\n");
183 fclose(output);
184 }
185
GraphVizHelper_ComputeBundleLabel(LLBundle & bundle,char * label)186 void GraphVizHelper_ComputeBundleLabel
187 (
188 LLBundle& bundle, // C++ Reference to the bundle
189 char *label // (output) The label to use for the bundle
190 )
191 {
192 Int *next = bundle.Buckets->next;
193
194 char temp[16];
195 strcpy(temp, "");
196
197 strcpy(label, "");
198 if (bundle.Shadow != EMPTY)
199 {
200 sprintf(temp, "s%ld%s", bundle.Shadow,
201 (bundle.First != EMPTY ? "|" : ""));
202 strcat(label, temp);
203 }
204
205 for (int i = bundle.First; i!=EMPTY; i=next[i])
206 {
207 sprintf(temp, "%d%s", i, (next[i] != EMPTY ? "|" : ""));
208 strcat(label, temp);
209 }
210 for (int i = bundle.Delta; i!=EMPTY; i=next[i])
211 {
212 sprintf(temp, "|%s%d", (i == bundle.Delta ? "D" : "d"), i);
213 strcat(label, temp);
214 }
215 }
216 #endif
217