Changeset 2800


Ignore:
Timestamp:
Dec 27, 2012, 12:58:34 PM (7 years ago)
Author:
cameron
Message:

Initial BitPack? CCGO object

Location:
proto/Compiler
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • proto/Compiler/CCGO_HMCPS.py

    r2799 r2800  
    546546        return decls + [make_callStmt('BitBlock_declare', [mk_var(t)]) for t in temps]
    547547
     548#
     549#  A version of HMCPS_CCGO with bit packing using hsimd:signmask
     550#
     551class HMCPS_CCGO_BitPack(HMCPS_CCGO):
     552
     553    def allocate_all(self):
     554        self.aligned_size = determine_aligned_block_sizes(self.field_count, self.carryInfoSet)
     555        self.carryPack_count = (self.aligned_size[0] + self.BLOCK_SIZE - 1) / self.BLOCK_SIZE
     556        self.totalPack_count = self.carryPack_count + self.carryInfoSet.adv_n_count
     557        self.alloc_map = {}
     558        self.alloc_map[0] = 0
     559        self.adv_n_map = {}
     560        self.block_base = {}
     561        self.allocate_ops()
     562        # carry_offset is used within the inner body of while loops to access local carries.
     563        # The calculated (ub, rp) value is reduced by this amount for the local carry Pack(s).
     564        self.carry_offset = 0
     565
     566    def GenerateCarryInAccess(self, operation_no):
     567        block_no = self.carryInfoSet.containing_block[operation_no]
     568        posn = self.alloc_map[operation_no] - self.carry_offset
     569        pk = posn/self.BLOCK_SIZE
     570        rp = posn%self.BLOCK_SIZE
     571        if rp == 0: e = self.carry_pack_full(pk)
     572        elif rp < self.BLOCK_SIZE/2: e = make_call("simd<%i>::srli<%i>" %(self.BLOCK_SIZE/2, rp), [self.carry_pack_full(pk)])
     573        else: e = make_call("bitblock::srli<%i>" %(rp), [self.carry_pack_full(pk)])
     574        if rp == self.BLOCK_SIZE - 1:
     575          return e
     576        else: return make_call('simd_and', [e, mk_var("simd_const_1")])
     577
     578
     579    def GenerateCarryOutStore(self, operation_no, carry_out_expr):
     580        block_no = self.carryInfoSet.containing_block[operation_no]
     581        posn = self.alloc_map[operation_no] - self.carry_offset
     582        rp = posn%self.field_count
     583        # Save the carry in the carry temp variable and then merge
     584        # pending carry temps as far as possible.
     585        assigs = [make_assign(self.temp_prefix + repr(rp), carry_out_expr)]
     586        assigs += self.gen_merges(rp, rp)
     587        # Only generate an actual store for the last carryout in a pack.
     588        next_op = operation_no + 1
     589        while self.adv_n_map.has_key(next_op): next_op += 1
     590        next_posn = self.alloc_map[next_op] - self.carry_offset
     591        skip = next_posn - posn - 1
     592        if skip > 0:
     593          assigs += self.gen_multiple_carry_zero_then_pack(rp+1, skip)
     594        #print (posn, skip)
     595        if next_posn % self.field_count == 0:
     596          pk = posn/self.BLOCK_SIZE
     597          fd = (posn%self.BLOCK_SIZE)/self.field_count
     598          mask_op = "hsimd<%i>::signmask" % (self.fw)
     599          storable_carry_in_form = make_call(mask_op, [mk_var(self.cg_temp(self.field_count - 1, 0))])
     600          assigs.append(make_assign(self.carry_pack_index(self.field_count, pk, fd, mode = ast.Store()), storable_carry_in_form))
     601        return assigs
     602
     603
     604    def GenerateTest(self, block_no, testExpr):
     605        int_size = self.BLOCK_SIZE/2
     606        posn = self.block_base[block_no] - self.carry_offset
     607        pk = posn/self.BLOCK_SIZE
     608        fd = (posn%self.BLOCK_SIZE)/int_size
     609        rp = posn%int_size
     610        sz = self.aligned_size[block_no]
     611        if sz in [8, 16, 32, 64] and align(posn, sz) == posn:
     612            fd = (posn%self.BLOCK_SIZE)/sz
     613            t = self.carry_pack_index(sz, pk, fd)
     614            return TestHelper_Integer_Or(testExpr, t)
     615        elif rp + sz <= int_size:
     616            e = self.carry_pack_index(int_size, pk, fd)
     617            t = ast.BinOp(e, ast.BitAnd(), ast.Num(((1<<sz) - 1)<<rp))
     618            return TestHelper_Integer_Or(testExpr, t)
     619        else:
     620            e = self.carry_pack_index(int_size, pk, fd)
     621            t = ast.BinOp(e, ast.BitAnd(), ast.Num(((1<<(int_size-rp)) - 1)<<rp))
     622            sz -= (int_size-rp)
     623            posn += (int_size-rp)
     624            pk = posn/self.BLOCK_SIZE
     625            fd = (posn%self.BLOCK_SIZE)/int_size
     626            while sz >= int_size:
     627              t = ast.BinOp(t, ast.BitOr(), self.carry_pack_index(int_size, pk, fd))
     628              sz -= int_size
     629              posn += int_size
     630              pk = posn/self.BLOCK_SIZE
     631              fd = (posn%self.BLOCK_SIZE)/int_size
     632            if sz > 0:
     633              e = self.carry_pack_index(int_size, pk, fd)
     634              t = ast.BinOp(t, ast.BitOr(), ast.BinOp(e, ast.BitAnd(), ast.Num((1<<sz) -1)))
     635            return TestHelper_Integer_Or(testExpr, t)
     636           
     637    def GenerateInitializations(self):
     638        v = self.carryPackVar       
     639        inits = ""
     640        for i in range(0, self.totalPack_count):
     641          inits += "%s[%i]._128 = simd<%i>::constant<0>();\n" % (v, i, self.fw)
     642        for op_no in range(self.carryInfoSet.block_op_count[0]):
     643          if op_no in self.carryInfoSet.init_one_list:
     644            posn = self.alloc_map[op_no]
     645            pk = posn/self.BLOCK_SIZE
     646            fd = (posn%self.BLOCK_SIZE)/self.field_count
     647            rp = posn%self.BLOCK_SIZE
     648            inits += "%s[%i]._%i[%i] |= 1 << %i;\n" % (self.carryPackVar, pk, self.fw, fd, rp)
     649        return inits
     650
     651
     652    def GenerateCarryElseFinalization(self, block_no):
     653        # if the block consists of full carry packs, then
     654        # no action need be taken: the corresponding carry-in packs
     655        # must already be zero, or the then branch would have been taken.
     656        count = self.aligned_size[block_no]
     657        if count % self.field_count == 0: return []
     658        # The block has half a carry-pack or less.
     659        assigs = []
     660        posn = self.block_base[block_no] - self.carry_offset
     661        ub = posn / self.field_count
     662        rp = posn % self.field_count
     663        next_op = self.carryInfoSet.block_first_op[block_no] + self.carryInfoSet.block_op_count[block_no]
     664        end_pos = (self.alloc_map[next_op]  - self.carry_offset - 1) % self.field_count
     665        #print rp, next_op,self.alloc_map[next_op]
     666        #assigs = [make_assign(self.cg_temp(end_pos, rp), make_zero(self.fw))]
     667        assigs = self.gen_multiple_carry_zero_then_pack(rp, end_pos - rp + 1)
     668        if (end_pos + 1) % self.field_count == 0:
     669          pk = posn/self.BLOCK_SIZE
     670          fd = (posn%self.BLOCK_SIZE)/self.field_count
     671          mask_op = "hsimd<%i>::signmask" % (self.fw)
     672          storable_carry_in_form = make_call(mask_op, [mk_var(self.cg_temp(self.field_count - 1, 0))])
     673          assigs.append(make_assign(self.carry_pack_index(self.field_count, pk, fd, mode = ast.Store()), storable_carry_in_form))
     674        return assigs
     675
     676#
     677#  TO DO:
     678#
     679    def GenerateCarryWhileFinalization(self, block_no):
     680        posn = self.block_base[block_no]
     681        sz = self.aligned_size[block_no]
     682        if sz < self.field_count:
     683          rp = posn%self.field_count
     684          v0 = self.cg_temp(rp + sz - 1, rp)
     685          lv0 = self.local_temp(sz - 1, 0)
     686          return [make_assign(v0, make_call('simd_or', [mk_var(v0), mk_var(lv0)]))]
     687        local_posn = 0
     688        pk = posn/self.BLOCK_SIZE
     689        assigs = []
     690        for i in range((sz + self.field_count -1)/self.field_count): 
     691          pk = posn/self.BLOCK_SIZE
     692          fd = (posn%self.BLOCK_SIZE)/self.field_count
     693          local_pk = local_posn/self.BLOCK_SIZE
     694          local_fd = (local_posn%self.BLOCK_SIZE)/self.field_count
     695          v0 = self.carry_pack_index(self.field_count, pk, fd)
     696          lv0 = self.local_pack_index(self.field_count, local_pk, local_fd)
     697          assigs.append(make_assign([self.carry_pack_index(self.field_count, pk, fd, ast.Store())], ast.BinOp(v0, ast.BitOr(), lv0)))
     698          posn += self.field_count
     699          local_posn += self.field_count
     700        return assigs
  • proto/Compiler/pablo.py

    r2799 r2800  
    329329    elif ops <= 4: ccgo = CCGO_HMCPS.HMCPS_CCGO2(BLOCK_SIZE, 32, carryInfoSet, 'carryG', '__c')
    330330    #elif ops <= 8: ccgo = CCGO_HMCPS.HMCPS_CCGO(BLOCK_SIZE, 16, carryInfoSet, 'carryG', '__c')
    331     #else: ccgo = CCGO_HMCPS.HMCPS_CCGO(BLOCK_SIZE, 8, carryInfoSet, 'carryG', '__c')
    332     else: ccgo = CCGO_HMCPS.HMCPS_CCGO2(BLOCK_SIZE, 16, carryInfoSet, 'carryG', '__c')
     331    #else: ccgo = CCGO_HMCPS.HMCPS_CCGO2(BLOCK_SIZE, 16, carryInfoSet, 'carryG', '__c')
     332    else: ccgo = CCGO_HMCPS.HMCPS_CCGO_BitPack(BLOCK_SIZE, 8, carryInfoSet, 'carryG', '__c')
    333333  else:
    334334    ccgo = CCGO.testCCGO(BLOCK_SIZE, carryInfoSet, 'carryQ')
Note: See TracChangeset for help on using the changeset viewer.