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

Unified Diff: pkg/kernel/testcases/input/DeltaBlue.dart

Issue 2825063002: Move kernel baseline tests to front_end. (Closed)
Patch Set: Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/front_end/tool/fasta_perf.dart ('k') | pkg/kernel/testcases/input/argument.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/testcases/input/DeltaBlue.dart
diff --git a/pkg/kernel/testcases/input/DeltaBlue.dart b/pkg/kernel/testcases/input/DeltaBlue.dart
deleted file mode 100644
index 1b58f52f5e18b55881b197b0d7aa89e6fe51285c..0000000000000000000000000000000000000000
--- a/pkg/kernel/testcases/input/DeltaBlue.dart
+++ /dev/null
@@ -1,705 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-// Copyright 1996 John Maloney and Mario Wolczko
-//
-// This file is part of GNU Smalltalk.
-//
-// GNU Smalltalk is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2, or (at your option) any later version.
-//
-// GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-// details.
-//
-// You should have received a copy of the GNU General Public License along with
-// GNU Smalltalk; see the file COPYING. If not, write to the Free Software
-// Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// Translated first from Smalltalk to JavaScript, and finally to
-// Dart by Google 2008-2010.
-
-/**
- * A Dart implementation of the DeltaBlue constraint-solving
- * algorithm, as described in:
- *
- * "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver"
- * Bjorn N. Freeman-Benson and John Maloney
- * January 1990 Communications of the ACM,
- * also available as University of Washington TR 89-08-06.
- *
- * Beware: this benchmark is written in a grotesque style where
- * the constraint model is built by side-effects from constructors.
- * I've kept it this way to avoid deviating too much from the original
- * implementation.
- */
-
-main() {
- new DeltaBlue().run();
-}
-
-/// Benchmark class required to report results.
-class DeltaBlue {
- void run() {
- chainTest(100);
- projectionTest(100);
- }
-}
-
-/**
- * Strengths are used to measure the relative importance of constraints.
- * New strengths may be inserted in the strength hierarchy without
- * disrupting current constraints. Strengths cannot be created outside
- * this class, so == can be used for value comparison.
- */
-class Strength {
- final int value;
- final String name;
-
- const Strength(this.value, this.name);
-
- Strength nextWeaker() => const <Strength>[
- STRONG_PREFERRED,
- PREFERRED,
- STRONG_DEFAULT,
- NORMAL,
- WEAK_DEFAULT,
- WEAKEST
- ][value];
-
- static bool stronger(Strength s1, Strength s2) {
- return s1.value < s2.value;
- }
-
- static bool weaker(Strength s1, Strength s2) {
- return s1.value > s2.value;
- }
-
- static Strength weakest(Strength s1, Strength s2) {
- return weaker(s1, s2) ? s1 : s2;
- }
-
- static Strength strongest(Strength s1, Strength s2) {
- return stronger(s1, s2) ? s1 : s2;
- }
-}
-
-// Compile time computed constants.
-const REQUIRED = const Strength(0, "required");
-const STRONG_PREFERRED = const Strength(1, "strongPreferred");
-const PREFERRED = const Strength(2, "preferred");
-const STRONG_DEFAULT = const Strength(3, "strongDefault");
-const NORMAL = const Strength(4, "normal");
-const WEAK_DEFAULT = const Strength(5, "weakDefault");
-const WEAKEST = const Strength(6, "weakest");
-
-abstract class Constraint {
- final Strength strength;
-
- const Constraint(this.strength);
-
- bool isSatisfied();
- void markUnsatisfied();
- void addToGraph();
- void removeFromGraph();
- void chooseMethod(int mark);
- void markInputs(int mark);
- bool inputsKnown(int mark);
- Variable output();
- void execute();
- void recalculate();
-
- /// Activate this constraint and attempt to satisfy it.
- void addConstraint() {
- addToGraph();
- planner.incrementalAdd(this);
- }
-
- /**
- * Attempt to find a way to enforce this constraint. If successful,
- * record the solution, perhaps modifying the current dataflow
- * graph. Answer the constraint that this constraint overrides, if
- * there is one, or nil, if there isn't.
- * Assume: I am not already satisfied.
- */
- Constraint satisfy(mark) {
- chooseMethod(mark);
- if (!isSatisfied()) {
- if (strength == REQUIRED) {
- print("Could not satisfy a required constraint!");
- }
- return null;
- }
- markInputs(mark);
- Variable out = output();
- Constraint overridden = out.determinedBy;
- if (overridden != null) overridden.markUnsatisfied();
- out.determinedBy = this;
- if (!planner.addPropagate(this, mark)) print("Cycle encountered");
- out.mark = mark;
- return overridden;
- }
-
- void destroyConstraint() {
- if (isSatisfied()) planner.incrementalRemove(this);
- removeFromGraph();
- }
-
- /**
- * Normal constraints are not input constraints. An input constraint
- * is one that depends on external state, such as the mouse, the
- * keybord, a clock, or some arbitraty piece of imperative code.
- */
- bool isInput() => false;
-}
-
-/**
- * Abstract superclass for constraints having a single possible output variable.
- */
-abstract class UnaryConstraint extends Constraint {
- final Variable myOutput;
- bool satisfied = false;
-
- UnaryConstraint(this.myOutput, Strength strength) : super(strength) {
- addConstraint();
- }
-
- /// Adds this constraint to the constraint graph
- void addToGraph() {
- myOutput.addConstraint(this);
- satisfied = false;
- }
-
- /// Decides if this constraint can be satisfied and records that decision.
- void chooseMethod(int mark) {
- satisfied = (myOutput.mark != mark) &&
- Strength.stronger(strength, myOutput.walkStrength);
- }
-
- /// Returns true if this constraint is satisfied in the current solution.
- bool isSatisfied() => satisfied;
-
- void markInputs(int mark) {
- // has no inputs.
- }
-
- /// Returns the current output variable.
- Variable output() => myOutput;
-
- /**
- * Calculate the walkabout strength, the stay flag, and, if it is
- * 'stay', the value for the current output of this constraint. Assume
- * this constraint is satisfied.
- */
- void recalculate() {
- myOutput.walkStrength = strength;
- myOutput.stay = !isInput();
- if (myOutput.stay) execute(); // Stay optimization.
- }
-
- /// Records that this constraint is unsatisfied.
- void markUnsatisfied() {
- satisfied = false;
- }
-
- bool inputsKnown(int mark) => true;
-
- void removeFromGraph() {
- if (myOutput != null) myOutput.removeConstraint(this);
- satisfied = false;
- }
-}
-
-/**
- * Variables that should, with some level of preference, stay the same.
- * Planners may exploit the fact that instances, if satisfied, will not
- * change their output during plan execution. This is called "stay
- * optimization".
- */
-class StayConstraint extends UnaryConstraint {
- StayConstraint(Variable v, Strength str) : super(v, str);
-
- void execute() {
- // Stay constraints do nothing.
- }
-}
-
-/**
- * A unary input constraint used to mark a variable that the client
- * wishes to change.
- */
-class EditConstraint extends UnaryConstraint {
- EditConstraint(Variable v, Strength str) : super(v, str);
-
- /// Edits indicate that a variable is to be changed by imperative code.
- bool isInput() => true;
-
- void execute() {
- // Edit constraints do nothing.
- }
-}
-
-// Directions.
-const int NONE = 1;
-const int FORWARD = 2;
-const int BACKWARD = 0;
-
-/**
- * Abstract superclass for constraints having two possible output
- * variables.
- */
-abstract class BinaryConstraint extends Constraint {
- Variable v1;
- Variable v2;
- int direction = NONE;
-
- BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {
- addConstraint();
- }
-
- /**
- * Decides if this constraint can be satisfied and which way it
- * should flow based on the relative strength of the variables related,
- * and record that decision.
- */
- void chooseMethod(int mark) {
- if (v1.mark == mark) {
- direction =
- (v2.mark != mark && Strength.stronger(strength, v2.walkStrength))
- ? FORWARD
- : NONE;
- }
- if (v2.mark == mark) {
- direction =
- (v1.mark != mark && Strength.stronger(strength, v1.walkStrength))
- ? BACKWARD
- : NONE;
- }
- if (Strength.weaker(v1.walkStrength, v2.walkStrength)) {
- direction =
- Strength.stronger(strength, v1.walkStrength) ? BACKWARD : NONE;
- } else {
- direction =
- Strength.stronger(strength, v2.walkStrength) ? FORWARD : BACKWARD;
- }
- }
-
- /// Add this constraint to the constraint graph.
- void addToGraph() {
- v1.addConstraint(this);
- v2.addConstraint(this);
- direction = NONE;
- }
-
- /// Answer true if this constraint is satisfied in the current solution.
- bool isSatisfied() => direction != NONE;
-
- /// Mark the input variable with the given mark.
- void markInputs(int mark) {
- input().mark = mark;
- }
-
- /// Returns the current input variable
- Variable input() => direction == FORWARD ? v1 : v2;
-
- /// Returns the current output variable.
- Variable output() => direction == FORWARD ? v2 : v1;
-
- /**
- * Calculate the walkabout strength, the stay flag, and, if it is
- * 'stay', the value for the current output of this
- * constraint. Assume this constraint is satisfied.
- */
- void recalculate() {
- Variable ihn = input(), out = output();
- out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
- out.stay = ihn.stay;
- if (out.stay) execute();
- }
-
- /// Record the fact that this constraint is unsatisfied.
- void markUnsatisfied() {
- direction = NONE;
- }
-
- bool inputsKnown(int mark) {
- Variable i = input();
- return i.mark == mark || i.stay || i.determinedBy == null;
- }
-
- void removeFromGraph() {
- if (v1 != null) v1.removeConstraint(this);
- if (v2 != null) v2.removeConstraint(this);
- direction = NONE;
- }
-}
-
-/**
- * Relates two variables by the linear scaling relationship: "v2 =
- * (v1 * scale) + offset". Either v1 or v2 may be changed to maintain
- * this relationship but the scale factor and offset are considered
- * read-only.
- */
-
-class ScaleConstraint extends BinaryConstraint {
- final Variable scale;
- final Variable offset;
-
- ScaleConstraint(
- Variable src, this.scale, this.offset, Variable dest, Strength strength)
- : super(src, dest, strength);
-
- /// Adds this constraint to the constraint graph.
- void addToGraph() {
- super.addToGraph();
- scale.addConstraint(this);
- offset.addConstraint(this);
- }
-
- void removeFromGraph() {
- super.removeFromGraph();
- if (scale != null) scale.removeConstraint(this);
- if (offset != null) offset.removeConstraint(this);
- }
-
- void markInputs(int mark) {
- super.markInputs(mark);
- scale.mark = offset.mark = mark;
- }
-
- /// Enforce this constraint. Assume that it is satisfied.
- void execute() {
- if (direction == FORWARD) {
- v2.value = v1.value * scale.value + offset.value;
- } else {
- v1.value = (v2.value - offset.value) ~/ scale.value;
- }
- }
-
- /**
- * Calculate the walkabout strength, the stay flag, and, if it is
- * 'stay', the value for the current output of this constraint. Assume
- * this constraint is satisfied.
- */
- void recalculate() {
- Variable ihn = input(), out = output();
- out.walkStrength = Strength.weakest(strength, ihn.walkStrength);
- out.stay = ihn.stay && scale.stay && offset.stay;
- if (out.stay) execute();
- }
-}
-
-/**
- * Constrains two variables to have the same value.
- */
-class EqualityConstraint extends BinaryConstraint {
- EqualityConstraint(Variable v1, Variable v2, Strength strength)
- : super(v1, v2, strength);
-
- /// Enforce this constraint. Assume that it is satisfied.
- void execute() {
- output().value = input().value;
- }
-}
-
-/**
- * A constrained variable. In addition to its value, it maintain the
- * structure of the constraint graph, the current dataflow graph, and
- * various parameters of interest to the DeltaBlue incremental
- * constraint solver.
- **/
-class Variable {
- List<Constraint> constraints = <Constraint>[];
- Constraint determinedBy;
- int mark = 0;
- Strength walkStrength = WEAKEST;
- bool stay = true;
- int value;
- final String name;
-
- Variable(this.name, this.value);
-
- /**
- * Add the given constraint to the set of all constraints that refer
- * this variable.
- */
- void addConstraint(Constraint c) {
- constraints.add(c);
- }
-
- /// Removes all traces of c from this variable.
- void removeConstraint(Constraint c) {
- constraints.remove(c);
- if (determinedBy == c) determinedBy = null;
- }
-}
-
-class Planner {
- int currentMark = 0;
-
- /**
- * Attempt to satisfy the given constraint and, if successful,
- * incrementally update the dataflow graph. Details: If satifying
- * the constraint is successful, it may override a weaker constraint
- * on its output. The algorithm attempts to resatisfy that
- * constraint using some other method. This process is repeated
- * until either a) it reaches a variable that was not previously
- * determined by any constraint or b) it reaches a constraint that
- * is too weak to be satisfied using any of its methods. The
- * variables of constraints that have been processed are marked with
- * a unique mark value so that we know where we've been. This allows
- * the algorithm to avoid getting into an infinite loop even if the
- * constraint graph has an inadvertent cycle.
- */
- void incrementalAdd(Constraint c) {
- int mark = newMark();
- for (Constraint overridden = c.satisfy(mark);
- overridden != null;
- overridden = overridden.satisfy(mark));
- }
-
- /**
- * Entry point for retracting a constraint. Remove the given
- * constraint and incrementally update the dataflow graph.
- * Details: Retracting the given constraint may allow some currently
- * unsatisfiable downstream constraint to be satisfied. We therefore collect
- * a list of unsatisfied downstream constraints and attempt to
- * satisfy each one in turn. This list is traversed by constraint
- * strength, strongest first, as a heuristic for avoiding
- * unnecessarily adding and then overriding weak constraints.
- * Assume: [c] is satisfied.
- */
- void incrementalRemove(Constraint c) {
- Variable out = c.output();
- c.markUnsatisfied();
- c.removeFromGraph();
- List<Constraint> unsatisfied = removePropagateFrom(out);
- Strength strength = REQUIRED;
- do {
- for (int i = 0; i < unsatisfied.length; i++) {
- Constraint u = unsatisfied[i];
- if (u.strength == strength) incrementalAdd(u);
- }
- strength = strength.nextWeaker();
- } while (strength != WEAKEST);
- }
-
- /// Select a previously unused mark value.
- int newMark() => ++currentMark;
-
- /**
- * Extract a plan for resatisfaction starting from the given source
- * constraints, usually a set of input constraints. This method
- * assumes that stay optimization is desired; the plan will contain
- * only constraints whose output variables are not stay. Constraints
- * that do no computation, such as stay and edit constraints, are
- * not included in the plan.
- * Details: The outputs of a constraint are marked when it is added
- * to the plan under construction. A constraint may be appended to
- * the plan when all its input variables are known. A variable is
- * known if either a) the variable is marked (indicating that has
- * been computed by a constraint appearing earlier in the plan), b)
- * the variable is 'stay' (i.e. it is a constant at plan execution
- * time), or c) the variable is not determined by any
- * constraint. The last provision is for past states of history
- * variables, which are not stay but which are also not computed by
- * any constraint.
- * Assume: [sources] are all satisfied.
- */
- Plan makePlan(List<Constraint> sources) {
- int mark = newMark();
- Plan plan = new Plan();
- List<Constraint> todo = sources;
- while (todo.length > 0) {
- Constraint c = todo.removeLast();
- if (c.output().mark != mark && c.inputsKnown(mark)) {
- plan.addConstraint(c);
- c.output().mark = mark;
- addConstraintsConsumingTo(c.output(), todo);
- }
- }
- return plan;
- }
-
- /**
- * Extract a plan for resatisfying starting from the output of the
- * given [constraints], usually a set of input constraints.
- */
- Plan extractPlanFromConstraints(List<Constraint> constraints) {
- List<Constraint> sources = <Constraint>[];
- for (int i = 0; i < constraints.length; i++) {
- Constraint c = constraints[i];
- // if not in plan already and eligible for inclusion.
- if (c.isInput() && c.isSatisfied()) sources.add(c);
- }
- return makePlan(sources);
- }
-
- /**
- * Recompute the walkabout strengths and stay flags of all variables
- * downstream of the given constraint and recompute the actual
- * values of all variables whose stay flag is true. If a cycle is
- * detected, remove the given constraint and answer
- * false. Otherwise, answer true.
- * Details: Cycles are detected when a marked variable is
- * encountered downstream of the given constraint. The sender is
- * assumed to have marked the inputs of the given constraint with
- * the given mark. Thus, encountering a marked node downstream of
- * the output constraint means that there is a path from the
- * constraint's output to one of its inputs.
- */
- bool addPropagate(Constraint c, int mark) {
- List<Constraint> todo = <Constraint>[c];
- while (todo.length > 0) {
- Constraint d = todo.removeLast();
- if (d.output().mark == mark) {
- incrementalRemove(c);
- return false;
- }
- d.recalculate();
- addConstraintsConsumingTo(d.output(), todo);
- }
- return true;
- }
-
- /**
- * Update the walkabout strengths and stay flags of all variables
- * downstream of the given constraint. Answer a collection of
- * unsatisfied constraints sorted in order of decreasing strength.
- */
- List<Constraint> removePropagateFrom(Variable out) {
- out.determinedBy = null;
- out.walkStrength = WEAKEST;
- out.stay = true;
- List<Constraint> unsatisfied = <Constraint>[];
- List<Variable> todo = <Variable>[out];
- while (todo.length > 0) {
- Variable v = todo.removeLast();
- for (int i = 0; i < v.constraints.length; i++) {
- Constraint c = v.constraints[i];
- if (!c.isSatisfied()) unsatisfied.add(c);
- }
- Constraint determining = v.determinedBy;
- for (int i = 0; i < v.constraints.length; i++) {
- Constraint next = v.constraints[i];
- if (next != determining && next.isSatisfied()) {
- next.recalculate();
- todo.add(next.output());
- }
- }
- }
- return unsatisfied;
- }
-
- void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {
- Constraint determining = v.determinedBy;
- for (int i = 0; i < v.constraints.length; i++) {
- Constraint c = v.constraints[i];
- if (c != determining && c.isSatisfied()) coll.add(c);
- }
- }
-}
-
-/**
- * A Plan is an ordered list of constraints to be executed in sequence
- * to resatisfy all currently satisfiable constraints in the face of
- * one or more changing inputs.
- */
-class Plan {
- List<Constraint> list = <Constraint>[];
-
- void addConstraint(Constraint c) {
- list.add(c);
- }
-
- int size() => list.length;
-
- void execute() {
- for (int i = 0; i < list.length; i++) {
- list[i].execute();
- }
- }
-}
-
-/**
- * This is the standard DeltaBlue benchmark. A long chain of equality
- * constraints is constructed with a stay constraint on one end. An
- * edit constraint is then added to the opposite end and the time is
- * measured for adding and removing this constraint, and extracting
- * and executing a constraint satisfaction plan. There are two cases.
- * In case 1, the added constraint is stronger than the stay
- * constraint and values must propagate down the entire length of the
- * chain. In case 2, the added constraint is weaker than the stay
- * constraint so it cannot be accomodated. The cost in this case is,
- * of course, very low. Typical situations lie somewhere between these
- * two extremes.
- */
-void chainTest(int n) {
- planner = new Planner();
- Variable prev = null, first = null, last = null;
- // Build chain of n equality constraints.
- for (int i = 0; i <= n; i++) {
- Variable v = new Variable("v$i", 0);
- if (prev != null) new EqualityConstraint(prev, v, REQUIRED);
- if (i == 0) first = v;
- if (i == n) last = v;
- prev = v;
- }
- new StayConstraint(last, STRONG_DEFAULT);
- EditConstraint edit = new EditConstraint(first, PREFERRED);
- Plan plan = planner.extractPlanFromConstraints(<Constraint>[edit]);
- for (int i = 0; i < 100; i++) {
- first.value = i;
- plan.execute();
- if (last.value != i) {
- print("Chain test failed:");
- print("Expected last value to be $i but it was ${last.value}.");
- }
- }
-}
-
-/**
- * This test constructs a two sets of variables related to each
- * other by a simple linear transformation (scale and offset). The
- * time is measured to change a variable on either side of the
- * mapping and to change the scale and offset factors.
- */
-void projectionTest(int n) {
- planner = new Planner();
- Variable scale = new Variable("scale", 10);
- Variable offset = new Variable("offset", 1000);
- Variable src = null, dst = null;
-
- List<Variable> dests = <Variable>[];
- for (int i = 0; i < n; i++) {
- src = new Variable("src", i);
- dst = new Variable("dst", i);
- dests.add(dst);
- new StayConstraint(src, NORMAL);
- new ScaleConstraint(src, scale, offset, dst, REQUIRED);
- }
- change(src, 17);
- if (dst.value != 1170) print("Projection 1 failed");
- change(dst, 1050);
- if (src.value != 5) print("Projection 2 failed");
- change(scale, 5);
- for (int i = 0; i < n - 1; i++) {
- if (dests[i].value != i * 5 + 1000) print("Projection 3 failed");
- }
- change(offset, 2000);
- for (int i = 0; i < n - 1; i++) {
- if (dests[i].value != i * 5 + 2000) print("Projection 4 failed");
- }
-}
-
-void change(Variable v, int newValue) {
- EditConstraint edit = new EditConstraint(v, PREFERRED);
- Plan plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]);
- for (int i = 0; i < 10; i++) {
- v.value = newValue;
- plan.execute();
- }
- edit.destroyConstraint();
-}
-
-Planner planner;
« no previous file with comments | « pkg/front_end/tool/fasta_perf.dart ('k') | pkg/kernel/testcases/input/argument.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698