-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support wrapping a Java-side block of memory allocated off-heap to Python #203
Comments
See imglib/imglyb#14 |
This is already doable easily with currently released versions of scyjava + numpy + jpype, along with @mkitti's import scyjava
import numpy
import jpype
import random
scyjava.config.endpoints.append("net.imglib2:imglib2:6.0.0")
print("Populating 5 x 7 x 11 direct byte buffer")
ByteBuffer = scyjava.jimport('java.nio.ByteBuffer')
jbuf = ByteBuffer.allocateDirect(5 * 7 * 11)
for _ in range(jbuf.limit()):
jbuf.put(random.randint(-128, 127))
print(f"Buffer limit = {jbuf.limit()}")
print("Wrapping it to an ndarray")
view = memoryview(jbuf)
narr = numpy.frombuffer(view, count=jbuf.limit(), dtype=numpy.int8)
narr = narr.reshape([11, 7, 5])
print(f"Shape = {narr.shape}")
print()
print("Wrapping to ImgLib2 image")
ArrayImgs = scyjava.jimport('net.imglib2.img.array.ArrayImgs')
ByteBufferAccess = scyjava.jimport('net.imglib2.img.basictypeaccess.nio.ByteBufferAccess')
access = ByteBufferAccess(jbuf, True)
dims = scyjava.jarray('j', 3)
dims[0] = 5; dims[1] = 7; dims[2] = 11
img = ArrayImgs.bytes(access, dims);
print(img)
def print_value(x, y, z):
print(f"- narr[{z}, {y}, {x}] = {narr[z, y, x]}")
print(f"- jbuf.get({z}*5*7 + {y}*5 + {x}) = {jbuf.get(z*5*7 + y*5 + x)}")
pos = scyjava.jarray('j', 3)
pos[0] = x; pos[1] = y; pos[2] = z
print(f"- img.getAt({x}, {y}, {z}).get() = {img.getAt(pos).get()}")
print()
print("Initial values:")
print_value(0, 0, 0)
print_value(2, 4, 6)
print()
print("Changing values:")
print("- narr[6, 4, 2] -> 17")
narr[6, 4, 2] = 17
print("- narr[0, 0, 0] -> 23")
narr[0, 0, 0] = 23
print()
print("Values after:")
print_value(0, 0, 0)
print_value(2, 4, 6) produces:
Note: There is a bug in the above code relating to the memoryview, resulting in an error sometimes:
On my system it works maybe 10-20% of the time, producing the above error the other 80-90%. But I don't have time to debug right now—I just wanted to post the code as a starting point should anyone feel like working on this issue. This issue becomes mostly just: A) fixing said bug; and B) deciding how to slot in this logic most conveniently to PyImageJ's API; and C) generalizing it to use buffer views for other types besides just Note also that |
Could the error be related to the nbytes field incorrect in currently released versions of JPype? I fixed it recently but it after the release. |
@Thrameos Yep, works every time with JPype installed from the current master branch (jpype-project/jpype@4bacf4c). Thanks! |
Drat. That means I will need another micro release. Perhaps I can finish these requests for random access file conversions and then release it together in Nov/Dec timeframe? |
Sure, no rush on my side! JPype works great for how we're using it now. Supporting |
With
ByteBuffer.allocateDirect
you can allocate memory off-heap in Java, which can then be shared with other processes. We want to easy manufacturing of numpy arrays and xarrays that wrap this sort of off-heap memory, so that you can directly change data in Python that originated in Java (by some definition of "originated"—since it's off-heap).In #73, @hanslovsky wrote:
See also https://github.com/imglib/imglib2-cache-python
The text was updated successfully, but these errors were encountered: