1 /* ************************************************************************
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 * ************************************************************************/
16
17
18 #include <stdlib.h>
19 #include <assert.h>
20
21 #include <blas_mempat.h>
22 #include <blas_kgen.h>
23 #include <clblas-internal.h>
24 #include <kern_cache.h>
25 #include <blas_funcs.h>
26
27 #include "fileio.h"
28 #include "toolslib.h"
29
30 #include "tune.h"
31 #include "subdim.h"
32 #include <math.h>
33
34 #if defined(_MSC_VER)
35 #define fmin min
36 #define fmax max
37 #endif
38
39 #define isLdsUsed(pattern) \
40 (checkMatrixMemLevelSet(pattern, MATRIX_A, CLMEM_LEVEL_LDS) || \
41 checkMatrixMemLevelSet(pattern, MATRIX_B, CLMEM_LEVEL_LDS))
42
43 int VISIBILITY_HIDDEN
getDataTypeSize(DataType dataType)44 getDataTypeSize(DataType dataType)
45 {
46 int dataTypeSize = 0;
47
48 switch (dataType) {
49 case TYPE_FLOAT:
50 dataTypeSize = 4;
51 break;
52 case TYPE_DOUBLE:
53 case TYPE_COMPLEX_FLOAT:
54 dataTypeSize = 8;
55 break;
56 case TYPE_COMPLEX_DOUBLE:
57 dataTypeSize = 16;
58 break;
59 }
60 return dataTypeSize;
61 }
62 /*
63 * Checks current dimensionality on a validity
64 */
65 bool VISIBILITY_HIDDEN
isSubDimValid(SubDimInfo * sd)66 isSubDimValid(SubDimInfo* sd)
67 {
68 int j;
69 size_t wgX = sd->pgran.wgSize[0];
70 size_t wgY = sd->pgran.wgSize[1];
71 SubproblemDim l0 = sd->sdim[0];
72 SubproblemDim l1 = sd->sdim[1];
73 size_t dataTypeSize = getDataTypeSize(sd->dtype);
74 size_t dataFloatSize = getDataTypeSize(TYPE_FLOAT);
75 int maxRegistr = 64;
76 bool ret = true;
77 bool inv;
78 IgnoreItem* ii = sd->first;
79
80 // if pattern-based validation is available
81 if( NULL != sd->pattern->sops->checkCalcDecomp ){
82
83 return sd->pattern->sops->checkCalcDecomp(
84 &sd->pgran,
85 sd->sdim,
86 2,
87 sd->dtype,
88 PGRAN_CHECK );
89 }
90
91 ret = ret && (l1.y >= 4*dataFloatSize/dataTypeSize);
92
93 if (sd->blasLevel == 3) {
94 if (!isMatrixAccessColMaj(sd->func, sd->flag, MATRIX_A) ||
95 !isMatrixAccessColMaj(sd->func, sd->flag, MATRIX_B)) {
96 /* Avoid small bwidth and big x0, y0 for cases other than
97 * column major access to both matrixes */
98 ret = ret && (l1.bwidth >= 4*dataFloatSize/dataTypeSize);
99 ret = ret && (l0.y < 128);
100 ret = ret && (l0.x < 128);
101 }
102 }
103
104 if ( 0 == l1.bwidth ){
105 return false;
106 }
107 else{
108 ret = ret && ((l0.bwidth % l1.bwidth) == 0);
109 ret = ret && (wgX*wgY == 64);
110 }
111 //ret = ret && (wgX*wgY < sd->workGroupSizes);
112 //ret = ret && (wgX*wgY > 16);
113 if (sd->blasLevel == 2) {
114 ret = ret && (l0.y > l1.y);
115 }
116 else {
117 ret = ret && (l0.x > l1.x);
118 ret = ret && (l0.y > l1.y);
119 ret = ret && (l1.x >= 4*dataFloatSize/dataTypeSize);
120 }
121 if (sd->is2D) {
122 bool r = ret;
123 ret = ret && (wgY * l1.itemX == l0.x);
124 ret = ret && (wgX * l1.itemY == l0.y);
125 if (r != ret) {
126 return ret;
127 }
128 }
129
130 if (ret && sd->isSquareBlock) {
131 ret = ret && (l0.x == l0.y && l0.x == l0.bwidth);
132 }
133
134 //if (!(isLdsUsed(sd->pattern) || (sd->isSquareBlock && sd->nrLevel == 2))) {
135 // ret = ret && l0.bwidth == l1.bwidth;
136 //}
137
138 if (ret) {
139 int r ;
140 r = (int)(l1.x*l1.bwidth + l1.y*l1.bwidth + l1.x*l1.y);
141
142 r = r * (int)dataTypeSize / sizeof(cl_float4);
143
144 if (r > maxRegistr) {
145 return false;
146 }
147 }
148
149 if (ret && sd->pattern->sops->isFitToLDS != NULL) {
150 bool isFitToLDS;
151 CLBlasKargs args;
152
153 convKExtraFlagToArg(sd->flag, &args);
154
155 isFitToLDS = sd->pattern->sops->isFitToLDS(sd->sdim, sd->dtype,
156 sd->ldsSize, &args);
157 if (!isFitToLDS)
158 return false;
159 }
160
161 // Skip ignored dimension
162 for (;ii != NULL; ii = ii->next) {
163 inv = true;
164 for(j = 0; j < V_COUNT; ++j) {
165 int v1 = ii->var[j];
166 int v2 = get(&sd->var[j]);
167 if (v1 == -1) {
168 continue;
169 }
170 if (v1 == v2) {
171 continue;
172 }
173 inv = false;
174 break;
175 }
176 if (inv) {
177 ret = false;
178 }
179 }
180
181 return ret;
182 }
183
184 /*
185 * Set invalid SubDimension.
186 * Invalid SubDimensions will be skipped.
187 */
188 void VISIBILITY_HIDDEN
setInvalid(SubDimInfo * sdi,int l0x,int l0y,int l0w,int l1x,int l1y,int l1w)189 setInvalid(SubDimInfo* sdi, int l0x, int l0y, int l0w,
190 int l1x, int l1y, int l1w)
191 {
192 IgnoreItem* ii = malloc(sizeof(IgnoreItem));
193 ii->var[V_L0_X] = l0x;
194 ii->var[V_L0_Y] = l0y;
195 ii->var[V_L0_BW] = l0w;
196 ii->var[V_L1_X] = l1x;
197 ii->var[V_L1_Y] = l1y;
198 ii->var[V_L1_BW] = l1w;
199 ii->next = sdi->first;
200 sdi->first = ii;
201 }
202
203 void VISIBILITY_HIDDEN
initVector(SubDimInfo * sd)204 initVector(SubDimInfo* sd)
205 { //0 1 2 3 4 5 6 7 8 9 10 11
206 int dim [] = {1,2,4,8,16,32,64,128,256,512,1024,2048, 4096};
207 if (sd->blasLevel == 2 ) {
208 setVariable(sd, V_L0_X, 1, &dim[0]);
209 setVariable(sd, V_L0_Y, 6, &dim[4]);
210 setVariable(sd, V_L0_BW, 10, &dim[0]);
211 setVariable(sd, V_L1_X, 1, &dim[0]);
212 setVariable(sd, V_L1_Y, 6, &dim[1]);
213 setVariable(sd, V_L1_BW, 6, &dim[0]);
214 }
215 else {
216 setVariable(sd, V_L0_X, 4, &dim[4]);
217 setVariable(sd, V_L0_Y, 4, &dim[4]);
218 setVariable(sd, V_L0_BW, 6, &dim[0]);
219 setVariable(sd, V_L1_X, 6, &dim[0]);
220 setVariable(sd, V_L1_Y, 6, &dim[0]);
221 setVariable(sd, V_L1_BW, 6, &dim[0]);
222 }
223 }
224
225 void VISIBILITY_HIDDEN
initKNMVector(SubDimInfo * sd,unsigned int baseDim,unsigned int * K,unsigned int * N,unsigned int * M)226 initKNMVector(
227 SubDimInfo* sd,
228 unsigned int baseDim,
229 unsigned int* K,
230 unsigned int* N,
231 unsigned int* M
232 )
233 {
234 if (sd->blasLevel == 2 ) {
235 *K = 1;
236 *N = baseDim * 2;
237 *M = baseDim * 2;
238 } else
239 {
240 *K = baseDim;
241 *N = baseDim;
242 *M = baseDim;
243 }
244 }
245
246 int VISIBILITY_HIDDEN
get(SubDimItem * sd)247 get(SubDimItem* sd)
248 {
249 return sd->data[sd->curId];
250 }
251
252 void VISIBILITY_HIDDEN
calcPGranularity(SubDimInfo * sd)253 calcPGranularity (SubDimInfo* sd)
254 {
255 SubproblemDim* dim = sd->sdim;
256 PGranularity* pgran = &sd->pgran;
257 //int level = sd->cuLevel;
258
259 pgran->wgDim = 2;
260 pgran->wfSize = 64;
261 pgran->maxWorkGroupSize = sd->workGroupSizes;
262
263 // if pattern provides granularity calculation
264 // call the pattern function
265 if( NULL != sd->pattern->sops->checkCalcDecomp ){
266
267 sd->pattern->sops->checkCalcDecomp(
268 pgran,
269 dim,
270 2,
271 sd->dtype,
272 PGRAN_CALC );
273 }
274 else{
275 pgran->wgSize[1] = (unsigned int)(dim[0].x / dim[1].itemX);
276 pgran->wgSize[0] = (unsigned int)(dim[0].y / dim[1].itemY);
277
278 if (!sd->is2D) {
279 pgran->wgDim = 1;
280 pgran->wgSize[0] *= pgran->wgSize[1];
281 pgran->wgSize[1] = 1;
282 }
283 }
284
285 }
286
287 void VISIBILITY_HIDDEN
calcParam(SubDimInfo * sd)288 calcParam(SubDimInfo* sd)
289 {
290 SubproblemDim* dim = sd->sdim;
291
292 int dataTypeSize = getDataTypeSize(sd->dtype);
293
294 memset(dim, 0, sizeof(sd->sdim));
295
296 dim[0].x = get(&sd->var[V_L0_X]);
297 dim[0].itemX = get(&sd->var[V_L0_X]);
298 dim[0].y = get(&sd->var[V_L0_Y]);
299 dim[0].itemY = get(&sd->var[V_L0_Y]);
300 dim[0].bwidth = get(&sd->var[V_L0_BW]);
301
302 dim[1].x = get(&sd->var[V_L1_X]);
303 dim[1].itemX = get(&sd->var[V_L1_X]);
304 dim[1].y = get(&sd->var[V_L1_Y]);
305 dim[1].itemY = get(&sd->var[V_L1_Y]);
306 dim[1].bwidth = get(&sd->var[V_L1_BW])
307 / (dataTypeSize / getDataTypeSize(TYPE_FLOAT));
308
309 if (funcHasTriangMatrix((BlasFunctionID)sd->func) && !sd->is2D) {
310 dim[0].itemY = SUBDIM_UNUSED;
311 }
312
313 if (sd->blasLevel == 2) {
314 size_t xBlocks;
315
316 xBlocks = dim[0].x / dim[1].x;
317 dim[0].x = 1;
318 dim[1].itemX = 1;
319 dim[1].x = 1;
320 if( NULL == sd->pattern->sops->checkCalcDecomp ){
321 dim[0].bwidth = dim[1].bwidth * xBlocks;
322 }
323 }
324
325 calcPGranularity(sd);
326 }
327
328 bool VISIBILITY_HIDDEN
next(SubDimItem var[V_COUNT])329 next(SubDimItem var[V_COUNT])
330 {
331 int i = V_COUNT - 1;
332 bool next;
333 do {
334 next = false;
335 var[i].curId ++;
336 if (var[i].curId >= var[i].maxId) {
337 var[i].curId = 0;
338 next = true;
339 -- i;
340 }
341 } while (next && i >= 0 );
342 return (next && i < 0);
343 }
344
345 void VISIBILITY_HIDDEN
findValidSubdimInit(SubDimInfo * sd)346 findValidSubdimInit(SubDimInfo* sd)
347 {
348 bool n = false;
349 do {
350 n = false;
351 calcParam(sd);
352 sd->valid = sd->isValid(sd);
353 if (!sd->valid) {
354 n = !next(sd->var);
355 sd->valid = false;
356 }
357 } while (n);
358 }
359
360 bool
nextSubdimElem(SubDimInfo * sd)361 nextSubdimElem(SubDimInfo* sd)
362 {
363 bool n = false;
364
365 // !!! DEBUG
366 if (sd->count > 500) {
367 abort();
368 }
369
370 sd->count ++;
371 if (sd->valid == false) {
372 return false;
373 }
374
375 if (sd->init != NULL) {
376 sd->valid = false;
377 n = !next(sd->var);
378 if (n)
379 findValidSubdimInit(sd);
380 }
381 return sd->valid;
382 }
383
384 /*
385 * The variant included of the group.
386 */
387 bool
isMemberOfGroup(GroupStatInfo * gsi,Variant * vi)388 isMemberOfGroup(GroupStatInfo* gsi, Variant* vi)
389 {
390 bool res = true;
391 res &= gsi->var[V_L0_X] == -1 || vi->var[V_L0_X] == gsi->var[V_L0_X];
392 res &= gsi->var[V_L0_Y] == -1 || vi->var[V_L0_Y] == gsi->var[V_L0_Y];
393 res &= gsi->var[V_L0_BW] == -1 || vi->var[V_L0_BW] == gsi->var[V_L0_BW];
394 res &= gsi->var[V_L1_X] == -1 || vi->var[V_L1_X] == gsi->var[V_L1_X];
395 res &= gsi->var[V_L1_Y] == -1 || vi->var[V_L1_Y] == gsi->var[V_L1_Y];
396 res &= gsi->var[V_L1_BW] == -1 || vi->var[V_L1_BW] == gsi->var[V_L1_BW];
397 return res;
398 }
399
400 /*
401 * Calculate the minimum expected run time.
402 */
403
404 double
calcMinExpectedTimeForGroup(GroupStatInfo * gsi)405 calcMinExpectedTimeForGroup(GroupStatInfo* gsi)
406 {
407 /*
408 * K_INCREASE - Expected range of time values in the group
409 * K_GLOBAL -
410 */
411 const double K_INCREASE = 1.5;
412 const double K_GLOBAL = 0.97;
413
414 /* Number of variants in group */
415 double m = gsi->allCount;
416 /* Number of variants in group for whom time is measured*/
417 double i = gsi->count;
418
419 /*
420 * k - Reflects the expected spread of values in the group,
421 * depending on the number of measurements
422 * decreases with increasing i
423 * if i == 1 then k K_INCREASE
424 * if i == m then k = 1
425 */
426
427 double ki = 1/ ((K_INCREASE + K_INCREASE/(m+i) -1)/(i) + (m-K_INCREASE)/(m+1));
428 double averageTime = (gsi->allTime / m);
429
430 /*
431 * kdelta - Reflects the expected spread of values in the group,
432 * depending on the spread of values of the measured variations
433 */
434
435 double kdelta = (gsi->minTime*3)/((gsi->minTime*2) + averageTime);
436 double t = K_GLOBAL * kdelta * ki * gsi->minTime;
437
438 /*
439 * Select the minimum time between the minimum time for the current group
440 * and the minimum time for the previous groups
441 */
442 return t;
443 }
444
445 bool
nextSubdim(SubDimInfo * sd,int maxParam,double time)446 nextSubdim(SubDimInfo* sd, int maxParam, double time)
447 {
448 int i;
449 int j;
450 double minW = -5000;
451 int vari = 0;
452 double midTime;
453 int iCount = 0;
454 double maxTime;
455 const int MAX_WEIGHT = 99;
456
457 Variant* v0 = sd->curVar; // Current variant
458 Variant* varNext = NULL; // Next Variant
459
460 if (sd->count >= maxParam) {
461 return false;
462 }
463
464 if (sd->returnAll) {
465 bool ret = nextSubdimElem (sd);
466 calcParam(sd);
467 sd->curVarID = sd->count;
468 return ret;
469 }
470
471 v0->time = time;
472 sd->sumTime += time;
473
474 midTime = sd->sumTime/(sd->count + 1);
475
476 if (time > 0) {
477 sd->minTime = fmin(sd->minTime, (float)time);
478 }
479
480 maxTime = fmax(2.1*midTime - sd->minTime, sd->minTime*5);
481
482 /* Initialize all groups */
483 for (j = 0; j < sd->infoCount; j++ ) {
484 GroupStatInfo* si = &sd->info[j];
485 si->allTime = 0;
486 si->count = 0;
487 si->minTime = 1e9;
488 }
489
490 /* Calculate an estimate for the groups */
491 for (i = 0; i < sd->varCount; ++i) {
492 Variant* vi = &sd->allVariant[i];
493 /* If time for variant is measured*/
494 if (vi->time > 0) {
495 for (j = 0; j < sd->infoCount; j++ ) {
496 GroupStatInfo* gsi = &sd->info[j];
497 // For each group, if variant is member this group
498 if (isMemberOfGroup(gsi, vi)) {
499 gsi->minTime = fmin(gsi->minTime, vi->time);
500 gsi->allTime += fmin(vi->time, maxTime);
501 gsi->count ++;
502 gsi->minTime = calcMinExpectedTimeForGroup(gsi);
503 }
504 }
505 }
506 vi->minTime = 0;
507 vi->maxTime = 5000;
508 vi->weight = MAX_WEIGHT;
509 }
510
511 /*
512 * Calculate the estimate run-time variant
513 */
514 for (i = 0; i < sd->varCount; ++i) {
515 Variant* vi = &sd->allVariant[i];
516
517 vi->weight = MAX_WEIGHT;
518 if (vi->time == 0) {
519 double kgroup = 1.0;
520
521 for (j = 0; j < sd->infoCount; j++ ) {
522 GroupStatInfo* gsi = &sd->info[j];
523 // if the variant included of the group
524 if (isMemberOfGroup(gsi, vi)) {
525 if (gsi->count > 0) {
526 vi->minTime = fmax(vi->minTime, gsi->minTime);
527 vi->weight = sd->minTime/vi->minTime;
528 }
529 else {
530 /*
531 * If variant don't included of the group
532 * then to reduce estimated time
533 */
534 kgroup *= 1.1;
535 }
536 }
537 }
538 vi->weight *= kgroup;
539 vi->minTime /= kgroup;
540 }
541 }
542
543 /* Find variant with minimal run time */
544
545 for (i = 0; i < sd->varCount; ++i)
546 {
547 Variant* vi = &sd->allVariant[i];
548 if (vi->time == 0 && vi->weight >= 0.01 ) {
549 iCount ++;
550
551 if (minW < vi->weight) {
552 minW = vi->weight;
553 varNext = vi;
554 vari = i;
555 }
556 }
557 }
558
559 //
560 if (varNext == NULL) {
561 return false;
562 }
563
564 sd->curVar = varNext;
565 sd->curVarID = vari;
566 #ifdef TEST_LOG
567 printf ("%4d %6.2f [%6.2f:%5.2f ]",iCount, sd->minTime,
568 sd->curVar->minTime, sd->curVar->weight);
569 #endif
570
571 for(j = 0; j < V_COUNT; ++j) {
572 sd->var[j].curId = varNext->var[j];
573 }
574
575 calcParam(sd);
576 sd->count++;
577 return true;
578 }
579
580 void
resetSubdim(SubDimInfo * sd)581 resetSubdim(SubDimInfo* sd)
582 {
583 int i;
584 for (i=0; i< V_COUNT; ++i) {
585 sd->var[i].curId = 0;
586 }
587
588 sd->count = 0;
589
590 sd->valid = false;
591 if (sd->init != NULL) {
592 sd->init(sd);
593 findValidSubdimInit(sd);
594
595 assert(sd->valid);
596 }
597 }
598
599 /*
600 * Groups variants in nonzero parameters.
601 *
602 * Example: l0x = 1 and remaining parameters = 0;
603 * At different variants the parameter l0x accepts values 16, 32, 64.
604 * At the first stage creates are 3 groups (a set of groups).
605 * At the second stage all variants are arranged on these groups.
606 *
607 * The each variant included one group of the set of group.
608 * The each variant included in each set of group.
609 * In set of group can be only one group
610 */
611
setGroup(SubDimInfo * sd,int l0x,int l0y,int l0w,int l1x,int l1y,int l1w,int pg)612 void setGroup(SubDimInfo* sd,
613 int l0x, int l0y, int l0w,
614 int l1x, int l1y, int l1w,
615 int pg)
616 {
617 int i, j;
618 int start = sd->infoCount;
619 int end = sd->infoCount;
620
621 (void) pg;
622
623 //For each variant
624 for (i = 0; i < sd->varCount; ++i) {
625 Variant* vi = &sd->allVariant[i];
626 int id = -1;
627 // For each group of the set of group
628 for (j = start; j < end; j++ ) {
629 bool bj = true;
630 bj &= l0x == 0 || vi->var[V_L0_X] == sd->info[j].var[V_L0_X];
631 bj &= l0y == 0 || vi->var[V_L0_Y] == sd->info[j].var[V_L0_Y];
632 bj &= l0w == 0 || vi->var[V_L0_BW] == sd->info[j].var[V_L0_BW];
633 bj &= l1x == 0 || vi->var[V_L1_X] == sd->info[j].var[V_L1_X];
634 bj &= l1y == 0 || vi->var[V_L1_Y] == sd->info[j].var[V_L1_Y];
635 bj &= l1w == 0 || vi->var[V_L1_BW] == sd->info[j].var[V_L1_BW];
636 // if the variant belongs to group
637 if (bj) {
638 id = j;
639 break;
640 }
641 }
642 /*
643 * if the variant doesn't belong to any group create new group
644 */
645
646 if (id == -1) {
647 sd->info[end].var[V_L0_X] = (l0x == 1)? vi->var[V_L0_X] : -1;
648 sd->info[end].var[V_L0_Y] = (l0y == 1)? vi->var[V_L0_Y] : -1;
649 sd->info[end].var[V_L0_BW] = (l0w == 1)? vi->var[V_L0_BW] : -1;
650 sd->info[end].var[V_L1_X] = (l1x == 1)? vi->var[V_L1_X] : -1;
651 sd->info[end].var[V_L1_Y] = (l1y == 1)? vi->var[V_L1_Y] : -1;
652 sd->info[end].var[V_L1_BW] = (l1w == 1)? vi->var[V_L1_BW] : -1;
653 sd->info[end].pg = 0;
654
655 sd->info[end].allTime = 0;
656 sd->info[end].allCount = 1;
657
658 end++;
659 sd->infoCount++;
660 }
661 else {
662 sd->info[id].allCount++;
663 }
664 }
665 }
666
667 void
initSubDimInfo(SubDimInfo * sd,MemoryPattern * mempatt,DeviceInfo * devinfo,unsigned int func,unsigned int patt,DataType dtype,KernelExtraFlags flag)668 initSubDimInfo(SubDimInfo* sd,
669 MemoryPattern* mempatt,
670 DeviceInfo* devinfo,
671 unsigned int func,
672 unsigned int patt,
673 DataType dtype,
674 KernelExtraFlags flag)
675 {
676 int i = 0;
677
678 memset(sd, 0, sizeof(SubDimInfo));
679
680 sd->func = func;
681 sd->patt = patt;
682 sd->dtype = dtype;
683 sd->flag = flag;
684 sd->pattern = mempatt;
685 sd->first = NULL;
686
687 sd->is2D = (sd->pattern->sops->getFlags() & SF_WSPACE_2D)?true:false;
688 sd->isSquareBlock = ((sd->pattern->sops->getFlags() &
689 SF_TOP_INPUT_SQUARE_BLOCKS) != 0);
690 sd->blasLevel = funcBlasLevel(sd->func);
691 sd->nrLevel = sd->pattern->nrLevels;
692
693 sd->ldsSize = devinfo->ldsSize;
694 sd->workGroupSizes = devinfo->workGroupSizes;
695
696 // Virtual function
697 sd->isValid = isSubDimValid;
698 sd->init = initVector;
699
700 resetSubdim(sd);
701
702 i = 0;
703 do {
704 i++;
705 } while (nextSubdimElem(sd));
706 sd->allVariant = malloc(i* sizeof(Variant));
707
708 resetSubdim(sd);
709 sd->varCount = i;
710
711 for (i = 0; i < sd->varCount; ++i) {
712 int j;
713 int gpx;
714 int gpy;
715
716 for(j = 0; j < V_COUNT; ++j) {
717 sd->allVariant[i].var[j] = sd->var[j].curId;
718 }
719
720 sd->allVariant[i].minTime = 0.0;
721 sd->allVariant[i].probableTime = 0.0;
722 sd->allVariant[i].maxTime = 5000.0;
723 sd->allVariant[i].weight = 10;
724 sd->allVariant[i].time = 0;
725
726 gpx = get(&sd->var[V_L0_X])/ get(&sd->var[V_L1_X]);
727 gpy = get(&sd->var[V_L0_Y])/ get(&sd->var[V_L1_Y]);
728 sd->allVariant[i].pg = gpx * 1000 + gpy;
729
730 nextSubdimElem(sd);
731 }
732 resetSubdim(sd);
733
734 sd->minTime = 9999;
735 sd->curVar = &sd->allVariant[0];
736 sd->curVarID = 0;
737
738
739 // Initializing group
740 sd->infoMaxCount = 5000;
741 sd->infoCount = 0;
742 sd->info = malloc(sd->infoMaxCount * sizeof(GroupStatInfo) );
743
744 // L0 L1 PG
745 // x y w x y w
746 setGroup(sd, 1, 1, 0, 0, 0, 0, 0);
747 setGroup(sd, 1, 1, 1, 0, 0, 0, 0);
748 setGroup(sd, 0, 0, 0, 1, 1, 1, 0);
749 setGroup(sd, 1, 1, 0, 1, 1, 0, 0);
750 }
751
752 void
setVariable(struct SubDimInfo * sdi,SubDimVariable var,int dcount,int * dim)753 setVariable(struct SubDimInfo* sdi, SubDimVariable var, int dcount, int* dim)
754 {
755 size_t size = dcount*sizeof(int);
756
757 sdi->var[var].curId = 0;
758 sdi->var[var].maxId = dcount;
759
760 if (sdi->var[var].data != NULL) {
761 free (sdi->var[var].data);
762 sdi->var[var].data = NULL;
763 }
764 sdi->var[var].data = malloc(size);
765 memcpy(sdi->var[var].data, dim, size);
766 }
767
768
769