public static ReplicationControl Old_ConvertGuidesToInstructions(List<List<ProtoCore.ReplicationGuide>> partialGuides) { /* //Test to ensure that we're within the known limitations, supporting at most 1 guide per argument //Munge the format to use the legacy mechansi, //This is temporary code //@TODO(Luke) List<int?> singlePartialGuides = new List<int?>(); foreach (List<int> guideList in partialGuides) { if (guideList.Count == 0) singlePartialGuides.Add(null); else if (guideList.Count > 1) throw new NotImplementedException("Multiple guides on an argument not yet supported: {93AF9B93-7EDC-4EE9-8E20-1A5FF029871C}"); else singlePartialGuides.Add(guideList[0]); }*/ ReplicationControl rc = new ReplicationControl() { //Instructions = Old_BuildPartialReplicationInstructions(singlePartialGuides) Instructions = BuildPartialReplicationInstructions(partialGuides) }; //Now push the result to the legacy code to do the computation return rc; }
public static ReplicationControl Old_ConvertGuidesToInstructions(List <List <ProtoCore.ReplicationGuide> > partialGuides) { /* * //Test to ensure that we're within the known limitations, supporting at most 1 guide per argument * //Munge the format to use the legacy mechansi, * //This is temporary code * //@TODO(Luke) * List<int?> singlePartialGuides = new List<int?>(); * foreach (List<int> guideList in partialGuides) * { * if (guideList.Count == 0) * singlePartialGuides.Add(null); * else if (guideList.Count > 1) * throw new NotImplementedException("Multiple guides on an argument not yet supported: {93AF9B93-7EDC-4EE9-8E20-1A5FF029871C}"); * else * singlePartialGuides.Add(guideList[0]); * }*/ ReplicationControl rc = new ReplicationControl() { //Instructions = Old_BuildPartialReplicationInstructions(singlePartialGuides) Instructions = BuildPartialReplicationInstructions(partialGuides) }; //Now push the result to the legacy code to do the computation return(rc); }
private void ComputeFeps(StringBuilder log, ProtoCore.Runtime.Context context, List<StackValue> arguments, FunctionGroup funcGroup, ReplicationControl replicationControl, List<List<ProtoCore.ReplicationGuide>> partialReplicationGuides, StackFrame stackFrame, Core core, out List<FunctionEndPoint> resolvesFeps, out List<ReplicationInstruction> replicationInstructions) { //With replication guides only //Exact match //Match with single elements //Match with single elements with upcast //Try replication without type cast //Match with type conversion //Match with type conversion with upcast //Try replication + type casting //Try replication + type casting + Array promotion #region First Case: Replicate only according to the replication guides { log.AppendLine("Case 1: Exact Match"); FunctionEndPoint fep = Case1GetCompleteMatchFEP(context, arguments, funcGroup, replicationControl, stackFrame, core, log); if (fep != null) { //log.AppendLine("Resolution completed in " + sw.ElapsedMilliseconds + "ms"); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); resolvesFeps = new List<FunctionEndPoint>() { fep }; replicationInstructions = replicationControl.Instructions; return; } } #endregion #region Case 2: Replication with no type cast { log.AppendLine("Case 2: Beginning Auto-replication, no casts"); //Build the possible ways in which we might replicate List<List<ReplicationInstruction>> replicationTrials = Replicator.BuildReplicationCombinations(replicationControl.Instructions, arguments, core); foreach (List<ReplicationInstruction> replicationOption in replicationTrials) { ReplicationControl rc = new ReplicationControl() { Instructions = replicationOption }; log.AppendLine("Attempting replication control: " + rc); List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, rc.Instructions, core); int resolutionFailures; Dictionary<FunctionEndPoint, int> lookups = funcGroup.GetExactMatchStatistics( context, reducedParams, stackFrame, core, out resolutionFailures); if (resolutionFailures > 0) continue; log.AppendLine("Resolution succeeded against FEP Cluster"); foreach (FunctionEndPoint fep in lookups.Keys) log.AppendLine("\t - " + fep); List<FunctionEndPoint> feps = new List<FunctionEndPoint>(); feps.AddRange(lookups.Keys); //log.AppendLine("Resolution completed in " + sw.ElapsedMilliseconds + "ms"); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); //Otherwise we have a cluster of FEPs that can be used to dispatch the array resolvesFeps = feps; replicationInstructions = rc.Instructions; return; } } #endregion #region Case 3: Match with type conversion, but no array promotion { log.AppendLine("Case 3: Type conversion"); Dictionary<FunctionEndPoint, int> candidatesWithDistances = funcGroup.GetConversionDistances(context, arguments, replicationControl.Instructions, core.ClassTable, core); Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = funcGroup.GetCastDistances(context, arguments, replicationControl.Instructions, core.ClassTable, core); List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances); FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments, replicationControl.Instructions, stackFrame, core, candidatesWithCastDistances, candidateFunctions, candidatesWithDistances); if (compliantTarget != null) { log.AppendLine("Resolution Succeeded: " + compliantTarget); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); resolvesFeps = new List<FunctionEndPoint>() { compliantTarget }; replicationInstructions = replicationControl.Instructions; return; } } #endregion #region Case 4: Match with type conversion and replication log.AppendLine("Case 4: Replication + Type conversion"); { if (arguments.Any(arg => arg.IsArray)) { //Build the possible ways in which we might replicate List<List<ReplicationInstruction>> replicationTrials = Replicator.BuildReplicationCombinations(replicationControl.Instructions, arguments, core); foreach (List<ReplicationInstruction> replicationOption in replicationTrials) { ReplicationControl rc = new ReplicationControl() { Instructions = replicationOption }; log.AppendLine("Attempting replication control: " + rc); //@TODO: THis should use the proper reducer? Dictionary<FunctionEndPoint, int> candidatesWithDistances = funcGroup.GetConversionDistances(context, arguments, rc.Instructions, core.ClassTable, core); Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = funcGroup.GetCastDistances(context, arguments, rc.Instructions, core.ClassTable, core); List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances); FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments, rc.Instructions, stackFrame, core, candidatesWithCastDistances, candidateFunctions, candidatesWithDistances); if (compliantTarget != null) { log.AppendLine("Resolution Succeeded: " + compliantTarget); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); resolvesFeps = new List<FunctionEndPoint>() { compliantTarget }; replicationInstructions = rc.Instructions; return; } } } } #endregion #region Case 5: Match with type conversion, replication and array promotion log.AppendLine("Case 5: Replication + Type conversion + Array promotion"); { //Build the possible ways in which we might replicate List<List<ReplicationInstruction>> replicationTrials = Replicator.BuildReplicationCombinations(replicationControl.Instructions, arguments, core); //Add as a first attempt a no-replication, but allowing up-promoting replicationTrials.Insert(0, new List<ReplicationInstruction>() ); foreach (List<ReplicationInstruction> replicationOption in replicationTrials) { ReplicationControl rc = new ReplicationControl() { Instructions = replicationOption }; log.AppendLine("Attempting replication control: " + rc); //@TODO: THis should use the proper reducer? Dictionary<FunctionEndPoint, int> candidatesWithDistances = funcGroup.GetConversionDistances(context, arguments, rc.Instructions, core.ClassTable, core, true); Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = funcGroup.GetCastDistances(context, arguments, rc.Instructions, core.ClassTable, core); List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances); FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments, rc.Instructions, stackFrame, core, candidatesWithCastDistances, candidateFunctions, candidatesWithDistances); if (compliantTarget != null) { log.AppendLine("Resolution Succeeded: " + compliantTarget); if (core.Options.DumpFunctionResolverLogic) core.DSExecutable.EventSink.PrintMessage(log.ToString()); resolvesFeps = new List<FunctionEndPoint>() { compliantTarget }; replicationInstructions = rc.Instructions; return; } } } #endregion resolvesFeps = new List<FunctionEndPoint>(); replicationInstructions = replicationControl.Instructions; }
/// <summary> /// Get complete match attempts to locate a function endpoint where 1 FEP matches all of the requirements for dispatch /// </summary> /// <param name="context"></param> /// <param name="arguments"></param> /// <param name="funcGroup"></param> /// <param name="replicationControl"></param> /// <param name="stackFrame"></param> /// <param name="core"></param> /// <param name="log"></param> /// <returns></returns> private FunctionEndPoint Case1GetCompleteMatchFEP(ProtoCore.Runtime.Context context, List<StackValue> arguments, FunctionGroup funcGroup, ReplicationControl replicationControl, StackFrame stackFrame, Core core, StringBuilder log) { log.AppendLine("Attempting Dispatch with ---- RC: " + replicationControl); //Exact match List<FunctionEndPoint> exactTypeMatchingCandindates = funcGroup.GetExactTypeMatches(context, arguments, replicationControl.Instructions, stackFrame, core); FunctionEndPoint fep = null; if (exactTypeMatchingCandindates.Count > 0) { if (exactTypeMatchingCandindates.Count == 1) { //Exact match fep = exactTypeMatchingCandindates[0]; log.AppendLine("1 exact match found - FEP selected" + fep); } else { //Exact match with upcast fep = SelectFEPFromMultiple(stackFrame, core, exactTypeMatchingCandindates, arguments); log.AppendLine(exactTypeMatchingCandindates.Count + "exact matches found - FEP selected" + fep); } } return fep; }
/// <summary> /// Conservative guess as to whether this call will replicate or not /// This may give inaccurate answers if the node cluster doesn't actually exist /// </summary> /// <param name="context"></param> /// <param name="arguments"></param> /// <param name="stackFrame"></param> /// <param name="core"></param> /// <returns></returns> public bool WillCallReplicate(ProtoCore.Runtime.Context context, List<StackValue> arguments, List<List<ProtoCore.ReplicationGuide>> partialReplicationGuides, StackFrame stackFrame, Core core, out List<List<ReplicationInstruction>> replicationTrials) { replicationTrials = new List<List<ReplicationInstruction>>(); if (partialReplicationGuides.Count > 0) { // Jun Comment: And at least one of them contains somthing for (int n = 0; n < partialReplicationGuides.Count; ++n) { if (partialReplicationGuides[n].Count > 0) { return true; } } } #region Get Function Group //@PERF: Possible optimisation point here, to deal with static dispatches that don't need replication analysis //Handle resolution Pass 1: Name -> Method Group FunctionGroup funcGroup; try { funcGroup = globalFunctionTable.GlobalFuncTable[classScope + 1][methodName]; } catch (KeyNotFoundException) { return false; } #endregion //Replication Control is an ordered list of the elements that we have to replicate over //Ordering implies containment, so element 0 is the outer most forloop, element 1 is nested within it etc. //Take the explicit replication guides and build the replication structure //Turn the replication guides into a guide -> List args data structure ReplicationControl replicationControl = Replicator.Old_ConvertGuidesToInstructions(partialReplicationGuides); #region First Case: Replicate only according to the replication guides { FunctionEndPoint fep = Case1GetCompleteMatchFEP(context, arguments, funcGroup, replicationControl, stackFrame, core, new StringBuilder()); if (fep != null) { //found an exact match return false; } } #endregion #region Case 2: Replication with no type cast { //Build the possible ways in which we might replicate replicationTrials = Replicator.BuildReplicationCombinations(replicationControl.Instructions, arguments, core); foreach (List<ReplicationInstruction> replicationOption in replicationTrials) { ReplicationControl rc = new ReplicationControl() {Instructions = replicationOption}; List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, rc. Instructions, core); int resolutionFailures; Dictionary<FunctionEndPoint, int> lookups = funcGroup.GetExactMatchStatistics( context, reducedParams, stackFrame, core, out resolutionFailures); if (resolutionFailures > 0) continue; return true; //Replicates against cluster } } #endregion #region Case 3: Match with type conversion, but no array promotion { Dictionary<FunctionEndPoint, int> candidatesWithDistances = funcGroup.GetConversionDistances(context, arguments, replicationControl.Instructions, core.ClassTable, core); Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = funcGroup.GetCastDistances(context, arguments, replicationControl.Instructions, core.ClassTable, core); List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances); FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments, replicationControl.Instructions, stackFrame, core, candidatesWithCastDistances, candidateFunctions, candidatesWithDistances); if (compliantTarget != null) { return false; //Type conversion but no replication } } #endregion #region Case 5: Match with type conversion, replication and array promotion { //Build the possible ways in which we might replicate replicationTrials = Replicator.BuildReplicationCombinations(replicationControl.Instructions, arguments, core); //Add as a first attempt a no-replication, but allowing up-promoting replicationTrials.Insert(0, new List<ReplicationInstruction>() ); } #endregion return true; //It'll replicate if it suceeds }