private List <FunctionParameter> ParseOutParams(string function) { var outParams = new List <FunctionParameter>(); string functionHeader = SourceHelper.ExtractFunctionHeader(function); string[] headerSplit = functionHeader.Split(','); foreach (string variable in headerSplit) { string[] variableSplit = variable.Trim().Split(' '); if (variableSplit.Length == 3 && variableSplit[0] == "out") { outParams.Add(new FunctionParameter { // Fix any parameter names that come at the end of the function Name = variableSplit[2].Replace(")", string.Empty), Type = variableSplit[1] }); } } return(outParams); }
private int DetectFunctionEnd(string[] code, int functionStart, int codeEnd) { int indentationCounter = 0; for (int i = functionStart; i < codeEnd; i++) { int openBracket = SourceHelper.ParseDown(code, "{", i); int closeBracket = SourceHelper.ParseDown(code, "}", i); if (openBracket > 0 && openBracket < closeBracket) { i = openBracket; indentationCounter++; } if (closeBracket > 0) { i = closeBracket; if (indentationCounter == 0) { return(closeBracket); } indentationCounter--; } } throw new Exception("Could not find the end of the function!"); }
public FunctionMapping(string[] code) { _functionTable = new Dictionary <string, string[]>(); int blockStart = SourceHelper.ParseDown(code, "FUNCTIONS START", 0) + 1; int blockEnd = SourceHelper.ParseDown(code, "FUNCTIONS END", blockStart); for (int i = blockStart; i < blockEnd; i++) { if (string.IsNullOrEmpty(code[i])) { continue; } // Found a function opening if (code[i].Contains("protected void")) { string functionName = SourceHelper.ExtractFunctionName(code[i]); List <FunctionParameter> outParams = ParseOutParams(code[i]); if (outParams.Count == 0) { throw new Exception($"Function '{code[i]}' must contain out parameters!"); } var functionCode = new List <string>(); var paramsReplaced = new HashSet <string>(); int functionEnd = DetectFunctionEnd(code, i + 2, blockEnd); // Assume the function starts two lines below the function declaration for (int lineIndex = i + 2; lineIndex < functionEnd; lineIndex++) { foreach (FunctionParameter outParam in outParams) { // Only replace the first usage of the parameter with it's type definition if (code[lineIndex].Contains(outParam.Name) && !paramsReplaced.Contains(outParam.Name)) { code[lineIndex] = code[lineIndex].Replace(outParam.Name, $"{outParam.Type} {outParam.Name}"); paramsReplaced.Add(outParam.Name); break; } } functionCode.Add(code[lineIndex].Trim()); } AddFunction(functionName, functionCode.ToArray()); } } }
private static KernelFile CreateKernel(string codePath, ConstantMapping constants, FunctionMapping functions) { string[] lines = File.ReadAllLines(codePath); int kernelIndex = SourceHelper.ParseDown(lines, "public void Run", 0); string kernelFunction = lines[kernelIndex]; string kernelParameters = SourceHelper.ExtractFunctionHeader(kernelFunction); kernelParameters = kernelParameters.Replace("int[]", "global int*"); kernelParameters = kernelParameters.Replace("float[]", "global float*"); var clCode = new List <string>(); if (IsFP64(kernelFunction)) { clCode.Add("#pragma OPENCL EXTENSION cl_khr_fp64 : enable"); } clCode.Add("kernel void Run " + kernelParameters); int codeEnd = lines.Length; for (int i = 0; i < 3; i++) { codeEnd = SourceHelper.ParseUp(lines, "}", codeEnd - 1); } for (int i = kernelIndex + 1; i < codeEnd + 1; i++) { clCode.Add(lines[i].Trim()); } // Replace constants and inline functions functions.Inline(clCode); constants.Replace(clCode); return(new KernelFile { Code = string.Join("\n", clCode) }); }
public ConstantMapping(string[] code) { _constantTable = new Dictionary <string, string>(); int constantStart = SourceHelper.ParseDown(code, "CONSTANTS START", 0) + 1; int constantEnd = SourceHelper.ParseDown(code, "CONSTANTS END", constantStart); for (int i = constantStart; i < constantEnd; i++) { if (string.IsNullOrEmpty(code[i])) { continue; } string cleanedLine = code[i].Trim(); string[] lineSplit = cleanedLine.Split(' '); string value = lineSplit[5].Substring(0, lineSplit[5].Length - 1); AddConstant(lineSplit[3], value); } }