예제 #1
0
  /**
   * generate the switch code for 1 data item given the list of destinations we do not want to
   * duplicate items until neccessary, so we have to keep track of all the routes and then generate
   * the switch code this way we can route multiple dests per route instruction
   */
  protected void generateSwitchCode(FlatNode fire, List<FlatNode> dests) {
    assert !(layout.getIdentities().contains(fire));

    // should only have one previous
    HashMap<ComputeNode, ComputeNode> prev = new HashMap<ComputeNode, ComputeNode>();
    HashMap<ComputeNode, HashSet> next = new HashMap<ComputeNode, HashSet>();

    ListIterator<FlatNode> destsIt = dests.listIterator();
    while (destsIt.hasNext()) {
      FlatNode dest = destsIt.next();
      assert dest != null;
      assert !(layout.getIdentities().contains(dest));
      //  System.out.println("  Dest: " + dest + " " + layout.getTile(dest));
      ComputeNode[] hops =
          layout
              .router
              .getRoute(ssg, layout.getComputeNode(fire), layout.getComputeNode(dest))
              .toArray(new ComputeNode[0]);

      assert hops.length > 1
          : "Error: Bad Layout (could not find route from "
              + fire.toString()
              + " -> "
              + dest.toString();

      // for (int i = 0; i < hops.length; i++)
      //      System.out.println("     " + hops[i]);

      // add to fire's next
      if (!next.containsKey(layout.getComputeNode(fire)))
        next.put(layout.getComputeNode(fire), new HashSet());
      next.get(layout.getComputeNode(fire)).add(hops[1]);
      // add to all other previous, next
      for (int i = 1; i < hops.length - 1; i++) {
        if (prev.containsKey(hops[i]))
          if (prev.get(hops[i]) != hops[i - 1])
            Utils.fail("More than one previous tile for a single data item");
        prev.put(hops[i], hops[i - 1]);
        if (!next.containsKey(hops[i])) next.put(hops[i], new HashSet());
        next.get(hops[i]).add(hops[i + 1]);
      }
      // add the last step, plus the dest to the dest map
      if (prev.containsKey(hops[hops.length - 1]))
        if (prev.get(hops[hops.length - 1]) != hops[hops.length - 2])
          Utils.fail("More than one previous tile for a single data item (2)");
      prev.put(hops[hops.length - 1], hops[hops.length - 2]);
      if (!next.containsKey(hops[hops.length - 1])) next.put(hops[hops.length - 1], new HashSet());
      next.get(hops[hops.length - 1]).add(hops[hops.length - 1]);
    }

    // create the appropriate amount of routing instructions
    int elements = Util.getTypeSize(CommonUtils.getOutputType(fire));
    for (int i = 0; i < elements; i++) asm(layout.getComputeNode(fire), prev, next);
  }
예제 #2
0
 public static SIRJoiner create(SIRContainer parent, SIRJoinType type, JExpression[] weights) {
   if (type == SIRJoinType.NULL) {
     return new SIRJoiner(parent, type, Utils.initLiteralArray(weights.length, 0), true);
   } else if (type == SIRJoinType.WEIGHTED_RR) {
     return createWeightedRR(parent, weights);
   } else if (type == SIRJoinType.ROUND_ROBIN) {
     JExpression weight = (weights.length > 0 ? weights[0] : new JIntLiteral(1));
     return createUniformRR(parent, weight);
   } else {
     Utils.fail("Unrecognized joiner type.");
     return null;
   }
 }
예제 #3
0
  /** consume the data and return the number of items produced * */
  protected int fireMe(
      FlatNode fire, SimulationCounter counters, HashMap<FlatNode, Integer> executionCounts) {
    if (fire.contents instanceof SIRFilter) {
      // decrement the schedule execution counter
      decrementExecutionCounts(fire, executionCounts, counters);

      // consume the date from the buffer
      counters.decrementBufferCount(fire, consumedItems(fire, counters, executionCounts));

      // for a steady state execution return the normal push
      int ret = ((SIRFilter) fire.contents).getPushInt();

      // if the filter is a two stage, and it has not fired
      // return the initPush() unless the initWork does nothing
      if (initSimulation && !counters.hasFired(fire) && fire.contents instanceof SIRTwoStageFilter)
        ret = ((SIRTwoStageFilter) fire.contents).getInitPushInt();
      else if (!initSimulation && KjcOptions.ratematch) {
        // we are ratematching so produce all the data on the one firing.
        ret *= ssg.getMult(fire, false);
      }
      // now this node has fired
      counters.setFired(fire);
      return ret;
    } else if (fire.contents instanceof SIRJoiner) {
      return fireJoiner(fire, counters, executionCounts);
    }

    Utils.fail("Trying to fire a non-filter or joiner");
    return -1;
  }
예제 #4
0
 /**
  * Tests whether or not this has the same type and the same weights as obj. This can return true
  * for splitters with different numbers of outputs if the type is not a weighted round robin.
  */
 public boolean equals(SIRJoiner obj) {
   if (type != SIRJoinType.WEIGHTED_RR || obj.type != SIRJoinType.WEIGHTED_RR) {
     return type == obj.type;
   } else {
     return Utils.equalArrays(getWeights(), obj.getWeights());
   }
 }
예제 #5
0
 /** Constructs a joiner with given parent, type and n number of inputs. */
 public static SIRJoiner create(SIRContainer parent, SIRJoinType type, int n) {
   if (type == SIRJoinType.COMBINE) {
     // fill weights with 1
     return new SIRJoiner(parent, type, Utils.initLiteralArray(n, 1), true);
   } else if (type == SIRJoinType.NULL) {
     // for null type, fill with zero weights
     return new SIRJoiner(parent, type, Utils.initLiteralArray(n, 0), true);
   } else if (type == SIRJoinType.WEIGHTED_RR) {
     // if making a weighted round robin, should use other constructor
     Utils.fail("Need to specify weights for weighted round robin");
     return null;
   } else if (type == SIRJoinType.ROUND_ROBIN) {
     // if making a round robin, should use other constructor
     Utils.fail("Need to specify weight for uniform round robin");
     return null;
   } else {
     Utils.fail("Unreckognized joiner type.");
     return null;
   }
 }
예제 #6
0
  /** Give that a node has just fired, update the simulation state * */
  protected void decrementExecutionCounts(
      FlatNode fire, HashMap<FlatNode, Integer> executionCounts, SimulationCounter counters) {
    // decrement one from the execution count
    int oldVal = executionCounts.get(fire).intValue();
    if (oldVal - 1 < 0) Utils.fail("Executed too much");

    // if we are ratematching the node only fires once but only do this
    // for filters
    if (!initSimulation && KjcOptions.ratematch && fire.contents instanceof SIRFilter) {
      executionCounts.put(fire, new Integer(0));
    } else executionCounts.put(fire, new Integer(oldVal - 1));
  }
예제 #7
0
  protected SIRStream doCut(
      LinkedList<PartitionRecord> partitions,
      PartitionRecord curPartition,
      int x1,
      int x2,
      int xPivot,
      int tileLimit,
      int tPivot,
      SIRStream str) {
    // there's a division at this <yPivot>.  We'll
    // return result of a horizontal cut.
    int[] arr = {1 + (xPivot - x1), x2 - xPivot};
    PartitionGroup pg = PartitionGroup.createFromArray(arr);

    SIRContainer result;
    // might have either pipeline or feedback loop at this point...
    if (str instanceof SIRPipeline) {
      result = RefactorPipeline.addHierarchicalChildren((SIRPipeline) str, pg);
    } else if (str instanceof SIRFeedbackLoop) {
      // if we have a feedbackloop, then factored is
      // just the original, since it will have only
      // two children
      result = (SIRContainer) str;
    } else {
      result = null;
      Utils.fail("Unrecognized stream type: " + str);
    }

    // recurse up and down
    SIRStream top = traceback(partitions, curPartition, x1, xPivot, tPivot, result.get(0));
    // mark that we have a partition here
    curPartition = new PartitionRecord();
    partitions.add(curPartition);
    SIRStream bot =
        traceback(partitions, curPartition, xPivot + 1, x2, tileLimit - tPivot, result.get(1));

    // mutate ourselves if we haven't been mutated yet
    result.set(0, top);
    result.set(1, bot);

    // all done
    return result;
  }
예제 #8
0
 /** Throws an exception (NOT SUPPORTED YET) */
 public JExpression analyse(CExpressionContext context) throws PositionedError {
   at.dms.util.Utils.fail("Analysis of SIR nodes not supported yet.");
   return this;
 }
예제 #9
0
 /*
  * Generates JVM bytecode to evaluate this expression.  NOT SUPPORTED YET.
  *
  * @param   code        the bytecode sequence
  * @param   discardValue    discard the result of the evaluation ?
  */
 public void genCode(CodeSequence code, boolean discardValue) {
   at.dms.util.Utils.fail("Codegen of SIR nodes not supported yet.");
 }
예제 #10
0
 /** This is for creating a round robin with uniform weights across the stream. */
 public static SIRJoiner createUniformRR(SIRContainer parent, JExpression weight) {
   // make a uniform rr joiner
   return new SIRJoiner(
       parent, SIRJoinType.WEIGHTED_RR, Utils.initArray(Math.max(parent.size(), 1), weight), true);
 }
예제 #11
0
 /**
  * Constructs a weighted round-robin joiner with the given parent and weights. Here the number of
  * weights must match the number of weights in the splitjoin.
  */
 public static SIRJoiner createWeightedRR(SIRContainer parent, JExpression[] weights) {
   return new SIRJoiner(parent, SIRJoinType.WEIGHTED_RR, weights, Utils.isUniform(weights));
 }
예제 #12
0
 /**
  * If this is a joiner that has equal weight per way, then rescale the weights to be of the given
  * <extent>
  */
 public void rescale(int extent) {
   if (uniform) {
     this.weights = Utils.initArray(extent, weights[0]);
   }
 }
예제 #13
0
 /** Generates a sequence of bytescodes - NOT SUPPORTED YET. */
 public void genCode(CodeSequence code) {
   at.dms.util.Utils.fail("Codegen of SIR nodes not supported yet.");
 }
예제 #14
0
 /** Analyses the statement (semantically) - NOT SUPPORTED YET. */
 public void analyse(CBodyContext context) throws PositionedError {
   at.dms.util.Utils.fail("Analysis of SIR nodes not supported yet.");
 }
예제 #15
0
  /*
   * File reader code currently works by using fread.
   *
   * The File* is declared outside any function / method.
   *
   * This code follows the model in the library of stalling (not pushing)
   * at end of file (detected by fread returning 0).
   *
   */
  private static void genFileReaderWork(
      SIRFileReader filter, Tape outputTape, int selfID, CodegenPrintWriter p) {

    if (KjcOptions.asciifileio) {
      System.err.println("Error: -asciifileio not supported in cluster backend.");
      System.err.println("Exiting...");
      System.exit(1);
    }

    String theType = "" + filter.getOutputType();
    // dispatch to special routine for bit type
    if (theType.equals("bit")) {
      genFileReaderWorkBit(filter, outputTape, selfID, p);
      return;
    }

    // get source and destination ids of outgoing tape
    Tape out = RegisterStreams.getFilterOutStream(filter);
    int s = out.getSource();
    int d = out.getDest();

    // template code to generate, using symbolic free vars above.
    StringBuilder sb = new StringBuilder();
    sb.append("\n  int __index;\n");
    sb.append("  for (__index=0; __index < ____n; __index++) {\n");
    if (KjcOptions.compressed) {
      sb.append("    unsigned char __temp = 0;\n");
      sb.append("    FileReader_read(__file_descr__");
      sb.append(selfID);
      sb.append(", &__temp, 1);\n");
      sb.append("    PUSH(__temp);\n");
      sb.append("    unsigned int __frame_size = __temp;\n");

      sb.append("    FileReader_read(__file_descr__");
      sb.append(selfID);
      sb.append(", &__temp, 1);\n");
      sb.append("    PUSH(__temp);\n");
      sb.append("    __frame_size <<= 8;\n");
      sb.append("    __frame_size += __temp;\n");

      sb.append("    FileReader_read(__file_descr__");
      sb.append(selfID);
      sb.append(", &__temp, 1);\n");
      sb.append("    PUSH(__temp);\n");
      sb.append("    __frame_size <<= 8;\n");
      sb.append("    __frame_size += __temp;\n");

      sb.append("    FileReader_read(__file_descr__");
      sb.append(selfID);
      sb.append(", &__temp, 1);\n");
      sb.append("    PUSH(__temp);\n");
      sb.append("    __frame_size <<= 8;\n");
      sb.append("    __frame_size += __temp;\n");

      // the frame size includes the four bytes used to state the frame size
      sb.append("    FileReader_read(__file_descr__");
      sb.append(selfID);
      sb.append(", (void *)(BUFFER + HEAD), __frame_size - 4);\n");
      sb.append("    HEAD += __frame_size - 4;\n");
    } else {
      sb.append("    PUSH(FileReader_read<");
      sb.append(theType);
      sb.append(">(__file_descr__");
      sb.append(selfID);
      sb.append("));\n");
    }
    sb.append("  }\n");

    String template = sb.toString();

    /*
               "  #ifdef FUSED" + "\n" +
               "    #ifdef NOMOD" + "\n" +
               "      // read directly into buffer" + "\n" +
               "      if (fread(&(BUFFER[HEAD]), sizeof(BUFFER[HEAD]), ____n, FILEREADER)) {" + "\n" +
               "        HEAD+=____n;" + "\n" +
               "      }" + "\n" +
               "    #else" + "\n" +
               "      // wraparound buffer, might have to read in two pieces (but never" + "\n" +
               "      // more, since we would overwrote what we already wrote on this call)" + "\n" +
               "      if (HEAD+____n <= __BUF_SIZE_MASK) {" + "\n" +
               "          // no overflow" + "\n" +
               "          if (fread(&(BUFFER[HEAD]), sizeof(BUFFER[HEAD]), ____n, FILEREADER)) {" + "\n" +
               "             HEAD+=____n;" + "\n" +
               "          }" + "\n" +
               "      } else {" + "\n" +
               "          // overflow, need two pieces" + "\n" +
               "          int piece1 = __BUF_SIZE_MASK - HEAD;" + "\n" +
               "          int piece2 = ____n - piece1;" + "\n" +
               "          if (fread(&(BUFFER[HEAD]), sizeof(BUFFER[HEAD]), piece1, FILEREADER)) {" + "\n" +
               "              if (fread(&(BUFFER[0]), sizeof(BUFFER[HEAD]), piece2, FILEREADER)) {" + "\n" +
               "                HEAD+=____n;" + "\n" +
               "                HEAD&=__BUF_SIZE_MASK;" + "\n" +
               "              }" + "\n" +
               "          }" + "\n" +
               "      }" + "\n" +
               "     #endif" + "\n" +
               "  #else" + "\n" +
               "    // read as a block" + "\n" +
               "    TYPE __buffer[____n];" + "\n" +
               "    int __index;" + "\n" +
               "    if (fread(__buffer, sizeof(__buffer[0]), ____n, FILEREADER)) {" + "\n" +
               "      for (__index=0; __index < ____n; __index++) {" + "\n" +
               "       // should move push out of loop, but not clear if mult-push implemented yet" + "\n" +
               "       PUSH(__buffer[__index]);" + "\n" +
               "      }" + "\n" +
               "    }" + "\n" +
               "  #endif";
    */

    // set values of free variables
    String TYPE = theType;
    String FILEREADER = fpName(filter);
    String FUSED = "__FUSED_" + s + "_" + d;
    String NOMOD = "__NOMOD_" + s + "_" + d;
    String BUFFER = "BUFFER_" + s + "_" + d;
    String HEAD = "HEAD_" + s + "_" + d;
    String BUF_SIZE_MASK = "__BUF_SIZE_MASK_" + s + "_" + d;
    String PUSH = outputTape.getPushName();

    // replace templates with correct values
    template = Utils.replaceAll(template, "TYPE", TYPE);
    template = Utils.replaceAll(template, "FILEREADER", FILEREADER);
    template = Utils.replaceAll(template, "FUSED", FUSED);
    template = Utils.replaceAll(template, "NOMOD", NOMOD);
    template = Utils.replaceAll(template, "BUFFER", BUFFER);
    template = Utils.replaceAll(template, "HEAD", HEAD);
    template = Utils.replaceAll(template, "BUF_SIZE_MASK", BUF_SIZE_MASK);
    template = Utils.replaceAll(template, "PUSH", PUSH);

    // output code
    p.println(template);
  }