9

I'd like to quickly fill with as few copies as possible a long array of structs that I'm receiving incrementally from C.

If my struct is only primary data types, like the following:

cdef packed struct oh_hi:
    int lucky
    char unlucky

Then the following works fine:

  DEF MAXPOWER = 1000000
  cdef oh_hi * hi2u = <oh_hi *>malloc(sizeof(oh_hi)*MAXPOWER)
  cdef oh_hi [:] hi2me = <oh_hi[:MAXPOWER]> hi2u

But once I change my struct to hold a character array:

cdef packed struct oh_hi:
    int lucky
    char unlucky[10]

The previous memoryview casting compiles but when run gives a:

  ValueError: Expected 1 dimension(s), got 1

Is there an easy way to do this in Cython? I'm aware that I could create a structured array, but afaik, that wouldn't let me assign the C structs straight into it.

1
  • 1
    This seems to be very similar to this issue with numpy structured arrays. The problem is that cython does not seem to like mixing arrays with scalar values if the first item in a struct is a scalar. The workaround is just to rearrange the items in the struct such that there is always an array member/item first. Commented Jan 28, 2018 at 23:35

1 Answer 1

6

Actually, just building a structured numpy array and then a memoryview works just fine.

cdef np.ndarray hi2u = np.ndarray((MAXPOWER,),dtype=[('lucky','i4'),('unlucky','a10')])
cdef oh_hi [:] hi2me = hi2u

The performance of this seems quite good and this saves a later copy if you need the data back in python. As per usual, the numpy version is pretty good. =p

Sign up to request clarification or add additional context in comments.

3 Comments

This did not work for me. Maybe because I used fixed array of int32 and not string 'a10'. I ended up flattening the structures.
I'll look into this, but how were you hoping these would be stored in the numpy structure?
for 10 integers, something line ('lucky',(np.int32,10))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.