Changeset 2701


Ignore:
Timestamp:
Nov 29, 2012, 6:03:35 AM (7 years ago)
Author:
cameron
Message:

Various fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • proto/Compiler/CCGO_HMCPS.py

    r2700 r2701  
    155155    if low_bit == 1: pending = '%s%i' % (temp_pfx, carry_num - 1)
    156156    else: pending = '%s%i_%i' % (temp_pfx, carry_num - 1, base)
    157     while base != 0 and carry_num < p2f:
     157    while base != 0 and carry_num <= p2f:
    158158       next_bit = base &~ (base - 1)
    159159       shift = next_bit - low_bit
     
    170170    shift = p2f - low_bit
    171171    if shift != 0:
    172        shift_result = '%s%i_0' % (temp_pfx, carry_num - 1 + shift)
     172       shift_result = '%s%i_%i' % (temp_pfx, carry_num - 1 + shift, base)
    173173       assign_list.append(make_assign(shift_result, make_call('mvmd<%i>::slli<%i>' % (pack_fw, shift), [mk_var(pending)])))
    174174       carry_count -= shift
     
    215215def align(n, align_base):
    216216  return ((n + align_base - 1) / align_base) * align_base
    217 
    218 def old_determine_aligned_block_sizes(pack_size, cis):
    219   aligned_size = {}
    220   for i in range(cis.block_count): aligned_size[i] = 0
    221   seen = []
    222   for i in range(cis.block_count):
    223     # Work backwards to process all child blocks before the parent
    224     # so that the parent incorporates the updated child counts.
    225     b = cis.block_count - i - 1
    226     # Start with the inherited carry count from processing childrem.
    227     if not aligned_size.has_key(b): carry_count = 0
    228     else: carry_count = aligned_size[b]
    229     for op in range(cis.block_first_op[b], cis.block_first_op[b] + cis.block_op_count[b]):
    230       if op in seen: continue
    231       if op not in cis.advance_amount.keys(): carry_count += 1
    232       elif cis.advance_amount[op] == 1: carry_count += 1
    233       seen.append(op)
    234     if carry_count > pack_size:
    235       aligned_size[b] = ((carry_count - 1) / pack_size) * (pack_size + 1)
    236     elif cis.whileblock[b]:
    237       aligned_size[b] = pack_size
    238     else:
    239       aligned_size[b] = pow2ceil(carry_count)
    240     if b != 0: aligned_size[cis.parent_block[b]] += aligned_size[b]
    241   print aligned_size
    242   return aligned_size
    243217
    244218def determine_aligned_block_sizes(pack_size, cis):
     
    264238        b_carries += aligned_size[sb]
    265239        op += cis.block_op_count[sb]
    266     if cis.whileblock[b] or aligned_size[b] > pack_size:
     240 #   if cis.whileblock[b] or aligned_size[b] > pack_size:
     241    if b_carries > pack_size:
    267242      aligned_size[b] = align(b_carries, pack_size)
    268243    else:
    269244      aligned_size[b] = pow2ceil(b_carries)
     245  print aligned_size
    270246  return aligned_size
    271247 
     
    289265          decls += ";"
    290266  return decls
    291 
     267 
     268def block_contains(b0, b1, parent_block_map):
     269  if b0 == b1: return True
     270  elif b1 == 0: return False
     271  else: return block_contains(b0, parent_block_map[b1], parent_block_map)
    292272 
    293273class HMCPS_CCGO(CCGO.CCGO):
     
    304284        self.block_base = {}
    305285        self.allocate_ops()
    306              
    307              
     286        # carry_offset is used within the inner body of while loops to access local carries.
     287        # The calculated (ub, rp) value is reduced by this amount for the local carry group(s).
     288        self.carry_offset = 0
     289
    308290    def allocate_ops(self):
    309291      carry_count = 0
    310292      for op in range(self.carryInfoSet.operation_count):
    311         b = self.carryInfoSet.containing_block[op]
    312         if b !=0:
    313           if self.carryInfoSet.block_first_op[b] == op:
    314             align_base = self.aligned_size[b]
     293        b = self.carryInfoSet.containing_block[op]
     294        if op != 0:
     295          # If we've just left a block, ensure that we are aligned.
     296          b_last = self.carryInfoSet.containing_block[op-1]
     297          if not block_contains(b_last, b, self.carryInfoSet.parent_block):
     298            # find the max-sized block just exited.
     299            while not block_contains(self.carryInfoSet.parent_block[b_last], b, self.carryInfoSet.parent_block):
     300              b_last = self.carryInfoSet.parent_block[b_last]
     301            align_base = self.aligned_size[b_last]
    315302            if align_base > self.field_count: align_base = self.field_count
    316             carry_count = align(carry_count, align_base)
    317             self.block_base[b] = carry_count
     303            carry_count = align(carry_count, align_base)         
     304        if self.carryInfoSet.block_first_op[b] == op:
     305          # If we're just entering a block, ensure that we are aligned.
     306          align_base = self.aligned_size[b]
     307          if align_base > self.field_count: align_base = self.field_count
     308          carry_count = align(carry_count, align_base)
     309          self.block_base[b] = carry_count
    318310        if op not in self.carryInfoSet.advance_amount.keys():
    319311          self.alloc_map[op] = carry_count
     
    322314          self.alloc_map[op] = carry_count
    323315          carry_count += 1
     316      # When processing the last operation, make sure that the "next" operation
     317      # appears to start a new pack.
     318      self.alloc_map[self.carryInfoSet.operation_count] = align(carry_count, self.field_count)
     319      print self.alloc_map
    324320     
    325321    def GenerateCarryDecls(self):
     
    353349    def GenerateCarryInAccess(self, operation_no):
    354350        block_no = self.carryInfoSet.containing_block[operation_no]
    355         posn = self.alloc_map[operation_no]
     351        posn = self.alloc_map[operation_no] - self.carry_offset
    356352        ub = posn/self.field_count
    357353        rp = posn%self.field_count
     
    361357    def GenerateCarryOutStore(self, operation_no, carry_out_expr):
    362358        block_no = self.carryInfoSet.containing_block[operation_no]
    363         posn = self.alloc_map[operation_no]
     359        posn = self.alloc_map[operation_no] - self.carry_offset
    364360        ub = posn/self.field_count
    365361        rp = posn%self.field_count
     
    367363        assigs = [make_assign(self.temp_prefix + repr(rp), carry_out_expr)]
    368364        assigs += gen_carry_pack(self.fw, rp, self.temp_prefix)
    369         skip = 0
    370         if operation_no + 1 == self.carryInfoSet.operation_count:
    371           # Last operation
    372           skip = self.field_count - rp - 1
    373         else:
    374           skip = self.alloc_map[operation_no + 1] - posn - 1
     365        next_posn = self.alloc_map[operation_no + 1] - self.carry_offset
     366        skip = next_posn - posn - 1
    375367        if skip > 0:
    376368          assigs += gen_multiple_carry_zero_then_pack(self.fw, rp+1, skip, self.temp_prefix)
    377         print (posn, skip)
    378         if skip + posn + 1 == self.field_count:
     369        #print (posn, skip)
     370        if next_posn % self.field_count == 0:
    379371          v_ub = make_index_load(self.carryGroupVar, ub)
    380372          shift_op = "simd<%i>::srli<%i>" % (self.fw, self.fw-1)
    381           assigs.append(make_assign(make_att_store(v_ub, '_128'), make_call(shift_op, [mk_var(self.temp_prefix + '%i_0' % (self.field_count - 1))])))
     373          storable_carry_in_form = make_call(shift_op, [mk_var(self.temp_prefix + '%i_0' % (self.field_count - 1))])
     374          assigs.append(make_assign(make_att_store(v_ub, '_128'), storable_carry_in_form))
    382375        return assigs
    383376    def GenerateAdvanceInAccess(self, operation_no): pass
     
    390383                           #mkCall("bitblock::srli<64>", [adv_out_expr]))]
    391384    def GenerateTest(self, block_no, testExpr):
    392         posn = self.block_base[block_no]
     385        posn = self.block_base[block_no] - self.carry_offset
    393386        ub = posn/self.field_count
    394387        rp = posn%self.field_count
     
    414407        count = self.aligned_size[block_no]
    415408        if count % self.field_count == 0: return []
     409        # The block has half a carry-pack or less.
    416410        assigs = []
    417         posn = self.block_base[block_no]
    418         ub = posn/self.field_count
    419         rp = posn%self.field_count
    420         assigs = gen_multiple_carry_zero_then_pack(self.fw, rp, count, self.temp_prefix)
     411        posn = self.block_base[block_no] - self.carry_offset
     412        ub = posn / self.field_count
     413        rp = posn % self.field_count
     414        next_op = self.carryInfoSet.block_first_op[block_no] + self.carryInfoSet.block_op_count[block_no]
     415        end_pos = (self.alloc_map[next_op] - 1) % self.field_count
     416        print rp, next_op,self.alloc_map[next_op]
     417        if rp == end_pos: v = mk_var('%s%i' % (self.temp_prefix, rp))
     418        else: v = mk_var('%s%i_%i' % (self.temp_prefix, end_pos, rp))
     419        assigs = [make_assign(v, make_zero(self.fw))]
     420        #assigs = gen_multiple_carry_zero_then_pack(self.fw, rp, end_pos - rp + 1, self.temp_prefix)
    421421        return assigs
    422422
    423423    def GenerateLocalDeclare(self, block_no):
    424424        if self.carryInfoSet.block_op_count[block_no] == 0: return []
    425         ub_count = (self.carryInfoSet.block_op_count[block_no] + self.field_count - 1) / self.field_count
    426         decls = [make_callStmt('ubitblock_declare', [mk_var('sub' + self.carryGroupVar), ast.Num(ub_count)])]
    427         # Generate all carry pack temps in case they are needed.
    428         # This might be overkill in some cases.
    429         f = self.field_count
    430         temps = [self.temp_prefix + repr(i) for i in range(self.field_count)]
     425        count = self.aligned_size[block_no]
     426        if count >= self.field_count:
     427          ub_count = count / self.field_count
     428          decls = [make_callStmt('ubitblock_declare', [mk_var('sub' + self.carryGroupVar), ast.Num(ub_count)])]
     429          count = self.field_count
     430        else: decls = []
     431        # Generate carry pack temps.
     432        temps = ["sub" + self.temp_prefix + repr(i) for i in range(count)]
     433        f = count
    431434        while f > 1:
    432435          f = f/2
    433           s = self.field_count/f
    434           temps += [self.temp_prefix + "%i_%i" % (s*(i+1)-1, s*i) for i in range(f)]
     436          s = count/f
     437          temps += ["sub" + self.temp_prefix + "%i_%i" % (s*(i+1)-1, s*i) for i in range(f)]
    435438        #return BitBlock_decls_from_vars(decls)
    436439        return decls + [make_callStmt('BitBlock_declare', [mk_var(t)]) for t in temps]
     
    441444    def EnterLocalWhileBlock(self, operation_offset): 
    442445        self.carryGroupVar = "sub" + self.carryGroupVar
     446        self.temp_prefix = "sub" + self.temp_prefix
     447        self.carry_offset = self.alloc_map[operation_offset]
     448        print "self.carry_offset = %i" % self.carry_offset
    443449    def ExitLocalWhileBlock(self): 
    444450        self.carryGroupVar = self.carryGroupVar[3:]
    445 
     451        self.temp_prefix = self.temp_prefix[3:]
     452        self.carry_offset = 0
    446453       
    447454    def GenerateCarryWhileFinalization(self, block_no):
    448         posn = self.alloc_map[block_no]
     455        posn = self.block_base[block_no]
    449456        ub = posn/self.field_count
     457        rp = posn%self.field_count
    450458        count = self.aligned_size[block_no]
    451459        v = self.carryGroupVar
    452460        lv = "sub" + v
     461        if count < self.field_count:
     462          if count == 1:
     463            v0 = '%s%i' % (self.temp_prefix, rp)
     464            lv0 = '%s%0' % ("sub" + self.temp_prefix)
     465          else:
     466            v0 = '%s%i_%i' % (self.temp_prefix, rp + count - 1, rp)
     467            lv0 = '%s%i_0' % ("sub" + self.temp_prefix, count - 1)
     468          return [make_assign(v0, make_call('simd_or', [mk_var(v0), mk_var(lv0)]))]
    453469        n = (count+self.field_count-1)/self.field_count
    454470        assigs = []
     
    460476        if self.carryInfoSet.carry_count == 0: return []
    461477        # Generate statements to shift all carries from carry-out form to carry-in form.
    462         v = self.carryGroupVar
    463         n = (self.aligned_size[0] + self.field_count - 1)/self.field_count
    464         shift_op = "simd<%i>::srli<%i>" % (self.fw, self.fw-1)
    465         return [make_assign(make_att_store(make_index_load(v, i), '_128'), make_call(shift_op, [make_att_load(make_index_load(v, i), '_128')])) for i in range(n)]
    466 
     478        #v = self.carryGroupVar
     479        #n = (self.aligned_size[0] + self.field_count - 1)/self.field_count
     480        #shift_op = "simd<%i>::srli<%i>" % (self.fw, self.fw-1)
     481        #return [make_assign(make_att_store(make_index_load(v, i), '_128'), make_call(shift_op, [make_att_load(make_index_load(v, i), '_128')])) for i in range(n)]
     482        #
     483        # Now arranging shifts with original stores.
     484        return []
     485
Note: See TracChangeset for help on using the changeset viewer.