Example #1
0
/*NUMPY_API
 * Update Several Flags at once.
 */
NPY_NO_EXPORT void
PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
{
    /* Always update both, as its not trivial to guess one from the other */
    if (flagmask & (NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_C_CONTIGUOUS)) {
        _UpdateContiguousFlags(ret);
    }
    if (flagmask & NPY_ARRAY_ALIGNED) {
        if (_IsAligned(ret)) {
            PyArray_ENABLEFLAGS(ret, NPY_ARRAY_ALIGNED);
        }
        else {
            PyArray_CLEARFLAGS(ret, NPY_ARRAY_ALIGNED);
        }
    }
    /*
     * This is not checked by default WRITEABLE is not
     * part of UPDATE_ALL
     */
    if (flagmask & NPY_ARRAY_WRITEABLE) {
        if (_IsWriteable(ret)) {
            PyArray_ENABLEFLAGS(ret, NPY_ARRAY_WRITEABLE);
        }
        else {
            PyArray_CLEARFLAGS(ret, NPY_ARRAY_WRITEABLE);
        }
    }
    return;
}
Example #2
0
/*NUMPY_API
 * Update Several Flags at once.
 */
NPY_NO_EXPORT void
PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
{

    if (flagmask & NPY_ARRAY_F_CONTIGUOUS) {
        if (_IsFortranContiguous(ret)) {
            PyArray_ENABLEFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
            if (PyArray_NDIM(ret) > 1) {
                PyArray_CLEARFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
            }
        }
        else {
            PyArray_CLEARFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
        }
    }
    if (flagmask & NPY_ARRAY_C_CONTIGUOUS) {
        if (_IsContiguous(ret)) {
            PyArray_ENABLEFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
            if (PyArray_NDIM(ret) > 1) {
                PyArray_CLEARFLAGS(ret, NPY_ARRAY_F_CONTIGUOUS);
            }
        }
        else {
            PyArray_CLEARFLAGS(ret, NPY_ARRAY_C_CONTIGUOUS);
        }
    }
    if (flagmask & NPY_ARRAY_ALIGNED) {
        if (_IsAligned(ret)) {
            PyArray_ENABLEFLAGS(ret, NPY_ARRAY_ALIGNED);
        }
        else {
            PyArray_CLEARFLAGS(ret, NPY_ARRAY_ALIGNED);
        }
    }
    /*
     * This is not checked by default WRITEABLE is not
     * part of UPDATE_ALL
     */
    if (flagmask & NPY_ARRAY_WRITEABLE) {
        if (_IsWriteable(ret)) {
            PyArray_ENABLEFLAGS(ret, NPY_ARRAY_WRITEABLE);
        }
        else {
            PyArray_CLEARFLAGS(ret, NPY_ARRAY_WRITEABLE);
        }
    }
    return;
}
Example #3
0
NRT_adapt_ndarray_to_python(arystruct_t* arystruct, int ndim,
                            int writeable, PyArray_Descr *descr)
{
    PyArrayObject *array;
    MemInfoObject *miobj = NULL;
    PyObject *args;
    npy_intp *shape, *strides;
    int flags = 0;

    if (!PyArray_DescrCheck(descr)) {
        PyErr_Format(PyExc_TypeError,
                     "expected dtype object, got '%.200s'",
                     Py_TYPE(descr)->tp_name);
        return NULL;
    }

    if (arystruct->parent) {
        PyObject *obj = try_to_return_parent(arystruct, ndim, descr);
        if (obj) {
            /* Release NRT reference to the numpy array */
            NRT_MemInfo_release(arystruct->meminfo);
            return obj;
        }
    }

    if (arystruct->meminfo) {
        /* wrap into MemInfoObject */
        miobj = PyObject_New(MemInfoObject, &MemInfoType);
        args = PyTuple_New(1);
        /* SETITEM steals reference */
        PyTuple_SET_ITEM(args, 0, PyLong_FromVoidPtr(arystruct->meminfo));
        /*  Note: MemInfo_init() does not incref.  This function steals the
         *        NRT reference.
         */
        if (MemInfo_init(miobj, args, NULL)) {
            return NULL;
        }
        Py_DECREF(args);
    }

    shape = arystruct->shape_and_strides;
    strides = shape + ndim;
    Py_INCREF((PyObject *) descr);
    array = (PyArrayObject *) PyArray_NewFromDescr(&PyArray_Type, descr, ndim,
            shape, strides, arystruct->data,
            flags, (PyObject *) miobj);

    if (array == NULL)
        return NULL;

    /* Set writable */
#if NPY_API_VERSION >= 0x00000007
    if (writeable) {
        PyArray_ENABLEFLAGS(array, NPY_ARRAY_WRITEABLE);
    }
    else {
        PyArray_CLEARFLAGS(array, NPY_ARRAY_WRITEABLE);
    }
#else
    if (writeable) {
        array->flags |= NPY_WRITEABLE;
    }
    else {
        array->flags &= ~NPY_WRITEABLE;
    }
#endif

    if (miobj) {
        /* Set the MemInfoObject as the base object */
#if NPY_API_VERSION >= 0x00000007
        if (-1 == PyArray_SetBaseObject(array,
                                        (PyObject *) miobj))
        {
            Py_DECREF(array);
            Py_DECREF(miobj);
            return NULL;
        }
#else
        PyArray_BASE(array) = (PyObject *) miobj;
#endif

    }
    return (PyObject *) array;
}
Example #4
0
/*
 * Check whether the given array is stored contiguously
 * in memory. And update the passed in ap flags appropriately.
 *
 * The traditional rule is that for an array to be flagged as C contiguous,
 * the following must hold:
 *
 * strides[-1] == itemsize
 * strides[i] == shape[i+1] * strides[i + 1]
 *
 * And for an array to be flagged as F contiguous, the obvious reversal:
 *
 * strides[0] == itemsize
 * strides[i] == shape[i - 1] * strides[i - 1]
 *
 * According to these rules, a 0- or 1-dimensional array is either both
 * C- and F-contiguous, or neither; and an array with 2+ dimensions
 * can be C- or F- contiguous, or neither, but not both. Though there
 * there are exceptions for arrays with zero or one item, in the first
 * case the check is relaxed up to and including the first dimension
 * with shape[i] == 0. In the second case `strides == itemsize` will
 * can be true for all dimensions and both flags are set.
 *
 * When NPY_RELAXED_STRIDES_CHECKING is set, we use a more accurate
 * definition of C- and F-contiguity, in which all 0-sized arrays are
 * contiguous (regardless of dimensionality), and if shape[i] == 1
 * then we ignore strides[i] (since it has no affect on memory layout).
 * With these new rules, it is possible for e.g. a 10x1 array to be both
 * C- and F-contiguous -- but, they break downstream code which assumes
 * that for contiguous arrays strides[-1] (resp. strides[0]) always
 * contains the itemsize.
 */
static void
_UpdateContiguousFlags(PyArrayObject *ap)
{
    npy_intp sd;
    npy_intp dim;
    int i;
    npy_bool is_c_contig = 1;

    sd = PyArray_ITEMSIZE(ap);
    for (i = PyArray_NDIM(ap) - 1; i >= 0; --i) {
        dim = PyArray_DIMS(ap)[i];
#if NPY_RELAXED_STRIDES_CHECKING
        /* contiguous by definition */
        if (dim == 0) {
            PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
            PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
            return;
        }
        if (dim != 1) {
            if (PyArray_STRIDES(ap)[i] != sd) {
                is_c_contig = 0;
            }
            sd *= dim;
        }
#else /* not NPY_RELAXED_STRIDES_CHECKING */
        if (PyArray_STRIDES(ap)[i] != sd) {
            is_c_contig = 0;
            break;
         }
        /* contiguous, if it got this far */
        if (dim == 0) {
            break;
        }
        sd *= dim;
#endif /* not NPY_RELAXED_STRIDES_CHECKING */
    }
    if (is_c_contig) {
        PyArray_ENABLEFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
    }
    else {
        PyArray_CLEARFLAGS(ap, NPY_ARRAY_C_CONTIGUOUS);
    }

    /* check if fortran contiguous */
    sd = PyArray_ITEMSIZE(ap);
    for (i = 0; i < PyArray_NDIM(ap); ++i) {
        dim = PyArray_DIMS(ap)[i];
#if NPY_RELAXED_STRIDES_CHECKING
        if (dim != 1) {
            if (PyArray_STRIDES(ap)[i] != sd) {
                PyArray_CLEARFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
                return;
            }
            sd *= dim;
        }
#else /* not NPY_RELAXED_STRIDES_CHECKING */
        if (PyArray_STRIDES(ap)[i] != sd) {
            PyArray_CLEARFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
            return;
        }
        if (dim == 0) {
            break;
        }
        sd *= dim;
#endif /* not NPY_RELAXED_STRIDES_CHECKING */
    }
    PyArray_ENABLEFLAGS(ap, NPY_ARRAY_F_CONTIGUOUS);
    return;
}
Example #5
0
static PyObject * enz_vnmpocnp(PyObject *self, PyObject *args,
			       PyObject *keywds)
{
	static char *kwlist[] = { "r",		 "f",		"n",	       "m",	"L_max",
				  "bessel_name", "ncpus",	"verb",	       NULL };
	long syscpus = sysconf(_SC_NPROCESSORS_ONLN);

	PyObject *r_o, *f_o, *n_o, *m_o;
	PyObject *r = NULL;
	PyObject *f = NULL;
	PyObject *n = NULL;
	PyObject *m = NULL;
	const char *error = NULL;
	npy_intp r_n, f_n, beta_n;

	PyObject *vnm = NULL;
	npy_intp vnm_dims[3];

	double *datar = NULL;
	complex double *dataf = NULL;
	int *datan = NULL;
	int *datam = NULL;
	complex double *datap = NULL;

	int kL_max = 35;
	int kncpus = -1;
	int kverb = 0;
	char *kbessel_name = "jn";
	int ret;

	if (syscpus <= 0)
		syscpus = 1;

	if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!O!O!O!|isii",
					 kwlist,
					 &PyArray_Type, &r_o,
					 &PyArray_Type, &f_o,
					 &PyArray_Type, &n_o,
					 &PyArray_Type, &m_o,
					 &kL_max, &kbessel_name, &kncpus, &kverb)) {
		PyErr_SetString(PyExc_SyntaxError, "failed to parse args");
		return NULL;
	}

	r = PyArray_FROM_OTF(r_o, NPY_FLOAT64, NPY_ARRAY_IN_ARRAY);
	f = PyArray_FROM_OTF(f_o, NPY_COMPLEX128, NPY_ARRAY_IN_ARRAY);
	n = PyArray_FROM_OTF(n_o, NPY_INT64, NPY_ARRAY_IN_ARRAY);
	m = PyArray_FROM_OTF(m_o, NPY_INT64, NPY_ARRAY_IN_ARRAY);

	if (!r) {
		PyErr_SetString(PyExc_ValueError, "cannot convert r to PyArray");
		return NULL;
	}
	if (!f) {
		PyErr_SetString(PyExc_ValueError, "cannot convert f to PyArray");
		return NULL;
	}
	if (!n) {
		PyErr_SetString(PyExc_ValueError, "cannot convert n to PyArray");
		return NULL;
	}
	if (!m) {
		PyErr_SetString(PyExc_ValueError, "cannot convert m to PyArray");
		return NULL;
	}

	if (!r || not_vect(r) || PyArray_TYPE((PyArrayObject*)r) != NPY_FLOAT64) {
		error = "r is not a vector of doubles";
		goto exit_decrement;
	}
	r_n = PyArray_DIM((PyArrayObject*)r, 0);

	if (!f || not_vect(f) ||
	    PyArray_TYPE((PyArrayObject*)f) != NPY_COMPLEX128) {
		error = "f is not a vector of complex numbers";
		goto exit_decrement;
	}
	f_n = PyArray_DIM((PyArrayObject*)f, 0);

	if (!n || not_vect(n) || PyArray_TYPE((PyArrayObject*)n) != NPY_INT64) {
		error = "n is not a vector of integers";
		goto exit_decrement;
	}
	if (!m || not_vect(m) || PyArray_TYPE((PyArrayObject*)m) != NPY_INT64) {
		error = "m is not a vector of integers";
		goto exit_decrement;
	}
	if (PyArray_DIM((PyArrayObject*)n, 0) !=
	    PyArray_DIM((PyArrayObject*)m, 0)) {
		error = "n and m must have the same length";
		goto exit_decrement;
	}
	beta_n = PyArray_DIM((PyArrayObject*)n, 0);

	vnm_dims[0] = r_n;
	vnm_dims[1] = f_n;
	vnm_dims[2] = beta_n;

	vnm = PyArray_New(&PyArray_Type, 3, vnm_dims, NPY_COMPLEX128, NULL, NULL,
			  0, NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_ALIGNED, NULL);

	if (!vnm) {
		error = "cannot create vnm";
		goto exit_decrement;
	}

	PyArray_CLEARFLAGS((PyArrayObject*)vnm, NPY_ARRAY_C_CONTIGUOUS);

	assert(PyArray_Size(vnm) == (r_n * f_n * beta_n));
	assert(PyArray_NBYTES(vnm) == (r_n * f_n * beta_n * sizeof(double complex)));
	datap = PyArray_DATA((PyArrayObject*)vnm);

	if (kncpus < 0)
		kncpus = beta_n < syscpus ? beta_n : syscpus;
	else
		kncpus = kncpus > syscpus ? syscpus : kncpus;

	if ((r_n * f_n * beta_n) != 0) {
		datar = PyArray_DATA((PyArrayObject*)r);
		dataf = PyArray_DATA((PyArrayObject*)f);
		datan = PyArray_DATA((PyArrayObject*)n);
		datam = PyArray_DATA((PyArrayObject*)m);
		Py_BEGIN_ALLOW_THREADS
			ret = vnmpocnp(r_n, datar,
				       f_n, dataf,
				       beta_n,
				       datan, datam,
				       kL_max, kbessel_name,
				       kncpus,
				       kverb, datap, &error);
		Py_END_ALLOW_THREADS
		if (ret) {
			Py_XDECREF(vnm);
			goto exit_decrement;
		}
	}