internal HasIncrement(IncrementStatement incrementStatement) { this.incrementStatement = incrementStatement; }
protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie) { // Insert an Increment statement to support Sequential loops // if we find the pattern: // forwardExpr = ReplicateOp_Divide.UsesAverageConditional(backwardExpr[index], marginalExpr, index, forwardExpr) // then when backwardExpr is updated, we insert the following statement: // MarginalIncrement(marginalExpr, forwardExpr, backwardExpr[index]); if (Recognizer.IsStaticMethod(imie, typeof(ReplicateOp_Divide), "UsesAverageConditional")) { IExpression backwardExpr = imie.Arguments[0]; object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); IExpression marginalExpr = imie.Arguments[1]; IExpression indexExpr = imie.Arguments[2]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[3]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; MethodInfo method = itr.DotNetType.GetMethod("MarginalIncrement"); method = method.MakeGenericMethod(imre.Method.MethodInfo.GetGenericArguments()); IExpression rhs = Builder.StaticGenericMethod(method, marginalExpr, forwardExpr, backwardExpr); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); onUpdate[backwardDecl] = increment; } } // if we find the pattern: // forwardExpr = Replicate2BufferOp.UsesAverageConditional(backwardExpr, *, marginalExpr, index, forwardExpr) // then when backwardExpr is updated, we insert the following statement: // marginalExpr = MarginalIncrement(marginalExpr, forwardExpr, backwardExpr[index]); if (Recognizer.IsStaticMethod(imie, typeof(Replicate2BufferOp), "UsesAverageConditional")) { IExpression backwardExpr = imie.Arguments[0]; object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); IExpression marginalExpr = imie.Arguments[2]; IExpression indexExpr = imie.Arguments[3]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[4]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; MethodInfo method = itr.DotNetType.GetMethod("MarginalIncrement"); method = method.MakeGenericMethod(imre.Method.MethodInfo.GetGenericArguments()); IExpression rhs = Builder.StaticGenericMethod(method, marginalExpr, forwardExpr, Builder.ArrayIndex(backwardExpr, indexExpr)); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); onUpdate[backwardDecl] = increment; } } // if we find the pattern: // forwardExpr = JaggedSubarrayOp<>.ItemsAverageConditional(backwardExpr[index], *, marginalExpr, indices, index, forwardExpr) // then when backwardExpr is updated, we insert the following statement: // MarginalIncrement(marginalExpr, forwardExpr, backwardExpr[index], indices, index) if (Recognizer.IsStaticGenericMethod(imie, typeof(JaggedSubarrayOp <>), "ItemsAverageConditional")) { IExpression backwardExpr = imie.Arguments[0]; object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); IExpression marginalExpr = imie.Arguments[2]; IExpression indicesExpr = imie.Arguments[3]; IExpression indexExpr = imie.Arguments[4]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[5]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; IExpression[] args2 = new IExpression[] { marginalExpr, forwardExpr, backwardExpr, indicesExpr, indexExpr }; Type[] argTypes = Array.ConvertAll(args2, e => e.GetExpressionType()); Exception exception; MethodInfo method = (MethodInfo)Reflection.Invoker.GetBestMethod(itr.DotNetType, "MarginalIncrement", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy, null, argTypes, out exception); if (method == null) { Error("Cannot find a compatible MarginalIncrement method for JaggedSubarrayOp", exception); } else { IExpression rhs = Builder.StaticGenericMethod(method, args2); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); onUpdate[backwardDecl] = increment; } } } // if we find the pattern: // forwardExpr = JaggedSubarrayWithMarginalOp<>.ItemsAverageConditional(backwardExpr[index], *, marginalExpr, indices, index, forwardExpr) // then when backwardExpr is updated, we insert the following statement: // MarginalIncrementItems(backwardExpr[index], forwardExpr, indices, index, marginalExpr) if (Recognizer.IsStaticGenericMethod(imie, typeof(JaggedSubarrayWithMarginalOp <>), "ItemsAverageConditional")) { IExpression backwardExpr = imie.Arguments[0]; IExpression marginalExpr = imie.Arguments[2]; IExpression indicesExpr = imie.Arguments[3]; IExpression indexExpr = imie.Arguments[4]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[5]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; IExpression[] args2 = new IExpression[] { backwardExpr, forwardExpr, indicesExpr, indexExpr, marginalExpr }; Type[] argTypes = Array.ConvertAll(args2, e => e.GetExpressionType()); Exception exception; MethodInfo method = (MethodInfo)Reflection.Invoker.GetBestMethod(itr.DotNetType, "MarginalIncrementItems", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy, null, argTypes, out exception); if (method == null) { Error("Cannot find a compatible MarginalIncrementItems method for JaggedSubarrayWithMarginalOp", exception); } else { IExpression rhs = Builder.StaticGenericMethod(method, args2); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); onUpdate[backwardDecl] = increment; IVariableDeclaration marginalVar = Recognizer.GetVariableDeclaration(marginalExpr); suppressUpdate[marginalVar] = attr; } var indicesVar = Recognizer.GetDeclaration(indicesExpr); if (indicesVar != null) { DistributedCommunicationExpression dce = context.GetAttribute <DistributedCommunicationExpression>(indicesVar); if (dce != null) { context.OutputAttributes.Set(imie, dce); } } } } // if we find the pattern: // backwardExpr = JaggedSubarrayWithMarginalOp<>.ArrayAverageConditional(forwardExpr, marginalExpr, backwardExpr) // then when forwardExpr is updated, we insert the following statement: // MarginalIncrementArray if (Recognizer.IsStaticGenericMethod(imie, typeof(JaggedSubarrayWithMarginalOp <>), "ArrayAverageConditional")) { IExpression forwardExpr = imie.Arguments[0]; IExpression marginalExpr = imie.Arguments[1]; IExpression backwardExpr = imie.Arguments[2]; if (true) { IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; IExpression[] args2 = new IExpression[] { forwardExpr, backwardExpr, marginalExpr }; Type[] argTypes = Array.ConvertAll(args2, e => e.GetExpressionType()); Exception exception; MethodInfo method = (MethodInfo)Reflection.Invoker.GetBestMethod(itr.DotNetType, "MarginalIncrementArray", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy, null, argTypes, out exception); if (method == null) { Error("Cannot find a compatible MarginalIncrementArray method for JaggedSubarrayWithMarginalOp", exception); } else { IExpression rhs = Builder.StaticGenericMethod(method, args2); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var attr = new IncrementStatement(null, false); context.OutputAttributes.Set(increment, attr); object forwardDecl = Recognizer.GetArrayDeclaration(forwardExpr); onUpdate[forwardDecl] = increment; } IVariableDeclaration marginalVar = Recognizer.GetVariableDeclaration(marginalExpr); // only suppress when we also have MarginalIncrementItems //suppressUpdate.Add(marginalVar); } } // if we find the pattern: // forwardExpr = GetItemsOp<>.ItemsAverageConditional(backwardExpr[index], *, marginalExpr, indices, index, forwardExpr) // then when backwardExpr is updated, we insert the following statement: // MarginalIncrement(marginalExpr, forwardExpr, backwardExpr[index], indices, index) if (Recognizer.IsStaticGenericMethod(imie, typeof(GetItemsOp <>), "ItemsAverageConditional") || Recognizer.IsStaticGenericMethod(imie, typeof(GetJaggedItemsOp <>), "ItemsAverageConditional") || Recognizer.IsStaticGenericMethod(imie, typeof(GetDeepJaggedItemsOp <>), "ItemsAverageConditional")) { IExpression backwardExpr = imie.Arguments[0]; object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); IExpression marginalExpr = imie.Arguments[2]; IExpression indicesExpr = imie.Arguments[3]; IExpression indexExpr = imie.Arguments[4]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[5]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; MethodInfo method = itr.GenericType.DotNetType.GetMethod("MarginalIncrement"); method = method.MakeGenericMethod(imre.Method.MethodInfo.GetGenericArguments()); IExpression rhs = Builder.StaticGenericMethod(method, marginalExpr, forwardExpr, backwardExpr, indicesExpr, indexExpr); //IStatement increment = Builder.ExprStatement(rhs); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); onUpdate[backwardDecl] = increment; } } // if we find the pattern: // forwardExpr = GetItemsOp<>.ItemsAverageConditional(backwardExpr[index], *, marginalExpr, indices, index, forwardExpr) // then when backwardExpr is updated, we insert the following statement: // MarginalIncrement(marginalExpr, forwardExpr, backwardExpr[index], indices, index) if (Recognizer.IsStaticGenericMethod(imie, typeof(GetItemsWithDictionaryOp <>), "ItemsAverageConditional")) { IExpression backwardExpr = imie.Arguments[0]; object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); IExpression marginalExpr = imie.Arguments[2]; IExpression indicesExpr = imie.Arguments[3]; IExpression dictExpr = imie.Arguments[4]; IExpression indexExpr = imie.Arguments[5]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[6]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; MethodInfo method = itr.GenericType.DotNetType.GetMethod("MarginalIncrement"); method = method.MakeGenericMethod(imre.Method.MethodInfo.GetGenericArguments()); IExpression rhs = Builder.StaticGenericMethod(method, marginalExpr, forwardExpr, backwardExpr, indicesExpr, dictExpr, indexExpr); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); onUpdate[backwardDecl] = increment; } } // if we find the pattern: // partialExpr = GetItemsOp2<>.Partial(backwardExpr[index], to_array, indices, index, partialExpr); // then when backwardExpr is updated, we insert the following statement: // to_array[indices[index]] = ArrayIncrement(partialExpr, backwardExpr[index]) if (Recognizer.IsStaticGenericMethod(imie, typeof(GetItemsOp2 <>), "Partial")) { IExpression backwardExpr = imie.Arguments[0]; object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); IExpression to_array = imie.Arguments[1]; IExpression indicesExpr = imie.Arguments[2]; IExpression indexExpr = imie.Arguments[3]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[4]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; MethodInfo method = itr.GenericType.DotNetType.GetMethod("ArrayIncrement"); method = method.MakeGenericMethod(imre.Method.MethodInfo.GetGenericArguments()); IExpression resultExpr = Builder.ArrayIndex(to_array, Builder.ArrayIndex(indicesExpr, indexExpr)); IExpression rhs = Builder.StaticGenericMethod(method, forwardExpr, backwardExpr, resultExpr); IStatement increment = Builder.AssignStmt(resultExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); onUpdate[backwardDecl] = increment; } } // if we find the pattern: // forwardExpr = GetItemsJaggedOp<>.ItemsAverageConditional(backwardExpr[index], *, marginalExpr, indices, indices2, index, forwardExpr) // then when backwardExpr is updated, we insert the following statement: // MarginalIncrement(marginalExpr, forwardExpr, backwardExpr[index], indices, indices2, index) if (Recognizer.IsStaticGenericMethod(imie, typeof(GetItemsFromJaggedOp <>), "ItemsAverageConditional")) { IExpression backwardExpr = imie.Arguments[0]; object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); IExpression marginalExpr = imie.Arguments[2]; IExpression indicesExpr = imie.Arguments[3]; IExpression indices2Expr = imie.Arguments[4]; IExpression indexExpr = imie.Arguments[5]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[6]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; MethodInfo method = itr.GenericType.DotNetType.GetMethod("MarginalIncrement"); method = method.MakeGenericMethod(imre.Method.MethodInfo.GetGenericArguments()); IExpression rhs = Builder.StaticGenericMethod(method, marginalExpr, forwardExpr, backwardExpr, indicesExpr, indices2Expr, indexExpr); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); onUpdate[backwardDecl] = increment; } } // if we find the pattern: // forwardExpr = GetItemsDeepJaggedOp<>.ItemsAverageConditional(backwardExpr[index], *, marginalExpr, indices, indices2, indices3, index, forwardExpr) // then when backwardExpr is updated, we insert the following statement: // MarginalIncrement(marginalExpr, forwardExpr, backwardExpr[index], indices, indices2, indices3, index) if (Recognizer.IsStaticGenericMethod(imie, typeof(GetItemsFromDeepJaggedOp <>), "ItemsAverageConditional")) { IExpression backwardExpr = imie.Arguments[0]; object backwardDecl = Recognizer.GetArrayDeclaration(backwardExpr); IExpression marginalExpr = imie.Arguments[2]; IExpression indicesExpr = imie.Arguments[3]; IExpression indices2Expr = imie.Arguments[4]; IExpression indices3Expr = imie.Arguments[5]; IExpression indexExpr = imie.Arguments[6]; IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(indexExpr); IExpression forwardExpr = imie.Arguments[7]; if (indexVar != null && context.InputAttributes.Has <Sequential>(indexVar)) { if (!compiler.UseSerialSchedules) { context.Warning(indexVar.Name + " is marked Sequential but engine.Compiler.UseSerialSchedules = false"); } IMethodReferenceExpression imre = imie.Method; ITypeReference itr = ((ITypeReferenceExpression)imre.Target).Type; MethodInfo method = itr.GenericType.DotNetType.GetMethod("MarginalIncrement"); method = method.MakeGenericMethod(imre.Method.MethodInfo.GetGenericArguments()); IExpression rhs = Builder.StaticGenericMethod(method, marginalExpr, forwardExpr, backwardExpr, indicesExpr, indices2Expr, indices3Expr, indexExpr); IStatement increment = Builder.AssignStmt(marginalExpr, rhs); var seq = context.InputAttributes.Get <Sequential>(indexVar); var attr = new IncrementStatement(indexVar, seq.BackwardPass); context.OutputAttributes.Set(increment, attr); onUpdate[backwardDecl] = increment; } } return(base.ConvertMethodInvoke(imie)); }