public static void GenerateMultivectorSizeArray(Specification S, G25.CG.Shared.CGdata cgd, StringBuilder SB) { G25.GMV gmv = S.m_GMV; // size of multivector based on grade usage bitmap SB.AppendLine("const int " + S.m_namespace + "_mvSize[" + (1 << gmv.NbGroups) + "] = {"); SB.Append("\t"); for (int i = 0; i < (1 << gmv.NbGroups); i++) { int s = 0; for (int j = 0; j < gmv.NbGroups; j++) { if ((i & (1 << j)) != 0) { s += gmv.Group(j).Length; } } SB.Append(s); if (i != ((1 << gmv.NbGroups) - 1)) { SB.Append(", "); } if ((i % 20) == 19) { SB.AppendLine(""); SB.Append("\t"); } } SB.AppendLine("};"); }
/// <summary> /// Writes functions to set the GMV types to scalar value. /// </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 WriteSetScalar(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; 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 typeName = FT.GetMangledName(S, gmv.Name); String funcName = typeName + "_setScalar"; // write comment declSB.AppendLine("/** Sets a " + typeName + " to a scalar value */"); // do we inline this func? String inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); String funcDecl = inlineStr + "void " + funcName + "(" + typeName + " *M, " + FT.type + " val)"; declSB.Append(funcDecl); declSB.AppendLine(";"); defSB.Append(funcDecl); defSB.AppendLine(" {"); defSB.AppendLine("\tM->gu = " + (1 << gmv.GetGroupIdx(RefGA.BasisBlade.ONE)) + ";"); defSB.AppendLine("\tM->c[0] = val;"); defSB.AppendLine("}"); } }
/// <summary> /// Takes a general multivector specification (G25.GMV) and converts it into a one symbolic multivector per group/grade part. /// /// The symbolic weights of the multivector are the coordinates of the GMV, labelled according to 'gmvName'. /// Currently, the indices start at zero for each group. /// </summary> /// <param name="S">Specification of the algebra. Used for the access convention (. or ->) and for how to name the coordinates ([0] or e1, e2, e3).</param> /// <param name="gmv">The specification of the general multivector.</param> /// <param name="gmvName">Name the variable should have.</param> /// <param name="ptr">Is 'gmvName' a pointer? (not used currently)</param> /// <param name="groupIdx">Index of group/grade to convert (use -1 for all groups)</param> /// <returns></returns> public static RefGA.Multivector[] GMVtoSymbolicMultivector(Specification S, G25.GMV gmv, String gmvName, bool ptr, int groupIdx) { RefGA.Multivector[] R = new RefGA.Multivector[gmv.NbGroups]; //String accessStr = (ptr) ? "->" : "."; for (int g = 0; g < gmv.NbGroups; g++) { if ((groupIdx >= 0) && (g != groupIdx)) { continue; // only one group requested? } RefGA.BasisBlade[] B = gmv.Group(g); RefGA.BasisBlade[] L = new RefGA.BasisBlade[B.Length]; for (int i = 0; i < B.Length; i++) { RefGA.BasisBlade b = B[i]; String fullCoordName = gmvName + "[" + i + "]"; // merge L[i] = new RefGA.BasisBlade(b.bitmap, b.scale, fullCoordName); } R[g] = new RefGA.Multivector(L); } return(R); } // end of function GMVtoSymbolicMultivector()
/// <summary> /// Writes functions to set the GMV types by array value. /// </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 WriteSetArray(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; 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 typeName = FT.GetMangledName(S, gmv.Name); string funcName = typeName + "_setArray"; // write comment declSB.AppendLine("/** Sets a " + typeName + " to the value in the array. 'gu' is a group usage bitmap. */"); // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string funcDecl = inlineStr + "void " + funcName + "(" + typeName + " *M, int gu, const " + FT.type + " *arr)"; declSB.Append(funcDecl); declSB.AppendLine(";"); defSB.Append(funcDecl); defSB.AppendLine(" {"); defSB.AppendLine("\tM->gu = gu;"); defSB.AppendLine("\t" + G25.CG.Shared.Util.GetCopyCode(S, FT, "arr", "M->c", S.m_namespace + "_mvSize[gu]")); defSB.AppendLine("}"); } }
/// <summary> /// Writes functions to set the GMV types to zero. /// </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 WriteSetZero(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; 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 typeName = FT.GetMangledName(S, gmv.Name); string funcName = typeName + "_setZero"; // write comment declSB.AppendLine("/** Sets a " + typeName + " to zero */"); // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string funcDecl = inlineStr + "void " + funcName + "(" + typeName + " *M)"; declSB.Append(funcDecl); declSB.AppendLine(";"); defSB.Append(funcDecl); defSB.AppendLine(" {"); defSB.AppendLine("\tM->gu = 0;"); defSB.AppendLine("}"); } }
/// <summary> /// Writes functions to set the GMV types by array value. /// </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 WriteSetArray(Specification S, G25.CG.Shared.CGdata cgd) { //StringBuilder declSB = cgd.m_declSB; 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 className = FT.GetMangledName(S, gmv.Name); string funcName = "set"; // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string funcDecl = inlineStr + "void " + className + "::" + funcName + "(int gu, const " + FT.type + " *arr)"; defSB.Append(funcDecl); defSB.AppendLine(" {"); defSB.AppendLine("\t" + SET_GROUP_USAGE + "(gu);"); defSB.AppendLine("\t" + G25.CG.Shared.Util.GetCopyCode(S, FT, "arr", "m_c", S.m_namespace + "_mvSize[gu]")); if (S.m_reportUsage) { defSB.AppendLine("\tm_t = " + G25.CG.Shared.ReportUsage.GetSpecializedConstantName(S, gmv.Name) + ";"); } defSB.AppendLine("}"); } }
/// <summary> /// Writes functions to set the GMV types to scalar value. /// </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 WriteSetScalar(Specification S, G25.CG.Shared.CGdata cgd) { //StringBuilder declSB = cgd.m_declSB; 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 className = FT.GetMangledName(S, gmv.Name); string funcName = "set"; // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string funcDecl = inlineStr + "void " + className + "::" + funcName + "(" + FT.type + " val)"; defSB.Append(funcDecl); defSB.AppendLine(" {"); defSB.AppendLine("\t" + SET_GROUP_USAGE + "(" + (1 << gmv.GetGroupIdx(RefGA.BasisBlade.ONE)) + ");"); defSB.AppendLine("\tm_c[0] = val;"); if (S.m_reportUsage) { defSB.AppendLine("\tm_t = " + G25.CG.Shared.ReportUsage.GetSpecializedConstantName(S, FT.type) + ";"); } defSB.AppendLine("}"); } }
} // end of GenerateSMVassignmentCode /// <summary> /// Generates the code to assign a multivector value (which may have symbolic coordinates) to one specific coordinate group of a multivector. /// </summary> /// <param name="S">Specification of algebra. Used to known names of basis vector, output language, access strings, etc.</param> /// <param name="FT">Floating point type of destination.</param> /// <param name="mustCast">set to true if a cast to 'FT' must be performed before assigned to 'dstName'.</param> /// <param name="dstGmv">Type of general multivector assigned to.</param> /// <param name="dstName">Name of specialized multivector assigned to.</param> /// <param name="dstGroupIdx">Write to which group in destination type?</param> /// <param name="dstBaseIdx">Base index of coordinate 0 of group (needed for C# and Java)</param> /// <param name="value">Multivector value to assign to the GMV. Must not contain basis blades inside the symbolic scalars.</param> /// <param name="nbTabs">Number of tabs to put before the code.</param> /// <param name="writeZeros">Some callers want to skip "= 0.0" assignments because they would be redundant. So they set this argument to true.</param> /// <returns>String of code for dstName = value;</returns> public static string GenerateGMVassignmentCode(Specification S, FloatType FT, bool mustCast, G25.GMV dstGmv, string dstName, int dstGroupIdx, int dstBaseIdx, RefGA.Multivector value, int nbTabs, bool writeZeros) { RefGA.BasisBlade[] BL = dstGmv.Group(dstGroupIdx); string[] accessStr = GetAccessStr(S, dstGmv, dstName, dstGroupIdx, dstBaseIdx); string[] assignedStr = GetAssignmentStrings(S, FT, mustCast, BL, value, writeZeros); return(GenerateAssignmentCode(S, accessStr, assignedStr, nbTabs, writeZeros)); } // end of GenerateSMVassignmentCode
public static void WriteCompressSource(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd) { G25.GMV gmv = S.m_GMV; foreach (G25.FloatType FT in S.m_floatTypes) { //cgd.m_cog.ClearOutput(); cgd.m_cog.EmitTemplate(SB, "compress", "S=", S, "FT=", FT, "gmv=", gmv); //SB.Append(cgd.m_cog.GetOutputAndClear()); } }
} // end of GetAccessStr() /// <summary> /// Returns an array of 'access strings' for a specific group of the general multivector. /// Access strings are source code expressions that can be /// used to access the coordinates of one specific group of coordinates of <c>gmv</c>. /// </summary> /// <param name="S">Used for basis blade names, language, COORD_STORAGE , etc.</param> /// <param name="gmv">The specialized multivector for which access strings are generated.</param> /// <param name="gmvName">The variable name of the _array_ of float to be used in the access strings. /// For example, specify <c>"A"</c> to get <c>"A[0]"</c> and so on.</param> /// <param name="groupIdx">Specifies for that group index the access strings should be generated.</param> /// <param name="baseIdx">Index of first coordinate of group (required for C# and Java)</param> /// <returns>Array of strings that can be used to access the coordinates of group <c>groupIdx</c> of the <c>gmv</c>.</returns> public static string[] GetAccessStr(Specification S, G25.GMV gmv, String gmvName, int groupIdx, int baseIdx) { string[] AL = new String[gmv.Group(groupIdx).Length]; for (int i = 0; i < gmv.Group(groupIdx).Length; i++) { AL[i] = gmvName + "[" + (baseIdx + i) + "]"; } return(AL); } // end of GetAccessStr()
/// <summary> /// Writes functions to copy GMVs from one float type to another. /// </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 WriteGMVtoGMVcopy(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; G25.GMV gmv = S.m_GMV; foreach (G25.FloatType srcFT in S.m_floatTypes) { String srcTypeName = srcFT.GetMangledName(S, gmv.Name); foreach (G25.FloatType dstFT in S.m_floatTypes) { //if (dstFT == srcFT) continue; string dstTypeName = dstFT.GetMangledName(S, gmv.Name); // write comment if (dstFT == srcFT) { declSB.AppendLine("/** Copies a " + srcTypeName + " */"); } else { declSB.AppendLine("/** Copies a " + srcTypeName + " (floating point type " + srcFT.type + ") to a " + dstTypeName + " (floating point type " + dstFT.type + ") */"); } string funcName; if (dstFT == srcFT) { funcName = srcTypeName + "_copy"; } else { funcName = srcTypeName + "_to_" + dstTypeName; } // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string funcDecl = inlineStr + dstTypeName + "* " + funcName + "(" + dstTypeName + " *dst, const " + srcTypeName + " *src)"; declSB.Append(funcDecl); declSB.AppendLine(";"); defSB.Append(funcDecl); defSB.AppendLine(" {"); defSB.AppendLine("\tint i;"); defSB.AppendLine("\tdst->gu = src->gu;"); defSB.AppendLine("\tfor (i = 0; i < " + S.m_namespace + "_mvSize[src->gu]; i++)"); defSB.AppendLine("\t\tdst->c[i] = (" + dstFT.type + ")src->c[i];"); defSB.AppendLine("\treturn dst;"); defSB.AppendLine("}"); } } }
/// <summary> /// Writes functions to set coordinates of the GMV /// </summary> /// <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> /// <param name="SB"></param> public static void WriteSetCoord(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, StringBuilder SB) { G25.GMV gmv = S.m_GMV; string typeName = FT.GetMangledName(S, gmv.Name); for (int groupIdx = 0; groupIdx < gmv.NbGroups; groupIdx++) { for (int elementIdx = 0; elementIdx < gmv.Group(groupIdx).Length; elementIdx++) { WriteSetCoordFunction(S, cgd, FT, SB, typeName, groupIdx, elementIdx, gmv.Group(groupIdx).Length, gmv.Group(groupIdx)[elementIdx]); } } }
} // end of WriteExtractScalarPart() public void WriteCompressExpand(Specification S, G25.CG.Shared.CGdata cgd) { G25.GMV gmv = S.m_GMV; StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = cgd.m_defSB; foreach (G25.FloatType FT in S.m_floatTypes) { string className = FT.GetMangledName(S, gmv.Name); string fabsFunc = (FT.type == "float") ? "fabsf" : "fabs"; cgd.m_cog.EmitTemplate(declSB, "compressDecl", "S=", S, "FT=", FT, "className=", className, "gmv=", gmv); cgd.m_cog.EmitTemplate(defSB, "compressDef", "S=", S, "FT=", FT, "className=", className, "gmv=", gmv, "fabsFunc=", fabsFunc); } }
} // end of WriteLargestCoordinateFunctions() /// <summary> /// Writes code to extract the scalar part of an SMV via a non-member function. /// </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 WriteExtractScalarPart(Specification S, G25.CG.Shared.CGdata cgd) { G25.GMV gmv = S.m_GMV; StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineFunctions) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); const string gmvName = "x"; RefGA.BasisBlade scalarBlade = RefGA.BasisBlade.ONE; string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineFunctions, " "); foreach (G25.FloatType FT in S.m_floatTypes) { string className = FT.GetMangledName(S, gmv.Name); string funcName = "_" + FT.type; string altFuncName = "_Float"; string comment = "/// Returns scalar part of " + className; declSB.AppendLine(comment); string funcDecl = FT.type + " " + funcName + "(const " + className + " &" + gmvName + ")"; declSB.Append(funcDecl); declSB.AppendLine(";"); declSB.AppendLine(comment); string altFuncDecl = FT.type + " " + altFuncName + "(const " + className + " &" + gmvName + ")"; declSB.Append(G25.CG.Shared.Util.GetInlineString(S, true, " ") + altFuncDecl + " {return " + funcName + "(" + gmvName + "); }"); declSB.AppendLine(";"); defSB.Append(inlineStr + funcDecl); { defSB.AppendLine(" {"); int elementIdx = gmv.GetElementIdx(scalarBlade); double multiplier = 1.0 / gmv.BasisBlade(0, elementIdx).scale; string multiplerString = (multiplier != 1.0) ? (FT.DoubleToString(S, multiplier) + " * ") : ""; // this line assumes that the scalar is the first element of the first group (which is a requirement). defSB.AppendLine("\treturn ((x.gu() & 1) != 0) ? " + multiplerString + "x.getC()[0] : " + FT.DoubleToString(S, 0.0) + ";"); defSB.AppendLine("}"); } } // end of loop over all float types } // end of WriteExtractScalarPart()
/// <summary> /// Writes functions to reserve a coordinate group /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> public static void WriteReserveGroups(Specification S, G25.CG.Shared.CGdata cgd) { //StringBuilder declSB = cgd.m_declSB; //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 typeName = FT.GetMangledName(S, gmv.Name); for (int groupIdx = 0; groupIdx < gmv.NbGroups; groupIdx++) { WriteReserveGroup(S, cgd, FT, typeName, groupIdx, gmv.Group(groupIdx).Length); } } }
public static void GenerateGroupSizeArray(Specification S, G25.CG.Shared.CGdata cgd, StringBuilder SB) { // group size G25.GMV gmv = S.m_GMV; SB.AppendLine("const int " + S.m_namespace + "_groupSize[" + gmv.NbGroups + "] = {"); SB.Append("\t"); for (int i = 0; i < gmv.NbGroups; i++) { if (i > 0) { SB.Append(", "); } SB.Append(gmv.Group(i).Length); } SB.AppendLine(""); SB.AppendLine("};"); }
/// <summary> /// Writes functions to extract coordinates from the GMV /// </summary> /// <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> /// <param name="SB"></param> public static void WriteGetCoord(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, StringBuilder SB) { G25.GMV gmv = S.m_GMV; string typeName = FT.GetMangledName(S, gmv.Name); for (int groupIdx = 0; groupIdx < gmv.NbGroups; groupIdx++) { for (int elementIdx = 0; elementIdx < gmv.Group(groupIdx).Length; elementIdx++) { WriteGetCoordFunction(S, cgd, FT, SB, typeName, groupIdx, elementIdx, gmv.Group(groupIdx)[elementIdx]); } } SB.AppendLine("\t/// Returns array of compressed coordinates."); SB.AppendLine("\tinline const " + FT.type + " *getC() const { return m_c;}"); }
private static string GetDualCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool dual) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()"; string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()"; // allocate memory to store result: SB.AppendLine("int idx = 0;"); bool resultIsScalar = false; bool initResultToZero = true; // must init to zero because of compression SB.Append(GPparts.GetExpandCode(S, cgd, FT, null, resultIsScalar, initResultToZero)); // get number of groups: int nbGroups = gmv.NbGroups; // for each combination of groups, check if the dual goes from one to the other for (int gi = 0; gi < nbGroups; gi++) { SB.AppendLine("if (" + agu + " & " + (1 << gi) + ") {"); for (int go = 0; go < nbGroups; go++) { string funcName = (dual) ? GetDualPartFunctionName(S, FT, M, gi, go) : GetUndualPartFunctionName(S, FT, M, gi, go); Tuple <string, string, string> key = new Tuple <string, string, string>(FT.type, M.m_name, funcName); if (cgd.m_gmvDualPartFuncNames.ContainsKey(key) && cgd.m_gmvDualPartFuncNames[key]) { SB.AppendLine("\t" + funcName + "(" + ac + " + idx, c + " + gmv.GroupStartIdx(go) + ");"); } } if (gi < (nbGroups - 1)) { SB.AppendLine("\tidx += " + gmv.Group(gi).Length + ";"); } SB.AppendLine("}"); SB.AppendLine(""); } // compress result SB.Append(GPparts.GetCompressCode(S, FT, FAI, resultName, resultIsScalar)); return(SB.ToString()); } // end of GetDualCodeCppOrC()
public static void GenerateBasisElementsArray(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd) { string accessModifierArr = Keywords.ConstArrayAccessModifier(S); G25.GMV gmv = S.m_GMV; // basis vectors in basis elements new G25.CG.Shared.Comment("This array of integers contains the order of basis elements in the general multivector.\n" + "Use it to answer: 'what basis vectors are in the basis element at position [x]?").Write(SB, S, 1); SB.Append("\tpublic " + accessModifierArr + " int[][] BasisElements = "); if (S.m_gmvCodeGeneration == GMV_CODE.EXPAND) { SB.AppendLine("new int[][] {"); { bool comma = false; for (int i = 0; i < gmv.NbGroups; i++) { for (int j = 0; j < gmv.Group(i).Length; j++) { if (comma) { SB.Append(",\n"); } RefGA.BasisBlade B = gmv.Group(i)[j]; SB.Append("\t\tnew int[] {"); for (int k = 0; k < S.m_dimension; k++) { if ((B.bitmap & (1 << k)) != 0) { SB.Append(k + ", "); } } SB.Append("-1}"); comma = true; } } } SB.AppendLine(""); SB.AppendLine("\t};"); } else { SB.AppendLine(G25.CG.CSJ.Util.GetFunctionName(S, "initBasisElementsArray") + "();"); SB.AppendLine(); cgd.m_cog.EmitTemplate(SB, "initBasisElementsArray", "S=", S); } }
public static void GenerateGroupSizeArray(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd) { // group size string accessModifierArr = Keywords.ConstArrayAccessModifier(S); G25.GMV gmv = S.m_GMV; new G25.CG.Shared.Comment("This array can be used to lookup the number of coordinates for a group part of a general multivector.").Write(SB, S, 1); SB.Append("\tpublic " + accessModifierArr + " int[] GroupSize = { "); for (int i = 0; i < gmv.NbGroups; i++) { if (i > 0) { SB.Append(", "); } SB.Append(gmv.Group(i).Length); } SB.AppendLine(" };"); }
/// <summary> /// Writes functions to copy GMVs from one float type to another. /// </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="dstFT"></param> public static void WriteGMVtoGMVcopy(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType dstFT) { G25.GMV gmv = S.m_GMV; foreach (G25.FloatType srcFT in S.m_floatTypes) { string srcClassName = srcFT.GetMangledName(S, gmv.Name); //string dstClassName = dstFT.GetMangledName(S, gmv.Name); string funcName = GetSetFuncName(S); string funcDecl = "\tpublic void " + funcName + "(" + srcClassName + " src)"; int nbTabs = 1; new G25.CG.Shared.Comment("sets this to multivector value.").Write(SB, S, nbTabs); SB.Append(funcDecl); SB.AppendLine(" {"); SB.AppendLine("\t\t" + GetAllocateGroupsString(S) + "(src.gu());"); for (int g = 0; g < gmv.NbGroups; g++) { SB.AppendLine("\t\tif (m_c[" + g + "] != null) {"); if (dstFT == srcFT) { SB.Append("\t\t\t" + G25.CG.Shared.Util.GetCopyCode(S, dstFT, "src.m_c[" + g + "]", "m_c[" + g + "]", gmv.Group(g).Length)); } else { SB.AppendLine("\t\t\tfor (int i = 0; i < " + gmv.Group(g).Length + "; i++)"); SB.AppendLine("\t\t\t\tm_c[" + g + "][i] = (" + dstFT.type + ")src.m_c[" + g + "][i];"); } SB.AppendLine("\t\t}"); } if (S.m_reportUsage) { SB.AppendLine("\t\tm_t = src.m_t;"); } SB.AppendLine("\t}"); } }
} // end of GetApplyGomCodeCppOrC private static string GetApplyGomCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; bool groupedByGrade = gmv.IsGroupedByGrade(S.m_dimension); StringBuilder SB = new StringBuilder(); // allocate memory to store result: SB.AppendLine(FT.type + "[][] bc = " + FAI[1].Name + ".to_" + FAI[1].MangledTypeName + "().c();"); bool resultIsScalar = false; bool initResultToZero = !groupedByGrade; SB.Append(GPparts.GetExpandCode(S, cgd, FT, null, resultIsScalar, initResultToZero)); // get number of groups: int nbGroups = gmv.NbGroups; // for each combination of groups, check if the OM goes from one to the other for (int srcGroup = 0; srcGroup < nbGroups; srcGroup++) { SB.AppendLine("if (bc[" + srcGroup + "] != null) {"); for (int dstGroup = 0; dstGroup < nbGroups; dstGroup++) { string funcName = GetGomPartFunctionName(S, FT, srcGroup, dstGroup); Tuple <string, string> key = new Tuple <string, string>(FT.type, funcName); if (cgd.m_gmvGomPartFuncNames.ContainsKey(key) && cgd.m_gmvGomPartFuncNames[key]) { string allocCcode = "if (cc[" + dstGroup + "] == null) cc[" + dstGroup + "] = new " + FT.type + "[" + gmv.Group(dstGroup).Length + "];"; SB.AppendLine("\t" + allocCcode); SB.AppendLine("\t" + funcName + "(" + FAI[0].Name + ", bc[" + srcGroup + "], cc[" + dstGroup + "]);"); } } SB.AppendLine("}"); SB.AppendLine(""); } SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return(SB.ToString()); } // end of GetApplyGomCodeCSharpOrJava()
/// <summary> /// Writes functions to copy GMVs from one float type to another. /// </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 WriteGMVtoGMVcopy(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 srcFT in S.m_floatTypes) { String srcClassName = srcFT.GetMangledName(S, gmv.Name); foreach (G25.FloatType dstFT in S.m_floatTypes) { string dstClassName = dstFT.GetMangledName(S, gmv.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(" {"); defSB.AppendLine("\t" + SET_GROUP_USAGE + "(src.gu());"); defSB.AppendLine("\tconst " + srcFT.type + "*srcC = src.getC();"); if (dstFT == srcFT) { defSB.AppendLine("\t" + G25.CG.Shared.Util.GetCopyCode(S, dstFT, "srcC", "m_c", S.m_namespace + "_mvSize[src.gu()]")); } else { defSB.AppendLine("\tfor (int i = 0; i < " + S.m_namespace + "_mvSize[src.gu()]; i++)"); defSB.AppendLine("\t\tm_c[i] = (" + dstFT.type + ")srcC[i];"); } if (S.m_reportUsage) { defSB.AppendLine("\tm_t = src.m_t;"); } defSB.AppendLine("}"); } } }
/// <summary> /// Writes functions to extract coordinates from the GMV /// </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 WriteCoordAccess(Specification S, G25.CG.Shared.CGdata cgd) { //StringBuilder declSB = cgd.m_declSB; //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 typeName = FT.GetMangledName(S, gmv.Name); for (int groupIdx = 0; groupIdx < gmv.NbGroups; groupIdx++) { for (int elementIdx = 0; elementIdx < gmv.Group(groupIdx).Length; elementIdx++) { WriteCoordExtractFunction(S, cgd, FT, typeName, groupIdx, elementIdx, gmv.Group(groupIdx)[elementIdx]); WriteCoordSetFunction(S, cgd, FT, typeName, groupIdx, elementIdx, gmv.Group(groupIdx).Length, gmv.Group(groupIdx)[elementIdx]); } } } }
/// <summary> /// Writes functions to set the GMV types by compressed array value. /// </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 WriteSetCompressedArray(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT) { int nbTabs = 1; new G25.CG.Shared.Comment("sets this coordinates in 'arr'."). AddParamComment("gu", "bitwise or of the GROUPs and GRADEs which are present in 'arr'."). AddParamComment("arr", "compressed coordinates."). Write(SB, S, nbTabs); G25.GMV gmv = S.m_GMV; //string className = FT.GetMangledName(S, gmv.Name); string funcName = GetSetFuncName(S); string groupBitmapStr = GetGroupBitmapType(S); string funcDecl = "\tpublic void " + funcName + "(" + groupBitmapStr + " gu, " + FT.type + "[] arr)"; SB.Append(funcDecl); SB.AppendLine(" {"); SB.AppendLine("\t\t" + GetAllocateGroupsString(S) + "(gu);"); if (S.m_reportUsage) { SB.AppendLine("\t\tm_t = " + G25.CG.CSJ.GMV.SMV_TYPE + "." + G25.CG.Shared.ReportUsage.GetSpecializedConstantName(S, gmv.Name) + ";"); } SB.AppendLine("\t\tint idx = 0;"); for (int g = 0; g < S.m_GMV.NbGroups; g++) { SB.AppendLine("\t\tif ((gu & " + GroupBitmap.GetGroupBitmapCode(g) + ") != 0) {"); SB.AppendLine("\t\t\tfor (int i = 0; i < " + S.m_GMV.Group(g).Length + "; i++)"); SB.AppendLine("\t\t\t\tm_c[" + g + "][i] = arr[idx + i];"); SB.AppendLine("\t\t\tidx += " + S.m_GMV.Group(g).Length + ";"); SB.AppendLine("\t\t}"); } SB.AppendLine("\t}"); }
} // end of GetDualCodeCppOrC() private static string GetDualCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool dual) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); bool resultIsScalar = false; bool initResultToZero = true; // must init to zero because of compression SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero)); // get number of groups: int nbGroups = gmv.NbGroups; // for each combination of groups, check if the dual goes from one to the other for (int gi = 0; gi < nbGroups; gi++) { SB.AppendLine("if (ac[" + gi + "] != null) {"); for (int go = 0; go < nbGroups; go++) { string funcName = (dual) ? GetDualPartFunctionName(S, FT, M, gi, go) : GetUndualPartFunctionName(S, FT, M, gi, go); Tuple <string, string, string> key = new Tuple <string, string, string>(FT.type, M.m_name, funcName); if (cgd.m_gmvDualPartFuncNames.ContainsKey(key) && cgd.m_gmvDualPartFuncNames[key]) { SB.AppendLine("\tif (cc[" + go + "] == null) cc[" + go + "] = new " + FT.type + "[" + gmv.Group(go).Length + "];"); SB.AppendLine("\t" + funcName + "(ac[" + gi + "], cc[" + go + "]);"); } } SB.AppendLine("}"); SB.AppendLine(""); } SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return(SB.ToString()); } // end of GetDualCodeCppOrC()
/// <summary> /// Writes code for abs largest coordinate /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> public static void WriteLargestCoordinateDefinitions(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder defSB = cgd.m_defSB; G25.GMV gmv = S.m_GMV; foreach (G25.FloatType FT in S.m_floatTypes) { string fabsFunc = "fabs"; if (FT.type == "float") { fabsFunc = "fabsf"; } string gmvName = FT.GetMangledName(S, gmv.Name); cgd.m_cog.EmitTemplate(defSB, "GMVlargestCoordinateDef", "S=", S, "FT=", FT, "gmvName=", gmvName, "fabsFunc=", fabsFunc); } } // end of WriteLargestCoordinateFunctions()
/// <summary> /// Writes functions to set the GMV types to scalar value. /// </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 WriteSetScalar(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT) { int nbTabs = 1; new G25.CG.Shared.Comment("sets this to scalar value.").Write(SB, S, nbTabs); G25.GMV gmv = S.m_GMV; // string className = FT.GetMangledName(S, gmv.Name); string funcName = GetSetFuncName(S); string funcDecl = "\tpublic void " + funcName + "(" + FT.type + " val)"; SB.Append(funcDecl); SB.AppendLine(" {"); SB.AppendLine("\t\t" + GetAllocateGroupsString(S) + "(GroupBitmap.GROUP_" + gmv.GetGroupIdx(RefGA.BasisBlade.ONE) + ");"); SB.AppendLine("\t\tm_c[0][0] = val;"); if (S.m_reportUsage) { SB.AppendLine("\t\tm_t = " + G25.CG.CSJ.GMV.SMV_TYPE + "." + G25.CG.Shared.ReportUsage.GetSpecializedConstantName(S, FT.type) + ";"); } SB.AppendLine("\t}"); }
/// <summary> /// Generates a source file with the GMV class definition. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <returns></returns> public static string GenerateCode(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT) { G25.GMV gmv = S.m_GMV; string className = FT.GetMangledName(S, gmv.Name); // get filename, list of generated filenames List <string> generatedFiles = new List <string>(); string sourceFilename = MainGenerator.GetClassOutputPath(S, className); generatedFiles.Add(sourceFilename); // get StringBuilder where all generated code goes StringBuilder SB = new StringBuilder(); // get a new 'cgd' where all ouput goes to the one StringBuilder SB cgd = new G25.CG.Shared.CGdata(cgd, SB, SB, SB); // output license, copyright G25.CG.Shared.Util.WriteCopyright(SB, S); G25.CG.Shared.Util.WriteLicense(SB, S); // using ... Util.WriteGenericUsing(SB, S); // open namespace G25.CG.Shared.Util.WriteOpenNamespace(SB, S); // write class comment G25.CG.CSJ.GMV.WriteComment(SB, S, cgd, FT, gmv); // open class string[] implements = new string[] { MvInterface.GetMvInterfaceName(S, FT) }; G25.CG.Shared.Util.WriteOpenClass(SB, S, G25.CG.Shared.AccessModifier.AM_public, className, null, implements); // write member vars WriteMemberVariables(SB, S, cgd, FT, gmv); // write constructors WriteConstructors(SB, S, cgd, FT, gmv, className); WriteGetGuC(SB, S, cgd, FT); // write 'set' functions G25.CG.CSJ.GMV.WriteSetZero(SB, S, cgd, FT); G25.CG.CSJ.GMV.WriteSetScalar(SB, S, cgd, FT); G25.CG.CSJ.GMV.WriteSetCompressedArray(SB, S, cgd, FT); G25.CG.CSJ.GMV.WriteSetExpandedArray(SB, S, cgd, FT); G25.CG.CSJ.GMV.WriteGMVtoGMVcopy(SB, S, cgd, FT); G25.CG.CSJ.GMV.WriteSMVtoGMVcopy(SB, S, cgd, FT); // write 'get coordinate' functions G25.CG.CSJ.GMV.WriteGetCoord(SB, S, cgd, FT); // write SetGroupUsage() G25.CG.CSJ.GMV.WriteSetGroupUsage(SB, S, cgd, FT); // write 'reserve group' functions G25.CG.CSJ.GMV.WriteReserveGroup(SB, S, cgd, FT); // write 'set coordinate' functions G25.CG.CSJ.GMV.WriteSetCoord(SB, S, cgd, FT); // write 'largest coordinate' functions G25.CG.CSJ.GMV.WriteLargestCoordinates(SB, S, cgd, FT); // write compress functions G25.CG.CSJ.GMV.WriteCompress(SB, S, cgd, FT); // write 'ToString' functions G25.CG.CSJ.GMV.WriteToString(SB, S, cgd, FT, gmv); // write multivector interface implementation G25.CG.CSJ.GMV.WriteMultivectorInterface(SB, S, cgd, FT); // write shortcuts for functions G25.CG.Shared.Shortcut.WriteFunctionShortcuts(SB, S, cgd, FT, gmv); // close class G25.CG.Shared.Util.WriteCloseClass(SB, S, className); // close namespace G25.CG.Shared.Util.WriteCloseNamespace(SB, S); // write all to file G25.CG.Shared.Util.WriteFile(sourceFilename, SB.ToString()); return(sourceFilename); }
/// <summary> /// Writes constructors of a GMV class to 'SB'. /// </summary> /// <param name="SB">Where the comment goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float point type of 'SMV'.</param> /// <param name="gmv">The general multivector for which the struct should be written.</param> /// <param name="className">Mangled name of GMV class.</param> public static void WriteConstructors(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.GMV gmv, string className) { cgd.m_cog.EmitTemplate(SB, "GMVconstructors", "S=", S, "FT=", FT, "className=", className); }
/// <summary> /// Must be called before CompleteFGS(), CheckDepencies() or WriteFunction() is called. /// Subclass can override, but if so, must always call superclass version of Init() /// </summary> /// <param name="S"></param> /// <param name="F"></param> /// <param name="cgd">Where the generate code goes.</param> public virtual void Init(Specification S, G25.fgs F, G25.CG.Shared.CGdata cgd) { m_specification = S; m_fgs = F; m_cgd = cgd; m_gmv = m_specification.m_GMV; m_G25M = m_specification.GetMetric(m_fgs.MetricName); m_M = m_G25M.m_metric; m_sane = true; }