/// <summary> /// Writes functions to copy GMVs to SMVs /// </summary> /// <param name="S"></param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteGMVtoSMVcopy(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; G25.GMV gmv = S.m_GMV; foreach (G25.FloatType FT in S.m_floatTypes) { string srcClassName = FT.GetMangledName(S, gmv.Name); for (int s = 0; s < S.m_SMV.Count; s++) { G25.SMV smv = S.m_SMV[s]; string dstClassName = FT.GetMangledName(S, smv.Name); bool dstPtr = true; String[] smvAccessStr = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr); string funcName = "set"; // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string funcDecl = inlineStr + "void " + dstClassName + "::" + funcName + "(const " + srcClassName + " &src)"; defSB.Append(funcDecl); { defSB.AppendLine(" {"); defSB.AppendLine("\tconst " + FT.type + " *ptr = src.getC();\n"); // get a dictionary which tells you for each basis blade of 'smv' where it is in 'gmv' Dictionary <Tuple <int, int>, Tuple <int, int> > D = G25.MV.GetCoordMap(smv, gmv); // what is the highest group of the 'gmv' that must be (partially) copied to the 'smv' int highestGroup = -1; foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { if (KVP.Value.Value1 > highestGroup) { highestGroup = KVP.Value.Value1; } } // generate code for each group for (int g = 0; g <= highestGroup; g++) { // determine if group 'g' is to be copied to smv: bool groupIsUsedBySMV = false; foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { if (KVP.Value.Value1 == g) { groupIsUsedBySMV = true; break; } } // if group is present in GMV: defSB.AppendLine("\tif (src.gu() & " + (1 << g) + ") {"); if (groupIsUsedBySMV) { bool mustCast = false; bool srcPtr = true; int nbTabs = 2; RefGA.Multivector[] value = G25.CG.Shared.Symbolic.GMVtoSymbolicMultivector(S, gmv, "ptr", srcPtr, g); bool writeZeros = false; string str = G25.CG.Shared.CodeUtil.GenerateSMVassignmentCode(S, FT, mustCast, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr, value[g], nbTabs, writeZeros); defSB.Append(str); } if ((g + 1) <= highestGroup) { defSB.AppendLine("\t\tptr += " + gmv.Group(g).Length + ";"); } defSB.AppendLine("\t}"); // else, if group is not present in GMV: if (groupIsUsedBySMV) { defSB.AppendLine("\telse {"); foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { if ((KVP.Value.Value1 == g) && (!smv.IsCoordinateConstant(KVP.Key.Value2))) { // translate KVP.Key.Value2 to non-const idx, because the accessStrs are only about non-const blades blades! int bladeIdx = smv.BladeIdxToNonConstBladeIdx(KVP.Key.Value2); defSB.AppendLine("\t\t" + smvAccessStr[bladeIdx] + " = " + FT.DoubleToString(S, 0.0) + ";"); } } defSB.AppendLine("\t}"); } } defSB.AppendLine("}"); } } // end of loop over all SMVs } // end of loop over all float types } // end of WriteGMVtoSMVcopy()
} // end of WriteSetCopyCrossFloat() /// <summary> /// Writes functions to copy GMVs to SMVs /// </summary> /// <param name="S"></param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteGMVtoSMVcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv) { StringBuilder defSB = cgd.m_defSB; G25.GMV gmv = S.m_GMV; string srcClassName = FT.GetMangledName(S, gmv.Name); //string dstClassName = FT.GetMangledName(S, smv.Name); bool dstPtr = false; string[] smvAccessStr = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr); string funcName = GMV.GetSetFuncName(S); string FINAL = (S.OutputJava()) ? "final " : ""; string funcDecl = "\tpublic " + FINAL + "void " + funcName + "(" + FINAL + srcClassName + " src)"; defSB.Append(funcDecl); { defSB.AppendLine(" {"); // get a dictionary which tells you for each basis blade of 'smv' where it is in 'gmv' // A dictionary from <smv group, smv element> to <gmv group, gmv element> Dictionary <Tuple <int, int>, Tuple <int, int> > D = G25.MV.GetCoordMap(smv, gmv); // what is the highest group of the 'gmv' that must be (partially) copied to the 'smv' int highestGroup = -1; foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { if (KVP.Value.Value1 > highestGroup) { highestGroup = KVP.Value.Value1; } } // generate code for each group for (int g = 0; g <= highestGroup; g++) { // determine if group 'g' is to be copied to smv: bool groupIsUsedBySMV = false; foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { // KVP.Key = SMV<group, element> // KVP.Value = GMV<group, element> if (KVP.Value.Value1 == g) { if (!smv.IsCoordinateConstant(KVP.Key.Value2)) { groupIsUsedBySMV = true; break; } } } // if group is present in GMV: if (groupIsUsedBySMV) { defSB.AppendLine("\t\tif (src.c()[" + g + "] != null) {"); defSB.AppendLine("\t\t\t" + FT.type + "[] ptr = src.c()[" + g + "];"); bool mustCast = false; bool srcPtr = true; int nbTabs = 3; RefGA.Multivector[] value = G25.CG.Shared.Symbolic.GMVtoSymbolicMultivector(S, gmv, "ptr", srcPtr, g); bool writeZeros = false; string str = G25.CG.Shared.CodeUtil.GenerateSMVassignmentCode(S, FT, mustCast, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr, value[g], nbTabs, writeZeros); defSB.Append(str); defSB.AppendLine("\t\t}"); defSB.AppendLine("\t\telse {"); foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { if ((KVP.Value.Value1 == g) && (!smv.IsCoordinateConstant(KVP.Key.Value2))) { // translate KVP.Key.Value2 to non-const idx, because the accessStrs are only about non-const blades blades! int bladeIdx = smv.BladeIdxToNonConstBladeIdx(KVP.Key.Value2); defSB.AppendLine("\t\t\t" + smvAccessStr[bladeIdx] + " = " + FT.DoubleToString(S, 0.0) + ";"); } } defSB.AppendLine("\t\t}"); } } defSB.AppendLine("\t}"); } } // end of WriteGMVtoSMVcopy()