Пример #1
0
        /// <summary>
        /// Allocate an aligned vector with the given alignment (in bytes).
        /// The alignment must be a power of two and at least sizeof(Float).
        /// </summary>
        public CpuAlignedVector(int size, int cbAlign)
        {
            Contracts.Assert(0 < size);
            // cbAlign should be a power of two.
            Contracts.Assert(sizeof(Float) <= cbAlign);
            Contracts.Assert((cbAlign & (cbAlign - 1)) == 0);

            int cfltAlign = cbAlign / sizeof(Float);
            int cflt      = RoundUp(size, cfltAlign);

            _items = new AlignedArray(cflt, cbAlign);
            _size  = size;
            AssertValid();
        }
Пример #2
0
 private static unsafe void ZeroItemsU(AlignedArray destination, int c, int[] indices, int cindices)
 {
     fixed(float *pdst = &destination.Items[0])
     fixed(int *pidx = &indices[0])
     {
         for (int i = 0; i < cindices; ++i)
         {
             int index = pidx[i];
             Contracts.Assert(index >= 0);
             Contracts.Assert(index < c);
             pdst[index] = 0;
         }
     }
 }
Пример #3
0
        /// <summary>
        /// Sets the matrix items to zero.
        /// </summary>
        /// <param name="destination">The destination values.</param>
        /// <param name="ccol">The stride column.</param>
        /// <param name="cfltRow">The row to use.</param>
        /// <param name="indices">The indicies.</param>
        public static void ZeroMatrixItems(AlignedArray destination, int ccol, int cfltRow, int[] indices)
        {
            Contracts.Assert(ccol > 0);
            Contracts.Assert(ccol <= cfltRow);

            if (ccol == cfltRow)
            {
                ZeroItemsU(destination, destination.Size, indices, indices.Length);
            }
            else
            {
                ZeroMatrixItemsCore(destination, destination.Size, ccol, cfltRow, indices, indices.Length);
            }
        }
Пример #4
0
        /// <summary>
        /// Multiplies a matrix times a source.
        /// </summary>
        /// <param name="matrix">The input matrix.</param>
        /// <param name="rgposSrc">The source positions.</param>
        /// <param name="sourceValues">The source values.</param>
        /// <param name="posMin">The minimum position.</param>
        /// <param name="iposMin">The minimum position index.</param>
        /// <param name="iposLimit">The position limit.</param>
        /// <param name="destination">The destination matrix.</param>
        /// <param name="stride">The column stride.</param>
        public static void MatrixTimesSource(AlignedArray matrix, ReadOnlySpan <int> rgposSrc, AlignedArray sourceValues,
                                             int posMin, int iposMin, int iposLimit, AlignedArray destination, int stride)
        {
            Contracts.Assert(iposMin >= 0);
            Contracts.Assert(iposMin <= iposLimit);
            Contracts.Assert(iposLimit <= rgposSrc.Length);
            Contracts.Assert(matrix.Size == destination.Size * sourceValues.Size);

            if (iposMin >= iposLimit)
            {
                destination.ZeroItems();
                return;
            }

            Contracts.AssertNonEmpty(rgposSrc);
            Contracts.Assert(stride >= 0);

            if (Avx.IsSupported)
            {
                Contracts.Assert(stride <= destination.Size);
                AvxIntrinsics.MatMulP(matrix, rgposSrc, sourceValues, posMin, iposMin, iposLimit, destination, stride, sourceValues.Size);
            }
            else if (Sse.IsSupported)
            {
                Contracts.Assert(stride <= destination.Size);
                SseIntrinsics.MatMulP(matrix, rgposSrc, sourceValues, posMin, iposMin, iposLimit, destination, stride, sourceValues.Size);
            }
            else
            {
                Contracts.Assert(stride <= destination.Size);
                for (int i = 0; i < stride; i++)
                {
                    float dotProduct = 0;
                    for (int j = iposMin; j < iposLimit; j++)
                    {
                        int col = rgposSrc[j] - posMin;
                        dotProduct += matrix[i * sourceValues.Size + col] * sourceValues[col];
                    }
                    destination[i] = dotProduct;
                }
            }
        }
Пример #5
0
        public static void ZeroMatrixItems(AlignedArray dst, int ccol, int cfltRow, int[] indices)
        {
            Contracts.Assert(0 < ccol && ccol <= cfltRow);

            unsafe
            {
                fixed(float *pdst = &dst.Items[0])
                fixed(int *pi = &indices[0])
                {
                    if (ccol == cfltRow)
                    {
                        Thunk.ZeroItemsU(Ptr(dst, pdst), dst.Size, pi, indices.Length);
                    }
                    else
                    {
                        Thunk.ZeroMatrixItemsCore(Ptr(dst, pdst), dst.Size, ccol, cfltRow, pi, indices.Length);
                    }
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Allocate an aligned matrix with the given alignment (in bytes).
        /// </summary>
        protected CpuAlignedMatrixBase(int runLen, int runCnt, int cbAlign)
        {
            Contracts.Assert(0 < runLen);
            Contracts.Assert(0 < runCnt);
            // cbAlign should be a power of two.
            Contracts.Assert(sizeof(Float) <= cbAlign);
            Contracts.Assert((cbAlign & (cbAlign - 1)) == 0);

            RunLen = runLen;
            RunCnt = runCnt;

            FloatAlign = cbAlign / sizeof(Float);
            Shift      = GeneralUtils.CbitLowZero((uint)FloatAlign);
            Mask       = FloatAlign - 1;

            RunLenPhy = RoundUp(runLen, FloatAlign);
            RunCntPhy = RoundUp(runCnt, FloatAlign);
            Items     = new AlignedArray(RunLenPhy * RunCntPhy, cbAlign);

            AssertValid();
        }
Пример #7
0
        /// <summary>
        /// Multiplies a matrix times a source.
        /// </summary>
        /// <param name="transpose"><see langword="true"/> to transpose the matrix; otherwise <see langword="false"/>.</param>
        /// <param name="matrix">The input matrix.</param>
        /// <param name="source">The source matrix.</param>
        /// <param name="destination">The destination matrix.</param>
        /// <param name="stride">The column stride.</param>
        public static void MatrixTimesSource(bool transpose, AlignedArray matrix, AlignedArray source, AlignedArray destination, int stride)
        {
            Contracts.Assert(matrix.Size == destination.Size * source.Size);
            Contracts.Assert(stride >= 0);

            if (Avx.IsSupported)
            {
                if (!transpose)
                {
                    Contracts.Assert(stride <= destination.Size);
                    AvxIntrinsics.MatMul(matrix, source, destination, stride, source.Size);
                }
                else
                {
                    Contracts.Assert(stride <= source.Size);
                    AvxIntrinsics.MatMulTran(matrix, source, destination, destination.Size, stride);
                }
            }
            else if (Sse.IsSupported)
            {
                if (!transpose)
                {
                    Contracts.Assert(stride <= destination.Size);
                    SseIntrinsics.MatMul(matrix, source, destination, stride, source.Size);
                }
                else
                {
                    Contracts.Assert(stride <= source.Size);
                    SseIntrinsics.MatMulTran(matrix, source, destination, destination.Size, stride);
                }
            }
            else
            {
                if (!transpose)
                {
                    Contracts.Assert(stride <= destination.Size);
                    for (int i = 0; i < stride; i++)
                    {
                        float dotProduct = 0;
                        for (int j = 0; j < source.Size; j++)
                        {
                            dotProduct += matrix[i * source.Size + j] * source[j];
                        }

                        destination[i] = dotProduct;
                    }
                }
                else
                {
                    Contracts.Assert(stride <= source.Size);
                    for (int i = 0; i < destination.Size; i++)
                    {
                        float dotProduct = 0;
                        for (int j = 0; j < stride; j++)
                        {
                            dotProduct += matrix[j * destination.Size + i] * source[j];
                        }

                        destination[i] = dotProduct;
                    }
                }
            }
        }
Пример #8
0
        public static void MatrixTimesSource(AlignedArray mat, ReadOnlySpan <int> rgposSrc, AlignedArray srcValues,
                                             int posMin, int iposMin, int iposLim, AlignedArray dst, int crun)
        {
            Contracts.Assert(Compat(mat));
            Contracts.Assert(Compat(srcValues));
            Contracts.Assert(Compat(dst));
            Contracts.Assert(0 <= iposMin && iposMin <= iposLim && iposLim <= rgposSrc.Length);
            Contracts.Assert(mat.Size == dst.Size * srcValues.Size);

            if (iposMin >= iposLim)
            {
                dst.ZeroItems();
                return;
            }
            Contracts.AssertNonEmpty(rgposSrc);
            unsafe
            {
                fixed(float *pdst = &dst.Items[0])
                fixed(float *pmat  = &mat.Items[0])
                fixed(float *psrc  = &srcValues.Items[0])
                fixed(int *ppossrc = &rgposSrc[0])
                {
                    Contracts.Assert(0 <= crun && crun <= dst.Size);
                    Thunk.MatMulP(Ptr(mat, pmat), ppossrc, Ptr(srcValues, psrc), posMin, iposMin, iposLim, Ptr(dst, pdst), crun, srcValues.Size);
                }
            }
        }
Пример #9
0
        public static void MatrixTimesSource(bool tran, AlignedArray mat, AlignedArray src, AlignedArray dst, int crun)
        {
            Contracts.Assert(Compat(mat));
            Contracts.Assert(Compat(src));
            Contracts.Assert(Compat(dst));
            Contracts.Assert(mat.Size == dst.Size * src.Size);

            unsafe
            {
                fixed(float *pmat = &mat.Items[0])
                fixed(float *psrc = &src.Items[0])
                fixed(float *pdst = &dst.Items[0])
                {
                    if (!tran)
                    {
                        Contracts.Assert(0 <= crun && crun <= dst.Size);
                        Thunk.MatMul(Ptr(mat, pmat), Ptr(src, psrc), Ptr(dst, pdst), crun, src.Size);
                    }
                    else
                    {
                        Contracts.Assert(0 <= crun && crun <= src.Size);
                        Thunk.MatMulTran(Ptr(mat, pmat), Ptr(src, psrc), Ptr(dst, pdst), dst.Size, crun);
                    }
                }
            }
        }
Пример #10
0
 private static bool Compat(AlignedArray a)
 {
     Contracts.AssertValue(a);
     Contracts.Assert(a.Size > 0);
     return(a.CbAlign == Vector128Alignment);
 }