Adding sypet to repo
[Benchmarks_CSolver.git] / sypet / src / edu / utexas / sypet / Experiment.java
diff --git a/sypet/src/edu/utexas/sypet/Experiment.java b/sypet/src/edu/utexas/sypet/Experiment.java
new file mode 100644 (file)
index 0000000..11bf052
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2017 The SyPet Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.utexas.sypet;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import com.google.gson.Gson;
+
+import edu.utexas.sypet.synthesis.PathFinder;
+import edu.utexas.sypet.synthesis.Sketcher;
+import edu.utexas.sypet.synthesis.SypetTestUtil;
+import edu.utexas.sypet.synthesis.model.Benchmark;
+import edu.utexas.sypet.synthesis.model.Pair;
+import edu.utexas.sypet.synthesis.sat4j.PetrinetEncoding.Option;
+import edu.utexas.sypet.util.SootUtil;
+import edu.utexas.sypet.util.TimeUtil;
+import polyglot.ext.jl.types.PlaceHolder_c;
+import soot.CompilationDeathException;
+import soot.Scene;
+import soot.options.Options;
+import uniol.apt.adt.pn.PetriNet;
+import uniol.apt.adt.pn.Place;
+import uniol.apt.adt.pn.Transition;
+
+// Status: ?
+/**
+ * Parametric framework for running benchmarks
+ *
+ */
+public class Experiment {
+       public static boolean VERBOSE = false;
+       public static String benchLoc = null;
+       public static long TIMEOUT = 600000;
+
+       public static final int maxTokens = 10;
+
+       public static Option objectiveOption = Option.AT_LEAST_ONE;
+       public static int maxIterations = 5;
+
+       public static List<String> clones;
+
+       public static PathFinder initPetriNet(Benchmark qb, List<PetriNet> pNetList, int pn, int local) {
+
+               if (pNetList.size() == 1) {
+                       pn = 0;
+               }
+
+               PetriNet pNet = pNetList.get(pn);
+
+               System.out.println("PetriNet for path length: " + local + " [places: " + pNet.getPlaces().size()
+                               + " ; transitions: " + pNet.getTransitions().size() + " ; edges: " + pNet.getEdges().size() + "]");
+
+               List<Place> inits = new ArrayList<>();
+               List<Pair<String, String>> vars = new ArrayList<>();
+               int index = 0;
+               for (String src : qb.getSrcTypes()) {
+                       Place srcPlace = pNet.getPlace(src);
+                       inits.add(srcPlace);
+                       String varName = qb.getParamNames().get(index);
+                       Pair<String, String> arg = new Pair<>(src, varName);
+                       vars.add(arg);
+                       index++;
+               }
+               // adding void to initial marking.
+               inits.add(pNet.getPlace("void"));
+               // tgt place.
+               String tgt = qb.getTgtType();
+               Place tgtPlace = pNet.getPlace(tgt);
+
+               PathFinder pf = new PathFinder(pNet, inits, tgtPlace, local, maxTokens, clones, objectiveOption, maxIterations);
+               pf.setVars(vars);
+               pf.setTgt(tgt);
+               return pf;
+
+       }
+
+       public static void main(String[] args) throws FileNotFoundException {
+               long startSoot = System.nanoTime();
+               int roundRobinPosition = 0;
+               int roundRobinIterations = 0;
+               int roundRobinIterationsLimit = 40;
+               int roundRobinRange = 3;
+               boolean roundRobinFlag = true;
+
+               Cli cmdOptions = new Cli(args);
+               cmdOptions.parse();
+
+               VERBOSE = cmdOptions.getVerbose();
+               TIMEOUT = cmdOptions.getTimeout();
+               roundRobinFlag = cmdOptions.getRoundRobin();
+               // The objective function can be used to add preferences over which
+               // methods to explore
+               objectiveOption = objectiveOption.AT_LEAST_ONE;
+               maxIterations = cmdOptions.getSolverLimit();
+
+               cmdOptions.printOptions();
+
+               benchLoc = cmdOptions.getFilename();
+               if (!new File(benchLoc).exists()) {
+                       System.out.println("Cannot find json file: " + benchLoc);
+                       System.exit(2);
+               }
+
+               double timeGetPath = 0;
+               double timeInitSketch = 0;
+               double timeFillHoles = 0;
+               double timeCompilation = 0;
+               double timeRunTest = 0;
+               double timeTotal = 0;
+               long cntFillHoles = 0;
+               Gson gson = new Gson();
+               BufferedReader br;
+               try {
+                       br = new BufferedReader(new FileReader(benchLoc));
+                       Benchmark qb = gson.fromJson(br, Benchmark.class);
+                       // generate the method header
+                       qb.setMethodHeader(genMethodHeader(qb));
+                       // generate the test string
+                       qb.setTestBody(genTest(qb));
+
+                       /////////////////////////////////////////////////////////////////////////////////
+                       System.out.println("----------" + benchLoc);
+                       System.out.println("Benchmark Id: " + qb.getId());
+                       System.out.println("Method name: " + qb.getMethodName());
+                       System.out.println("Packages: " + qb.getPackages());
+                       System.out.println("Libraries: " + qb.getLibs());
+                       System.out.println("Source type(s): " + qb.getSrcTypes());
+                       System.out.println("Target type: " + qb.getTgtType());
+                       System.out.println("--------------------------------------------------------");
+
+                       ///////////////////////////////////////////////////
+                       Set<String> pkgs = qb.getPackages();
+                       String keyword = qb.getMethodName();
+
+                       StringBuilder options = new StringBuilder();
+                       options.append("-prepend-classpath");
+                       options.append(" -full-resolver");
+                       options.append(" -allow-phantom-refs");
+                       StringBuilder cp = new StringBuilder();
+                       for (String lib : qb.getLibs()) {
+                               cp.append(lib);
+                               cp.append(":");
+                               options.append(" -process-dir " + lib);
+                       }
+
+                       options.append(" -cp " + cp.toString());
+
+                       if (!Options.v().parse(options.toString().split(" ")))
+                               throw new CompilationDeathException(CompilationDeathException.COMPILATION_ABORTED,
+                                               "Option parse error");
+
+                       Scene.v().loadBasicClasses();
+                       Scene.v().loadNecessaryClasses();
+
+                       List<PetriNet> pNetList = new ArrayList<>();
+
+                       // SootUtil.genDepGraph(qb.getLibs(), pkgs, qb.getTgtType());
+                       // FIXME: get lower bound. Will place with shortest path.
+                       // int low = Math.max(1, SootUtil.getLowerBound(qb));
+                       int low = 1;
+
+                       PetriNet pNet = new PetriNet();
+                       // only one petrinet without pruning.
+                       for (String lib : qb.getLibs()) {
+                               SootUtil.processJar(lib, pkgs, pNet);
+                       }
+                       SootUtil.handlePolymorphism(pNet);
+                       System.out.println("#Classes: " + SootUtil.classNum);
+                       System.out.println("#Methods: " + SootUtil.methodNum);
+                       long endSoot = System.nanoTime();
+                       double sootTime = TimeUtil.computeTime(startSoot, endSoot);
+                       System.out.println("Soot Time: " + sootTime);
+                       pNetList.add(pNet);
+
+                       // Multiple args: check if we need put clone as initial constraints.
+                       clones = SootUtil.getClones(qb.getSrcTypes());
+
+                       int petriIterator = 0;
+
+                       // System.out.println("Petri nets: " + pNetList.size());
+
+                       int cnt = 0;
+                       // int localMax = 1 + clones.size();
+                       // System.out.println("Lower bound: " + low);
+                       int localMax = low;
+                       boolean flag = false;
+                       long start0 = System.nanoTime();
+
+                       assert (roundRobinRange < 7);
+                       ArrayList<PathFinder> roundRobin = new ArrayList<>();
+                       if (roundRobinFlag) {
+                               for (int i = 0; i < roundRobinRange; i++) {
+                                       roundRobin.add(initPetriNet(qb, pNetList, petriIterator++, localMax++));
+                               }
+                       }
+
+                       while (!flag) {
+                               PathFinder pf;
+                               if (roundRobinFlag) {
+                                       pf = roundRobin.get(roundRobinPosition);
+                                       // if (VERBOSE)
+                                       // System.out.println("Searching with local max: " +
+                                       // pf.getEncoding().getTimeline());
+                               } else {
+                                       // pf = new PathFinder(pNet, inits, tgtPlace, localMax,
+                                       // maxTokens, nlplist, clones,
+                                       // objectiveOption, maxIterations);
+                                       if (pNetList.size() > 1)
+                                               assert (petriIterator < pNetList.size());
+                                       pf = initPetriNet(qb, pNetList, petriIterator++, localMax);
+                               }
+
+                               if (VERBOSE && !roundRobinFlag)
+                                       System.out.println("Searching with local max: " + localMax);
+                               while (roundRobinIterations < roundRobinIterationsLimit || !roundRobinFlag) {
+                                       long start1 = System.nanoTime();
+                                       List<String> res = pf.get();
+                                       long end1 = System.nanoTime();
+                                       timeGetPath += TimeUtil.computeTime(start1, end1);
+                                       if (VERBOSE)
+                                               TimeUtil.reportTime(start1, end1, "get path: ");
+                                       if (VERBOSE)
+                                               System.out.println("call SAT." + cnt + " val: " + res);
+
+                                       if (res.isEmpty())
+                                               break;
+
+                                       cnt++;
+
+                                       List<String> solution = new ArrayList<>();
+                                       for (String meth : res) {
+                                               if (meth.startsWith("sypet_clone_"))
+                                                       continue;
+
+                                               solution.add(meth);
+                                       }
+                                       // System.out.println("current sketch:" + res);
+                                       // init sketcher.
+                                       long start2 = System.nanoTime();
+                                       Sketcher sk = new Sketcher(solution, pf.getVars(), pf.getTgt());
+                                       boolean hasSketch = sk.initSketch();
+                                       long end2 = System.nanoTime();
+                                       timeInitSketch += TimeUtil.computeTime(start2, end2);
+                                       if (VERBOSE)
+                                               System.out.println("#holes: " + sk.getHolesNum());
+                                       if (VERBOSE)
+                                               TimeUtil.reportTime(start2, end2, "init sketch: ");
+                                       while (true) {
+                                               ++cntFillHoles;
+                                               long start3 = System.nanoTime();
+                                               String snippet = sk.fillHoles();
+                                               long end3 = System.nanoTime();
+                                               timeFillHoles += TimeUtil.computeTime(start3, end3);
+                                               if (VERBOSE)
+                                                       TimeUtil.reportTime(start3, end3, "fill hole: ");
+                                               if (snippet.equals("UNSAT"))
+                                                       break;
+
+                                               // invoke yuepeng's method.
+                                               if (VERBOSE)
+                                                       System.out.println("snippet:" + snippet);
+                                               qb.setBody(snippet);
+                                               boolean passTest = SypetTestUtil.runTest(qb);
+                                               timeCompilation += SypetTestUtil.getCompilationTime();
+                                               timeRunTest += SypetTestUtil.getRunningTime();
+                                               if (VERBOSE)
+                                                       System.out.println("Test result-------------" + passTest);
+                                               if (VERBOSE)
+                                                       System.out.println("Compilation Time: " + SypetTestUtil.getCompilationTime());
+                                               if (VERBOSE)
+                                                       System.out.println("Running Time: " + SypetTestUtil.getRunningTime());
+                                               long end0 = System.nanoTime();
+                                               // note: this should be = instead of +=
+                                               timeTotal = TimeUtil.computeTime(start0, end0);
+                                               if (passTest) {
+                                                       System.out.println("=========Statistics (time in milliseconds)=========");
+                                                       System.out.println("Benchmark Id: " + qb.getId());
+                                                       System.out.println("Sketch Generation Time: " + timeGetPath);
+                                                       System.out.println("Sketch Completion Time: " + (timeInitSketch + timeFillHoles));
+                                                       System.out.println("Compilation Time: " + timeCompilation);
+                                                       System.out.println("Running Test cases Time: " + timeRunTest);
+                                                       System.out.println(
+                                                                       "Synthesis Time: " + (timeGetPath + timeInitSketch + timeFillHoles + timeRunTest));
+                                                       System.out.println("Total Time: "
+                                                                       + (timeGetPath + timeInitSketch + timeFillHoles + timeRunTest + timeCompilation));
+                                                       System.out.println("Number of components: " + res.size());
+                                                       System.out.println("Number of holes: " + sk.getHolesNum());
+                                                       System.out.println("Number of completed programs: " + cntFillHoles);
+                                                       System.out.println("Number of sketches: " + cnt);
+                                                       System.out.println("Solution:\n " + snippet.replace(";", ";\n "));
+
+                                                       System.out.println("============================");
+                                                       br.close();
+                                                       return;
+                                               } else if (timeTotal > TIMEOUT) {
+                                                       System.out.println("=========Statistics=========");
+                                                       System.out.println("Benchmark Id: " + qb.getId());
+                                                       System.out.println("Sketch Generation Time: " + timeGetPath);
+                                                       System.out.println("Sketch Completion Time: " + (timeInitSketch + timeFillHoles));
+                                                       System.out.println("Compilation Time: " + timeCompilation);
+                                                       System.out.println("Running Test cases Time: " + timeRunTest);
+                                                       System.out.println("Number of completed programs: " + cntFillHoles);
+                                                       System.out.println("Number of sketches: " + cnt);
+                                                       System.out.println("TIMEOUT after " + TIMEOUT + " ms");
+                                                       System.out.println("============================");
+                                                       br.close();
+                                                       return;
+                                               }
+                                       }
+                                       roundRobinIterations++;
+                               }
+                               if (roundRobinFlag) {
+                                       if (roundRobinIterations != roundRobinIterationsLimit) {
+                                               if (pNetList.size() > 1)
+                                                       assert (petriIterator < pNetList.size());
+                                               roundRobin.set(roundRobinPosition, initPetriNet(qb, pNetList, petriIterator++, localMax++));
+                                       }
+                                       roundRobinPosition = (roundRobinPosition + 1) % roundRobin.size();
+                                       roundRobinIterations = 0;
+                               } else {
+                                       localMax++;
+                               }
+                       }
+               } catch (CompilationDeathException e) {
+                       e.printStackTrace();
+                       if (e.getStatus() != CompilationDeathException.COMPILATION_SUCCEEDED)
+                               throw e;
+                       else
+                               return;
+               } catch (IOException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+
+       }
+
+       protected static String genMethodHeader(Benchmark bench) {
+               StringBuilder builder = new StringBuilder();
+               builder.append(bench.getTgtType().replaceAll("\\$", ".")).append(' ');
+               builder.append(bench.getMethodName()).append('(');
+               ArrayList<String> paramTypes = new ArrayList<String>(bench.getSrcTypes());
+               ArrayList<String> paramNames = new ArrayList<String>(bench.getParamNames());
+               assert paramTypes.size() == paramNames.size();
+               for (int i = 0; i < paramTypes.size(); ++i) {
+                       builder.append(paramTypes.get(i)).append(' ').append(paramNames.get(i));
+                       if (i < paramTypes.size() - 1) {
+                               builder.append(", ");
+                       }
+               }
+               builder.append(')');
+               return builder.toString();
+       }
+
+       protected static String genTest(Benchmark bench) {
+               StringBuilder builder = new StringBuilder();
+               try {
+                       BufferedReader reader = new BufferedReader(new FileReader(bench.getTestPath()));
+                       String line = null;
+                       while ((line = reader.readLine()) != null) {
+                               builder.append(line);
+                       }
+                       reader.close();
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+               return builder.toString();
+       }
+}