Search code examples
pythonnumpyopenclpyopencl

How to create variable of dtype cl.cltypes.uint2 in Python


I need to create variable with type cl.cltypes.uint2 for pyopencl in Python. Now i have created it this way:

key = np.array([(0x01020304, 0x05060708)], dtype=cl.cltypes.uint2)[0]

Its definitely dirty hack( How to create it with more clean way?

this: key = cl.cltypes.uint2((0x01020304, 0x05060708))

not works because of error: 'numpy.dtype' object is not callable


Solution

  • A quick read of your link suggests that it is making a compound dtype. With out loading and running it, I think your example is something like

    In [164]: dt = np.dtype([('x',np.uint16),('y',np.uint16)])                                             
    In [165]: np.array([(0x01020304, 0x05060708)], dtype=dt)                                               
    Out[165]: array([(772, 1800)], dtype=[('x', '<u2'), ('y', '<u2')])
    In [166]: dt((0x01020304, 0x05060708))                                                                 
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-166-d71cce4777b9> in <module>
    ----> 1 dt((0x01020304, 0x05060708))
    
    TypeError: 'numpy.dtype' object is not callable
    

    and pulling out one record from the array:

    In [167]: np.array([(0x01020304, 0x05060708)], dtype=dt)[0]                                            
    Out[167]: (772, 1800)
    In [168]: _.dtype                                                                                      
    Out[168]: dtype([('x', '<u2'), ('y', '<u2')])
    

    A compound dtype is never callable.

    I think a 0d, 'scalar' array is better than an object created with the dtype function (though they have similar methods).

    For a compound dtype:

    In [228]: v = np.array((0x01020304, 0x05060708), dtype=dt)                                             
    In [229]: v                                                                                            
    Out[229]: array((772, 1800), dtype=[('x', '<u2'), ('y', '<u2')])
    In [230]: type(v)                                                                                      
    Out[230]: numpy.ndarray
    In [231]: v[()]                                                                                        
    Out[231]: (772, 1800)
    In [232]: type(_)                                                                                      
    Out[232]: numpy.void
    In [233]: _231.dtype                                                                                   
    Out[233]: dtype([('x', '<u2'), ('y', '<u2')])
    

    You can cast such an array to recarray and get a record object, but I don't think creating these is any easier.

    In [234]: v.view(np.recarray)                                                                          
    Out[234]: 
    rec.array((772, 1800),
              dtype=[('x', '<u2'), ('y', '<u2')])
    In [235]: _.x                                                                                          
    Out[235]: array(772, dtype=uint16)
    In [238]: v.view(np.recarray)[()]                                                                      
    Out[238]: (772, 1800)
    In [239]: type(_)                                                                                      
    Out[239]: numpy.record