Skip to content

Commit 5b934d7

Browse files
authoredAug 19, 2024··
Merge pull request #1196 from Thrameos/numpy2.0
Changes for numpy 2.0 to fix test matrix.
2 parents 653ccff + f6849c5 commit 5b934d7

10 files changed

+135
-29
lines changed
 

‎doc/CHANGELOG.rst

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ Latest Changes:
1919
For editable installs, ``python setup.py --enable-tracing develop``
2020
must now be done with ``python setup.py develop --enable-tracing``.
2121

22+
- Update for tests for numpy 2.0.
23+
24+
- Support of np.float16 conversion with arrays.
25+
26+
2227
- **1.5.0 - 2023-04-03**
2328

2429
- Support for Python 3.12

‎native/common/jp_convert.cpp

+76
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,61 @@
1414
See NOTICE file for details.
1515
*****************************************************************************/
1616
#include "jpype.h"
17+
#include <math.h>
18+
#include <bitset>
1719

1820
namespace
1921
{
2022

23+
template <jvalue func(void *c) >
24+
class Half
25+
{
26+
public:
27+
static jvalue convert(void* c)
28+
{
29+
uint16_t i = *(uint16_t*) c;
30+
uint32_t sign = (i&0x8000)>>15;
31+
uint32_t man = (i&0x7C00)>>10;
32+
uint32_t frac = (i&0x03ff);
33+
uint32_t k = sign<<31;
34+
35+
if (man == 0)
36+
{
37+
// subnormal numbers
38+
if (frac != 0)
39+
{
40+
frac = frac | (frac >> 1);
41+
frac = frac | (frac >> 2);
42+
frac = frac | (frac >> 4);
43+
frac = frac | (frac >> 8);
44+
int zeros = std::bitset<32>(~frac).count();
45+
man = 127-zeros+7;
46+
man <<= 23;
47+
frac <<= zeros-8;
48+
frac &= 0x7fffff;
49+
k |= man | frac;
50+
}
51+
}
52+
else if (man < 31)
53+
{
54+
// normal numbers
55+
man = man-15+127;
56+
man <<= 23;
57+
frac <<= 13;
58+
k |= man | frac;
59+
}
60+
else
61+
{
62+
// to infinity and beyond!
63+
if (frac == 0)
64+
k |= 0x7f800000;
65+
else
66+
k |= 0x7f800001 | ((frac&0x200)<<12);
67+
}
68+
return func(&k);
69+
}
70+
};
71+
2172
template <class T>
2273
class Convert
2374
{
@@ -385,6 +436,31 @@ jconverter getConverter(const char* from, int itemsize, const char* to)
385436
case 'd': return &Convert<double>::toD;
386437
}
387438
break;
439+
case 'e':
440+
if (reverse) switch (to[0])
441+
{
442+
case 'z': return &Reverse<Half<Convert<float>::toZ>::convert>::call4;
443+
case 'b': return &Reverse<Half<Convert<float>::toB>::convert>::call4;
444+
case 'c': return &Reverse<Half<Convert<float>::toC>::convert>::call4;
445+
case 's': return &Reverse<Half<Convert<float>::toS>::convert>::call4;
446+
case 'i': return &Reverse<Half<Convert<float>::toI>::convert>::call4;
447+
case 'j': return &Reverse<Half<Convert<float>::toJ>::convert>::call4;
448+
case 'f': return &Reverse<Half<Convert<float>::toF>::convert>::call4;
449+
case 'd': return &Reverse<Half<Convert<float>::toD>::convert>::call4;
450+
}
451+
else switch (to[0])
452+
{
453+
case 'z': return &Half<Convert<float>::toZ>::convert;
454+
case 'b': return &Half<Convert<float>::toB>::convert;
455+
case 'c': return &Half<Convert<float>::toC>::convert;
456+
case 's': return &Half<Convert<float>::toS>::convert;
457+
case 'i': return &Half<Convert<float>::toI>::convert;
458+
case 'j': return &Half<Convert<float>::toJ>::convert;
459+
case 'f': return &Half<Convert<float>::toF>::convert;
460+
case 'd': return &Half<Convert<float>::toD>::convert;
461+
}
462+
break;
463+
388464
case 'n':
389465
if (reverse) switch (to[0])
390466
{

‎test/jpypetest/test_buffer.py

+16-15
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,11 @@ def testMemoryByte(self):
315315
jtype = jpype.JByte[:]
316316

317317
# Simple checks
318-
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
318+
for dtype in "c?bBhHiIlLqQfdnN":
319319
jtype(mv.cast(dtype))
320320
jtype(mv.cast("@" + dtype))
321321

322-
for dtype in ("s", "p", "P", "e"):
322+
for dtype in "spP":
323323
with self.assertRaises(Exception):
324324
jtype(mv.cast(dtype))
325325

@@ -328,11 +328,12 @@ def testMemoryInt(self):
328328
jtype = jpype.JInt[:]
329329

330330
# Simple checks
331-
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
331+
for dtype in "c?bBhHiIlLqQfdnN":
332+
print(dtype)
332333
jtype(mv.cast(dtype))
333334
jtype(mv.cast("@" + dtype))
334335

335-
for dtype in ("s", "p", "P", "e"):
336+
for dtype in "spP":
336337
with self.assertRaises(Exception):
337338
jtype(mv.cast(dtype))
338339

@@ -341,11 +342,11 @@ def testMemoryShort(self):
341342
jtype = jpype.JShort[:]
342343

343344
# Simple checks
344-
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
345+
for dtype in "c?bBhHiIlLqQfdnN":
345346
jtype(mv.cast(dtype))
346347
jtype(mv.cast("@" + dtype))
347348

348-
for dtype in ("s", "p", "P", "e"):
349+
for dtype in "spP":
349350
with self.assertRaises(Exception):
350351
jtype(mv.cast(dtype))
351352

@@ -354,11 +355,11 @@ def testMemoryLong(self):
354355
jtype = jpype.JLong[:]
355356

356357
# Simple checks
357-
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
358+
for dtype in "c?bBhHiIlLqQfdnN":
358359
jtype(mv.cast(dtype))
359360
jtype(mv.cast("@" + dtype))
360361

361-
for dtype in ("s", "p", "P", "e"):
362+
for dtype in "spP":
362363
with self.assertRaises(Exception):
363364
jtype(mv.cast(dtype))
364365

@@ -367,11 +368,11 @@ def testMemoryFloat(self):
367368
jtype = jpype.JFloat[:]
368369

369370
# Simple checks
370-
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
371+
for dtype in "c?bBhHiIlLqQfdnN":
371372
jtype(mv.cast(dtype))
372373
jtype(mv.cast("@" + dtype))
373374

374-
for dtype in ("s", "p", "P", "e"):
375+
for dtype in "spP":
375376
with self.assertRaises(Exception):
376377
jtype(mv.cast(dtype))
377378

@@ -380,11 +381,11 @@ def testMemoryDouble(self):
380381
jtype = jpype.JDouble[:]
381382

382383
# Simple checks
383-
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
384+
for dtype in "c?bBhHiIlLqQfdnN":
384385
jtype(mv.cast(dtype))
385386
jtype(mv.cast("@" + dtype))
386387

387-
for dtype in ("s", "p", "P", "e"):
388+
for dtype in "spP":
388389
with self.assertRaises(Exception):
389390
jtype(mv.cast(dtype))
390391

@@ -393,11 +394,11 @@ def testMemoryBoolean(self):
393394
jtype = jpype.JBoolean[:]
394395

395396
# Simple checks
396-
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "f", "d", "n", "N"):
397+
for dtype in "c?bBhHiIlLqQfdnN":
397398
jtype(mv.cast(dtype))
398399
jtype(mv.cast("@" + dtype))
399400

400-
for dtype in ("s", "p", "P", "e"):
401+
for dtype in "spP":
401402
with self.assertRaises(Exception):
402403
jtype(mv.cast(dtype))
403404

@@ -406,7 +407,7 @@ def testMemoryChar(self):
406407
jtype = jpype.JChar[:]
407408

408409
# Simple checks
409-
for dtype in ("c", "?", "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", "n", "N"):
410+
for dtype in "c?bBhHiIlLqQnN":
410411
jtype(mv.cast(dtype))
411412
jtype(mv.cast("@" + dtype))
412413

‎test/jpypetest/test_conversionInt.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ def testIntFromFloat(self):
7373
self.Test.callInt(float(2))
7474

7575
@common.unittest.skipUnless(haveNumpy(), "numpy not available")
76-
def testIntFromNPFloat(self):
76+
def testIntFromNPFloat16(self):
7777
import numpy as np
7878
with self.assertRaises(TypeError):
79-
self.Test.callInt(np.float_(2))
79+
self.Test.callInt(np.float16(2))
8080

8181
@common.unittest.skipUnless(haveNumpy(), "numpy not available")
8282
def testIntFromNPFloat32(self):

‎test/jpypetest/test_conversionLong.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ def testLongFromFloat(self):
7373
self.Test.callLong(float(2))
7474

7575
@common.unittest.skipUnless(haveNumpy(), "numpy not available")
76-
def testLongFromNPFloat(self):
76+
def testLongFromNPFloat16(self):
7777
import numpy as np
7878
with self.assertRaises(TypeError):
79-
self.Test.callLong(np.float_(2))
79+
self.Test.callLong(np.float16(2))
8080

8181
@common.unittest.skipUnless(haveNumpy(), "numpy not available")
8282
def testLongFromNPFloat32(self):

‎test/jpypetest/test_conversionShort.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ def testShortFromFloat(self):
7373
self.Test.callShort(float(2))
7474

7575
@common.unittest.skipUnless(haveNumpy(), "numpy not available")
76-
def testShortFromNPFloat(self):
76+
def testShortFromNPFloat16(self):
7777
import numpy as np
7878
with self.assertRaises(TypeError):
79-
self.Test.callShort(np.float_(2))
79+
self.Test.callShort(np.float16(2))
8080

8181
@common.unittest.skipUnless(haveNumpy(), "numpy not available")
8282
def testShortFromNPFloat32(self):

‎test/jpypetest/test_jboolean.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ def testBooleanFromFloat(self):
100100
self.Test.callBoolean(float(2))
101101

102102
@common.requireNumpy
103-
def testBooleanFromNPFloat(self):
103+
def testBooleanFromNPFloat16(self):
104104
import numpy as np
105105
with self.assertRaises(TypeError):
106-
self.Test.callBoolean(np.float_(2))
106+
self.Test.callBoolean(np.float16(2))
107107

108108
@common.requireNumpy
109109
def testBooleanFromNPFloat32(self):

‎test/jpypetest/test_jbyte.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ def testByteFromFloat(self):
108108
self.fixture.callByte(float(2))
109109

110110
@common.requireNumpy
111-
def testByteFromNPFloat(self):
111+
def testByteFromNPFloat16(self):
112112
import numpy as np
113113
with self.assertRaises(TypeError):
114-
self.fixture.callByte(np.float_(2))
114+
self.fixture.callByte(np.float16(2))
115115

116116
@common.requireNumpy
117117
def testByteFromNPFloat32(self):

‎test/jpypetest/test_jdouble.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ def testArraySetFromNPDouble(self):
374374
self.assertElementsAlmostEqual(a, jarr)
375375

376376
@common.requireNumpy
377-
def testArrayInitFromNPFloat(self):
378-
a = np.random.random(100).astype(np.float_)
377+
def testArrayInitFromNPFloat16(self):
378+
a = np.random.random(100).astype(np.float16)
379379
jarr = JArray(JDouble)(a)
380380
self.assertElementsAlmostEqual(a, jarr)
381381

@@ -436,3 +436,15 @@ def __len__(self):
436436

437437
def testCastBoolean(self):
438438
self.assertEqual(JDouble._canConvertToJava(JBoolean(True)), "none")
439+
440+
@common.requireNumpy
441+
def testNPFloat16(self):
442+
v= [0.000000e+00, 5.960464e-08, 1.788139e-07, 1.788139e-07, 4.172325e-07, 8.940697e-07, 1.847744e-06, 3.755093e-06, 7.569790e-06, 1.519918e-05, 3.045797e-05, 6.097555e-05, 6.103516e-05, 3.332520e-01, 1.000000e+00, 6.550400e+04, np.inf, -np.inf]
443+
a = np.array(v, dtype=np.float16)
444+
jarr = JArray(JDouble)(a)
445+
for v1,v2 in zip(a, jarr):
446+
self.assertEqual(v1,v2)
447+
a = np.array([np.nan], dtype=np.float16)
448+
jarr = JArray(JDouble)(a)
449+
self.assertTrue(np.isnan(jarr[0]))
450+

‎test/jpypetest/test_jfloat.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@ def testArraySetFromNPDouble(self):
382382
self.assertElementsAlmostEqual(a, jarr)
383383

384384
@common.requireNumpy
385-
def testArrayInitFromNPFloat(self):
386-
a = np.random.random(100).astype(np.float_)
385+
def testArrayInitFromNPFloat16(self):
386+
a = np.random.random(100).astype(np.float16)
387387
jarr = JArray(JFloat)(a)
388388
self.assertElementsAlmostEqual(a, jarr)
389389

@@ -441,3 +441,15 @@ def __len__(self):
441441
ja[:] = [1, 2, 3]
442442
with self.assertRaisesRegex(ValueError, "mismatch"):
443443
ja[:] = a
444+
445+
@common.requireNumpy
446+
def testNPFloat16(self):
447+
v= [0.000000e+00, 5.960464e-08, 1.788139e-07, 1.788139e-07, 4.172325e-07, 8.940697e-07, 1.847744e-06, 3.755093e-06, 7.569790e-06, 1.519918e-05, 3.045797e-05, 6.097555e-05, 6.103516e-05, 3.332520e-01, 1.000000e+00, 6.550400e+04, np.inf, -np.inf]
448+
a = np.array(v, dtype=np.float16)
449+
jarr = JArray(JFloat)(a)
450+
for v1,v2 in zip(a, jarr):
451+
self.assertEqual(v1,v2)
452+
a = np.array([np.nan], dtype=np.float16)
453+
jarr = JArray(JFloat)(a)
454+
self.assertTrue(np.isnan(jarr[0]))
455+

0 commit comments

Comments
 (0)
Please sign in to comment.