Esempio n. 1
0
        public static void MatTimesSrc(bool tran, bool add, AlignedArray mat, int[] rgposSrc, AlignedArray srcValues,
                                       int posMin, int iposMin, int iposLim, AlignedArray dst, int crun)
        {
            Contracts.AssertValue(rgposSrc);
            Contracts.Assert(iposMin >= 0);
            Contracts.Assert(iposMin <= iposLim);
            Contracts.Assert(iposLim <= rgposSrc.Length);
            Contracts.Assert(mat.Size == dst.Size * srcValues.Size);

            if (iposMin >= iposLim)
            {
                if (!add)
                {
                    dst.ZeroItems();
                }
                return;
            }

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

            if (Avx.IsSupported)
            {
                if (!tran)
                {
                    Contracts.Assert(crun <= dst.Size);
                    AvxIntrinsics.MatMulPX(add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, crun, srcValues.Size);
                }
                else
                {
                    Contracts.Assert(crun <= srcValues.Size);
                    AvxIntrinsics.MatMulTranPX(add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, dst.Size);
                }
            }
            else if (Sse.IsSupported)
            {
                if (!tran)
                {
                    Contracts.Assert(crun <= dst.Size);
                    SseIntrinsics.MatMulPA(add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, crun, srcValues.Size);
                }
                else
                {
                    Contracts.Assert(crun <= srcValues.Size);
                    SseIntrinsics.MatMulTranPA(add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, dst.Size);
                }
            }
            else
            {
                if (!tran)
                {
                    Contracts.Assert(crun <= dst.Size);
                    for (int i = 0; i < crun; i++)
                    {
                        float dotProduct = 0;
                        for (int j = iposMin; j < iposLim; j++)
                        {
                            int col = rgposSrc[j] - posMin;
                            dotProduct += mat[i * srcValues.Size + col] * srcValues[col];
                        }

                        if (add)
                        {
                            dst[i] += dotProduct;
                        }
                        else
                        {
                            dst[i] = dotProduct;
                        }
                    }
                }
                else
                {
                    Contracts.Assert(crun <= srcValues.Size);
                    for (int i = 0; i < dst.Size; i++)
                    {
                        float dotProduct = 0;
                        for (int j = iposMin; j < iposLim; j++)
                        {
                            int col = rgposSrc[j] - posMin;
                            dotProduct += mat[col * dst.Size + i] * srcValues[col];
                        }

                        if (add)
                        {
                            dst[i] += dotProduct;
                        }
                        else
                        {
                            dst[i] = dotProduct;
                        }
                    }
                }
            }
        }