Background
I'm developing a small python wrapper PyWSTP. The wrapper is still in very early stage and lacking features. One important feature I'm considering is transferring dense array between math kernel and python. (Yep, the all awesome NumPy) I do realize LibraryLink would be better suited for this, but WSTP has the capability of sending stuff over TCP.
Problem
Whenever kernel sends packed array to a 3rd party app via LinkWrite[_LinkObject, _]
, it sends unpacked array. On the receiving side, tokens such WSTKPACKED
are never seen. Thus WSTP C APIs such as WSGetReal64Array
cannot be used.
Here's some simple code to illustrate the problem:
server.m
(* run via "math -script" *)
Needs["Developer`"];
link = LinkCreate["testlink", LinkMode->Listen];
obj1 = Image[RandomInteger[{0, 255}, {4, 4}]];
obj2 = Developer`ToPackedArray[RandomReal[1., {4,4}]];
LinkWrite[link, #]& /@ {obj1, obj2};
InputString["Done, ENTER to exit ..."];
LinkClose[link];
client.py
import wstp
ctx = wstp.WSTPContext()
link = ctx.open_link('testlink', mode='connect')
obj1 = link.recv()
print('got object1:')
print(obj1)
obj2 = link.recv()
print('got object2:')
print(obj2)
input('Done, ENTER to exit ...')
ctx.close_link('testlink')
On PyWSTP, I have not implemented handlers for WSTKPACKED
yet. Only basic data types (WSTKSYM
, WSTKFUNC
, WSTKINT
, WSTKREAL
, WSTKSTR
) are implemented. Yet client side is able to correctly receive the object:
got object1:
Image[RawArray["Real64", List[List[207.0, 142.0, 166.0, 205.0], List[137.0, 115.0, 60.0, 39.0], List[37.0, 110.0, 9.0, 89.0], List[56.0, 162.0, 116.0, 225.0]]], "Real", Rule[ColorSpace, Automatic], Rule[Interleaving, None]]
got object2:
List[List[0.8681530207587866, 0.0734728851659936, 0.9233463976844913, 0.1346824422121633], List[0.7711652733626824, 0.88933420636346, 0.9202474236790081, 0.5288719560153152], List[0.18096422954894353, 0.04400711306110572, 0.2330108388845873, 0.7479540642843265], List[0.4382030298759463, 0.42470372650663424, 0.9718400392443247, 0.6100416353164417]]
Done, ENTER to exit ...
This indicates math kernel unpacks dense array before sending over WSTP.
Question summary
How to make sure kernel sends packed array to 3rd party app over WSTP?
Is it possible to achieve 1. without writing C code?