I write methods for a c extension type:
static PyObject *
RawGraphState_apply_C_L(RawGraphState * self
, PyObject * args)
{
npy_uint8 vop = 0xdeadbeef;
npy_intp i;// = 0xdeadbeef;
if(!PyArg_ParseTuple(args, "II", &i, &vop))
{
return NULL;
}
printf("i = %ld\n", i);
if(vop >= 24)
{
PyErr_SetString(PyExc_ValueError, "vop index must be in [0, 23]");
return NULL;
}
if(i >= self->length)
{
PyErr_SetString(PyExc_ValueError, "qbit index out of range");
return NULL;
}
printf("mapping vop[%ld] %d,%d -> %d\n", i, vop, self->vops[i], vop_lookup_table[vop][self->vops[i]]);
self->vops[i] = vop_lookup_table[vop][self->vops[i]];
Py_RETURN_NONE;
}
However this does not read the first argument correctly. It either defaults to 0 or to a huge number (depending on wheter I call the method in pytest
or using ipython
):
In [1]: from pyqcs.graph.backend.raw_state import RawGraphState
^[[A
In [2]: g = RawGraphState(2)
In [3]: g.apply_C_L(1, 0)
i = 140200617443328
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-57081093fbb3> in <module>
----> 1 g.apply_C_L(1, 0)
ValueError: qbit index out of range
What am I doing wrong here?
--
You can find the code here:
https://github.com/daknuett/PyQCS/blob/graph_simulation/src/pyqcs/graph/backend/raw_state.c
starting at line 300.
The format code I
expects to be passed a pointer to an unsigned int
. Not an npy_uint8
or an npy_intp
. An unsigned int
and only an unsigned int
. An 8 bit uint
like vop
is is definitely the wrong size, as an attempt to write to it as if it were a normal unsigned int
will likely overwrite some other data. A npy_intp
might or might not be the right size, but since it could be wrong, don't use it.
For the first argument you want either b
or B
, which is an unsigned char (8 bits on pretty much every platform). Read the documentation for the difference. For the second argument would probably want to use K
for an unsigned long long
, pass it an unsigned long long
(which should be big enough...), and then convert that to npy_intp
checking for overflow yourself. Alternatively you might use O
then call PyLong_AsVoidPtr
on that to get the number to C.
As an aside: npy_uint8 vop = 0xdeadbeef;
should probably generate a warning since the number won't fit into 8 bits.
User contributions licensed under CC BY-SA 3.0