public static ConversionResult ConvertApply(ConversionState state, ConversionResult arg, MethodStruct methodStruct, Identifier receiveBufferIdentifier) { if (arg.HasComplexIndexer) { #region // argument has a complex indexer // store new size in variable Int32 kernelIndex = state.GetNextKernelIndex(); Identifier kernelSizeIdentifier = Identifier.For(String.Format("_kernel{0}Size", kernelIndex)); // get problem global size ConversionHelper.GenerateKernelSizeArrayField(state, kernelSizeIdentifier); state.Constructor.Body.Statements.Add( NodeHelper.GetAssignmentStatementForNewSizeArray(kernelSizeIdentifier, 1) ); if (arg.Type.Rank == 2) { state.Constructor.Body.Statements.Add(new AssignmentStatement { Target = NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0), Source = new BinaryExpression { NodeType = NodeType.Mul, Operand1 = NodeHelper.GetConstantIndexerForExpression(arg.SizeIdentifier, 0), Operand2 = NodeHelper.GetConstantIndexerForExpression(arg.SizeIdentifier, 1) } }); } else { state.Constructor.Body.Statements.Add(new AssignmentStatement { Target = NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0), Source = NodeHelper.GetConstantIndexerForExpression(arg.SizeIdentifier, 0) }); } Dictionary <String, KernelArgumentDetails> arguments = arg.KernelArguments; String kernelSource = ComputeKernelTemplates.apply_indexer; kernelSource = kernelSource.Replace("{type}", arg.Type.ScalarType.OpenCLTypeName); kernelSource = kernelSource.Replace("{expression}", arg.AccessExpression); kernelSource = kernelSource.Replace("{operation}", methodStruct.Operation); List <Identifier> waitHandles = arg.WaitHandles; Identifier kernelGlobalRangeIdentifier = Identifier.For(String.Format("kernel{0}GlobalRange", kernelIndex)); Func <List <Identifier>, Expression, Identifier> generate = (buffers, kernelExpression) => { Identifier kernelIdentifier = Identifier.For("_kernel" + kernelIndex.ToString()); state.CodeletMethod.Body.Statements.Add(new VariableDeclaration { Name = kernelGlobalRangeIdentifier, Type = SystemTypes.UInt64.GetArrayType(1), Initializer = new ConstructArray { ElementType = SystemTypes.UInt64, Rank = 1, Operands = new ExpressionList( Literal.Int32Two ) } }); ConversionHelper.GenerateSizeFromBufferIdentifier(state, state.CodeletMethod, String.Format("_buffer{0}", arg.ArgumentIndex), kernelGlobalRangeIdentifier); // get kernel ConversionHelper.GenerateGetKernelForProgram(state, kernelIdentifier, kernelExpression); // set kernel arguments Int32 index = 0; ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index++, NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0)); foreach (var buffer in buffers) { ConversionHelper.GenerateKernelSetGlobalArgument(state, kernelIdentifier, index, buffer); index += 1; #region Complex Indexer if (arg.HasComplexIndexer) { ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index, Identifier.For(String.Format("_{0}n", buffer.Name))); index++; for (int dimension = 0; dimension < 2 /* FIXME */; dimension++) { ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index, Identifier.For(String.Format("_{0}from{1}", buffer.Name, dimension))); index++; ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index, Identifier.For(String.Format("_{0}by{1}", buffer.Name, dimension))); index++; } } #endregion } Identifier kernelPredecessorsIdentifier = Identifier.For(String.Format("kernel{0}predecessors", kernelIndex)); ConversionHelper.GenerateKernelPredecessors(state, kernelPredecessorsIdentifier, waitHandles); Identifier waitHandleIdentifier = Identifier.For("_eventObject" + kernelIndex.ToString()); ConversionHelper.GenerateEventObjectAndStartKernel(state, waitHandleIdentifier, kernelIdentifier, kernelGlobalRangeIdentifier, Literal.Null, kernelPredecessorsIdentifier); ConversionHelper.GenerateFlushCommandQueue(state); return(waitHandleIdentifier); }; String completeExpression = string.Format("{0}({1})", methodStruct.Name, arg.CompleteExpression); return(new ConversionResult( new KernelDetails(kernelSource, generate), "value", arg.Type, kernelGlobalRangeIdentifier, arguments, new List <Identifier>(), completeExpression )); #endregion } else { // store new size in variable Int32 kernelIndex = state.GetNextKernelIndex(); Identifier kernelSizeIdentifier = Identifier.For(String.Format("_kernel{0}Size", kernelIndex)); // get problem global size ConversionHelper.GenerateKernelSizeArrayField(state, kernelSizeIdentifier); state.Constructor.Body.Statements.Add( NodeHelper.GetAssignmentStatementForNewSizeArray(kernelSizeIdentifier, 1) ); if (arg.Type.Rank == 2) { state.Constructor.Body.Statements.Add(new AssignmentStatement { Target = NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0), Source = new BinaryExpression { NodeType = NodeType.Mul, Operand1 = NodeHelper.GetConstantIndexerForExpression(arg.SizeIdentifier, 0), Operand2 = NodeHelper.GetConstantIndexerForExpression(arg.SizeIdentifier, 1) } }); } else { state.Constructor.Body.Statements.Add(new AssignmentStatement { Target = NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0), Source = NodeHelper.GetConstantIndexerForExpression(arg.SizeIdentifier, 0) }); } Dictionary <String, KernelArgumentDetails> arguments = arg.KernelArguments; String kernelSource = methodStruct.KernelSource; kernelSource = kernelSource.Replace("{type}", arg.Type.ScalarType.OpenCLTypeName); kernelSource = kernelSource.Replace("{expression}", arg.AccessExpression); kernelSource = kernelSource.Replace("{operation}", methodStruct.Operation); List <Identifier> waitHandles = arg.WaitHandles; Func <List <Identifier>, Expression, Identifier> generate = (buffers, kernelExpression) => { Identifier kernelIdentifier = Identifier.For("_kernel" + kernelIndex.ToString()); // get kernel ConversionHelper.GenerateGetKernelForProgram(state, kernelIdentifier, kernelExpression); // set kernel arguments Int32 index = 0; ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index++, NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0)); //ConversionHelper.GenerateKernelSetLocalArgument(state, kernelIdentifier, index++, localSize); foreach (var buffer in buffers) { ConversionHelper.GenerateKernelSetGlobalArgument(state, kernelIdentifier, index, buffer); index += 1; } Identifier kernelPredecessorsIdentifier = Identifier.For(String.Format("kernel{0}predecessors", kernelIndex)); ConversionHelper.GenerateKernelPredecessors(state, kernelPredecessorsIdentifier, waitHandles); Identifier waitHandleIdentifier = Identifier.For("_eventObject" + kernelIndex.ToString()); ConversionHelper.GenerateEventObjectAndStartKernel(state, waitHandleIdentifier, kernelIdentifier, kernelSizeIdentifier, Literal.Null, kernelPredecessorsIdentifier); ConversionHelper.GenerateFlushCommandQueue(state); return(waitHandleIdentifier); }; String completeExpression = string.Format("{0}({1})", methodStruct.Name, arg.CompleteExpression); return(new ConversionResult( new KernelDetails(kernelSource, generate), "value", arg.Type, kernelSizeIdentifier, arguments, new List <Identifier>(), completeExpression )); } }
public static ConversionResult ConvertPPS(ConversionState state, ConversionResult arg, MethodStruct methodStruct, Identifier receiveBufferIdentifier) { #region // 1st stage // store new size in variable Int32 kernelIndex = state.GetNextKernelIndex(); // get problem global size Identifier kernelSizeIdentifier = Identifier.For(String.Format("_kernel{0}Size", kernelIndex)); ConversionHelper.GenerateKernelSizeArrayField(state, kernelSizeIdentifier); state.Constructor.Body.Statements.Add( NodeHelper.GetAssignmentStatementForNewSizeArray(kernelSizeIdentifier, arg.Type.Rank) ); for (Int32 index = 0; index < arg.Type.Rank; index++) { state.Constructor.Body.Statements.Add( NodeHelper.GetAssignmentStatementForIndices(kernelSizeIdentifier, index, arg.SizeIdentifier, index) ); } Dictionary <String, KernelArgumentDetails> arguments = arg.KernelArguments; String kernelSource = ComputeKernelTemplates.pps1; kernelSource = kernelSource.Replace("{type}", arg.Type.ScalarType.OpenCLTypeName); kernelSource = kernelSource.Replace("{expression}", arg.AccessExpression); kernelSource = kernelSource.Replace("{operation}", methodStruct.Operation); kernelSource = kernelSource.Replace("{identity}", methodStruct.Identity); List <Identifier> waitHandles = arg.WaitHandles; Func <List <Identifier>, Expression, Identifier> generate = (buffers, kernelExpression) => { Identifier kernelIdentifier = Identifier.For("_kernel" + kernelIndex.ToString()); // get kernel ConversionHelper.GenerateGetKernelForProgram(state, kernelIdentifier, kernelExpression); Identifier globalSizeIdent = Identifier.For("globalSize"); state.CodeletMethod.Body.Statements.Add(new VariableDeclaration { Name = globalSizeIdent, Type = SystemTypes.UInt64.GetArrayType(1), Initializer = new ConstructArray { ElementType = SystemTypes.UInt64, Rank = 1, Operands = new ExpressionList(Literal.Int32One), Initializers = new ExpressionList(new Literal(2048 /* FIXME */, SystemTypes.UInt64)) } }); Expression localSize = new ConstructArray { ElementType = SystemTypes.UInt64, Rank = 1, Operands = new ExpressionList(Literal.Int32One), Initializers = new ExpressionList(new Literal(64 /* FIXME */, SystemTypes.UInt64)) }; // localSize is 64 elements Expression localSizeMem = new BinaryExpression { NodeType = NodeType.Mul, Operand1 = new Literal(64 /* FIXME */, SystemTypes.UInt64), Operand2 = new Literal(arg.Type.ScalarType.ByteSize, SystemTypes.UInt64) }; // set kernel arguments Int32 index = 0; ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index++, NodeHelper.GetSizeMultiplicationClosure(kernelSizeIdentifier, arg.Type.Rank)); ConversionHelper.GenerateKernelSetLocalArgument(state, kernelIdentifier, index++, localSizeMem); foreach (var buffer in buffers) { ConversionHelper.GenerateKernelSetGlobalArgument(state, kernelIdentifier, index, buffer); index += 1; } Identifier kernelPredecessorsIdentifier = Identifier.For(String.Format("kernel{0}predecessors", kernelIndex)); ConversionHelper.GenerateKernelPredecessors(state, kernelPredecessorsIdentifier, waitHandles); Identifier waitHandleIdentifier = Identifier.For("_eventObject" + kernelIndex.ToString()); ConversionHelper.GenerateEventObjectAndStartKernel(state, waitHandleIdentifier, kernelIdentifier, globalSizeIdent, localSize, kernelPredecessorsIdentifier); ConversionHelper.GenerateFlushCommandQueue(state); return(waitHandleIdentifier); }; String completeExpression = string.Format("{0}({1})", methodStruct.Name, arg.CompleteExpression); ConversionResult firstStage = new ConversionResult( new KernelDetails(kernelSource, generate), "value", arg.Type, kernelSizeIdentifier, arguments, new List <Identifier>(), completeExpression ); arg = ConversionHelper.GenerateKernelExecution(state, firstStage, null); #endregion #region // 2nd stage // store new size in variable kernelIndex = state.GetNextKernelIndex(); kernelSizeIdentifier = Identifier.For(String.Format("_kernel{0}Size", kernelIndex)); // get problem global size ConversionHelper.GenerateKernelSizeArrayField(state, kernelSizeIdentifier); state.Constructor.Body.Statements.Add( NodeHelper.GetAssignmentStatementForNewSizeArray(kernelSizeIdentifier, 1) ); state.Constructor.Body.Statements.Add(new AssignmentStatement { Target = NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0), Source = new BinaryExpression { NodeType = NodeType.Div, Operand1 = new Literal(2048 /* FIXME */, SystemTypes.UInt64), Operand2 = new Literal(64 /* FIXME */, SystemTypes.UInt64) } }); arguments = arg.KernelArguments; kernelSource = ComputeKernelTemplates.pps2; kernelSource = kernelSource.Replace("{type}", arg.Type.ScalarType.OpenCLTypeName); kernelSource = kernelSource.Replace("{expression}", arg.AccessExpression); kernelSource = kernelSource.Replace("{operation}", methodStruct.Operation); kernelSource = kernelSource.Replace("{identity}", methodStruct.Identity); waitHandles = arg.WaitHandles; generate = (buffers, kernelExpression) => { Identifier kernelIdentifier = Identifier.For("_kernel" + kernelIndex.ToString()); // get kernel ConversionHelper.GenerateGetKernelForProgram(state, kernelIdentifier, kernelExpression); // set kernel arguments Int32 index = 0; ConversionHelper.GenerateKernelSetValueArgument(state, kernelIdentifier, index++, NodeHelper.GetConstantIndexerForExpression(kernelSizeIdentifier, 0)); //ConversionHelper.GenerateKernelSetLocalArgument(state, kernelIdentifier, index++, localSize); foreach (var buffer in buffers) { ConversionHelper.GenerateKernelSetGlobalArgument(state, kernelIdentifier, index, buffer); index += 1; } Identifier kernelPredecessorsIdentifier = Identifier.For(String.Format("kernel{0}predecessors", kernelIndex)); ConversionHelper.GenerateKernelPredecessors(state, kernelPredecessorsIdentifier, waitHandles); Identifier waitHandleIdentifier = Identifier.For("_eventObject" + kernelIndex.ToString()); ConversionHelper.GenerateEventObjectAndStartKernel(state, waitHandleIdentifier, kernelIdentifier, kernelSizeIdentifier, Literal.Null, kernelPredecessorsIdentifier); ConversionHelper.GenerateFlushCommandQueue(state); return(waitHandleIdentifier); }; completeExpression = string.Format("{0}({1})", methodStruct.Name, arg.CompleteExpression); return(new ConversionResult( new KernelDetails(kernelSource, generate), "value", arg.Type, kernelSizeIdentifier, arguments, new List <Identifier>(), completeExpression )); #endregion }