private static void ExecuteSingleVectorOperation <T>(NArrayOperation <T> operation,
                                                             ArrayPoolStack <T> arrayPoolStack, List <T[]> temporaryArrays,
                                                             int vectorLength,
                                                             int chunkIndex, int startIndex)
        {
            if (operation == null)
            {
                return;
            }

            if (operation is AssignOperation <T> )
            {
                return;
            }

            NArray <T> result;

            if (IsLocal(operation.Result))
            {
                result = operation.Result;
                var chunkyStorage = result.Storage as ChunkyStorage <T>;
                temporaryArrays.Add(arrayPoolStack.Pop());
                chunkyStorage.SetChunk(chunkIndex, temporaryArrays.Last());
            }
            else
            {
                result = operation.Result;
            }

            if (operation is UnaryVectorOperation <T> )
            {
                var unaryOperation = operation as UnaryVectorOperation <T>;

                unaryOperation.Operation(Slice(unaryOperation.Operand, chunkIndex, startIndex, vectorLength),
                                         Slice(result, chunkIndex, startIndex, vectorLength));
            }

            if (operation is BinaryVectorOperation <T> )
            {
                var binaryOperation = operation as BinaryVectorOperation <T>;

                binaryOperation.Operation(Slice(binaryOperation.Operand1, chunkIndex, startIndex, vectorLength),
                                          Slice(binaryOperation.Operand2, chunkIndex, startIndex, vectorLength),
                                          Slice(result, chunkIndex, startIndex, vectorLength));
            }
        }
示例#2
0
        private static void ExecuteSingleVectorOperation <T>(BinaryExpression operation,
                                                             LinearAlgebraProvider provider,
                                                             ArrayPoolStack <T> arrayPoolStack, List <NArray <T> > localsToFree,
                                                             OutputGetter <T> getter, Aggregator aggregator,
                                                             int vectorLength,
                                                             int chunkIndex, int startIndex, ExecutionTimer timer)
        {
            if (operation == null || operation.NodeType != ExpressionType.Assign)
            {
                return;
            }

            if (operation == null)
            {
                return;
            }

            NArray <T> result;
            var        left = operation.Left as ReferencingVectorParameterExpression <T>;

            NArray <T> aggregationTarget = null;

            if (left.ParameterType == ParameterType.Local)
            {
                result = left.Array;
                var chunkyStorage = result.Storage as ChunkyStorage <T>;
                if (chunkyStorage != null)
                {
                    var newStorage = arrayPoolStack.Pop();
                    chunkyStorage.SetChunk(chunkIndex, newStorage);
                }
                aggregationTarget = getter.TryGetNext(left.Index);
            }
            else
            {
                result = (operation.Left as ReferencingVectorParameterExpression <T>).Array;
            }

            if (operation.Right is UnaryMathsExpression)
            {
                var unaryOperation = operation.Right as UnaryMathsExpression;

                if (unaryOperation.UnaryType == UnaryElementWiseOperation.ScaleOffset)
                {
                    var scaleOffset = unaryOperation as ScaleOffsetExpression <T>;
                    (provider as IElementWise <T>).ScaleOffset(Slice <T>(unaryOperation.Operand, chunkIndex, startIndex, vectorLength),
                                                               scaleOffset.Scale, scaleOffset.Offset,
                                                               Slice(result, chunkIndex, startIndex, vectorLength));
                }
                else if (unaryOperation.UnaryType == UnaryElementWiseOperation.ScaleInverse)
                {
                    var scaleInverse = unaryOperation as ScaleInverseExpression <T>;
                    (provider as IElementWise <T>).ScaleInverse(Slice <T>(unaryOperation.Operand, chunkIndex, startIndex, vectorLength),
                                                                scaleInverse.Scale,
                                                                Slice(result, chunkIndex, startIndex, vectorLength));
                }
                else
                {
                    (provider as IElementWise <T>).UnaryElementWiseOperation(
                        Slice <T>(unaryOperation.Operand, chunkIndex, startIndex, vectorLength),
                        Slice(result, chunkIndex, startIndex, vectorLength),
                        unaryOperation.UnaryType);
                }
            }

            if (operation.Right is BinaryExpression)
            {
                var binaryOperation = operation.Right as BinaryExpression;
                (provider as IElementWise <T>).BinaryElementWiseOperation(Slice <T>(binaryOperation.Left, chunkIndex, startIndex, vectorLength),
                                                                          Slice <T>(binaryOperation.Right, chunkIndex, startIndex, vectorLength),
                                                                          Slice(result, chunkIndex, startIndex, vectorLength),
                                                                          binaryOperation.NodeType);
            }

            if (aggregationTarget != null)
            {
                if (aggregator != Aggregator.ElementwiseAdd)
                {
                    throw new NotImplementedException();
                }
                if (aggregationTarget.IsScalar)
                {
                    throw new Exception();
                }

                var slice = Slice <T>(aggregationTarget, chunkIndex, startIndex, vectorLength);
                (provider as IElementWise <T>).BinaryElementWiseOperation(
                    slice,
                    Slice(result, chunkIndex, startIndex, vectorLength),
                    slice, ExpressionType.Add);
            }
            foreach (var item in localsToFree)
            {
                arrayPoolStack.Push((item.Storage as ChunkyStorage <T>).GetChunk(chunkIndex));
            }
        }