Esempio n. 1
0
    def __init__(self, v=None, mode=None, nbits=None, es=None):
        nbits_given = True
        es_given = True
        if nbits is None:
            nbits_given = False
            nbits = 32
        if es is None:
            es_given = False
            es = 2

        if v is None:
            self.rep = coder.create_zero_positrep(nbits=nbits, es=es)
            return
        elif isinstance(v, PCPosit):
            if nbits_given and v.rep['nbits'] != nbits:
                raise NotImplementedError('Mismatched nbits posit conversion is not implemented.')
            if es_given and v.rep['es'] != es:
                raise NotImplementedError('Mismatched es posit conversion is not implemented.')
            self.rep = coder.copy_positrep(v.rep)
            return
        elif mode == 'bits':
            if isinstance(v, int):
                self.rep = coder.decode_posit_binary(v, nbits=nbits, es=es)
                return
            elif isinstance(v, str):
                raise NotImplementedError('Binary bit string posit conversion is not implemented.')

        raise ValueError('Input is not supported.')
Esempio n. 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
Esempio n. 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
Esempio n. 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
Esempio n. 5
0
    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
Esempio n. 6
0
    def __init__(self, v=None, mode=None, nbits=None, es=None, force=False):
        nbits_given = True
        es_given = True
        if nbits is None:
            nbits_given = False
            nbits = 32
        if es is None:
            es_given = False
            es = 2

        if v is None:
            self.rep = coder.create_zero_positrep(nbits=nbits, es=es)
            return
        elif isinstance(v, PCPosit):
            if not nbits_given:
                nbits = v.rep['nbits']
            if not es_given:
                es = v.rep['es']
            env_adjusted = v._resize_env(nbits, es)
            self.rep = coder.copy_positrep(env_adjusted.rep)
            return 
        elif mode == 'bits':
            if isinstance(v, numbers.Integral):
                self.rep = coder.decode_posit_binary(v, nbits=nbits, es=es)
                return
            elif isinstance(v, str):
                raise NotImplementedError('Binary bit string posit conversion is not implemented.')
        elif isinstance(v, str):
            if v in {'cinf'}:
                self.rep = coder.create_cinf_positrep(nbits=nbits, es=es)
            elif v == '0':
                self.rep = coder.create_zero_positrep(nbits=nbits, es=es)
            else:
                raise ValueError('Expect 0 or cinf posit constant from the input string.')

            return
        if force:
            return self._force_to_posit(v)
        raise ValueError('Input is not supported.')
    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)