/// <summary> /// Writes functions to copy SMVs to GMVs /// </summary> /// <param name="SB">Where the output goes.</param> /// <param name="S"></param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT"></param> public static void WriteSMVtoGMVcopy(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT) { int nbTabs; G25.GMV gmv = S.m_GMV; bool gmvParityPure = (S.m_GMV.MemoryAllocationMethod == G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE); //string dstClassName = FT.GetMangledName(S, gmv.Name); for (int s = 0; s < S.m_SMV.Count; s++) { G25.SMV smv = S.m_SMV[s]; // do not generate converter if the GMV cannot hold the type if (gmvParityPure && (!smv.IsParityPure())) { continue; } string srcClassName = FT.GetMangledName(S, smv.Name); SB.AppendLine(); nbTabs = 1; new G25.CG.Shared.Comment("sets this to " + srcClassName + " value.").Write(SB, S, nbTabs); string funcName = GetSetFuncName(S); string funcDecl = "\tpublic void " + funcName + "(" + srcClassName + " src)"; SB.Append(funcDecl); { SB.AppendLine(" {"); // get a dictionary which tells you for each basis blade of 'gmv' where it is in 'smv' Dictionary <Tuple <int, int>, Tuple <int, int> > D = G25.MV.GetCoordMap(smv, gmv); // convert SMV to symbolic Multivector: bool smvPtr = false; RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, "src", smvPtr); // find out which groups are present StringBuilder guSB = new StringBuilder(); int gu = 0; foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { int bit = 1 << KVP.Value.Value1; if ((gu & bit) == 0) { gu |= 1 << KVP.Value.Value1; if (guSB.Length > 0) { guSB.Append("|"); } guSB.Append("GroupBitmap.GROUP_" + KVP.Value.Value1); } } // generate the code to set group usage: SB.AppendLine("\t\t" + GetAllocateGroupsString(S) + "(" + guSB.ToString() + ");"); // a helper pointer string dstArrName = "ptr"; SB.AppendLine("\t\t" + FT.type + "[] " + dstArrName + ";"); // for each used group, generate the assignment code for (int g = 0; (1 << g) <= gu; g++) { if (((1 << g) & gu) != 0) { SB.AppendLine(); SB.AppendLine("\t\tptr = m_c[" + g + "];"); int dstBaseIdx = 0; bool mustCast = false; nbTabs = 2; bool writeZeros = true; string str = G25.CG.Shared.CodeUtil.GenerateGMVassignmentCode(S, FT, mustCast, gmv, dstArrName, g, dstBaseIdx, value, nbTabs, writeZeros); SB.Append(str); } } if (S.m_reportUsage) { SB.AppendLine("\t\tm_t = " + G25.CG.CSJ.GMV.SMV_TYPE + "." + G25.CG.Shared.ReportUsage.GetSpecializedConstantName(S, smv.Name) + ";"); } SB.AppendLine("\t}"); } } // end of loop over all SMVs } // end of WriteGMVtoSMVcopy()
} // end of WriteGMVtoSMVcopy() /// <summary> /// Writes functions to copy SMVs to GMVs /// </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 WriteSMVtoGMVcopy(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; G25.GMV gmv = S.m_GMV; Boolean gmvParityPure = (S.m_GMV.MemoryAllocationMethod == G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE); foreach (G25.FloatType FT in S.m_floatTypes) { String dstClassName = FT.GetMangledName(S, gmv.Name); for (int s = 0; s < S.m_SMV.Count; s++) { G25.SMV smv = S.m_SMV[s]; // do not generate converter if the GMV cannot hold the type if (gmvParityPure && (!smv.IsParityPure())) { continue; } string srcClassName = FT.GetMangledName(S, smv.Name); 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(" {"); // get a dictionary which tells you for each basis blade of 'gmv' where it is in 'smv' Dictionary <Tuple <int, int>, Tuple <int, int> > D = G25.MV.GetCoordMap(smv, gmv); // convert SMV to symbolic Multivector: bool smvPtr = false; RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, "src", smvPtr); // find out which groups are present int gu = 0; foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { gu |= 1 << KVP.Value.Value1; } // generate the code to set group usage: defSB.AppendLine("\t" + SET_GROUP_USAGE + "(" + gu + ");"); // a helper pointer which is incremented string dstArrName = "ptr"; defSB.AppendLine("\t" + FT.type + " *" + dstArrName + " = m_c;"); // for each used group, generate the assignment code for (int g = 0; (1 << g) <= gu; g++) { if (((1 << g) & gu) != 0) { bool mustCast = false; int nbTabs = 1; bool writeZeros = true; String str = G25.CG.Shared.CodeUtil.GenerateGMVassignmentCode(S, FT, mustCast, gmv, dstArrName, g, value, nbTabs, writeZeros); defSB.Append(str); if ((1 << (g + 1)) <= gu) { defSB.AppendLine("\tptr += " + gmv.Group(g).Length + ";"); } } } if (S.m_reportUsage) { defSB.AppendLine("\tm_t = " + G25.CG.Shared.ReportUsage.GetSpecializedConstantName(S, smv.Name) + ";"); } defSB.AppendLine("}"); } } // end of loop over all SMVs } // end of loop over all float types } // end of WriteGMVtoSMVcopy()