Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Side by Side Diff: nacl/deltablue.c

Issue 7821018: Add Richards and DeltaBlue benchmarks (Closed) Base URL: https://code.google.com/p/web-shootout/@master
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nacl/build.scons ('k') | nacl/richards.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* This is an implementation of the DeltaBlue incremental dataflow
2 constraint solver written in portable C.
3
4 The original version was by John Maloney.
5 This version was modified for portability and benchmarking
6 by Mario Wolczko, Sun Microsystems Labs, 2 Oct 96.
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <time.h>
13
14 typedef enum {false, true} Boolean;
15 typedef void (*Proc)();
16 typedef void * Element;
17
18 /*
19 List: Supports variable sized, ordered lists of elements. */
20
21 typedef struct {
22 Element *slots; /* variable-sized array of element slots */
23 int slotCount; /* number of slots currently allocated */
24 int first; /* index of first element */
25 int last; /* index of last element (first-1, if empty) */
26 } *List, ListStruct;
27
28 /*
29 Constraint, variable, and strength data definitions for DeltaBlue.
30 */
31
32 /* Strength Constants */
33 typedef enum {
34 S_required= 0,
35 S_strongPreferred= 1,
36 S_preferred= 2,
37 S_strongDefault= 3,
38 S_default= 4,
39 S_weakDefault= 5,
40 S_weakest= 6
41 } Strength;
42
43 struct constraint;
44
45 typedef struct {
46 long value;
47 List constraints;
48 struct constraint* determinedBy;
49 long mark;
50 Strength walkStrength;
51 Boolean stay;
52 char name[10];
53 } *Variable, VariableStruct;
54
55 typedef struct constraint {
56 Proc execute;
57 Boolean inputFlag;
58 Strength strength;
59 char whichMethod;
60 char methodCount;
61 char varCount;
62 char methodOuts[7];
63 Variable variables[1];
64 } *Constraint, ConstraintStruct;
65
66 /* Other Constants and Macros */
67 #define NO_METHOD (-1)
68 #define SATISFIED(c) ((c)->whichMethod != NO_METHOD)
69 #define Weaker(a,b) (a > b)
70
71 /*
72 Implementation of List
73 Invariants and relationships:
74 slots != NULL
75 slotCount > 0
76 sizeof(*slots) == slotCount * sizeof(Element)
77 0 <= first < slotCount
78 -1 <= last < slotCount
79 last >= first (if not empty)
80 last == first - 1 (if empty)
81 NumberOfItems == (last - first) + 1
82 */
83
84 /* Private Prototypes */
85 void Error(char*);
86 void Grow(List);
87 void MakeRoom(List);
88 char* StrengthString(Strength strength);
89
90 /* Variables */
91 Variable Variable_Create(char *, long);
92 Variable Variable_CreateConstant(char *, long);
93 void Variable_Destroy(Variable);
94 void Variable_Print(Variable);
95
96 /* Constraints */
97 Constraint Constraint_Create(int, Strength);
98 void Constraint_Destroy(Constraint);
99 void Constraint_Print(Constraint);
100
101 /* Miscellaneous */
102 void ExecutePlan(List);
103
104 Constraint StayC(Variable v, Strength); /* keep v constant */
105 Constraint EditC(Variable v, Strength); /* change v */
106 Constraint EqualsC(Variable a, Variable b, Strength); /* a = b */
107 /* (src * scale) + offset = dest*/
108 Constraint ScaleOffsetC(Variable src, Variable scale, Variable offset,
109 Variable dest, Strength);
110
111 void InitDeltaBlue(void);
112 void AddVariable(Variable);
113 void DestroyVariable(Variable);
114 void AddConstraint(Constraint);
115 void DestroyConstraint(Constraint);
116 List ExtractPlan(void);
117 List ExtractPlanFromConstraint(Constraint);
118 List ExtractPlanFromConstraints(List);
119
120
121
122 /****** Create and Destruction ******/
123
124 List List_Create(int initialCount)
125 {
126 List newList;
127
128 newList = (List) malloc(sizeof(ListStruct));
129 if (newList == NULL) Error("out of memory");
130 newList->slots = (Element *) malloc(initialCount * sizeof(Element));
131 if (newList->slots == NULL) Error("out of memory");
132 newList->slotCount = initialCount;
133 newList->first = 0;
134 newList->last = -1;
135 return newList;
136 }
137
138 void List_Destroy(List list)
139 {
140 if (list->slots == NULL) Error("bad ListStruct; already freed?");
141 free(list->slots);
142 list->slots = NULL;
143 list->slotCount = 0;
144 list->first = 0;
145 list->last = -1;
146 free(list);
147 }
148
149 /****** Enumeration and Queries ******/
150
151 void List_Do(List list, Proc proc)
152 {
153 Element *nextPtr = &(list->slots[list->first]);
154 Element *lastPtr = &(list->slots[list->last]);
155
156 while (nextPtr <= lastPtr) {
157 (*proc)(*nextPtr++);
158 }
159 }
160
161 int List_Size(List list)
162 {
163 return (list->last - list->first) + 1;
164 }
165
166 void* List_At(List list, int index)
167 {
168 if (index < 0 || index > list->last - list->first + 1)
169 Error("List access out of bounds");
170 return list->slots[index + list->first];
171 }
172
173 /****** Adding ******/
174
175 void List_Add(List list, Element element)
176 {
177 if (list->last >= (list->slotCount - 1)) MakeRoom(list);
178 list->slots[++list->last] = element;
179 }
180
181 void List_Append(List list1, List list2)
182 {
183 Element *nextPtr = &(list2->slots[list2->first]);
184 Element *lastPtr = &(list2->slots[list2->last]);
185
186 while (nextPtr <= lastPtr) {
187 List_Add(list1, *nextPtr++);
188 }
189 }
190
191 /****** Removing ******/
192
193 void List_Remove(List list, Element element)
194 {
195 Element *srcPtr = &list->slots[list->first];
196 Element *destPtr = &list->slots[0];
197 Element *lastPtr = &list->slots[list->last];
198
199 list->last = list->last - list->first;
200 list->first = 0;
201 while (srcPtr <= lastPtr) {
202 if (*srcPtr == element) {
203 list->last--;
204 } else {
205 *destPtr++ = *srcPtr;
206 }
207 srcPtr++;
208 }
209 }
210
211 Element List_RemoveFirst(List list)
212 {
213 Element element;
214
215 if (list->last < list->first) return NULL;
216 element = list->slots[list->first++];
217 return element;
218 }
219
220 void List_RemoveAll(List list)
221 {
222 list->first = 0;
223 list->last = -1;
224 }
225
226 /****** Private ******/
227
228 #define max(x, y) ((x) > (y) ? (x) : (y))
229 #define min(x, y) ((x) < (y) ? (x) : (y))
230
231 void Error(char *errorString)
232 {
233 printf("error: %s.\n", errorString);
234 exit(-1);
235 }
236
237 void Grow(List list)
238 {
239 list->slotCount += min(max(list->slotCount, 2), 512);
240 list->slots = realloc(list->slots, (list->slotCount * sizeof(Element)));
241 if (list->slots == NULL) Error("out of memory");
242 }
243
244 void MakeRoom(List list)
245 {
246 Element *srcPtr = &list->slots[list->first];
247 Element *destPtr = &list->slots[0];
248 Element *lastPtr = &list->slots[list->last];
249
250 if (((list->last - list->first) + 1) >= list->slotCount) Grow(list);
251 if (list->first == 0) return;
252 while (srcPtr <= lastPtr) {
253 *destPtr++ = *srcPtr++;
254 }
255 list->last = list->last - list->first;
256 list->first = 0;
257 }
258
259 /*
260 Constraint, variable, and other operations for DeltaBlue.
261 */
262
263 /******* Private *******/
264
265 void Execute(Constraint c)
266 {
267 c->execute(c);
268 }
269
270 void Noop(Constraint c)
271 {
272 /* default execute procedure; does nothing */
273 };
274
275 /******* Variables *******/
276
277 Variable Variable_Create(char *name, long initialValue)
278 {
279 Variable new;
280
281 new = (Variable) malloc(sizeof(VariableStruct));
282 if (new == NULL) Error("out of memory");
283 new->value = initialValue;
284 new->constraints = List_Create(2);
285 new->determinedBy = NULL;
286 new->mark = 0;
287 new->walkStrength = S_weakest;
288 new->stay = true;
289 strncpy(new->name, name, 10);
290 new->name[9] = 0;
291 AddVariable(new);
292 return new;
293 }
294
295 Variable Variable_CreateConstant(char *name, long value)
296 {
297 Variable new;
298
299 new = (Variable) malloc(sizeof(VariableStruct));
300 if (new == NULL) Error("out of memory");
301 new->value = value;
302 new->constraints = List_Create(0);
303 new->determinedBy = NULL;
304 new->mark = 0;
305 new->walkStrength = S_required;
306 new->stay = true;
307 strncpy(new->name, name, 10);
308 new->name[9] = 0;
309 AddVariable(new);
310 return new;
311 }
312
313 void Variable_Destroy(Variable v)
314 {
315 if (v->constraints == NULL) {
316 Error("bad VariableStruct; already freed?");
317 }
318 List_Destroy(v->constraints);
319 v->constraints = NULL;
320 free(v);
321 }
322
323 void Variable_Print(Variable v)
324 {
325 printf(
326 "%s(%s,%ld)",
327 v->name, StrengthString(v->walkStrength), v->value);
328 }
329
330 /******* Constraints *******/
331
332 Constraint Constraint_Create(int variableCount, Strength strength)
333 {
334 Constraint new;
335 int i;
336
337 new = (Constraint) malloc(sizeof(ConstraintStruct)
338 + ((variableCount - 1) * sizeof(Variable)));
339 if (new == NULL) Error("out of memory");
340 new->execute = Noop;
341 new->inputFlag = false;
342 new->strength = strength;
343 new->whichMethod = NO_METHOD;
344 new->methodCount = 0;
345 for (i = 0; i < 7; i++) {
346 new->methodOuts[i] = 0;
347 }
348 new->varCount = variableCount;
349 for (i = 0; i < new->varCount; i++) {
350 new->variables[i] = NULL;
351 }
352 return new;
353 }
354
355 void Constraint_Destroy(Constraint c)
356 {
357 if (c->execute == NULL) {
358 Error("bad ConstraintStruct; already freed?");
359 }
360 c->execute = NULL;
361 free(c);
362 }
363
364 void Constraint_Print(Constraint c)
365 {
366 int i, outIndex;
367
368 if (!SATISFIED(c)) {
369 printf("Unsatisfied(");
370 for (i = 0; i < c->varCount; i++) {
371 Variable_Print(c->variables[i]);
372 printf(" ");
373 }
374 printf(")");
375 } else {
376 outIndex = c->methodOuts[c->whichMethod];
377 printf("Satisfied(");
378 for (i = 0; i < c->varCount; i++) {
379 if (i != outIndex) {
380 Variable_Print(c->variables[i]);
381 printf(" ");
382 }
383 }
384 printf("-> ");
385 Variable_Print(c->variables[outIndex]);
386 printf(")");
387 }
388 printf("\n");
389 }
390
391 /******* Miscellaneous Functions *******/
392
393 char* StrengthString(Strength strength)
394 {
395 static char temp[20];
396
397 switch (strength) {
398 case S_required: return "required";
399 case S_strongPreferred: return "strongPreferred";
400 case S_preferred: return "preferred";
401 case S_strongDefault: return "strongDefault";
402 case S_default: return "default";
403 case S_weakDefault: return "weakDefault";
404 case S_weakest: return "weakest";
405 default:
406 sprintf(temp, "strength[%d]", strength);
407 return temp;
408 }
409 }
410
411 void ExecutePlan(List list)
412 {
413 List_Do(list, Execute);
414 }
415
416
417 /*
418
419 DeltaBlue, an incremental dataflow constraint solver.
420
421 */
422
423 /******* Private Macros and Prototypes *******/
424
425 #define OUT_VAR(c) (c->variables[c->methodOuts[c->whichMethod]])
426
427 void FreeVariable(Variable);
428 void AddIfSatisfiedInput(Constraint);
429 void CollectSatisfiedInputs(Variable);
430 List MakePlan(void);
431 void IncrementalAdd(Constraint);
432 void AddAtStrength(Constraint);
433 void IncrementalRemove(Constraint);
434 Boolean AddPropagate(Constraint);
435 void CollectUnsatisfied(Constraint);
436 void RemovePropagateFrom(Variable);
437 Constraint Satisfy(Constraint);
438 int ChooseMethod(Constraint);
439 void Recalculate(Constraint);
440 int OutputWalkStrength(Constraint);
441 Boolean ConstantOutput(Constraint);
442 Boolean InputsKnown(Constraint);
443 void NewMark(void);
444 void Error(char *);
445 Constraint NextDownstreamConstraint(List, Variable);
446
447 /******* DeltaBlue Globals *******/
448
449 List allVariables = NULL;
450 long currentMark = 0;
451
452 /******** Public: Initialization *******/
453
454 void InitDeltaBlue(void)
455 {
456 Variable v;
457
458 if (allVariables == NULL) allVariables = List_Create(128);
459 v = (Variable) List_RemoveFirst(allVariables);
460 while (v != NULL) {
461 FreeVariable(v);
462 v = (Variable) List_RemoveFirst(allVariables);
463 }
464 List_RemoveAll(allVariables);
465 currentMark = 0;
466 }
467
468 /* this is used when we know we are going to throw away all variables */
469 void FreeVariable(Variable v)
470 {
471 Constraint c;
472 int i;
473
474 c = (Constraint) List_RemoveFirst(v->constraints);
475 while (c != NULL) {
476 for (i = c->varCount - 1; i >= 0; i--) {
477 List_Remove((c->variables[i])->constraints, (Element) c);
478 }
479 Constraint_Destroy(c);
480 c = (Constraint) List_RemoveFirst(v->constraints);
481 }
482 Variable_Destroy(v);
483 }
484
485 /******** Public: Variables and Constraints *******/
486
487 void AddVariable(Variable v)
488 {
489 List_Add(allVariables, v);
490 }
491
492 void DestroyConstraint(Constraint c);
493
494 void DestroyVariable(Variable v)
495 {
496 Constraint c;
497
498 c = (Constraint) List_RemoveFirst(v->constraints);
499 while (c != NULL) {
500 DestroyConstraint(c);
501 c = (Constraint) List_RemoveFirst(v->constraints);
502 }
503 List_Remove(allVariables, v);
504 Variable_Destroy(v);
505 }
506
507 void AddConstraint(Constraint c)
508 {
509 int i;
510
511 for (i = c->varCount - 1; i >= 0; i--) {
512 List_Add((c->variables[i])->constraints, (Element) c);
513 }
514 c->whichMethod = NO_METHOD;
515 IncrementalAdd(c);
516 }
517
518 void DestroyConstraint(Constraint c)
519 {
520 int i;
521
522 if (SATISFIED(c)) IncrementalRemove(c);
523 for (i = c->varCount - 1; i >= 0; i--) {
524 List_Remove((c->variables[i])->constraints, (Element) c);
525 }
526 Constraint_Destroy(c);
527 }
528
529 /******** Public: Plan Extraction *******/
530
531 List hot = NULL; /* used to collect "hot" constraints */
532
533 void AddIfSatisfiedInput(Constraint c)
534 {
535 if (c->inputFlag && SATISFIED(c)) {
536 List_Add(hot, c);
537 }
538 }
539
540 void CollectSatisfiedInputs(Variable v)
541 {
542 List_Do(v->constraints, AddIfSatisfiedInput);
543 }
544
545 List ExtractPlan(void)
546 {
547 if (hot == NULL) hot = List_Create(128);
548 List_RemoveAll(hot);
549 List_Do(allVariables, CollectSatisfiedInputs);
550 return MakePlan();
551 }
552
553 List ExtractPlanFromConstraint(Constraint c)
554 {
555 if (hot == NULL) hot = List_Create(128);
556 List_RemoveAll(hot);
557 AddIfSatisfiedInput(c);
558 return MakePlan();
559 }
560
561 List ExtractPlanFromConstraints(List constraints)
562 {
563 if (hot == NULL) hot = List_Create(128);
564 List_RemoveAll(hot);
565 List_Do(constraints, AddIfSatisfiedInput);
566 return MakePlan();
567 }
568
569 /******* Private: Plan Extraction *******/
570
571 List MakePlan()
572 {
573 List plan;
574 Constraint nextC;
575 Variable out;
576
577 NewMark();
578 plan = List_Create(128);
579 nextC = (Constraint) List_RemoveFirst(hot);
580 while (nextC != NULL) {
581 out = OUT_VAR(nextC);
582 if ((out->mark != currentMark) && InputsKnown(nextC)) {
583 List_Add(plan, nextC);
584 out->mark = currentMark;
585 nextC = NextDownstreamConstraint(hot, out);
586 } else {
587 nextC = (Constraint) List_RemoveFirst(hot);
588 }
589 }
590 return plan;
591 }
592
593 Boolean InputsKnown(Constraint c)
594 {
595 int outIndex, i;
596 Variable in;
597
598 outIndex = c->methodOuts[c->whichMethod];
599 for (i = c->varCount - 1; i >= 0; i--) {
600 if (i != outIndex) {
601 in = c->variables[i];
602 if ((in->mark != currentMark) &&
603 (!in->stay) &&
604 (in->determinedBy != NULL)) {
605 return false;
606 }
607 }
608 }
609 return true;
610 }
611
612 /******* Private: Adding *******/
613
614 void IncrementalAdd(Constraint c)
615 {
616 Constraint overridden;
617
618 NewMark();
619 overridden = Satisfy(c);
620 while (overridden != NULL) {
621 overridden = Satisfy(overridden);
622 }
623 }
624
625 Constraint Satisfy(Constraint c)
626 {
627 int outIndex, i;
628 Constraint overridden;
629 Variable out;
630
631 c->whichMethod = ChooseMethod(c);
632 if (SATISFIED(c)) {
633 /* mark inputs to allow cycle detection in AddPropagate */
634 outIndex = c->methodOuts[c->whichMethod];
635 for (i = c->varCount - 1; i >= 0; i--) {
636 if (i != outIndex) {
637 c->variables[i]->mark = currentMark;
638 }
639 }
640 out = c->variables[outIndex];
641 overridden = (Constraint) out->determinedBy;
642 if (overridden != NULL) overridden->whichMethod = NO_METHOD;
643 out->determinedBy = c;
644 if (!AddPropagate(c)) {
645 Error("Cycle encountered");
646 return NULL;
647 }
648 out->mark = currentMark;
649 return overridden;
650 } else {
651 if (c->strength == S_required) {
652 Error("Could not satisfy a required constraint");
653 }
654 return NULL;
655 }
656 }
657
658 int ChooseMethod(Constraint c)
659 {
660 int best, m;
661 Strength bestOutStrength;
662 Variable mOut;
663
664 best = NO_METHOD;
665 bestOutStrength = c->strength;
666 for (m = c->methodCount - 1; m >= 0; m--) {
667 mOut = c->variables[c->methodOuts[m]];
668 if ((mOut->mark != currentMark) &&
669 (Weaker(mOut->walkStrength, bestOutStrength))) {
670 best = m;
671 bestOutStrength = mOut->walkStrength;
672 }
673 }
674 return best;
675 }
676
677 Boolean AddPropagate(Constraint c)
678 {
679 List todo;
680 Constraint nextC;
681 Variable out;
682
683 todo = List_Create(8); /* unprocessed constraints */
684 nextC = c;
685 while (nextC != NULL) {
686 out = OUT_VAR(nextC);
687 if (out->mark == currentMark) {
688 /* remove the cycle-causing constraint */
689 IncrementalRemove(c);
690 return false;
691 }
692 Recalculate(nextC);
693 nextC = NextDownstreamConstraint(todo, out);
694 }
695 List_Destroy(todo);
696 return true;
697 }
698
699 /******* Private: Removing *******/
700
701 List unsatisfied; /* used to collect unsatisfied downstream constraints */
702 Strength strength; /* used to add unsatisfied constraints in strength order */
703
704 void AddAtStrength(Constraint c)
705 {
706 if (c->strength == strength) IncrementalAdd(c);
707 }
708
709 void CollectUnsatisfied(Constraint c)
710 {
711 if (!SATISFIED(c)) List_Add(unsatisfied, c);
712 }
713
714 void IncrementalRemove(Constraint c)
715 {
716 Variable out;
717 int i;
718
719 out = OUT_VAR(c);
720 c->whichMethod = NO_METHOD;
721 for (i = c->varCount - 1; i >= 0; i--) {
722 List_Remove((c->variables[i])->constraints, (Element) c);
723 }
724 unsatisfied = List_Create(8);
725 RemovePropagateFrom(out);
726 for (strength = S_required; strength <= S_weakest; strength++) {
727 List_Do(unsatisfied, AddAtStrength);
728 }
729 List_Destroy(unsatisfied);
730 }
731
732 void RemovePropagateFrom(Variable v)
733 {
734 Constraint nextC;
735 List todo;
736
737 v->determinedBy = NULL;
738 v->walkStrength = S_weakest;
739 v->stay = true;
740 todo = List_Create(8);
741 while (true) {
742 List_Do(v->constraints, CollectUnsatisfied);
743 nextC = NextDownstreamConstraint(todo, v);
744 if (nextC == NULL) {
745 break;
746 } else {
747 Recalculate(nextC);
748 v = OUT_VAR(nextC);
749 }
750 }
751 List_Destroy(todo);
752 }
753
754 /******* Private: Recalculation *******/
755
756 void Recalculate(Constraint c)
757 {
758 Variable out;
759
760 out = OUT_VAR(c);
761 out->walkStrength = OutputWalkStrength(c);
762 out->stay = ConstantOutput(c);
763 if (out->stay) c->execute(c);
764 }
765
766 int OutputWalkStrength(Constraint c)
767 {
768 int outIndex, m, mOutIndex;
769 Strength minStrength;
770
771 minStrength = c->strength;
772 outIndex = c->methodOuts[c->whichMethod];
773 for (m = c->methodCount - 1; m >= 0; m--) {
774 mOutIndex = c->methodOuts[m];
775 if ((mOutIndex != outIndex) &&
776 (Weaker(c->variables[mOutIndex]->walkStrength, minStrength))) {
777 minStrength = c->variables[mOutIndex]->walkStrength;
778 }
779 }
780 return minStrength;
781 }
782
783 Boolean ConstantOutput(Constraint c)
784 {
785 int outIndex, i;
786
787 if (c->inputFlag) return false;
788 outIndex = c->methodOuts[c->whichMethod];
789 for (i = c->varCount - 1; i >= 0; i--) {
790 if (i != outIndex) {
791 if (!c->variables[i]->stay) return false;
792 }
793 }
794 return true;
795 }
796
797 /******* Private: Miscellaneous *******/
798
799 void NewMark(void)
800 {
801 currentMark++;
802 }
803
804 Constraint NextDownstreamConstraint(List todo, Variable variable)
805 {
806 List allC = variable->constraints;
807 Constraint *nextPtr = (Constraint *) &(allC->slots[allC->first]);
808 Constraint *lastPtr = (Constraint *) &(allC->slots[allC->last]);
809 Constraint determiningC = variable->determinedBy;
810 Constraint first = NULL;
811
812 for ( ; nextPtr <= lastPtr; nextPtr++) {
813 if ((*nextPtr != determiningC) && SATISFIED(*nextPtr)) {
814 if (first == NULL) {
815 first = *nextPtr;
816 } else {
817 List_Add(todo, *nextPtr);
818 }
819 }
820 }
821 if (first == NULL) {
822 first = (Constraint) List_RemoveFirst(todo);
823 }
824 return first;
825 }
826
827
828 /*
829 Some useful constraints. Each function instantiates and installs
830 a constraint on the argument variables.
831 */
832
833
834 /* macro to reference a constraint variable value */
835 #define var(i) ((c->variables[i])->value)
836
837 /******* Stay Constraint *******/
838
839 Constraint StayC(Variable v, Strength strength)
840 {
841 Constraint new = Constraint_Create(1, strength);
842 new->variables[0] = v;
843 new->methodCount = 1;
844 new->methodOuts[0] = 0;
845 AddConstraint(new);
846 return new;
847 };
848
849 /******* Edit Constraint *******/
850
851 Constraint EditC(Variable v, Strength strength)
852 {
853 Constraint new = Constraint_Create(1, strength);
854 new->inputFlag = true;
855 new->variables[0] = v;
856 new->methodCount = 1;
857 new->methodOuts[0] = 0;
858 AddConstraint(new);
859 return new;
860 };
861
862 /****** Equals Constraint ******/
863
864 void EqualsC_Execute(Constraint c)
865 {
866 /* a = b */
867 switch (c->whichMethod) {
868 case 0:
869 var(0) = var(1);
870 break;
871 case 1:
872 var(1) = var(0);
873 break;
874 }
875 }
876
877 Constraint EqualsC(Variable a, Variable b, Strength strength)
878 {
879 Constraint new = Constraint_Create(2, strength);
880 new->execute = EqualsC_Execute;
881 new->variables[0] = a;
882 new->variables[1] = b;
883 new->methodCount = 2;
884 new->methodOuts[0] = 0;
885 new->methodOuts[1] = 1;
886 AddConstraint(new);
887 return new;
888 };
889
890 /******** Add Constraint *******/
891
892 void AddC_Execute(Constraint c)
893 {
894 /* a + b = sum */
895 switch (c->whichMethod) {
896 case 0:
897 var(2) = var(0) + var(1);
898 break;
899 case 1:
900 var(1) = var(2) - var(0);
901 break;
902 case 2:
903 var(0) = var(2) - var(1);
904 break;
905 }
906 }
907
908 Constraint AddC(Variable a, Variable b, Variable sum, Strength strength)
909 {
910 Constraint new = Constraint_Create(3, strength);
911 new->execute = AddC_Execute;
912 new->variables[0] = a;
913 new->variables[1] = b;
914 new->variables[2] = sum;
915 new->methodCount = 3;
916 new->methodOuts[0] = 2;
917 new->methodOuts[1] = 1;
918 new->methodOuts[2] = 0;
919 AddConstraint(new);
920 return new;
921 };
922
923 /******** ScaleOffset Constraint *******/
924
925 void ScaleOffsetC_Execute(Constraint c)
926 {
927 /* (src * scale) + offset = dest */
928 switch (c->whichMethod) {
929 case 0:
930 var(3) = (var(0) * var(1)) + var(2);
931 break;
932 case 1:
933 var(0) = (var(3) - var(2)) / var(1);
934 break;
935 }
936 }
937
938 Constraint ScaleOffsetC(Variable src, Variable scale, Variable offset,
939 Variable dest, Strength strength)
940 {
941 Constraint new = Constraint_Create(4, strength);
942 new->execute = ScaleOffsetC_Execute;
943 new->variables[0] = src;
944 new->variables[1] = scale;
945 new->variables[2] = offset;
946 new->variables[3] = dest;
947 new->methodCount = 2;
948 new->methodOuts[0] = 3;
949 new->methodOuts[1] = 0;
950 AddConstraint(new);
951 return new;
952 };
953
954 /***************************************************************************
955
956 Timing Functions
957
958 ****************************************************************************/
959
960 long startTime;
961
962 long Milliseconds()
963 {
964 int millisecondsPerClock = CLOCKS_PER_SEC / 1000;
965 return (clock() / millisecondsPerClock);
966 }
967
968 void Start()
969 {
970 startTime = Milliseconds();
971 }
972
973 void Finish(long *milliseconds)
974 {
975 *milliseconds = Milliseconds() - startTime;
976 }
977
978 /***************************************************************************
979 *
980 * This is the standard DeltaBlue benchmark. A long chain of equality
981 * constraints is constructed with a stay constraint on one end. An edit
982 * constraint is then added to the opposite end and the time is measured for
983 * adding and removing this constraint, and extracting and executing a
984 * constraint satisfaction plan. There are two cases. In case 1, the added
985 * constraint is stronger than the stay constraint and values must propagate
986 * down the entire length of the chain. In case 2, the added constraint is
987 * weaker than the stay constraint so it cannot be accomodated. The cost in
988 * this case is, of course, very low. Typical situations lie somewhere between
989 * these two extremes.
990 *
991 ****************************************************************************/
992
993 void ChainTest(int n)
994 {
995 long msecs, i;
996 char name[20];
997 Variable prev, v, first, last;
998 Constraint editC;
999 List plan;
1000
1001 InitDeltaBlue();
1002 prev = first = last = NULL;
1003
1004 for (i = 0; i < n; i++) {
1005 sprintf(name, "v%ld", i);
1006 v = Variable_Create(name, 0);
1007 if (prev != NULL) {
1008 EqualsC(prev, v, S_required);
1009 }
1010 if (i == 0) first = v;
1011 if (i == (n-1)) last = v;
1012 prev = v;
1013 }
1014 StayC(last, S_default);
1015 editC = EditC(first, S_strongDefault);
1016 plan = ExtractPlanFromConstraint(editC);
1017 for (i = 0; i < 100; i++) {
1018 first->value = i;
1019 ExecutePlan(plan);
1020 if (last->value != i)
1021 Error("ChainTest failed!");
1022 }
1023 List_Destroy(plan);
1024 DestroyConstraint(editC);
1025 }
1026
1027 /***************************************************************************
1028 *
1029 * This test constructs a two sets of variables related to each other by a
1030 * simple linear transformation (scale and offset). The time is measured to
1031 * change a variable on either side of the mapping and to change the scale or
1032 * offset factors. It has been tested for up to 2000 variable pairs.
1033 *
1034 ****************************************************************************/
1035
1036 void Change(Variable v, long newValue)
1037 {
1038 Constraint editC;
1039 long i, msecs;
1040 List plan;
1041
1042 editC = EditC(v, S_strongDefault);
1043 plan = ExtractPlanFromConstraint(editC);
1044 v->value = newValue;
1045 for (i = 0; i < 10; i++) {
1046 ExecutePlan(plan);
1047 }
1048 List_Destroy(plan);
1049 DestroyConstraint(editC);
1050 }
1051
1052 void ProjectionTest(int n)
1053 {
1054 Variable src, scale, offset, dest;
1055 long msecs, i;
1056 char name[20];
1057 List dests;
1058
1059 InitDeltaBlue();
1060
1061 scale = Variable_Create("scale", 10);
1062 offset = Variable_Create("offset", 1000);
1063 dests = List_Create(n);
1064
1065 for (i = 1; i <= n; i++) {
1066 /* make src and dest variables */
1067 sprintf(name, "src%ld", i);
1068 src = Variable_Create(name, i);
1069 sprintf(name, "dest%ld", i);
1070 dest = Variable_Create(name, i);
1071 List_Add(dests, dest);
1072
1073 /* add stay on src */
1074 StayC(src, S_default);
1075
1076 /* add scale/offset constraint */
1077 ScaleOffsetC(src, scale, offset, dest, S_required);
1078 }
1079 Change(src, 17);
1080 if (dest->value != 1170)
1081 Error("Projection Test 1 failed!");
1082
1083 Change(dest, 1050);
1084 if (src->value != 5)
1085 Error("Projection Test 2 failed!");
1086
1087 Change(scale, 5);
1088 for (i = 1; i < List_Size(dests); ++i)
1089 if (((Variable)List_At(dests, i - 1))->value != i * 5 + 1000)
1090 Error("Projection Test 3 failed!");
1091
1092 Change(offset, 2000);
1093 for (i = 1; i < List_Size(dests); ++i)
1094 if (((Variable)List_At(dests, i - 1))->value != i * 5 + 2000)
1095 Error("Projection Test 4 failed!");
1096
1097 List_Destroy(dests);
1098 }
1099
1100 int run_deltablue(int n)
1101 {
1102 const int iterations= 1;
1103 int j;
1104 long msecs;
1105
1106 Start();
1107 for (j= 0; j < iterations; ++j) {
1108 ChainTest(n);
1109 ProjectionTest(n);
1110 }
1111 Finish(&msecs);
1112 /*printf("Total time for %d iterations of chain and projection tests: %ld ms\n ",
1113 iterations, msecs);
1114 printf("Average time per iteration: %g ms\n", (double)msecs / iteration s);*/
1115 return 0;
1116 }
OLDNEW
« no previous file with comments | « nacl/build.scons ('k') | nacl/richards.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698