Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Ticket #1789: Support half floats via buffer interface #68

Closed
wants to merge 1 commit into from

2 participants

@elistevens

Changes (and tests) to allow exporting half-floats through the buffer interface.

Code:
Added NPY_HALF to switch (descr->type_num) in _buffer_format_string.
Added 'e' keys to the _pep3118_native_map and _pep3118_standard_map.

Tests:
Added entries to the generic round-trip tests.
Added specialized half-float test that round-trips example values from the wikipedia page.

http://en.wikipedia.org/wiki/Half_precision_floating-point_format
http://mail.scipy.org/pipermail/numpy-discussion/2011-March/055795.html
http://projects.scipy.org/numpy/ticket/1789

@elistevens elistevens Changes (and tests) to allow exporting half-floats through the buffer…
… interface.

Code:
Added NPY_HALF to switch (descr->type_num) in _buffer_format_string.
Added 'e' keys to the _pep3118_native_map and _pep3118_standard_map.

Tests:
Added entries to the generic round-trip tests.
Added specialized half-float test that round-trips example values from the wikipedia page.

http://en.wikipedia.org/wiki/Half_precision_floating-point_format
http://mail.scipy.org/pipermail/numpy-discussion/2011-March/055795.html
3357996
@mwiebe mwiebe closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 2, 2011
  1. @elistevens

    Changes (and tests) to allow exporting half-floats through the buffer…

    elistevens authored
    … interface.
    
    Code:
    Added NPY_HALF to switch (descr->type_num) in _buffer_format_string.
    Added 'e' keys to the _pep3118_native_map and _pep3118_standard_map.
    
    Tests:
    Added entries to the generic round-trip tests.
    Added specialized half-float test that round-trips example values from the wikipedia page.
    
    http://en.wikipedia.org/wiki/Half_precision_floating-point_format
    http://mail.scipy.org/pipermail/numpy-discussion/2011-March/055795.html
This page is out of date. Refresh to see the latest.
View
2  numpy/core/_internal.py
@@ -363,6 +363,7 @@ def _index_fields(ary, fields):
'L': 'L',
'q': 'q',
'Q': 'Q',
+ 'e': 'e',
'f': 'f',
'd': 'd',
'g': 'g',
@@ -388,6 +389,7 @@ def _index_fields(ary, fields):
'L': 'u4',
'q': 'i8',
'Q': 'u8',
+ 'e': 'f2',
'f': 'f',
'd': 'd',
'Zf': 'F',
View
1  numpy/core/src/multiarray/buffer.c
@@ -348,6 +348,7 @@ _buffer_format_string(PyArray_Descr *descr, _tmp_string_t *str,
break;
case NPY_LONGLONG: if (_append_char(str, 'q')) return -1; break;
case NPY_ULONGLONG: if (_append_char(str, 'Q')) return -1; break;
+ case NPY_HALF: if (_append_char(str, 'e')) return -1; break;
case NPY_FLOAT: if (_append_char(str, 'f')) return -1; break;
case NPY_DOUBLE: if (_append_char(str, 'd')) return -1; break;
case NPY_LONGDOUBLE: if (_append_char(str, 'g')) return -1; break;
View
35 numpy/core/tests/test_multiarray.py
@@ -1954,9 +1954,11 @@ def test_roundtrip(self):
('l', 'S4'),
('m', 'U4'),
('n', 'V3'),
- ('o', '?')]
+ ('o', '?'),
+ ('p', np.half),
+ ]
x = np.array([(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- asbytes('aaaa'), 'bbbb', asbytes('xxx'), True)],
+ asbytes('aaaa'), 'bbbb', asbytes('xxx'), True, 1.0)],
dtype=dt)
self._check_roundtrip(x)
@@ -1988,6 +1990,25 @@ def test_roundtrip(self):
x = np.array([1,2,3], dtype='<q')
assert_raises(ValueError, self._check_roundtrip, x)
+ def test_roundtrip_half(self):
+ half_list = [
+ 1.0,
+ -2.0,
+ 6.5504 * 10**4, # (max half precision)
+ 2**-14, # ~= 6.10352 * 10**-5 (minimum positive normal)
+ 2**-24, # ~= 5.96046 * 10**-8 (minimum strictly positive subnormal)
+ 0.0,
+ -0.0,
+ float('+inf'),
+ float('-inf'),
+ 0.333251953125, # ~= 1/3
+ ]
+
+ x = np.array(half_list, dtype='>e')
+ self._check_roundtrip(x)
+ x = np.array(half_list, dtype='<e')
+ self._check_roundtrip(x)
+
def test_export_simple_1d(self):
x = np.array([1,2,3,4,5], dtype='i')
y = memoryview(x)
@@ -2038,9 +2059,11 @@ def test_export_record(self):
('l', 'S4'),
('m', 'U4'),
('n', 'V3'),
- ('o', '?')]
+ ('o', '?'),
+ ('p', np.half),
+ ]
x = np.array([(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- asbytes('aaaa'), 'bbbb', asbytes(' '), True)],
+ asbytes('aaaa'), 'bbbb', asbytes(' '), True, 1.0)],
dtype=dt)
y = memoryview(x)
assert_equal(y.shape, (1,))
@@ -2049,9 +2072,9 @@ def test_export_record(self):
sz = sum([dtype(b).itemsize for a, b in dt])
if dtype('l').itemsize == 4:
- assert_equal(y.format, 'T{b:a:=h:b:i:c:l:d:^q:dx:B:e:@H:f:=I:g:L:h:^Q:hx:=f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:}')
+ assert_equal(y.format, 'T{b:a:=h:b:i:c:l:d:^q:dx:B:e:@H:f:=I:g:L:h:^Q:hx:=f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
else:
- assert_equal(y.format, 'T{b:a:=h:b:i:c:q:d:^q:dx:B:e:@H:f:=I:g:Q:h:^Q:hx:=f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:}')
+ assert_equal(y.format, 'T{b:a:=h:b:i:c:q:d:^q:dx:B:e:@H:f:=I:g:Q:h:^Q:hx:=f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
assert_equal(y.strides, (sz,))
assert_equal(y.itemsize, sz)
Something went wrong with that request. Please try again.