예제 #1
0
    def run_posit_op(self,
                     abits=None,
                     op_str=None,
                     bbits=None,
                     ref_cbits=None,
                     nbits=None,
                     es=None):
        a = PCPosit(abits, nbits=nbits, es=es, mode='bits')
        b = PCPosit(bbits, nbits=nbits, es=es, mode='bits')
        c = None

        if op_str == '+':
            c = a + b
        elif op_str == '-':
            c = a - b
        elif op_str == '*':
            c = a * b
        elif op_str == '/':
            c = a / b
        elif op_str == 'u-':
            c = -a
        else:
            raise NotImplementedError("op={}".format(op_str))

        cbits = coder.encode_posit_binary(c.rep)
        self.assertEqual(cbits, ref_cbits)
예제 #2
0
    def __truediv__(self, other):
        if self.rep['t'] == 'c' or other.rep['t'] == 'z':
            p = PCPosit() # FIXME: Use constructor to directly initialized to posit zero.
            p.rep = coder.create_cinf_positrep(nbits=self.rep['nbits'], es=self.rep['es'])
            return p
        elif self.rep['t'] == 'z' or other.rep['t'] == 'c':
            p = PCPosit() # FIXME
            p.rep = coder.create_zero_positrep(nbits=self.rep['nbits'], es=self.rep['es'])
            return p

        assert self.rep['t'] == 'n' and other.rep['t'] == 'n'

        xa = ( -1)**self.rep['s'] * ( 2**self.rep['h'] +  self.rep['f'])
        xb = (-1)**other.rep['s'] * (2**other.rep['h'] + other.rep['f'])
        ma =  2**self.rep['es'] *  self.rep['k'] +  self.rep['e'] -  self.rep['h']
        mb = 2**other.rep['es'] * other.rep['k'] + other.rep['e'] - other.rep['h']

        pc = PCPosit() # FIXME
        pc.rep = coder.create_zero_positrep(nbits=self.rep['nbits'], es=self.rep['es'])
        pc.rep['t'] = 'n'

        if (xa < 0) ^ (xb < 0): pc.rep['s'] = 1
        if xa < 0: xa = -xa
        if xb < 0: xb = -xb

        g = ma - mb + (2**pc.rep['es'])*(pc.rep['nbits']-2) + pc.rep['nbits'] - 1
        g = max(0, g)
        xc = (xa * 2**g) // xb
        mc = ma - mb - g

        if xc != 0:
            while xc != 0 and xc % 2 == 0:
                xc >>= 1
                mc += 1

            g = 0
            x = xc
            while x >= 2:
                x >>= 1
                g -= 1

            assert x >= 1 and x < 2, "x={}".format(x)

            pc.rep['e'] = (mc - g) % 2**pc.rep['es']
            pc.rep['k'] = (mc - g) // 2**pc.rep['es']

            pc.rep['h'] = -g
            pc.rep['f'] = xc - 2**pc.rep['h']

        else:
            pc.rep = coder.create_zero_positrep(nbits=self.rep['nbits'], es=self.rep['es'])

        bits = coder.encode_posit_binary(pc.rep)
        pc.rep = coder.decode_posit_binary(bits, nbits=pc.rep['nbits'], es=pc.rep['es'])

        return pc
예제 #3
0
    def __add__(self, other):
        if self.rep['t'] == 'z':
            return PCPosit(other)
        elif other.rep['t'] == 'z':
            return PCPosit(self)
        elif self.rep['t'] == 'c' or other.rep['t'] == 'c':
            ret = PCPosit(2**(self.rep['nbits']-1), mode='bits', nbits=self.rep['nbits'], es=self.rep['es'])
            return ret

        assert self.rep['t'] == 'n' and other.rep['t'] == 'n'

        xa = ( -1)**self.rep['s'] * ( 2**self.rep['h'] +  self.rep['f'])
        xb = (-1)**other.rep['s'] * (2**other.rep['h'] + other.rep['f'])
        ma =  2**self.rep['es'] *  self.rep['k'] +  self.rep['e'] -  self.rep['h']
        mb = 2**other.rep['es'] * other.rep['k'] + other.rep['e'] - other.rep['h']

        m = max(ma, mb)
        xc = xa*2**(m-mb) + xb*2**(m-ma)
        mc = ma + mb - m

        pc = PCPosit(self, nbits=self.rep['nbits'], es=self.rep['es'])
        pc.rep = coder.create_positrep(nbits=self.rep['nbits'], es=self.rep['es'])

        if xc == 0:
            pc.rep['t'] = 'z'
            return pc
        elif xc < 0:
            xc = -xc
            pc.rep['s'] = 1

        while xc != 0 and xc % 2 == 0:
            xc >>= 1
            mc += 1

        g = 0
        x = xc
        while x >= 2:
            x >>= 1
            g -= 1

        assert x >= 1 and x < 2, "x={}".format(x)

        pc.rep['e'] = (mc - g) % 2**pc.rep['es']
        pc.rep['k'] = (mc - g) // 2**pc.rep['es']

        pc.rep['h'] = -g
        pc.rep['f'] = xc - 2**pc.rep['h']

        bits = coder.encode_posit_binary(pc.rep)
        pc.rep = coder.decode_posit_binary(bits, nbits=pc.rep['nbits'], es=pc.rep['es'])

        return pc
예제 #4
0
    def __mul__(self, other):
        if self.rep['t'] == 'c' or other.rep['t'] == 'c':
            p = PCPosit() # FIXME: Use constructor to directly initialized to posit zero.
            p.rep = coder.create_cinf_positrep(nbits=self.rep['nbits'], es=self.rep['es'])
            return p
        elif self.rep['t'] == 'z' or other.rep['t'] == 'z':
            p = PCPosit() # FIXME
            p.rep = coder.create_zero_positrep(nbits=self.rep['nbits'], es=self.rep['es'])
            return p

        assert self.rep['t'] == 'n' and other.rep['t'] == 'n'

        xa = ( -1)**self.rep['s'] * ( 2**self.rep['h'] +  self.rep['f'])
        xb = (-1)**other.rep['s'] * (2**other.rep['h'] + other.rep['f'])
        ma =  2**self.rep['es'] *  self.rep['k'] +  self.rep['e'] -  self.rep['h']
        mb = 2**other.rep['es'] * other.rep['k'] + other.rep['e'] - other.rep['h']

        xc = xa * xb
        mc = ma + mb

        pc = PCPosit() # FIXME
        pc.rep = coder.create_zero_positrep(nbits=self.rep['nbits'], es=self.rep['es'])
        pc.rep['t'] = 'n'

        if xc < 0:
            xc = -xc
            pc.rep['s'] = 1

        while xc != 0 and xc % 2 == 0:
            xc >>= 1
            mc += 1

        g = 0
        x = xc
        while x >= 2:
            x >>= 1
            g -= 1

        assert x >= 1 and x < 2, "x={}".format(x)

        pc.rep['e'] = (mc - g) % 2**pc.rep['es']
        pc.rep['k'] = (mc - g) // 2**pc.rep['es']

        pc.rep['h'] = -g
        pc.rep['f'] = xc - 2**pc.rep['h']

        bits = coder.encode_posit_binary(pc.rep)
        pc.rep = coder.decode_posit_binary(bits, nbits=pc.rep['nbits'], es=pc.rep['es'])

        return pc
예제 #5
0
파일: pcposit.py 프로젝트: xman/sgpositpy
    def _fixedpoint_to_posit(cls, x, m, nbits=None, es=None):
        assert nbits is not None
        assert es is not None

        if x == 0:
            return PCPosit('0', nbits=nbits, es=es)

        p = PCPosit(nbits=nbits, es=es)
        p.rep['t'] = 'n'
        p.rep['s'] = 0

        if x < 0:
            x = -x
            p.rep['s'] = 1

        assert x != 0

        while x != 0 and x % 2 == 0:
            x >>= 1
            m += 1

        g = 0
        y = x
        while y >= 2:
            y >>= 1
            g -= 1

        assert y >= 1 and y < 2, "y={}".format(y)

        p.rep['e'] = (m - g) % 2**es
        p.rep['k'] = (m - g) // 2**es

        p.rep['h'] = -g
        p.rep['f'] = x - 2**p.rep['h']

        bits = coder.encode_posit_binary(p.rep)
        p.rep = coder.decode_posit_binary(bits, nbits=nbits, es=es)

        return p
예제 #6
0
    def run_posit_2op_exhaustive(self,
                                 op_str=None,
                                 nbits_range=None,
                                 es_range=None):
        op = None
        mpop = None
        if op_str == '+':
            op = PCPosit.__add__
            mpop = mp.mpf.__add__
        elif op_str == '-':
            op = PCPosit.__sub__
            mpop = mp.mpf.__sub__
        elif op_str == '*':
            op = PCPosit.__mul__
            mpop = mp.mpf.__mul__
        elif op_str == '/':
            op = PCPosit.__truediv__
            mpop = mp.mpf.__truediv__
        else:
            raise NotImplementedError("op={}".format(op_str))

        if nbits_range is None:
            nbits_range = self.nbits_range
        if es_range is None:
            es_range = self.es_range

        for nbits in nbits_range:
            mask = bitops.create_mask(nbits)
            cinf_bits = 1 << (nbits - 1)
            is_special = lambda bits: bits == 0 or bits == cinf_bits
            is_normal = lambda bits: not is_special(bits)
            for es in es_range:
                for abits in range(2**nbits):
                    for bbits in range(2**nbits):
                        a = PCPosit(abits, nbits=nbits, es=es, mode='bits')
                        b = PCPosit(bbits, nbits=nbits, es=es, mode='bits')
                        c = op(a, b)
                        cbits = coder.encode_posit_binary(c.rep)

                        test_info = {
                            'nbits': nbits,
                            'es': es,
                            'a': str(a),
                            'b': str(b),
                            'c': str(c),
                            'abits': abits,
                            'bbits': bbits,
                            'cbits': cbits,
                            'arep': a.rep,
                            'brep': b.rep,
                            'crep': c.rep,
                        }

                        if is_normal(abits) and is_normal(
                                bbits) and cbits == 0:
                            self.assertTrue(op_str in ['+', '-'])
                            if op_str == '+':
                                self.assertEqual(abits, -bbits & mask)
                            else:  # '-'
                                self.assertEqual(abits, bbits)

                        elif is_normal(abits) and is_normal(bbits):
                            self.assertNotEqual(cbits, 0)
                            self.assertNotEqual(cbits, cinf_bits)

                            amp = mp.mpf(
                                eval(coder.positrep_to_rational_str(a.rep)))
                            bmp = mp.mpf(
                                eval(coder.positrep_to_rational_str(b.rep)))
                            c2mp = mpop(amp, bmp)

                            c0bits = (cbits - 1) & mask
                            while c0bits == 0 or c0bits == cinf_bits:
                                c0bits = (c0bits - 1) & mask

                            c1bits = (cbits + 1) & mask
                            while c1bits == 0 or c1bits == cinf_bits:
                                c1bits = (c1bits + 1) & mask

                            c0 = PCPosit(c0bits,
                                         nbits=nbits,
                                         es=es,
                                         mode='bits')
                            c1 = PCPosit(c1bits,
                                         nbits=nbits,
                                         es=es,
                                         mode='bits')

                            test_info['c0'] = str(c0)
                            test_info['c1'] = str(c1)
                            test_info['c0bits'] = c0bits
                            test_info['c1bits'] = c1bits
                            test_info['c0rep'] = c0.rep
                            test_info['c1rep'] = c1.rep

                            rcmp = mp.mpf(
                                eval(coder.positrep_to_rational_str(c.rep)))
                            cratiodiffmp = mp.fabs(mp.log(
                                rcmp / c2mp)) if c2mp != 0 else mp.fabs(rcmp -
                                                                        c2mp)
                            cabsdiffmp = mp.fabs(rcmp - c2mp)

                            c0mp = mp.mpf(
                                eval(coder.positrep_to_rational_str(c0.rep)))
                            c0ratiodiffmp = mp.fabs(mp.log(
                                c0mp / c2mp)) if c2mp != 0 else mp.fabs(c0mp -
                                                                        c2mp)
                            c0absdiffmp = mp.fabs(c0mp - c2mp)
                            self.assertTrue(
                                cratiodiffmp <= c0ratiodiffmp
                                or cabsdiffmp <= c0absdiffmp, test_info)

                            c1mp = mp.mpf(
                                eval(coder.positrep_to_rational_str(c1.rep)))
                            c1ratiodiffmp = mp.fabs(mp.log(
                                c1mp / c2mp)) if c2mp != 0 else mp.fabs(c1mp -
                                                                        c2mp)
                            c1absdiffmp = mp.fabs(c1mp - c2mp)
                            self.assertTrue(
                                cratiodiffmp <= c1ratiodiffmp
                                or cabsdiffmp <= c1absdiffmp, test_info)

                        elif abits == cinf_bits:
                            self.assertTrue(op_str in ['+', '-', '*', '/'])
                            self.assertEqual(cbits, cinf_bits)

                        elif abits != cinf_bits and bbits == cinf_bits:
                            self.assertTrue(op_str in ['+', '-', '*', '/'])
                            if op_str == '/':
                                self.assertEqual(cbits, 0)
                            else:
                                self.assertEqual(cbits, cinf_bits)

                        elif abits == 0 and bbits == 0:
                            self.assertTrue(op_str in ['+', '-', '*', '/'])
                            if op_str == '/':
                                self.assertEqual(cbits, cinf_bits)
                            else:
                                self.assertEqual(cbits, 0)

                        elif is_normal(abits) and bbits == 0:
                            if op_str == '+' or op_str == '-':
                                self.assertEqual(cbits, abits)
                            elif op_str == '*':
                                self.assertEqual(cbits, 0)
                            elif op_str == '/':
                                self.assertEqual(cbits, cinf_bits)
                            else:
                                self.assertTrue(False)

                        elif abits == 0 and is_normal(bbits):
                            self.assertTrue(op_str in ['+', '-', '*', '/'])
                            if op_str == '+':
                                self.assertEqual(cbits, bbits)
                            elif op_str == '-':
                                self.assertEqual(cbits, -bbits & mask)
                            else:
                                self.assertEqual(cbits, 0)

                        else:
                            self.assertTrue(False)
예제 #7
0
 def __repr__(self):
     nbits, es = self.rep['nbits'], self.rep['es']
     bits = coder.encode_posit_binary(self.rep)
     template = "PCPosit({}, mode='bits', nbits={}, es={})"
     return template.format(hex(bits), nbits, es)
    def run_posit_2op_exhaustive(self,
                                 op_str=None,
                                 nbits_range=None,
                                 es_range=None):
        op = None
        mpop = None
        if op_str == '+':
            op = PCPosit.__add__
            mpop = mp.mpf.__add__
        elif op_str == '-':
            op = PCPosit.__sub__
            mpop = mp.mpf.__sub__
        elif op_str == '*':
            op = PCPosit.__mul__
            mpop = mp.mpf.__mul__
        elif op_str == '/':
            op = PCPosit.__truediv__
            mpop = mp.mpf.__truediv__
        else:
            raise NotImplementedError("op={}".format(op_str))

        for nbits in nbits_range:
            mask = bitops.create_mask(nbits)
            for es in es_range:
                for abits in range(2**nbits):
                    for bbits in range(2**nbits):
                        a = PCPosit(abits, nbits=nbits, es=es, mode='bits')
                        b = PCPosit(bbits, nbits=nbits, es=es, mode='bits')
                        c = op(a, b)

                        if a.rep['t'] == 'n' and b.rep['t'] == 'n':
                            amp = mp.mpf(
                                eval(coder.positrep_to_rational_str(a.rep)))
                            bmp = mp.mpf(
                                eval(coder.positrep_to_rational_str(b.rep)))
                            c2mp = mpop(amp, bmp)
                            c0 = PCPosit((bbits - 1) & mask,
                                         nbits=nbits,
                                         es=es,
                                         mode='bits')
                            c1 = PCPosit((bbits + 1) & mask,
                                         nbits=nbits,
                                         es=es,
                                         mode='bits')

                            cbits = coder.encode_posit_binary(c.rep)
                            roundedc = coder.decode_posit_binary(cbits,
                                                                 nbits=nbits,
                                                                 es=es)

                            rcmp = mp.mpf(
                                eval(coder.positrep_to_rational_str(roundedc)))
                            cratiodiffmp = mp.fabs(mp.log(
                                rcmp / c2mp)) if c2mp != 0 else mp.fabs(rcmp -
                                                                        c2mp)
                            cabsdiffmp = mp.fabs(rcmp - c2mp)
                            if c0.rep['t'] != 'c':
                                c0mp = mp.mpf(
                                    eval(coder.positrep_to_rational_str(
                                        c0.rep)))
                                c0ratiodiffmp = mp.fabs(mp.log(
                                    c0mp /
                                    c2mp)) if c2mp != 0 else mp.fabs(c0mp -
                                                                     c2mp)
                                c0absdiffmp = mp.fabs(c0mp - c2mp)
                                self.assertTrue(cratiodiffmp <= c0ratiodiffmp
                                                or cabsdiffmp <= c0absdiffmp)
                            if c1.rep['t'] != 'c':
                                c1mp = mp.mpf(
                                    eval(coder.positrep_to_rational_str(
                                        c1.rep)))
                                c1ratiodiffmp = mp.fabs(mp.log(
                                    c1mp /
                                    c2mp)) if c2mp != 0 else mp.fabs(c1mp -
                                                                     c2mp)
                                c1absdiffmp = mp.fabs(c1mp - c2mp)
                                self.assertTrue(cratiodiffmp <= c1ratiodiffmp
                                                or cabsdiffmp <= c1absdiffmp)