Beispiel #1
0
            internal static void Reduce <T, C>(C op, long axis, NdArray <T> in1, NdArray <T> @out)
                where C : struct, IBinaryOp <T>
            {
                bool largeInput       = in1.Shape.Dimensions[0].Length >= _no_blocks;
                bool largeOutput      = @out.Shape.Dimensions[0].Length >= _no_blocks && @out.Shape.Dimensions[Math.Max(0, axis - 1)].Length >= _no_blocks;
                bool scalarReduction  = axis == 0 && in1.Shape.Dimensions.LongLength == 1;
                bool doubleLargeInput = in1.Shape.Dimensions[0].Length >= (_no_blocks * 2);

                if ((SINGLE_CORE_THREAD || _no_blocks > 1) && ((largeInput && largeOutput) || (doubleLargeInput && scalarReduction)))
                {
                    int totalblocks = _no_blocks;
                    in1.DataAccessor.Allocate();
                    @out.DataAccessor.Allocate();

                    //Special handling required for 1D to scalar
                    if (axis == 0 && in1.Shape.Dimensions.LongLength == 1)
                    {
                        //Allocate some temp storage
                        T[] tmpout = new T[totalblocks];
                        _threads.RunParallel((block) =>
                                             UFunc.UFunc_Reduce_Inner_Flush(
                                                 op,
                                                 axis,
                                                 Reshape(in1, block, totalblocks),
                                                 new NdArray <T>(tmpout, new Shape(new long[] { 1 }, block))
                                                 )
                                             );

                        //Make the final reduction on the thread results
                        T r = tmpout[0];
                        for (var i = 1; i < totalblocks; i++)
                        {
                            r = op.Op(r, tmpout[i]);
                        }

                        @out.Value[@out.Shape.Offset] = r;
                    }
                    else
                    {
                        _threads.RunParallel((block) =>
                        {
                            var v1 = Reshape(in1, block, totalblocks, axis == 0 ? 1 : axis - 1);
                            var v2 = Reshape(@out, block, totalblocks, axis == 0 ? 0 : axis - 1);
                            UFunc.UFunc_Reduce_Inner_Flush(op, axis, v1, v2);
                        });
                    }
                }
                else
                {
                    UFunc.UFunc_Reduce_Inner_Flush(op, axis, in1, @out);
                }
            }
Beispiel #2
0
            /// <summary>
            /// Calculates the scalar result of applying the binary operation to all elements
            /// </summary>
            /// <typeparam name="T">The value to operate on</typeparam>
            /// <typeparam name="C">The operation to perform</typeparam>
            /// <param name="op">The operation to reduce with</param>
            /// <param name="in1">The array to aggregate</param>
            /// <param name="result">A scalar value that is the result of aggregating all elements</param>
            /// <returns>True if the operation was applied, false otherwise</returns>
            public static void ApplyAggregate <T, C>(C op, NdArray <T> in1, out T result)
                where C : struct, IBinaryOp <T>
            {
                foreach (var n in _handlers)
                {
                    if (n.Item2.ApplyAggregate <T, C>(op, in1, out result))
                    {
                        return;
                    }
                }

                //Fallback
                result = UFunc.UFunc_Aggregate_Inner_Flush <T, C>(op, in1);
            }
Beispiel #3
0
            /// <summary>
            /// Performs matrix multiplication on the two operands, using the supplied methods,
            /// without using lazy evaluation.
            /// </summary>
            /// <typeparam name="T">The type of data to operate on</typeparam>
            /// <typeparam name="CADD">The typed add operator</typeparam>
            /// <typeparam name="CMUL">The typed multiply operator</typeparam>
            /// <param name="addop">The add operator</param>
            /// <param name="mulop">The multiply operator</param>
            /// <param name="in1">The left-hand-side argument</param>
            /// <param name="in2">The right-hand-side argument</param>
            /// <param name="out">An optional output argument, use for in-place operations</param>
            /// <returns>True if the operation was applied, false otherwise</returns>
            public static void ApplyMatmul <T, CADD, CMUL>(CADD addop, CMUL mulop, NdArray <T> in1, NdArray <T> in2, NdArray <T> @out = null)
                where CADD : struct, IBinaryOp <T>
                where CMUL : struct, IBinaryOp <T>
            {
                foreach (var n in _handlers)
                {
                    if (n.Item2.ApplyMatmul <T, CADD, CMUL>(addop, mulop, in1, in2, @out))
                    {
                        return;
                    }
                }

                //Fallback
                UFunc.UFunc_Matmul_Inner_Flush <T, CADD, CMUL>(addop, mulop, in1, in2, @out);
            }
Beispiel #4
0
            internal static void NullaryOp <T, C>(C op, NdArray <T> @out)
                where C : struct, INullaryOp <T>
            {
                if ((SINGLE_CORE_THREAD || _no_blocks > 1) && @out.Shape.Dimensions[0].Length >= _no_blocks)
                {
                    int totalblocks = _no_blocks;
                    @out.DataAccessor.Allocate();

                    _threads.RunParallel((block) =>
                                         UFunc.UFunc_Op_Inner_Nullary_Flush(op, Reshape(@out, block, totalblocks))
                                         );
                }
                else
                {
                    UFunc.UFunc_Op_Inner_Nullary_Flush(op, @out);
                }
            }
Beispiel #5
0
            internal static void UnaryConvOp <Ta, Tb, C>(IUnaryConvOp <Ta, Tb> op, NdArray <Ta> in1, NdArray <Tb> @out)
                where C : struct, IUnaryConvOp <Ta, Tb>
            {
                if ((SINGLE_CORE_THREAD || _no_blocks > 1) && @out.Shape.Dimensions[0].Length >= _no_blocks)
                {
                    int totalblocks = _no_blocks;
                    in1.DataAccessor.Allocate();
                    @out.DataAccessor.Allocate();

                    _threads.RunParallel((block) =>
                                         UFunc.UFunc_Op_Inner_UnaryConv_Flush(
                                             op,
                                             Reshape(in1, block, totalblocks),
                                             Reshape(@out, block, totalblocks)
                                             )
                                         );
                }
                else
                {
                    UFunc.UFunc_Op_Inner_UnaryConv_Flush(op, in1, @out);
                }
            }