public void GenerateCode(VectorBlockExpression block) { Visit(block, _bodySection); _code.Replace(functionName, "TestFunction"); ReplaceWithIndentation(_code, bodySection, _bodySection); var code = _code.ToString(); }
/// <summary> /// Assign ChunkyStorage to locals and determines when each local can be freed-up /// </summary> /// <typeparam name="T"></typeparam> /// <param name="localsToFree">Contains the idices of the locals that can be freed once the operation is complete</param> private static void AssignNArrayStorage <T>(VectorBlockExpression block, int chunkCount, int chunksLength, int vectorLength, out List <NArray <T> >[] localsToFree) { var localNArrays = block.LocalParameters.Select(r => r as ReferencingVectorParameterExpression <T>). ToList(); var lastUseOfLocal = Enumerable.Repeat(block.Operations.Count - 1, block.LocalParameters.Last().Index + 1).ToArray(); // the operation index that represents the last time a result is used int firstLocal = block.LocalParameters.First().Index; for (int i = 0; i < block.Operations.Count; ++i) { foreach (int index in GetOperandIndices <T>(block.Operations[i])) { if (index >= firstLocal) { lastUseOfLocal[index] = i; } } } localsToFree = Enumerable.Range(0, block.Operations.Count) .Select(i => new List <NArray <T> >()).ToArray(); foreach (var localNArray in localNArrays) { if (localNArray.Array == null) { continue; } localNArray.Array.Storage = new ChunkyStorage <T>(chunkCount, chunksLength); } for (int i = firstLocal; i < lastUseOfLocal.Length; ++i) { if (lastUseOfLocal[i] >= 0) { var local = localNArrays[i - firstLocal]; if (local.Array != null) { localsToFree[lastUseOfLocal[i]].Add(local.Array); } } } }
private Expression VisitBlock(VectorBlockExpression block, StringBuilder builder) { _code.Append(prototype_vectorOperation); var arguments = block.ArgumentParameters; var locals = block.LocalParameters; //builder. SetKernelArguments(arguments.Select(a => a.Name)); SetKernelLocals(locals.Select(a => a.Name)); foreach (var expression in block.Operations) { Visit(expression, builder); WriteNewLine(builder); } return(block); }
private static void GetFunctions(VectorBlockExpression block, out Function[] f, out List<int>[] jLookup) { int N = block.ArgumentParameters.Count + block.LocalParameters.Count; // this stores the indices of the operations which make use of expression i jLookup = new List<int>[N]; for (int i = 0; i < N; ++i) jLookup[i] = new List<int>(); f = new Function[N]; // The first set of functions are simply the arguments for (int i = 0; i < block.ArgumentParameters.Count; ++i) { f[i] = new Function() { Expression = block.ArgumentParameters[i], Parameter = block.ArgumentParameters[i] }; } // The next set are the operations for (int i = 0; i < block.Operations.Count; ++i) { var assignment = block.Operations[i]; if (!(assignment.Left is VectorParameterExpression)) throw new NotImplementedException(); VectorParameterExpression parameter = assignment.Left as VectorParameterExpression; int operationIndex = parameter.Index; //if (operationIndex != i + block.ArgumentParameters.Count) throw new Exception("index mismatch"); var operation = assignment.Right; f[operationIndex] = new Function() { Expression = assignment.Right, Parameter = parameter }; if (operation is BinaryExpression) { UpdateOperationIndices(jLookup, (operation as BinaryExpression).Left as VectorParameterExpression, operationIndex); UpdateOperationIndices(jLookup, (operation as BinaryExpression).Right as VectorParameterExpression, operationIndex); } else if (operation is UnaryMathsExpression) { UpdateOperationIndices(jLookup, (operation as UnaryMathsExpression).Operand, operationIndex); } } }