Esempio n. 1
0
        /*
         * Must be broadcastable.
         * This code is very similar to NpyArray_CopyInto/NpyArray_MoveInto
         * except casting is done --- NPY_BUFSIZE is used
         * as the size of the casting buffer.
         */

        /*
         * Cast to an already created array.
         */
        internal static int NpyArray_CastTo(NpyArray dest, NpyArray src)
        {
            bool simple;
            bool same;
            NpyArray_VectorUnaryFunc castfunc = null;
            npy_intp srcSize = NpyArray_SIZE(src);
            bool     iswap, oswap;

            if (srcSize == 0)
            {
                return(0);
            }
            if (!NpyArray_ISWRITEABLE(dest))
            {
                NpyErr_SetString(npyexc_type.NpyExc_ValueError, "output array is not writeable");
                return(-1);
            }

            castfunc = NpyArray_GetCastFunc(src.descr, dest.descr.type_num);
            if (castfunc == null)
            {
                return(-1);
            }

            same   = NpyArray_SAMESHAPE(dest, src);
            simple = same && (NpyArray_ISWRITEABLE(src) && NpyArray_ISWRITEABLE(dest)) &&
                     ((NpyArray_ISCARRAY_RO(src) && NpyArray_ISCARRAY(dest)) ||
                      (NpyArray_ISFARRAY_RO(src) && NpyArray_ISFARRAY(dest)));

            if (simple)
            {
                castfunc(src.data, dest.data, srcSize, src, dest);

                if (NpyErr_Occurred())
                {
                    return(-1);
                }
                return(0);
            }

            /*
             * If the input or output is OBJECT, STRING, UNICODE, or VOID
             *  then getitem and setitem are used for the cast
             *  and byteswapping is handled by those methods
             */
            if (NpyArray_ISFLEXIBLE(src) || NpyArray_ISOBJECT(src) ||
                NpyArray_ISOBJECT(dest) || NpyArray_ISFLEXIBLE(dest))
            {
                iswap = oswap = false;
            }
            else
            {
                iswap = NpyArray_ISBYTESWAPPED(src);
                oswap = NpyArray_ISBYTESWAPPED(dest);
            }

            return(_broadcast_cast(dest, src, castfunc, iswap, oswap));
        }
Esempio n. 2
0
        internal static int NpyArray_CastAnyTo(NpyArray dst, NpyArray mp)
        {
            bool simple;
            NpyArray_VectorUnaryFunc castfunc = null;
            npy_intp mpsize = NpyArray_SIZE(mp);

            if (mpsize == 0)
            {
                return(0);
            }
            if (!NpyArray_ISWRITEABLE(dst))
            {
                NpyErr_SetString(npyexc_type.NpyExc_ValueError, "output array is not writeable");
                return(-1);
            }

            if (!(mpsize == NpyArray_SIZE(dst)))
            {
                NpyErr_SetString(npyexc_type.NpyExc_ValueError,
                                 "arrays must have the same number of elements for the cast.");
                return(-1);
            }

            castfunc = NpyArray_GetCastFunc(mp.descr, dst.descr.type_num);
            if (castfunc == null)
            {
                return(-1);
            }
            simple = (NpyArray_ISWRITEABLE(mp) && NpyArray_ISWRITEABLE(dst)) &&
                     ((NpyArray_ISCARRAY_RO(mp) && NpyArray_ISCARRAY(dst)) ||
                      (NpyArray_ISFARRAY_RO(mp) && NpyArray_ISFARRAY(dst)));
            if (simple)
            {
                castfunc(mp.data, dst.data, mpsize, mp, dst);
                return(0);
            }
            if (NpyArray_SAMESHAPE(dst, mp))
            {
                bool iswap, oswap;
                iswap = NpyArray_ISBYTESWAPPED(mp) && !NpyArray_ISFLEXIBLE(mp);
                oswap = NpyArray_ISBYTESWAPPED(dst) && !NpyArray_ISFLEXIBLE(dst);
                return(_broadcast_cast(dst, mp, castfunc, iswap, oswap));
            }
            return(_bufferedcast(dst, mp, castfunc));
        }
Esempio n. 3
0
        static void _strided_buffered_cast(VoidPtr dptr, npy_intp dstride, int delsize, bool dswap,
                                           NpyArray_CopySwapNFunc dcopyfunc,
                                           VoidPtr sptr, npy_intp sstride, int selsize, bool sswap,
                                           NpyArray_CopySwapNFunc scopyfunc,
                                           npy_intp N, VoidPtr[] buffers, int bufsize,
                                           NpyArray_VectorUnaryFunc castfunc,
                                           NpyArray dest, NpyArray src)
        {
            int i;


            if (N <= bufsize)
            {
                /*
                 * 1. copy input to buffer and swap
                 * 2. cast input to output
                 * 3. swap output if necessary and copy from output buffer
                 */

                scopyfunc(buffers[1], selsize, sptr, sstride, N, sswap, src);
                castfunc(buffers[1], buffers[0], N, src, dest);
                dcopyfunc(dptr, dstride, buffers[0], delsize, N, dswap, dest);
                return;
            }

            /* otherwise we need to divide up into bufsize pieces */
            i = 0;
            while (N > 0)
            {
                int newN = (int)Math.Min(N, bufsize);

                _strided_buffered_cast(dptr + i * dstride, dstride, delsize,
                                       dswap, dcopyfunc,
                                       sptr + i * sstride, sstride, selsize,
                                       sswap, scopyfunc,
                                       (npy_intp)newN, buffers, bufsize, castfunc, dest, src);
                i += newN;
                N -= (npy_intp)bufsize;
            }
            return;
        }
        public void NpyArray_GetCastFunc_Test1()
        {
            var NPY_TYPES_Values = Enum.GetValues(typeof(NPY_TYPES));

            foreach (NPY_TYPES type in NPY_TYPES_Values)
            {
                int ExpectedSize = Common.GetDefaultItemSize(type);
                if (ExpectedSize < 0)
                {
                    continue;
                }

                NpyArray_VectorUnaryFunc castfunc = null;
                var newDescr = numpyAPI.NpyArray_DescrNewFromType(type);
                castfunc = numpyAPI.NpyArray_GetCastFunc(newDescr, NPY_TYPES.NPY_INT32);
                Assert.IsTrue(castfunc != Common.DefaultCastFunction);

                int result = numpyAPI.NpyArray_RegisterCastFunc(newDescr, NPY_TYPES.NPY_INT32, Common.DefaultCastFunction);
                Assert.AreEqual(0, result);
                castfunc = numpyAPI.NpyArray_GetCastFunc(newDescr, NPY_TYPES.NPY_INT32);
                Assert.IsTrue(castfunc == Common.DefaultCastFunction);
            }
        }
Esempio n. 5
0
        /*
         * Get a cast function to cast from the input descriptor to the
         * output type_number (must be a registered data-type).
         * Returns null if un-successful.
         */
        internal static NpyArray_VectorUnaryFunc NpyArray_GetCastFunc(NpyArray_Descr descr, NPY_TYPES type_num)
        {
            NpyArray_VectorUnaryFunc castfunc = null;

            if (type_num < NPY_TYPES.NPY_NTYPES)
            {
                castfunc = descr.f.cast[(int)type_num];
            }
            else
            {
                /* Check castfuncs for casts to user defined types. */
                if (descr.f.castfuncs != null)
                {
                    NpyArray_CastFuncsItem pitem = descr.f.castfuncs.FirstOrDefault(t => t.totype == type_num);
                    if (pitem != null)
                    {
                        castfunc = pitem.castfunc;
                    }
                }
            }
            if (NpyTypeNum_ISCOMPLEX(descr.type_num) &&
                !NpyTypeNum_ISCOMPLEX(type_num) &&
                NpyTypeNum_ISNUMBER(type_num) &&
                !NpyTypeNum_ISBOOL(type_num))
            {
                NpyErr_SetString(npyexc_type.NpyExc_ComplexWarning,
                                 "Casting complex values to real discards the imaginary part");
            }

            if (null == castfunc)
            {
                NpyErr_SetString(npyexc_type.NpyExc_ValueError, "No cast function available.");
                return(null);
            }
            return(castfunc);
        }
Esempio n. 6
0
 internal static int NpyArray_RegisterCastFunc(NpyArray_Descr descr, NPY_TYPES totype, NpyArray_VectorUnaryFunc castfunc)
 {
     if (totype < NPY_TYPES.NPY_NTYPES)
     {
         descr.f.cast[(int)totype] = castfunc;
         return(0);
     }
     if (!NpyTypeNum_ISUSERDEF(totype))
     {
         NpyErr_SetString(npyexc_type.NpyExc_TypeError, "invalid type number.");
         return(-1);
     }
     if (descr.f.castfuncs == null)
     {
         descr.f.castfuncs = new List <NpyArray_CastFuncsItem>();
         if (descr.f.castfuncs == null)
         {
             return(-1);
         }
     }
     descr.f.castfuncs.Add(new NpyArray_CastFuncsItem()
     {
         castfunc = castfunc, totype = totype
     });
     return(0);
 }
Esempio n. 7
0
        static int _bufferedcast(NpyArray dst, NpyArray src, NpyArray_VectorUnaryFunc castfunc)
        {
            VoidPtr            inbuffer;
            VoidPtr            bptr;
            VoidPtr            optr;
            VoidPtr            outbuffer = null;
            NpyArrayIterObject it_in = null, it_out = null;
            npy_intp           i, index;
            npy_intp           ncopies = NpyArray_SIZE(dst) / NpyArray_SIZE(src);
            int  elsize = src.descr.elsize;
            int  nels   = npy_defs.NPY_BUFSIZE;
            int  el;
            bool inswap, outswap = false;
            bool obuf    = !NpyArray_ISCARRAY(dst);
            int  oelsize = dst.descr.elsize;
            int  retval  = -1;


            /*
             * If the input or output is STRING, UNICODE, or VOID
             * then getitem and setitem are used for the cast
             *  and byteswapping is handled by those methods
             */

            inswap = !(NpyArray_ISFLEXIBLE(src) || NpyArray_ISNOTSWAPPED(src));

            inbuffer = NpyDataMem_NEW(dst.descr.type_num, (ulong)(npy_defs.NPY_BUFSIZE * elsize));
            if (inbuffer == null)
            {
                return(-1);
            }

            it_in = NpyArray_IterNew(src);
            if (it_in == null)
            {
                goto exit;
            }
            if (obuf)
            {
                outswap = !(NpyArray_ISFLEXIBLE(dst) ||
                            NpyArray_ISNOTSWAPPED(dst));
                outbuffer = NpyDataMem_NEW(dst.descr.type_num, (ulong)(npy_defs.NPY_BUFSIZE * oelsize));
                if (outbuffer == null)
                {
                    goto exit;
                }

                it_out = NpyArray_IterNew(dst);
                if (it_out == null)
                {
                    goto exit;
                }
                nels = Math.Min(nels, npy_defs.NPY_BUFSIZE);
            }

            optr = new VoidPtr((obuf) ? outbuffer : dst.data);
            bptr = new VoidPtr(inbuffer);
            el   = 0;

            while (ncopies-- > 0)
            {
                index = it_in.size;
                NpyArray_ITER_RESET(it_in);
                while (index-- > 0)
                {
                    _default_copyswap(bptr, 0, it_in.dataptr, 0, 1, inswap, src);
                    bptr.data_offset += elsize;
                    NpyArray_ITER_NEXT(it_in);
                    el += 1;
                    if ((el == nels) || (index == 0))
                    {
                        /* buffer filled, do cast */
                        castfunc(inbuffer, optr, (npy_intp)el, src, dst);
                        if (obuf)
                        {
                            /* Copy from outbuffer to array */
                            for (i = 0; i < el; i++)
                            {
                                _default_copyswap(it_out.dataptr, 0, optr, 0, 1, outswap, dst);

                                optr.data_offset += oelsize;
                                NpyArray_ITER_NEXT(it_out);
                            }
                            optr = new VoidPtr(outbuffer);
                        }
                        else
                        {
                            optr.data_offset += dst.descr.elsize * nels;
                        }
                        el   = 0;
                        bptr = new VoidPtr(inbuffer);
                    }
                }
            }
            retval = 0;

exit:
            Npy_XDECREF(it_in);
            if (obuf)
            {
                Npy_XDECREF(it_out);
            }
            return(retval);
        }
Esempio n. 8
0
        internal static int _broadcast_cast(NpyArray dest, NpyArray src, NpyArray_VectorUnaryFunc castfunc, bool iswap, bool oswap)
        {
            int delsize, selsize, maxaxis, i, N;
            NpyArrayMultiIterObject multi;
            npy_intp maxdim, ostrides, istrides;

            VoidPtr []             buffers = new VoidPtr[2];
            NpyArray_CopySwapNFunc ocopyfunc, icopyfunc;

            delsize = NpyArray_ITEMSIZE(dest);
            selsize = NpyArray_ITEMSIZE(src);
            multi   = NpyArray_MultiIterFromArrays(null, 0, 2, dest, src);
            if (multi == null)
            {
                return(-1);
            }

            if (multi.size != NpyArray_SIZE(dest))
            {
                NpyErr_SetString(npyexc_type.NpyExc_ValueError,
                                 "array dimensions are not compatible for copy");
                Npy_DECREF(multi);
                return(-1);
            }

            icopyfunc = _default_copyswap;
            ocopyfunc = _default_copyswap;
            maxaxis   = NpyArray_RemoveSmallest(multi);
            if (maxaxis < 0)
            {
                /* cast 1 0-d array to another */
                N        = 1;
                maxdim   = 1;
                ostrides = (npy_intp)delsize;
                istrides = (npy_intp)selsize;
            }
            else
            {
                maxdim   = multi.dimensions[maxaxis];
                N        = (int)Math.Min(maxdim, npy_defs.NPY_BUFSIZE);
                ostrides = multi.iters[0].strides[maxaxis];
                istrides = multi.iters[1].strides[maxaxis];
            }
            buffers[0] = NpyDataMem_NEW(dest.descr.type_num, (ulong)(N * delsize));
            buffers[1] = NpyDataMem_NEW(src.descr.type_num, (ulong)(N * selsize));
            if (buffers[0] == null || buffers[1] == null)
            {
                NpyErr_MEMORY();
                return(-1);
            }

            // NpyArray_ITER_ParallelSplit system will not work here.  Processing must be done in sequential order.

            while (multi.index < multi.size)
            {
                _strided_buffered_cast(multi.iters[0].dataptr,
                                       ostrides,
                                       delsize, oswap, ocopyfunc,
                                       multi.iters[1].dataptr,
                                       istrides,
                                       selsize, iswap, icopyfunc,
                                       maxdim, buffers, N,
                                       castfunc, dest, src);
                NpyArray_MultiIter_NEXT(multi);
            }

            Npy_DECREF(multi);

            if (NpyErr_Occurred())
            {
                return(-1);
            }

            return(0);
        }
Esempio n. 9
0
 internal static int NpyArray_RegisterCastFunc(NpyArray_Descr descr, NPY_TYPES totype, NpyArray_VectorUnaryFunc castfunc)
 {
     return(numpyinternal.NpyArray_RegisterCastFunc(descr, totype, castfunc));
 }