Пример #1
0
        /// <summary>
        /// generic dswap
        /// </summary>
        static public void dswap <U, V>(int N, U DX, int INCX, V DY, int INCY)
            where U : IList <double>
            where V : IList <double>
        {
            if (object.ReferenceEquals(DX, DY))
            {
                // while formally there is no problem that this should work, it seems much more likely
                // that it's a bug.
                throw new ArgumentException("Illegal use: reference-equality of input vectors -- this might be a mis-use instead of intention.");
            }


            if ((DX is double[]) && (DY is double[]))
            {
                BLAS.dswap(N, DX as double[], INCX, DY as double[], INCY);
                return;
            }
            else
            {
                for (int i = 0; i < N; i++)
                {
                    double a;
                    a            = DX[i * INCX];
                    DX[i * INCX] = DY[i * INCY];
                    DY[i * INCY] = a;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// MPI-parallel 2-norm
        /// </summary>
        static public double drnm2 <TX>(int N, TX x, int incx, MPI_Comm comm) where TX : IList <double>
        {
            double locRes = 0;

            double[] dx = x as double[];
            if (dx != null)
            {
                // double[] - implementation
                locRes = BLAS.dnrm2(N, dx, incx);
                locRes = locRes * locRes;
            }
            else
            {
                ISparseVector <double> spx = x as ISparseVector <double>;

                if (spx != null)
                {
                    // sparse implementation

                    foreach (var entry in spx.SparseStruct)
                    {
                        int m = entry.Key % incx;
                        if (m != 0)
                        {
                            // entry is skipped by x-increment
                            continue;
                        }

                        double xi = entry.Value;
                        locRes += xi * xi;
                    }
                }
                else
                {
                    // default implementation
                    for (int n = 0; n < N; n++)
                    {
                        double xi = x[n * incx];
                        locRes += xi * xi;
                    }
                }
            }



            double globRes = double.NaN;

            unsafe {
                csMPI.Raw.Allreduce((IntPtr)(&locRes), (IntPtr)(&globRes), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.SUM, comm);
            }
            return(Math.Sqrt(globRes));
        }
Пример #3
0
        /// <summary>
        /// blas dscal: <paramref name="X"/> = <paramref name="X"/>*<paramref name="alpha"/>;
        /// </summary>
        static public void dscal <T>(int N, double alpha, T X, int incx) where T : IList <double>
        {
            ISparseVector <double> spx = X as ISparseVector <double>;

            double[] arx = X as double[];


            if (arx != null)
            {
                // double - array -> use BLAS
                // ++++++++++++++++++++++++++
                BLAS.dscal(N, alpha, arx, incx);
                return;
            }

            if (spx != null)
            {
                // sparce vector -> compute only nonzero entries
                // +++++++++++++++++++++++++++++++++++++++++++++

                int[] idx = new int[spx.NonZeros];
                spx.SparseStruct.Keys.CopyTo(idx, 0);

                foreach (int i in idx)
                {
                    int m = i % incx;
                    if (m != 0)
                    {
                        // entry is skipped by x-increment
                        continue;
                    }

                    spx[i] *= alpha;
                }

                return;
            }


            {
                // reference version
                // +++++++++++++++++

                for (int i = 0; i < N; i += incx)
                {
                    X[i] *= alpha;
                }
            }
        }
Пример #4
0
        /// <summary>
        /// MPI - parallel scalar product
        /// </summary>
        static public double ddot <TX, TY>(int N, TX x, int incx, TY y, int incy, MPI.Wrappers.MPI_Comm comm)
            where TX : IList <double>
            where TY : IList <double>
        {
            if (incx * x.Count < N)
            {
                throw new ArgumentException("vector too short.", "x");
            }
            if (incy * y.Count < N)
            {
                throw new ArgumentException("vector too short.", "y");
            }

            double locRes = 0;

            double[] dx = x as double[];
            double[] dy = y as double[];
            if (dx != null && dy != null)
            {
                // use dnese BLAS
                locRes = BLAS.ddot(N, dx, incx, dy, incy);
            }
            else
            {
                ISparseVector <double> spx = x as ISparseVector <double>;
                ISparseVector <double> spy = y as ISparseVector <double>;
                IList <double>         _y  = y;
                if (spy != null)
                {
                    if (spx == null || spy.Sparsity < spx.Sparsity)
                    {
                        // y is sparser than x, use y !
                        spx = spy;
                        spy = null;
                        _y  = x;
                        x   = default(TX);
                        y   = default(TY);
                        int buffy = incx;
                        incx = incy;
                        incy = buffy;
                    }
                }

                if (spx != null)
                {
                    // sparse implementation

                    foreach (var entry in spx.SparseStruct)
                    {
                        int m = entry.Key % incx;
                        if (m != 0)
                        {
                            // entry is skipped by x-increment
                            continue;
                        }

                        int n = entry.Key / incx;

                        locRes += entry.Value * _y[n * incy];
                    }
                }
                else
                {
                    // default IList<double> - implementation
                    for (int n = 0; n < N; n++)
                    {
                        locRes += x[n * incx] * y[n * incy];
                    }
                }
            }

            double globRes = double.NaN;

            unsafe {
                csMPI.Raw.Allreduce((IntPtr)(&locRes), (IntPtr)(&globRes), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.SUM, comm);
            }
            return(globRes);
        }
Пример #5
0
        /// <summary>
        /// blas daxpy: <paramref name="Y"/> = <paramref name="Y"/> + <paramref name="alpha"/>*<paramref name="X"/>;
        /// </summary>
        static public void daxpy <TX, TY>(int N,
                                          double alpha, TX X, int INCX,
                                          TY Y, int INCY)
            where TX : IList <double>
            where TY : IList <double>
        {
            if (object.ReferenceEquals(X, Y))
            {
                // while formally there is no problem that this should work, it seems much more likely
                // that it's a bug.
                throw new ArgumentException("Illegal use: reference-equality of input vectors -- this might be a mis-use instead of intention.");
            }

            {
                // sparse vector branch
                // ++++++++++++++++++++
                ISparseVector <double> spx = X as ISparseVector <double>;
                if (spx != null)
                {
                    foreach (var entry in spx.SparseStruct)
                    {
                        int m = entry.Key % INCX;
                        if (m != 0)
                        {
                            // entry is skipped by x-increment
                            continue;
                        }

                        int n = entry.Key / INCX;

                        double xi = entry.Value;
                        Y[n * INCY] += xi * alpha;
                    }

                    return;
                }
            }


            {
                // both arrays-branch -> use BLAS
                // ++++++++++++++++++++++++++++++


                double[] _XasDouble = X as double[];
                double[] _YasDouble = Y as double[];
                if (_XasDouble != null && _YasDouble != null)
                {
                    BLAS.daxpy(N, alpha, _XasDouble, INCX, _YasDouble, INCY);
                    return;
                }
            }
            {
                // default branch
                // ++++++++++++++

                for (int n = 0; n < N; n++)
                {
                    Y[n * INCY] += X[n * INCX] * alpha;
                }

                return;
            }
        }