예제 #1
0
 public KernelArgumentDetails(Int32 openCLArgumentId, ComputeType mathType, Boolean isElementwise)
     : this()
 {
     OpenCLArgumentId = openCLArgumentId;
     MathType         = mathType;
     IsElementwise    = isElementwise;
 }
예제 #2
0
 public ConversionResult(
     KernelDetails?kernelDetails,
     String accessExpression,
     ComputeType mathType,
     Identifier sizeIdentifier,
     Dictionary <String, KernelArgumentDetails> kernelArguments,
     List <Identifier> waitHandles,
     String completeExpression
     )
     : this(kernelDetails,
            accessExpression,
            mathType,
            sizeIdentifier,
            kernelArguments,
            waitHandles,
            completeExpression,
            null)
 {
 }
예제 #3
0
 public ConversionResult(
     KernelDetails?kernelDetails,
     String accessExpression,
     ComputeType mathType,
     Identifier sizeIdentifier,
     Dictionary <String, KernelArgumentDetails> kernelArguments,
     List <Identifier> waitHandles,
     String completeExpression,
     Int32?argumentIndex
     )
     : this()
 {
     KernelDetails      = kernelDetails;
     AccessExpression   = accessExpression;
     Type               = mathType;
     SizeIdentifier     = sizeIdentifier;
     KernelArguments    = kernelArguments;
     WaitHandles        = waitHandles;
     CompleteExpression = completeExpression;
     ArgumentIndex      = argumentIndex;
 }
예제 #4
0
        public static Statement Convert(ConversionState state, ConversionResult expressionResult, Identifier receiverIdentifier, ComputeType receiverComputeType, INDEXER indexer)
        {
            bool        complexIndexer;
            ComputeType computeType = receiverComputeType;

            Expression[] indices = ConversionHelper.GetExpressionsFromIndexer(indexer, ref receiverComputeType, out complexIndexer);
            // create empty indices if there is a complex indexer
            if (indices == null && complexIndexer)
            {
                receiverComputeType = computeType;
                indices             = new Expression[computeType.Rank];
            }
            if (indices == null || (receiverComputeType != expressionResult.Type && !complexIndexer))
            {
                return(null);
            }

            // if the right expression has a complex indexer, we need it too
            complexIndexer |= expressionResult.HasComplexIndexer;

            List <ConversionHelper.Argument> sortedArguments = ConversionHelper.ExtractArguments(state, false);
            List <ConversionHelper.Argument> scalarArguments = ConversionHelper.ExtractArguments(state, true);

            ExpressionArgument receiverArgument;

            ConversionHelper.ProcessReceiver(state, expressionResult, receiverIdentifier, receiverComputeType, indices, indexer, ref sortedArguments, complexIndexer, out receiverArgument);

            ConversionResult finalConversionResult = ConversionHelper.GenerateKernelExecution(state, expressionResult, Identifier.For("buffer" + receiverArgument.Index.ToString()), complexIndexer);

            // generate delegates
            DelegateNode getOpenCLTimeDelegateType;
            DelegateNode startOpenCLDelegateType;

            ConversionHelper.GenerateOpenCLDelegates(state, out getOpenCLTimeDelegateType, out startOpenCLDelegateType);

            // generate get time method
            ConversionHelper.GenerateTimeMethod(state);

            // generate the codelets
            Identifier codeletsIdentifier;

            ConversionHelper.GenerateCodelets(state, getOpenCLTimeDelegateType, startOpenCLDelegateType, out codeletsIdentifier);

            // process arguments
            Identifier     dataUsesIdentifier;
            ExpressionList constructArguments = new ExpressionList();

            ConversionHelper.ProcessArguments(state, sortedArguments, scalarArguments, complexIndexer, startOpenCLDelegateType, out dataUsesIdentifier, ref state.Constructor.Parameters, ref constructArguments);

            ConversionHelper.GenerateSubmitCodelet(state, codeletsIdentifier, dataUsesIdentifier);

            ConversionHelper.FinishOperation(state, finalConversionResult);

            String completeExpression   = string.Format("{0} = {1}", ConversionHelper.FormatIdentifierExpression(receiverComputeType, indices, receiverArgument.Index, complexIndexer), finalConversionResult.CompleteExpression);
            Class  actualOperationClass = CONTEXT._operationRegistry.RegisterOperation(completeExpression, state.Class);

            return(new ExpressionStatement {
                Expression = new Construct {
                    Constructor = new MemberBinding {
                        BoundMember = actualOperationClass.GetConstructors()[0],
                    },
                    Operands = constructArguments,
                }
            });
        }
예제 #5
0
        public static Expression Convert(ConversionState state, ConversionResult expressionResult, MethodStruct methodStruct)
        {
            #region // result will be stored in a temporary value
            bool        complexIndexer;
            ComputeType receiverComputeType;
            if (methodStruct.Type is ARRAY_TYPE)
            {
                // result is array
                ComputeType.FromType(methodStruct.Type).TryGetValue(out receiverComputeType);
            }
            else
            {
                // result is scalar
                receiverComputeType = new ComputeType(ComputeScalarType.Single, 1);
            }
            Identifier receiverIdentifier = Identifier.For("ret");

            Expression[] indices = ConversionHelper.GetExpressionsFromIndexer(null, ref receiverComputeType, out complexIndexer);

            complexIndexer |= expressionResult.HasComplexIndexer;

            #endregion

            List <ConversionHelper.Argument> sortedArguments = ConversionHelper.ExtractArguments(state, false);
            List <ConversionHelper.Argument> scalarArguments = ConversionHelper.ExtractArguments(state, true);

            //ExpressionArgument receiverArgument;
            //ConversionHelper.ProcessReceiver(state, expressionResult, receiverIdentifier, receiverComputeType, indices, null, ref sortedArguments, complexIndexer, out receiverArgument);

            #region // add the temporary variable as a receiver
            ExpressionArgument receiverArgument = new ExpressionArgument(sortedArguments.Count, indices, null, -1);
            sortedArguments.Add(new ConversionHelper.Argument {
                Index     = receiverArgument.Index,
                Name      = receiverIdentifier.ToString(),
                Indexers  = receiverArgument.Indexers,
                IsRead    = false,
                IsWritten = true,
                IsCall    = receiverArgument.IsCall,
                CallRank  = receiverArgument.CallRank,
            });

            Identifier receiverDataIdentifier = Identifier.For("data" + receiverArgument.Index);
            if (!expressionResult.HasComplexIndexer)
            {
                // allocate receiver (1D array with size 1 for scalar result, matrix (vector) in other cases)
                ExpressionList ctorExpr = new ExpressionList();
                for (int index = 0; index < receiverComputeType.Rank; index++)
                {
                    ctorExpr.Add(NodeHelper.GetConstantIndexerForExpression(expressionResult.SizeIdentifier, index));
                }
                state.Constructor.Body.Statements.Add(
                    new AssignmentStatement {
                    Target = new AddressDereference {
                        Address = receiverDataIdentifier,
                        Type    = STANDARD.Data,
                    },
                    Source = new Construct {
                        Constructor = new MemberBinding {
                            BoundMember = STANDARD.Data.GetConstructor(SystemTypes.Array),
                        },
                        Operands = new ExpressionList(
                            new ConstructArray {
                            ElementType = expressionResult.Type.ScalarType.TypeNode,
                            Rank        = (methodStruct.Type is ARRAY_TYPE) ? receiverComputeType.Rank : 1,
                            Operands    = (methodStruct.Type is ARRAY_TYPE) ? ctorExpr : new ExpressionList(Literal.Int32One),
                        }
                            ),
                    }
                }
                    );
            }
            else
            {
                state.Constructor.Body.Statements.Add(new Block {
                    Statements = ConversionHelper.GenerateIndexedSize(expressionResult, receiverComputeType, receiverDataIdentifier, state.GetNextTempSizeIdentifier())
                });
            }
            #endregion

            #region // generate kernel
            ConversionResult?result = GenereteKernel(state, expressionResult, Identifier.For("buffer" + receiverArgument.Index.ToString()), methodStruct);
            ConversionResult finalConversionResult;
            if (result.HasValue)
            {
                finalConversionResult = result.Value;
            }
            else
            {
                return(null);
            }
            #endregion

            #region // generate delegates
            DelegateNode getOpenCLTimeDelegateType;
            DelegateNode startOpenCLDelegateType;
            ConversionHelper.GenerateOpenCLDelegates(state, out getOpenCLTimeDelegateType, out startOpenCLDelegateType);
            #endregion

            #region // generate get time method
            ConversionHelper.GenerateTimeMethod(state);
            #endregion

            #region // generate the codelets
            Identifier codeletsIdentifier;
            ConversionHelper.GenerateCodelets(state, getOpenCLTimeDelegateType, startOpenCLDelegateType, out codeletsIdentifier);
            #endregion

            #region // process all arguments - add them to parameters and data uses
            ExpressionList  ctorArgs   = new ExpressionList();
            ExpressionList  callArgs   = new ExpressionList();
            ParameterList   callParams = new ParameterList();
            List <TypeNode> typeList   = new List <TypeNode>();

            Identifier dataUsesIdentifier;
            ConversionHelper.ProcessArguments(state, sortedArguments, scalarArguments, complexIndexer, startOpenCLDelegateType, out dataUsesIdentifier, ref callParams, ref callArgs, ref state.Constructor.Parameters, ref ctorArgs, ref typeList);

            #endregion

            ConversionHelper.GenerateSubmitCodelet(state, codeletsIdentifier, dataUsesIdentifier);
            ConversionHelper.FinishOperation(state, finalConversionResult);

            Class actualOperationClass = CONTEXT._operationRegistry.RegisterOperation(finalConversionResult.CompleteExpression, state.Class);

            #region // create method 'call'
            Identifier callIdentifier = Identifier.For("call");
            Method     callMethod     = actualOperationClass.GetMethod(callIdentifier, typeList.ToArray());
            Expression returnExp;
            if (methodStruct.Type is ARRAY_TYPE)
            {
                returnExp = receiverIdentifier;
            }
            else
            {
                returnExp = new BinaryExpression {
                    NodeType = NodeType.Castclass,
                    Operand2 = new MemberBinding {
                        BoundMember = expressionResult.Type.ScalarType.TypeNode.GetArrayType(1)
                    },
                    Operand1 = new MethodCall {
                        Callee = new MemberBinding {
                            TargetObject = receiverIdentifier,
                            BoundMember  = STANDARD.Data.GetMethod(Identifier.For("GetHostArray")),
                        },
                    }
                };
            }
            if (methodStruct.Type is ARRAY_TYPE)
            {
            }
            else
            {
                returnExp = NodeHelper.GetConstantIndexerForExpression(returnExp, 0);
                if (methodStruct.Type is BOOLEAN_TYPE)
                {
                    // if it was a boolean operation invert the value (1 is false in OpenCL kernel)
                    returnExp = new BinaryExpression {
                        NodeType = NodeType.Eq,
                        Operand1 = returnExp,
                        Operand2 = Literal.Int32Zero
                    };
                }
            }
            if (callMethod == null)
            {
                actualOperationClass.Members.Add(new Method {
                    DeclaringType = state.Class,
                    Flags         = MethodFlags.Static,
                    ReturnType    = (methodStruct.Type is ARRAY_TYPE) ? STANDARD.Data : methodStruct.Type.convert() as TypeNode /*receiverComputeType.ScalarType.TypeNode*/,
                    Parameters    = callParams,
                    Name          = callIdentifier,
                    Body          = new Block {
                        Statements = new StatementList(
                            new VariableDeclaration {
                            Name = receiverIdentifier,
                            Type = STANDARD.Data,
                        },
                            new ExpressionStatement(new Construct {
                            Constructor = new MemberBinding {
                                BoundMember = actualOperationClass.GetConstructors()[0],
                            },
                            Operands = ctorArgs,
                        }),

                            new Return(returnExp)
                            )
                    }
                });
            }
            #endregion

            #region // return call to 'call'
            return(new MethodCall {
                Operands = callArgs,
                Callee = new MemberBinding(null, actualOperationClass.GetMethod(callIdentifier, typeList.ToArray())),
                Type = expressionResult.Type.ScalarType.TypeNode,
            });

            #endregion
        }