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)); } }
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)); } }