Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/ml_dtypes/_finfo.py: 98%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

573 statements  

1# Copyright 2023 The ml_dtypes Authors. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Overload of numpy.finfo to handle dtypes defined in ml_dtypes.""" 

16 

17from ml_dtypes._ml_dtypes_ext import bfloat16 

18from ml_dtypes._ml_dtypes_ext import float4_e2m1fn 

19from ml_dtypes._ml_dtypes_ext import float6_e2m3fn 

20from ml_dtypes._ml_dtypes_ext import float6_e3m2fn 

21from ml_dtypes._ml_dtypes_ext import float8_e3m4 

22from ml_dtypes._ml_dtypes_ext import float8_e4m3 

23from ml_dtypes._ml_dtypes_ext import float8_e4m3b11fnuz 

24from ml_dtypes._ml_dtypes_ext import float8_e4m3fn 

25from ml_dtypes._ml_dtypes_ext import float8_e4m3fnuz 

26from ml_dtypes._ml_dtypes_ext import float8_e5m2 

27from ml_dtypes._ml_dtypes_ext import float8_e5m2fnuz 

28from ml_dtypes._ml_dtypes_ext import float8_e8m0fnu 

29import numpy as np 

30 

31_bfloat16_dtype = np.dtype(bfloat16) 

32_float4_e2m1fn_dtype = np.dtype(float4_e2m1fn) 

33_float6_e2m3fn_dtype = np.dtype(float6_e2m3fn) 

34_float6_e3m2fn_dtype = np.dtype(float6_e3m2fn) 

35_float8_e3m4_dtype = np.dtype(float8_e3m4) 

36_float8_e4m3_dtype = np.dtype(float8_e4m3) 

37_float8_e4m3b11fnuz_dtype = np.dtype(float8_e4m3b11fnuz) 

38_float8_e4m3fn_dtype = np.dtype(float8_e4m3fn) 

39_float8_e4m3fnuz_dtype = np.dtype(float8_e4m3fnuz) 

40_float8_e5m2_dtype = np.dtype(float8_e5m2) 

41_float8_e5m2fnuz_dtype = np.dtype(float8_e5m2fnuz) 

42_float8_e8m0fnu_dtype = np.dtype(float8_e8m0fnu) 

43 

44 

45class _Bfloat16MachArLike: 

46 

47 def __init__(self): 

48 smallest_normal = float.fromhex("0x1p-126") 

49 self.smallest_normal = bfloat16(smallest_normal) 

50 smallest_subnormal = float.fromhex("0x1p-133") 

51 self.smallest_subnormal = bfloat16(smallest_subnormal) 

52 

53 

54class _Float4E2m1fnMachArLike: 

55 

56 def __init__(self): 

57 smallest_normal = float.fromhex("0x1p0") 

58 self.smallest_normal = float4_e2m1fn(smallest_normal) 

59 smallest_subnormal = float.fromhex("0x0.8p0") 

60 self.smallest_subnormal = float4_e2m1fn(smallest_subnormal) 

61 

62 

63class _Float6E2m3fnMachArLike: 

64 

65 def __init__(self): 

66 smallest_normal = float.fromhex("0x1p0") 

67 self.smallest_normal = float6_e2m3fn(smallest_normal) 

68 smallest_subnormal = float.fromhex("0x0.2p0") 

69 self.smallest_subnormal = float6_e2m3fn(smallest_subnormal) 

70 

71 

72class _Float6E3m2fnMachArLike: 

73 

74 def __init__(self): 

75 smallest_normal = float.fromhex("0x1p-2") 

76 self.smallest_normal = float6_e3m2fn(smallest_normal) 

77 smallest_subnormal = float.fromhex("0x0.4p-2") 

78 self.smallest_subnormal = float6_e3m2fn(smallest_subnormal) 

79 

80 

81class _Float8E3m4MachArLike: 

82 

83 def __init__(self): 

84 smallest_normal = float.fromhex("0x1p-2") 

85 self.smallest_normal = float8_e3m4(smallest_normal) 

86 smallest_subnormal = float.fromhex("0x0.1p-2") 

87 self.smallest_subnormal = float8_e3m4(smallest_subnormal) 

88 

89 

90class _Float8E4m3MachArLike: 

91 

92 def __init__(self): 

93 smallest_normal = float.fromhex("0x1p-6") 

94 self.smallest_normal = float8_e4m3(smallest_normal) 

95 smallest_subnormal = float.fromhex("0x0.2p-6") 

96 self.smallest_subnormal = float8_e4m3(smallest_subnormal) 

97 

98 

99class _Float8E4m3b11fnuzMachArLike: 

100 

101 def __init__(self): 

102 smallest_normal = float.fromhex("0x1p-10") 

103 self.smallest_normal = float8_e4m3b11fnuz(smallest_normal) 

104 smallest_subnormal = float.fromhex("0x1p-13") 

105 self.smallest_subnormal = float8_e4m3b11fnuz(smallest_subnormal) 

106 

107 

108class _Float8E4m3fnMachArLike: 

109 

110 def __init__(self): 

111 smallest_normal = float.fromhex("0x1p-6") 

112 self.smallest_normal = float8_e4m3fn(smallest_normal) 

113 smallest_subnormal = float.fromhex("0x1p-9") 

114 self.smallest_subnormal = float8_e4m3fn(smallest_subnormal) 

115 

116 

117class _Float8E4m3fnuzMachArLike: 

118 

119 def __init__(self): 

120 smallest_normal = float.fromhex("0x1p-7") 

121 self.smallest_normal = float8_e4m3fnuz(smallest_normal) 

122 smallest_subnormal = float.fromhex("0x1p-10") 

123 self.smallest_subnormal = float8_e4m3fnuz(smallest_subnormal) 

124 

125 

126class _Float8E5m2MachArLike: 

127 

128 def __init__(self): 

129 smallest_normal = float.fromhex("0x1p-14") 

130 self.smallest_normal = float8_e5m2(smallest_normal) 

131 smallest_subnormal = float.fromhex("0x1p-16") 

132 self.smallest_subnormal = float8_e5m2(smallest_subnormal) 

133 

134 

135class _Float8E5m2fnuzMachArLike: 

136 

137 def __init__(self): 

138 smallest_normal = float.fromhex("0x1p-15") 

139 self.smallest_normal = float8_e5m2fnuz(smallest_normal) 

140 smallest_subnormal = float.fromhex("0x1p-17") 

141 self.smallest_subnormal = float8_e5m2fnuz(smallest_subnormal) 

142 

143 

144class _Float8E8m0fnuMachArLike: 

145 

146 def __init__(self): 

147 smallest_normal = float.fromhex("0x1p-127") 

148 self.smallest_normal = float8_e8m0fnu(smallest_normal) 

149 smallest_subnormal = float.fromhex("0x1p-127") 

150 self.smallest_subnormal = float8_e8m0fnu(smallest_subnormal) 

151 

152 

153class finfo(np.finfo): # pylint: disable=invalid-name,missing-class-docstring 

154 __doc__ = np.finfo.__doc__ 

155 

156 @staticmethod 

157 def _bfloat16_finfo(): 

158 def float_to_str(f): 

159 return "%12.4e" % float(f) 

160 

161 tiny = float.fromhex("0x1p-126") 

162 resolution = 0.01 

163 eps = float.fromhex("0x1p-7") 

164 epsneg = float.fromhex("0x1p-8") 

165 max_ = float.fromhex("0x1.FEp127") 

166 

167 obj = object.__new__(np.finfo) 

168 obj.dtype = _bfloat16_dtype 

169 obj.bits = 16 

170 obj.eps = bfloat16(eps) 

171 obj.epsneg = bfloat16(epsneg) 

172 obj.machep = -7 

173 obj.negep = -8 

174 obj.max = bfloat16(max_) 

175 obj.min = bfloat16(-max_) 

176 obj.nexp = 8 

177 obj.nmant = 7 

178 obj.iexp = obj.nexp 

179 obj.maxexp = 128 

180 obj.minexp = -126 

181 obj.precision = 2 

182 obj.resolution = bfloat16(resolution) 

183 # pylint: disable=protected-access 

184 obj._machar = _Bfloat16MachArLike() 

185 if not hasattr(obj, "tiny"): 

186 obj.tiny = bfloat16(tiny) 

187 if not hasattr(obj, "smallest_normal"): 

188 obj.smallest_normal = obj._machar.smallest_normal 

189 obj.smallest_subnormal = obj._machar.smallest_subnormal 

190 

191 obj._str_tiny = float_to_str(tiny) 

192 obj._str_smallest_normal = float_to_str(tiny) 

193 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

194 obj._str_max = float_to_str(max_) 

195 obj._str_epsneg = float_to_str(epsneg) 

196 obj._str_eps = float_to_str(eps) 

197 obj._str_resolution = float_to_str(resolution) 

198 # pylint: enable=protected-access 

199 return obj 

200 

201 @staticmethod 

202 def _float4_e2m1fn_finfo(): 

203 eps = float.fromhex("0x0.8p0") # 0.5 

204 max_ = float.fromhex("0x1.8p2") # 6.0 

205 

206 obj = object.__new__(np.finfo) 

207 obj.dtype = _float4_e2m1fn_dtype 

208 obj.bits = 4 

209 obj.eps = eps 

210 obj.epsneg = eps 

211 obj.machep = -1 

212 obj.negep = -1 

213 obj.max = float4_e2m1fn(max_) 

214 obj.min = float4_e2m1fn(-max_) 

215 obj.nexp = 2 

216 obj.nmant = 1 

217 obj.iexp = obj.nexp 

218 obj.maxexp = 3 

219 obj.minexp = 0 

220 obj.precision = 0 

221 obj.resolution = float4_e2m1fn(1.0) 

222 # pylint: disable=protected-access 

223 obj._machar = _Float4E2m1fnMachArLike() 

224 tiny = obj._machar.smallest_normal 

225 if not hasattr(obj, "tiny"): 

226 obj.tiny = tiny 

227 if not hasattr(obj, "smallest_normal"): 

228 obj.smallest_normal = tiny 

229 obj.smallest_subnormal = obj._machar.smallest_subnormal 

230 

231 float_to_str = str 

232 obj._str_tiny = float_to_str(tiny) 

233 obj._str_smallest_normal = float_to_str(tiny) 

234 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

235 obj._str_max = float_to_str(obj.max) 

236 obj._str_epsneg = float_to_str(obj.epsneg) 

237 obj._str_eps = float_to_str(obj.eps) 

238 obj._str_resolution = float_to_str(obj.resolution) 

239 # pylint: enable=protected-access 

240 return obj 

241 

242 @staticmethod 

243 def _float6_e2m3fn_finfo(): 

244 eps = float.fromhex("0x0.2p0") # 0.125 

245 max_ = float.fromhex("0x1.Ep2") # 7.5 

246 

247 obj = object.__new__(np.finfo) 

248 obj.dtype = _float6_e2m3fn_dtype 

249 obj.bits = 6 

250 obj.eps = eps 

251 obj.epsneg = eps 

252 obj.machep = -3 

253 obj.negep = -3 

254 obj.max = float6_e2m3fn(max_) 

255 obj.min = float6_e2m3fn(-max_) 

256 obj.nexp = 2 

257 obj.nmant = 3 

258 obj.iexp = obj.nexp 

259 obj.maxexp = 3 

260 obj.minexp = 0 

261 obj.precision = 0 

262 obj.resolution = float6_e2m3fn(1.0) 

263 # pylint: disable=protected-access 

264 obj._machar = _Float6E2m3fnMachArLike() 

265 tiny = obj._machar.smallest_normal 

266 if not hasattr(obj, "tiny"): 

267 obj.tiny = tiny 

268 if not hasattr(obj, "smallest_normal"): 

269 obj.smallest_normal = tiny 

270 obj.smallest_subnormal = obj._machar.smallest_subnormal 

271 

272 float_to_str = str 

273 obj._str_tiny = float_to_str(tiny) 

274 obj._str_smallest_normal = float_to_str(tiny) 

275 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

276 obj._str_max = float_to_str(obj.max) 

277 obj._str_epsneg = float_to_str(obj.epsneg) 

278 obj._str_eps = float_to_str(obj.eps) 

279 obj._str_resolution = float_to_str(obj.resolution) 

280 # pylint: enable=protected-access 

281 return obj 

282 

283 @staticmethod 

284 def _float6_e3m2fn_finfo(): 

285 eps = float.fromhex("0x1p-2") # 0.25 

286 max_ = float.fromhex("0x1.Cp4") # 28 

287 

288 obj = object.__new__(np.finfo) 

289 obj.dtype = _float6_e3m2fn_dtype 

290 obj.bits = 6 

291 obj.eps = eps 

292 obj.epsneg = eps / 2 

293 obj.machep = -2 

294 obj.negep = -3 

295 obj.max = float6_e3m2fn(max_) 

296 obj.min = float6_e3m2fn(-max_) 

297 obj.nexp = 3 

298 obj.nmant = 2 

299 obj.iexp = obj.nexp 

300 obj.maxexp = 5 

301 obj.minexp = -2 

302 obj.precision = 0 

303 obj.resolution = float6_e3m2fn(1.0) 

304 # pylint: disable=protected-access 

305 obj._machar = _Float6E3m2fnMachArLike() 

306 tiny = obj._machar.smallest_normal 

307 if not hasattr(obj, "tiny"): 

308 obj.tiny = tiny 

309 if not hasattr(obj, "smallest_normal"): 

310 obj.smallest_normal = tiny 

311 obj.smallest_subnormal = obj._machar.smallest_subnormal 

312 

313 float_to_str = str 

314 obj._str_tiny = float_to_str(tiny) 

315 obj._str_smallest_normal = float_to_str(tiny) 

316 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

317 obj._str_max = float_to_str(obj.max) 

318 obj._str_epsneg = float_to_str(obj.epsneg) 

319 obj._str_eps = float_to_str(obj.eps) 

320 obj._str_resolution = float_to_str(obj.resolution) 

321 # pylint: enable=protected-access 

322 return obj 

323 

324 @staticmethod 

325 def _float8_e3m4_finfo(): 

326 def float_to_str(f): 

327 return "%6.2e" % float(f) 

328 

329 tiny = float.fromhex("0x1p-2") # 1/4 min normal 

330 resolution = 0.1 

331 eps = float.fromhex("0x1p-4") # 1/16 

332 epsneg = float.fromhex("0x1p-5") # 1/32 

333 max_ = float.fromhex("0x1.Fp3") # 15.5 max normal 

334 

335 obj = object.__new__(np.finfo) 

336 obj.dtype = _float8_e3m4_dtype 

337 obj.bits = 8 

338 obj.eps = float8_e3m4(eps) 

339 obj.epsneg = float8_e3m4(epsneg) 

340 obj.machep = -4 

341 obj.negep = -5 

342 obj.max = float8_e3m4(max_) 

343 obj.min = float8_e3m4(-max_) 

344 obj.nexp = 3 

345 obj.nmant = 4 

346 obj.iexp = obj.nexp 

347 obj.maxexp = 4 

348 obj.minexp = -2 

349 obj.precision = 1 

350 obj.resolution = float8_e3m4(resolution) 

351 # pylint: disable=protected-access 

352 obj._machar = _Float8E3m4MachArLike() 

353 if not hasattr(obj, "tiny"): 

354 obj.tiny = float8_e3m4(tiny) 

355 if not hasattr(obj, "smallest_normal"): 

356 obj.smallest_normal = obj._machar.smallest_normal 

357 obj.smallest_subnormal = obj._machar.smallest_subnormal 

358 

359 obj._str_tiny = float_to_str(tiny) 

360 obj._str_smallest_normal = float_to_str(tiny) 

361 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

362 obj._str_max = float_to_str(max_) 

363 obj._str_epsneg = float_to_str(epsneg) 

364 obj._str_eps = float_to_str(eps) 

365 obj._str_resolution = float_to_str(resolution) 

366 # pylint: enable=protected-access 

367 return obj 

368 

369 @staticmethod 

370 def _float8_e4m3_finfo(): 

371 def float_to_str(f): 

372 return "%6.2e" % float(f) 

373 

374 tiny = float.fromhex("0x1p-6") # 1/64 min normal 

375 resolution = 0.1 

376 eps = float.fromhex("0x1p-3") # 1/8 

377 epsneg = float.fromhex("0x1p-4") # 1/16 

378 max_ = float.fromhex("0x1.Ep7") # 240 max normal 

379 

380 obj = object.__new__(np.finfo) 

381 obj.dtype = _float8_e4m3_dtype 

382 obj.bits = 8 

383 obj.eps = float8_e4m3(eps) 

384 obj.epsneg = float8_e4m3(epsneg) 

385 obj.machep = -3 

386 obj.negep = -4 

387 obj.max = float8_e4m3(max_) 

388 obj.min = float8_e4m3(-max_) 

389 obj.nexp = 4 

390 obj.nmant = 3 

391 obj.iexp = obj.nexp 

392 obj.maxexp = 8 

393 obj.minexp = -6 

394 obj.precision = 1 

395 obj.resolution = float8_e4m3(resolution) 

396 # pylint: disable=protected-access 

397 obj._machar = _Float8E4m3MachArLike() 

398 if not hasattr(obj, "tiny"): 

399 obj.tiny = float8_e4m3(tiny) 

400 if not hasattr(obj, "smallest_normal"): 

401 obj.smallest_normal = obj._machar.smallest_normal 

402 obj.smallest_subnormal = obj._machar.smallest_subnormal 

403 

404 obj._str_tiny = float_to_str(tiny) 

405 obj._str_smallest_normal = float_to_str(tiny) 

406 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

407 obj._str_max = float_to_str(max_) 

408 obj._str_epsneg = float_to_str(epsneg) 

409 obj._str_eps = float_to_str(eps) 

410 obj._str_resolution = float_to_str(resolution) 

411 # pylint: enable=protected-access 

412 return obj 

413 

414 @staticmethod 

415 def _float8_e4m3b11fnuz_finfo(): 

416 def float_to_str(f): 

417 return "%6.2e" % float(f) 

418 

419 tiny = float.fromhex("0x1p-10") 

420 resolution = 0.1 

421 eps = float.fromhex("0x1p-3") 

422 epsneg = float.fromhex("0x1p-4") 

423 max_ = float.fromhex("0x1.Ep4") 

424 

425 obj = object.__new__(np.finfo) 

426 obj.dtype = _float8_e4m3b11fnuz_dtype 

427 obj.bits = 8 

428 obj.eps = float8_e4m3b11fnuz(eps) 

429 obj.epsneg = float8_e4m3b11fnuz(epsneg) 

430 obj.machep = -3 

431 obj.negep = -4 

432 obj.max = float8_e4m3b11fnuz(max_) 

433 obj.min = float8_e4m3b11fnuz(-max_) 

434 obj.nexp = 4 

435 obj.nmant = 3 

436 obj.iexp = obj.nexp 

437 obj.maxexp = 5 

438 obj.minexp = -10 

439 obj.precision = 1 

440 obj.resolution = float8_e4m3b11fnuz(resolution) 

441 # pylint: disable=protected-access 

442 obj._machar = _Float8E4m3b11fnuzMachArLike() 

443 if not hasattr(obj, "tiny"): 

444 obj.tiny = float8_e4m3b11fnuz(tiny) 

445 if not hasattr(obj, "smallest_normal"): 

446 obj.smallest_normal = obj._machar.smallest_normal 

447 obj.smallest_subnormal = obj._machar.smallest_subnormal 

448 

449 obj._str_tiny = float_to_str(tiny) 

450 obj._str_smallest_normal = float_to_str(tiny) 

451 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

452 obj._str_max = float_to_str(max_) 

453 obj._str_epsneg = float_to_str(epsneg) 

454 obj._str_eps = float_to_str(eps) 

455 obj._str_resolution = float_to_str(resolution) 

456 # pylint: enable=protected-access 

457 return obj 

458 

459 @staticmethod 

460 def _float8_e4m3fn_finfo(): 

461 def float_to_str(f): 

462 return "%6.2e" % float(f) 

463 

464 tiny = float.fromhex("0x1p-6") 

465 resolution = 0.1 

466 eps = float.fromhex("0x1p-3") 

467 epsneg = float.fromhex("0x1p-4") 

468 max_ = float.fromhex("0x1.Cp8") 

469 

470 obj = object.__new__(np.finfo) 

471 obj.dtype = _float8_e4m3fn_dtype 

472 obj.bits = 8 

473 obj.eps = float8_e4m3fn(eps) 

474 obj.epsneg = float8_e4m3fn(epsneg) 

475 obj.machep = -3 

476 obj.negep = -4 

477 obj.max = float8_e4m3fn(max_) 

478 obj.min = float8_e4m3fn(-max_) 

479 obj.nexp = 4 

480 obj.nmant = 3 

481 obj.iexp = obj.nexp 

482 obj.maxexp = 9 

483 obj.minexp = -6 

484 obj.precision = 1 

485 obj.resolution = float8_e4m3fn(resolution) 

486 # pylint: disable=protected-access 

487 obj._machar = _Float8E4m3fnMachArLike() 

488 if not hasattr(obj, "tiny"): 

489 obj.tiny = float8_e4m3fn(tiny) 

490 if not hasattr(obj, "smallest_normal"): 

491 obj.smallest_normal = obj._machar.smallest_normal 

492 obj.smallest_subnormal = obj._machar.smallest_subnormal 

493 

494 obj._str_tiny = float_to_str(tiny) 

495 obj._str_smallest_normal = float_to_str(tiny) 

496 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

497 obj._str_max = float_to_str(max_) 

498 obj._str_epsneg = float_to_str(epsneg) 

499 obj._str_eps = float_to_str(eps) 

500 obj._str_resolution = float_to_str(resolution) 

501 # pylint: enable=protected-access 

502 return obj 

503 

504 @staticmethod 

505 def _float8_e4m3fnuz_finfo(): 

506 def float_to_str(f): 

507 return "%6.2e" % float(f) 

508 

509 tiny = float.fromhex("0x1p-7") 

510 resolution = 0.1 

511 eps = float.fromhex("0x1p-3") 

512 epsneg = float.fromhex("0x1p-4") 

513 max_ = float.fromhex("0x1.Ep7") 

514 

515 obj = object.__new__(np.finfo) 

516 obj.dtype = _float8_e4m3fnuz_dtype 

517 obj.bits = 8 

518 obj.eps = float8_e4m3fnuz(eps) 

519 obj.epsneg = float8_e4m3fnuz(epsneg) 

520 obj.machep = -3 

521 obj.negep = -4 

522 obj.max = float8_e4m3fnuz(max_) 

523 obj.min = float8_e4m3fnuz(-max_) 

524 obj.nexp = 4 

525 obj.nmant = 3 

526 obj.iexp = obj.nexp 

527 obj.maxexp = 8 

528 obj.minexp = -7 

529 obj.precision = 1 

530 obj.resolution = float8_e4m3fnuz(resolution) 

531 # pylint: disable=protected-access 

532 obj._machar = _Float8E4m3fnuzMachArLike() 

533 if not hasattr(obj, "tiny"): 

534 obj.tiny = float8_e4m3fnuz(tiny) 

535 if not hasattr(obj, "smallest_normal"): 

536 obj.smallest_normal = obj._machar.smallest_normal 

537 obj.smallest_subnormal = obj._machar.smallest_subnormal 

538 

539 obj._str_tiny = float_to_str(tiny) 

540 obj._str_smallest_normal = float_to_str(tiny) 

541 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

542 obj._str_max = float_to_str(max_) 

543 obj._str_epsneg = float_to_str(epsneg) 

544 obj._str_eps = float_to_str(eps) 

545 obj._str_resolution = float_to_str(resolution) 

546 # pylint: enable=protected-access 

547 return obj 

548 

549 @staticmethod 

550 def _float8_e5m2_finfo(): 

551 def float_to_str(f): 

552 return "%6.2e" % float(f) 

553 

554 tiny = float.fromhex("0x1p-14") 

555 resolution = 0.1 

556 eps = float.fromhex("0x1p-2") 

557 epsneg = float.fromhex("0x1p-3") 

558 max_ = float.fromhex("0x1.Cp15") 

559 

560 obj = object.__new__(np.finfo) 

561 obj.dtype = _float8_e5m2_dtype 

562 obj.bits = 8 

563 obj.eps = float8_e5m2(eps) 

564 obj.epsneg = float8_e5m2(epsneg) 

565 obj.machep = -2 

566 obj.negep = -3 

567 obj.max = float8_e5m2(max_) 

568 obj.min = float8_e5m2(-max_) 

569 obj.nexp = 5 

570 obj.nmant = 2 

571 obj.iexp = obj.nexp 

572 obj.maxexp = 16 

573 obj.minexp = -14 

574 obj.precision = 1 

575 obj.resolution = float8_e5m2(resolution) 

576 # pylint: disable=protected-access 

577 obj._machar = _Float8E5m2MachArLike() 

578 if not hasattr(obj, "tiny"): 

579 obj.tiny = float8_e5m2(tiny) 

580 if not hasattr(obj, "smallest_normal"): 

581 obj.smallest_normal = obj._machar.smallest_normal 

582 obj.smallest_subnormal = obj._machar.smallest_subnormal 

583 

584 obj._str_tiny = float_to_str(tiny) 

585 obj._str_smallest_normal = float_to_str(tiny) 

586 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

587 obj._str_max = float_to_str(max_) 

588 obj._str_epsneg = float_to_str(epsneg) 

589 obj._str_eps = float_to_str(eps) 

590 obj._str_resolution = float_to_str(resolution) 

591 # pylint: enable=protected-access 

592 return obj 

593 

594 @staticmethod 

595 def _float8_e5m2fnuz_finfo(): 

596 def float_to_str(f): 

597 return "%6.2e" % float(f) 

598 

599 tiny = float.fromhex("0x1p-15") 

600 resolution = 0.1 

601 eps = float.fromhex("0x1p-2") 

602 epsneg = float.fromhex("0x1p-3") 

603 max_ = float.fromhex("0x1.Cp15") 

604 

605 obj = object.__new__(np.finfo) 

606 obj.dtype = _float8_e5m2fnuz_dtype 

607 obj.bits = 8 

608 obj.eps = float8_e5m2fnuz(eps) 

609 obj.epsneg = float8_e5m2fnuz(epsneg) 

610 obj.machep = -2 

611 obj.negep = -3 

612 obj.max = float8_e5m2fnuz(max_) 

613 obj.min = float8_e5m2fnuz(-max_) 

614 obj.nexp = 5 

615 obj.nmant = 2 

616 obj.iexp = obj.nexp 

617 obj.maxexp = 16 

618 obj.minexp = -15 

619 obj.precision = 1 

620 obj.resolution = float8_e5m2fnuz(resolution) 

621 # pylint: disable=protected-access 

622 obj._machar = _Float8E5m2fnuzMachArLike() 

623 if not hasattr(obj, "tiny"): 

624 obj.tiny = float8_e5m2fnuz(tiny) 

625 if not hasattr(obj, "smallest_normal"): 

626 obj.smallest_normal = obj._machar.smallest_normal 

627 obj.smallest_subnormal = obj._machar.smallest_subnormal 

628 

629 obj._str_tiny = float_to_str(tiny) 

630 obj._str_smallest_normal = float_to_str(tiny) 

631 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

632 obj._str_max = float_to_str(max_) 

633 obj._str_epsneg = float_to_str(epsneg) 

634 obj._str_eps = float_to_str(eps) 

635 obj._str_resolution = float_to_str(resolution) 

636 # pylint: enable=protected-access 

637 return obj 

638 

639 @staticmethod 

640 def _float8_e8m0fnu_finfo(): 

641 def float_to_str(f): 

642 return "%6.2e" % float(f) 

643 

644 tiny = float.fromhex("0x1p-127") 

645 resolution = 0.1 

646 eps = float.fromhex("0x1p+0") 

647 epsneg = float.fromhex("0x1p-1") 

648 max_ = float.fromhex("0x1p+127") 

649 

650 obj = object.__new__(np.finfo) 

651 obj.dtype = _float8_e8m0fnu_dtype 

652 obj.bits = 8 

653 obj.eps = float8_e8m0fnu(eps) 

654 obj.epsneg = float8_e8m0fnu(epsneg) 

655 obj.machep = 0 

656 obj.negep = -1 

657 obj.max = float8_e8m0fnu(max_) 

658 obj.min = float8_e8m0fnu(tiny) 

659 obj.nexp = 8 

660 obj.nmant = 0 

661 obj.iexp = obj.nexp 

662 obj.maxexp = 128 

663 obj.minexp = -127 

664 obj.precision = 1 

665 obj.resolution = float8_e8m0fnu(resolution) 

666 # pylint: disable=protected-access 

667 obj._machar = _Float8E8m0fnuMachArLike() 

668 if not hasattr(obj, "tiny"): 

669 obj.tiny = float8_e8m0fnu(tiny) 

670 if not hasattr(obj, "smallest_normal"): 

671 obj.smallest_normal = obj._machar.smallest_normal 

672 obj.smallest_subnormal = obj._machar.smallest_subnormal 

673 

674 obj._str_tiny = float_to_str(tiny) 

675 obj._str_smallest_normal = float_to_str(tiny) 

676 obj._str_smallest_subnormal = float_to_str(obj.smallest_subnormal) 

677 obj._str_max = float_to_str(max_) 

678 obj._str_epsneg = float_to_str(epsneg) 

679 obj._str_eps = float_to_str(eps) 

680 obj._str_resolution = float_to_str(resolution) 

681 # pylint: enable=protected-access 

682 return obj 

683 

684 _finfo_type_map = { 

685 _bfloat16_dtype: _bfloat16_finfo, 

686 _float4_e2m1fn_dtype: _float4_e2m1fn_finfo, 

687 _float6_e2m3fn_dtype: _float6_e2m3fn_finfo, 

688 _float6_e3m2fn_dtype: _float6_e3m2fn_finfo, 

689 _float8_e3m4_dtype: _float8_e3m4_finfo, 

690 _float8_e4m3_dtype: _float8_e4m3_finfo, 

691 _float8_e4m3fn_dtype: _float8_e4m3fn_finfo, 

692 _float8_e4m3fnuz_dtype: _float8_e4m3fnuz_finfo, 

693 _float8_e4m3b11fnuz_dtype: _float8_e4m3b11fnuz_finfo, 

694 _float8_e5m2_dtype: _float8_e5m2_finfo, 

695 _float8_e5m2fnuz_dtype: _float8_e5m2fnuz_finfo, 

696 _float8_e8m0fnu_dtype: _float8_e8m0fnu_finfo, 

697 } 

698 _finfo_name_map = {t.name: t for t in _finfo_type_map} 

699 _finfo_cache = { 

700 t: init_fn.__func__() # pytype: disable=attribute-error 

701 for t, init_fn in _finfo_type_map.items() 

702 } 

703 

704 def __new__(cls, dtype): 

705 if isinstance(dtype, str): 

706 key = cls._finfo_name_map.get(dtype) 

707 elif isinstance(dtype, np.dtype): 

708 key = dtype 

709 else: 

710 key = np.dtype(dtype) 

711 i = cls._finfo_cache.get(key) 

712 if i is not None: 

713 return i 

714 return super().__new__(cls, dtype)