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.')
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
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
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
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
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)