Пример #1
0
        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
                           ));
            }
        }
Пример #2
0
        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
        }