/// <summary> /// Resolves a converter (underscore constructor) dependency. /// Searches for a converter from 'fromType' to 'toType'. /// /// If the function is not found, this is also enlisted in cgd.m_missingDependencies. /// Call cgd.PrintMissingDependencies() should be called to report the missing dependencies /// to the end-user. /// </summary> /// <param name="S">The spec.</param> /// <param name="cgd">Missing dependencies go into cgd.m_missingDependencies.</param> /// <param name="fromType"></param> /// <param name="toType"></param> /// <param name="FT"></param> /// <returns></returns> public static string GetConverterDependency(Specification S, CGdata cgd, string fromType, string toType, G25.FloatType FT) { // look for 'funcName' in all G25.fgs in the spec // string funcName = "_" + FT.GetMangledName(S, toType); string funcName = "_" + toType; foreach (G25.fgs F in S.m_functions) { if (F.IsConverter(S)) // is 'F' a converter (underscore constructor)? { if ((F.Name == funcName) && (F.ArgumentTypeNames[0] == fromType)) { return G25.CG.Shared.Converter.GetConverterName(S, F, FT.GetMangledName(S, fromType), FT.GetMangledName(S, toType)); } } } // converter not found: add it to missing deps: { // add dependency to list of missing deps: string outputName = null; string[] argumentTypes = new string[] { fromType }; string[] argVarNames = null; string returnTypeName = null; string metricName = null; string comment = null; Dictionary<string, string> options = null; G25.fgs F = new G25.fgs(funcName, outputName, returnTypeName, argumentTypes, argVarNames, new string[] { FT.type }, metricName, comment, options); cgd.AddMissingDependency(S, F); } // return fictional name: G25.fgs tmpF = null; return "missingFunction_" + G25.CG.Shared.Converter.GetConverterName(S, tmpF, FT.GetMangledName(S, fromType), FT.GetMangledName(S, toType)); }
private static string GetFuncDecl(Specification S, bool declOnly, G25.fgs FGS, G25.Operator op, G25.FloatType FT, bool assign, bool constVal, bool returnByReference) { StringBuilder SB = new StringBuilder(); string inlineStr = G25.CG.Shared.Util.GetInlineString(S, (!declOnly) && S.m_inlineOperators, " "); string returnTypeName = (FGS.m_returnTypeName.Length > 0) ? FGS.m_returnTypeName : FT.type; if (!S.IsFloatType(returnTypeName)) returnTypeName = FT.GetMangledName(S, returnTypeName); string arg1typeName = FT.GetMangledName(S, FGS.ArgumentTypeNames[0]); string arg2typeName = (FGS.NbArguments > 1) ? FT.GetMangledName(S, FGS.ArgumentTypeNames[1]) : ""; SB.Append(inlineStr); SB.Append(returnTypeName); SB.Append(" "); if (returnByReference) SB.Append("&"); SB.Append("operator"); SB.Append(op.Symbol); if (assign) SB.Append("="); SB.Append("("); if (constVal) SB.Append("const "); SB.Append(arg1typeName); SB.Append(" &"); SB.Append(FGS.ArgumentVariableNames[0]); if (op.IsBinary()) { SB.Append(", const "); SB.Append(arg2typeName); SB.Append(" &"); SB.Append(FGS.ArgumentVariableNames[1]); } else if ((S.OutputCpp()) && op.IsPostfixUnary()) { // add a dummy int argument so C++ knows this is a unary postfix op SB.Append(", int"); } SB.Append(")"); return SB.ToString(); }
/// <summary> /// Writes function for obtaining the largest coordinate of a multivector. /// </summary> /// <param name="SB"></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 WriteLargestCoordinates(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT) { string fabsFuncName = G25.CG.Shared.CodeUtil.OpNameToLangString(S, FT, RefGA.Symbolic.UnaryScalarOp.ABS); cgd.m_cog.EmitTemplate(SB, "GMVlargestCoordinate", "S=", S, "FT=", FT, "gmvName=", FT.GetMangledName(S, S.m_GMV.Name), "fabsFunc=", fabsFuncName); }
private static string GetGradeCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, int gradeIdx, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, string groupBitmapName) { G25.GMV gmv = S.m_GMV; if (gradeIdx >= 0) { // if a specific grade is requested, convert it into a group bitmap, and call the grade(A, groupBitmap) function // get name of grade function //bool returnTrueName = false; string gradeFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, EXTRACT_GRADE, new string[] { gmv.Name, G25.GroupBitmapType.GROUP_BITMAP }, FT, null); // turn grade into group int groupBitmap = gmv.GradeToGroupBitmap(gradeIdx); if (S.OutputC()) { return gradeFuncName + "(" + resultName + ", " + FAI[0].Name + ", " + groupBitmap + ");"; } else { return "return " + gradeFuncName + "(" + FAI[0].Name + ", " + groupBitmap + ");"; } } else { StringBuilder SB = new StringBuilder(); // get indices into coordinates for input and output SB.AppendLine("int aidx = 0, cidx = 0;"); string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()"; string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()"; if (S.OutputC()) { SB.AppendLine(resultName + "->gu = " + agu +" & " + groupBitmapName + ";"); } else { SB.AppendLine("int gu = " + agu + " & " + groupBitmapName + ";"); SB.AppendLine(FT.type + " c[" + (1 << S.m_dimension) + "];"); } string resultCoordPtr = (S.OutputC()) ? resultName + "->c" : "c"; // for each group, test if present int nbGroups = gmv.NbGroups; for (int g = 0; g < nbGroups; g++) { SB.AppendLine(""); string funcName = GetCopyPartFunctionName(S, FT, g); SB.AppendLine("if (" + agu + " & " + (1 << g) + ") {"); SB.AppendLine("\tif (" + groupBitmapName + " & " + (1 << g) + ") {"); SB.AppendLine("\t\t" + funcName + "(" + ac + " + aidx, " + resultCoordPtr + " + cidx);"); if (g < (nbGroups - 1)) SB.AppendLine("\t\tcidx += " + gmv.Group(g).Length + ";"); SB.AppendLine("\t}"); if (g < (nbGroups - 1)) SB.AppendLine("\taidx += " + gmv.Group(g).Length + ";"); SB.AppendLine("}"); } // return result if (S.m_outputLanguage != OUTPUT_LANGUAGE.C) { SB.AppendLine("return " + FT.GetMangledName(S, gmv.Name) + "(gu, c);"); } return SB.ToString(); } }
/// <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;}"); }
/// <summary> /// Returns the code for a inverse geometric product. /// /// The returned code is only the body. The function declaration is not included. /// </summary> /// <param name="S">Specification of algebra (used for output language and to obtain general multivector type).</param> /// <param name="cgd">Used for <c>m_gmvGPpartFuncNames</c>.</param> /// <param name="FT">Floating point type.</param> /// <param name="M">Metric type.</param> /// <param name="T">The product (e.g., geometric, outer, etc)</param> /// <param name="FAI">Info about function arguments. Used to know whether arguments are general multivectors or scalars.</param> /// <param name="resultName">Name of variable where the result goes (in the generated code).</param> /// <returns>code for the requested product type.</returns> public static string GetIGPcode(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); string divFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "div", new String[] { gmv.Name, FT.type }, FT, null); System.Collections.Hashtable argTable = new System.Collections.Hashtable(); argTable["S"] = S; argTable["gmvName"] = FT.GetMangledName(S, gmv.Name); argTable["FT"] = FT; argTable["arg1name"] = FAI[0].Name; argTable["arg2name"] = FAI[1].Name; argTable["divFuncName"] = divFuncName; if (S.OutputC()) argTable["dstName"] = resultName; bool arg1isGmv = FAI[0].Type is G25.GMV; bool arg2isGmv = FAI[1].Type is G25.GMV; if (arg2isGmv) { string norm2FuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "norm2", new String[] { gmv.Name }, FT, M.m_name) + CANSparts.RETURNS_SCALAR; string reverseFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "reverse", new String[] { gmv.Name }, FT, null); argTable["reverseFuncName"] = reverseFuncName; argTable["norm2FuncName"] = norm2FuncName; if (arg1isGmv) { string gpFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "gp", new String[] { gmv.Name, gmv.Name }, FT, M.m_name); argTable["gpFuncName"] = gpFuncName; cgd.m_cog.EmitTemplate(SB, "igp_GMV_GMV_body", argTable); } else { string gpFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "gp", new String[] { gmv.Name, FT.type }, FT, M.m_name); argTable["mulFuncName"] = gpFuncName; cgd.m_cog.EmitTemplate(SB, "igp_float_GMV_body", argTable); } } else if (arg1isGmv) { cgd.m_cog.EmitTemplate(SB, "igp_GMV_float_body", argTable); } return SB.ToString(); }
private static string GetExpandCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, bool resultIsScalar, bool initResultToZero) { StringBuilder SB = new StringBuilder(); // result coordinates code: int nbCoords = (resultIsScalar) ? 1 : (1 << S.m_dimension); SB.AppendLine(FT.type + " c[" + nbCoords + "];"); // expand code if (FAI != null) { for (int i = 0; i < FAI.Length; i++) { if (FAI[i].IsScalar()) { // 'expand' scalar SB.AppendLine("const " + FAI[i].FloatType.type + "* _" + FAI[i].Name + "[1] = {&" + FAI[i].Name + "};"); } else { // expand general multivector // SB.AppendLine("const " + FAI[i].FloatType.type + "* _" + FAI[i].Name + "[" + (S.m_dimension + 1) + "];"); SB.AppendLine("const " + FAI[i].FloatType.type + "* _" + FAI[i].Name + "[" + (S.m_GMV.NbGroups) + "];"); } } for (int i = 0; i < FAI.Length; i++) { if (!FAI[i].IsScalar()) { if (S.OutputC()) SB.AppendLine(FT.GetMangledName(S, "expand") + "(_" + FAI[i].Name + ", " + FAI[i].Name + ");"); else SB.AppendLine(FAI[i].Name + ".expand(_" + FAI[i].Name + ");"); } } } // set coordinates of 'c' to zero if (initResultToZero) { SB.Append(Util.GetSetToZeroCode(S, FT, "c", nbCoords)); } return SB.ToString(); }
/// <summary> /// Writes function for setting grade/group usage, reallocting memory /// </summary> /// <param name="SB"></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 WriteSetGroupUsage(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT) { string className = FT.GetMangledName(S, S.m_GMV.Name); cgd.m_cog.EmitTemplate(SB, "GMVsetGroupUsage", "S=", S, "FT=", FT, "className=", className, "gmv=", S.m_GMV); }
private static string GetSAScodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); SB.AppendLine("int idxa = 0, idxc = 0;"); string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()"; string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()"; string resultCoordPtr = (S.OutputC()) ? resultName + "->c" : "C"; // copy group usage / allocate memory for result if (S.OutputC()) { SB.AppendLine(resultName + "->gu = " + agu + " | ((" + FAI[2].Name + " != 0.0) ? GRADE_0 : 0); /* '| GRADE_0' to make sure the scalar part is included */"); } else { SB.AppendLine("int gu = " + agu + " | ((" + FAI[2].Name + " != 0.0) ? GRADE_0 : 0); // '| GRADE_0' to make sure the scalar part is included"); SB.AppendLine(FT.type + " C[" + (1 << S.m_dimension) + "];"); } int nbGroups = gmv.NbGroups; for (int g = 0; g < nbGroups; g++) { SB.AppendLine(""); // get func name string funcName = GetCopyMulPartFunctionName(S, FT, g); SB.AppendLine("if (" + agu + " & " + (1 << g) + ") {"); SB.AppendLine("\t" + funcName + "(" + ac + " + idxa, " + resultCoordPtr + " + idxc, " + FAI[1].Name + ");"); if (g == 0) { // also add scalar SB.AppendLine("\tif (" + FAI[2].Name + " != 0.0) " + resultCoordPtr + "[idxc] += " + FAI[2].Name + ";"); } if (g < (nbGroups - 1)) { SB.AppendLine("\tidxa += " + gmv.Group(g).Length + ";"); SB.AppendLine("\tidxc += " + gmv.Group(g).Length + ";"); } SB.AppendLine("}"); if (g == 0) { // always add the scalar: SB.AppendLine("else if (" + FAI[2].Name + " != 0.0) {"); SB.AppendLine("\t" + resultCoordPtr + "[idxc] = " + FAI[2].Name + ";"); SB.AppendLine("\tidxc += " + gmv.Group(g).Length + ";"); SB.AppendLine("}"); } } // return result if (S.m_outputLanguage != OUTPUT_LANGUAGE.C) { SB.AppendLine("return " + FT.GetMangledName(S, gmv.Name) + "(gu, C);"); } return SB.ToString(); }
/// <summary> /// Returns the name of a partial subtraction function. /// </summary> /// <param name="FT">Float type (used for mangled name).</param> /// <param name="g">Grade/group of arguments.</param> /// <returns>name of a partial subtraction function.</returns> public static string GetSubPartFunctionName(Specification S, G25.FloatType FT, int g) { return FT.GetMangledName(S, "sub") + "_" + g; }
/// <summary> /// Returns the name of a partial is-zero function /// </summary> /// <param name="FT">Float type (used for mangled name).</param> /// <param name="g">Grade/group of arguments.</param> /// <returns>name of a partial Hadamard product function.</returns> public static string GetZeroPartFunctionName(Specification S, G25.FloatType FT, int g) { return FT.GetMangledName(S, "zeroGroup") + "_" + g; }
/// <summary> /// Returns the name of a partial equality function /// </summary> /// <param name="FT">Float type (used for mangled name).</param> /// <param name="g">Grade/group of arguments.</param> /// <returns>name of a partial Hadamard product function.</returns> public static string GetEqualsPartFunctionName(Specification S, G25.FloatType FT, int g) { return FT.GetMangledName(S, "equals") + "_" + g + "_" + g; }
/// <summary> /// Returns the name of a partial Hadamard product function /// </summary> /// <param name="FT">Float type (used for mangled name).</param> /// <param name="g">Grade/group of arguments.</param> /// <returns>name of a partial Hadamard product function.</returns> public static string GetInverseHadamardProductPartFunctionName(Specification S, G25.FloatType FT, int g) { return FT.GetMangledName(S, "ihp") + "_" + g + "_" + g; }
private static string GetUnaryToggleSignCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, UnaryToggleSignType T, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); // get number of groups: int nbGroups = gmv.NbGroups; bool resultIsScalar = false , initResultToZero = false; SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero)); // for each group // test if present, then code / negate, etc for (int g = 0; g < nbGroups; g++) { SB.AppendLine(""); // do we need to negate this group? bool neg = NeedToNegate(gmv, g, T); string funcName = (neg) ? GetNegPartFunctionName(S, FT, g) : GetCopyPartFunctionName(S, FT, g); SB.AppendLine("if (ac[" + g + "] != null) {"); SB.AppendLine("\tcc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];"); SB.AppendLine("\t" + funcName + "(ac[" + g + "], cc[" + g + "]);"); SB.AppendLine("}"); } SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return SB.ToString(); }
private static string GetUnaryToggleSignCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, UnaryToggleSignType T, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { 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()"; string resultCoordPtr = (S.OutputC()) ? resultName + "->c" : "c"; SB.AppendLine("int idx = 0;"); if (S.OutputC()) { SB.AppendLine(resultName + "->gu = " + agu + ";"); } else { SB.AppendLine("int gu = " + agu + ";"); SB.AppendLine(FT.type + " c[" + (1 << S.m_dimension) + "];"); } // get number of groups: int nbGroups = gmv.NbGroups; // for each group // test if present, then code / negate, etc for (int g = 0; g < nbGroups; g++) { SB.AppendLine(""); // do we need to negate this group? bool neg = NeedToNegate(gmv, g, T); string funcName = (neg) ? GetNegPartFunctionName(S, FT, g) : GetCopyPartFunctionName(S, FT, g); SB.AppendLine("if (" + agu + " & " + (1 << g) + ") {"); SB.AppendLine("\t" + funcName + "(" + ac + " + idx, " + resultCoordPtr + " + idx);"); if (g < (nbGroups - 1)) SB.AppendLine("\tidx += " + gmv.Group(g).Length + ";"); SB.AppendLine("}"); } // return result if (S.m_outputLanguage != OUTPUT_LANGUAGE.C) { SB.AppendLine("return " + FT.GetMangledName(S, gmv.Name) + "(gu, c);"); } return SB.ToString(); }
private static string GetSAScodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, String resultName) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); bool resultIsScalar = false, initResultToZero = false; SB.Append(GPparts.GetExpandCode(S, cgd, FT, new FuncArgInfo[] { FAI[0] }, resultIsScalar, initResultToZero)); //SB.AppendLine("cc[0] = new " + FT.type + "[" + gmv // string allocCcode = "cc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];"; int nbGroups = gmv.NbGroups; for (int g = 0; g < nbGroups; g++) { SB.AppendLine(""); // get func name string funcName = GetCopyMulPartFunctionName(S, FT, g); SB.AppendLine("if (ac[" + g + "] != null) {"); SB.AppendLine("\tcc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];"); SB.AppendLine("\t" + funcName + "(ac[" + g + "], cc[" + g + "], " + FAI[1].Name + ");"); if (g == 0) { // also add scalar SB.AppendLine("\tcc[" + g + "][0] += " + FAI[2].Name + ";"); } SB.AppendLine("}"); if (g == 0) { // always add the scalar: SB.AppendLine("else if (" + FAI[2].Name + " != 0.0) {"); SB.AppendLine("\tcc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];"); SB.AppendLine("cc[" + g + "][0] = " + FAI[2].Name + ";"); SB.AppendLine("}"); } } // return result SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return SB.ToString(); }
/// <summary> /// Writes the implementation of the multivector interface. /// </summary> /// <param name="SB"></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 WriteMultivectorInterface(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT) { string gmvName = FT.GetMangledName(S, S.m_GMV.Name); cgd.m_cog.EmitTemplate(SB, "GMVmvInterfaceImpl", "gmvName=", gmvName); }
public static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; string srcTypeName = FT.GetMangledName(S, srcOm.Name); string dstTypeName = FT.GetMangledName(S, dstOm.Name); bool writeDecl = S.OutputC(); string funcName = GetFunctionName(S, (S.OutputC() ? "" : dstTypeName), "set", srcTypeName + "_to_" + dstTypeName); // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string dstArgStr = (S.OutputC()) ? (dstTypeName + " *dst, ") : ""; string refStr = (S.OutputC()) ? "*" : ((S.OutputCpp()) ? "&" : ""); string CONST = (S.OutputCppOrC()) ? "const " : ""; string funcDecl = inlineStr + "void " + funcName + "(" + dstArgStr + CONST + srcTypeName + " " + refStr + "src)"; // write comment, function declaration Comment comment = new Comment("Copies a " + srcTypeName + " to a " + dstTypeName + "\n" + "Warning 1: coordinates which cannot be represented are silenty lost.\n" + "Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.\n"); if (writeDecl) { comment.Write(declSB, S, 0); declSB.Append(funcDecl); declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) comment.Write(defSB, S, 0); defSB.Append(funcDecl); { defSB.AppendLine(" {"); Dictionary<Tuple<int, int, int>, Tuple<int, int, double>> D = dstOm.getMapping(srcOm); StringBuilder copySB = new StringBuilder(); List<string> setToZero = new List<string>(); string matrixStr = (S.OutputC()) ? "m" : "m_m"; string dstMatrixStr = (S.OutputC()) ? "dst->" + matrixStr : matrixStr; string ptrStr = (S.OutputC()) ? "->" : "."; // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null // Do not use foreach() on D because we want to fill in coordinates in their proper order. for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++) { for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++) { for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++) { Tuple<int, int, int> key = new Tuple<int, int, int>(gradeIdx, somDomainIdx, somRangeIdx); int somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx); string dstString = dstMatrixStr + gradeIdx + "[" + somMatrixIdx + "] = "; if (D.ContainsKey(key)) { Tuple<int, int, double> value = D[key]; int gomMatrixIdx = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2); double multiplier = value.Value3; string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * "); copySB.AppendLine("\t" + dstString + multiplierString + " src" + ptrStr + matrixStr + gradeIdx + "[" + gomMatrixIdx + "];"); } else { setToZero.Add(dstString); } } } } // append copy statements defSB.Append(copySB); // append statements to set coordinates to zero if (setToZero.Count > 0) { int cnt = 0; defSB.Append("\t"); foreach (string str in setToZero) { defSB.Append(str); cnt++; if (cnt > 8) { cnt = 0; defSB.AppendLine(""); defSB.Append("\t\t"); } } defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";"); } 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(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT) { 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(SB, S, cgd, FT, typeName, groupIdx, elementIdx, gmv.Group(groupIdx).Length, gmv.Group(groupIdx)[elementIdx]); } } }
private static string GetGPcodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, ProductTypes T, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); bool resultIsScalar = (T == ProductTypes.SCALAR_PRODUCT); bool initResultToZero = true; SB.Append(GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero)); // get number of groups int nbGroups1 = (FAI[0].IsScalar()) ? 1 : gmv.NbGroups; int nbGroups2 = (FAI[1].IsScalar()) ? 1 : gmv.NbGroups; bool[] GroupAlwaysPresent1 = new bool[nbGroups1]; bool[] GroupAlwaysPresent2 = new bool[nbGroups2]; if (FAI[0].IsScalar()) GroupAlwaysPresent1[0] = true; if (FAI[1].IsScalar()) GroupAlwaysPresent2[0] = true; if (resultIsScalar) { // make sure scalar part is present in result SB.AppendLine("cc[0] = new " + FT.type + "[" + gmv.Group(0).Length + "];"); } int g1Cond = -1; // grade 1 conditional which is open (-1 = none) int g2Cond = -1; // grade 2 conditional which is open (-1 = none) for (int g1 = 0; g1 < nbGroups1; g1++) { for (int g2 = 0; g2 < nbGroups2; g2++) { for (int g3 = 0; g3 < gmv.NbGroups; g3++) { if (!zero(S, cgd, FT, M, g1, g2, g3, T)) { // close conditionals if required if ((((g1Cond != g1) && (g1Cond >= 0)) || (g2Cond != g2)) && (g2Cond >= 0)) { SB.AppendLine("\t}"); g2Cond = -1; } if ((g1Cond != g1) && (g1Cond >= 0)) { SB.AppendLine("}"); g1Cond = -1; } // open conditionals if required (group not currently open, and not guaranteed to be present) if ((!GroupAlwaysPresent1[g1]) && (g1Cond != g1)) { SB.AppendLine("if (ac[" + g1 + "] != null) {"); g1Cond = g1; } if ((!GroupAlwaysPresent2[g2]) && (g2Cond != g2)) { SB.AppendLine("\tif (bc[" + g2+ "] != null) {"); g2Cond = g2; } if (!(resultIsScalar && (g3 == 0))) // grade 0 is always allocated for scalar result SB.AppendLine("\t\tif (cc[" + g3 + "] == null) cc[" + g3 + "] = new " + FT.type + "[" + gmv.Group(g3).Length + "];"); // get function name string funcName = GetGPpartFunctionName(S, FT, M, g1, g2, g3); SB.AppendLine("\t\t" + funcName + "(ac[" + g1 + "], bc[" + g2 + "], cc[" + g3 + "]);"); } } } } // close any open conditionals if (g2Cond >= 0) { SB.AppendLine("\t}"); g2Cond = -1; } if (g1Cond >= 0) { SB.AppendLine("}"); g1Cond = -1; } if (resultIsScalar) SB.AppendLine("return cc[0][0];"); else SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return SB.ToString(); }
private static string GetAddSubtractHpCode_CSharp_Java(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, ADD_SUB_HP_TYPE funcType, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; bool NOT_HP = (!((funcType == ADD_SUB_HP_TYPE.HP) || (funcType == ADD_SUB_HP_TYPE.IHP))); StringBuilder SB= new StringBuilder(); // get number of groups, and possible assurances that a group is always present: int nbGroups = gmv.NbGroups; bool resultIsScalar = false, initResultToZero = false; SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero)); // for each group // test if present in both-> then add both, etc for (int g = 0; g < nbGroups; g++) { SB.AppendLine(""); string funcName1_1 = GetCopyPartFunctionName(S, FT, g); string funcName2 = null; string funcName1_2 = null; switch (funcType) { case ADD_SUB_HP_TYPE.ADD: funcName2 = GetAdd2PartFunctionName(S, FT, g); funcName1_2 = GetCopyPartFunctionName(S, FT, g); break; case ADD_SUB_HP_TYPE.SUB: funcName2 = GetSub2PartFunctionName(S, FT, g); funcName1_2 = GetNegPartFunctionName(S, FT, g); break; case ADD_SUB_HP_TYPE.HP: funcName2 = GetHadamardProductPartFunctionName(S, FT, g); funcName1_2 = null; break; case ADD_SUB_HP_TYPE.IHP: funcName2 = GetInverseHadamardProductPartFunctionName(S, FT, g); funcName1_2 = null; break; } string allocCcode = "cc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];"; SB.AppendLine("if (ac[" + g + "] != null) {"); if (NOT_HP) SB.AppendLine("\t" + allocCcode); SB.AppendLine("\tif (bc[" + g + "] != null) {"); if (!NOT_HP) SB.AppendLine("\t\t" + allocCcode); SB.AppendLine("\t\t" + funcName2 + "(ac[" + g + "], bc[" + g + "], cc[" + g + "]);"); SB.AppendLine("\t}"); if (NOT_HP) SB.AppendLine("\telse " + funcName1_1 + "(ac[" + g + "], cc[" + g + "]);"); SB.AppendLine("}"); if (NOT_HP) { SB.AppendLine("else if (bc[" + g + "] != null) {"); SB.AppendLine("\t" + allocCcode); SB.AppendLine("\t" + funcName1_2 + "(bc[" + g + "], cc[" + g + "]);"); SB.AppendLine("}"); } } // return result SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return SB.ToString(); }
private static string GetGradeCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, int gradeIdx, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, string groupBitmapName) { G25.GMV gmv = S.m_GMV; if (gradeIdx >= 0) { // if a specific grade is requested, convert it into a group bitmap, and call the grade(A, groupBitmap) function // get name of grade function string gradeFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, EXTRACT_GRADE, new string[] { gmv.Name, G25.GroupBitmapType.GROUP_BITMAP }, FT, null); // turn grade into group int groupBitmap = gmv.GradeToGroupBitmap(gradeIdx); string castToGroupBitmap = (S.OutputCSharp()) ? "(GroupBitmap)" : ""; return "return " + gradeFuncName + "(" + FAI[0].Name + ", " + castToGroupBitmap + groupBitmap + ");"; } else { StringBuilder SB = new StringBuilder(); int nbGroups = gmv.NbGroups; string GroupBitmapType = (S.OutputCSharp()) ? "GroupBitmap" : "int"; SB.AppendLine(GroupBitmapType + " gu = " + FAI[0].Name + ".to_" + FAI[0].MangledTypeName + "().gu() & " + groupBitmapName + ";"); bool resultIsScalar = false, initResultToZero = false; SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero)); // for each group, test if present for (int g = 0; g < nbGroups; g++) { SB.AppendLine(""); string funcName = GetCopyPartFunctionName(S, FT, g); SB.AppendLine("if ((gu & GroupBitmap.GROUP_" + g + ") != 0) {"); SB.AppendLine("\tcc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];"); SB.AppendLine("\t" + funcName + "(ac[" + g + "], cc[" + g + "]);"); SB.AppendLine("}"); } SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return SB.ToString(); } }
public static void WriteSetVectorImages(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SOM som) { G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, som); // loop over som.DomainVectors // setup array of arguments, function specification, etc int NB_ARGS = som.DomainVectors.Length; string[] argTypes = new string[NB_ARGS]; string[] argNames = new string[NB_ARGS]; RefGA.Multivector[] argValue = new RefGA.Multivector[NB_ARGS]; for (int d = 0; d < NB_ARGS; d++) { argTypes[d] = rangeVectorType.Name; argNames[d] = "i" + som.DomainVectors[d].ToLangString(S.m_basisVectorNames); bool ptr = (S.OutputC()); argValue[d] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, rangeVectorType, argNames[d], ptr); } string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_setVectorImages"); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypes, argNames, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, som.Name, computeMultivectorValue); // setup instructions List<G25.CG.Shared.Instruction> I = new List<G25.CG.Shared.Instruction>(); { bool mustCast = false; int nbTabs = 1; string dstName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool dstPtr = S.OutputCppOrC(); bool declareDst = false; for (int g = 1; g < som.Domain.Length; g++) { for (int c = 0; c < som.DomainForGrade(g).Length; c++) { G25.SMVOM smvOM = som.DomainSmvForGrade(g)[c]; RefGA.BasisBlade domainBlade = som.DomainForGrade(g)[c]; RefGA.Multivector value = new RefGA.Multivector(new RefGA.BasisBlade(domainBlade, 0)); // copy the scalar part, ditch the basis blade for (uint v = 0; v < som.DomainVectors.Length; v++) { if ((domainBlade.bitmap & som.DomainVectors[v].bitmap) != 0) { value = RefGA.Multivector.op(value, argValue[v]); } } I.Add(new G25.CG.Shared.CommentInstruction(nbTabs, "Set image of " + domainBlade.ToString(S.m_basisVectorNames))); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, value, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Sets " + typeName + " from images of the domain vectors."); bool writeDecl = false; bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
private static string GetAddSubtractHpCode_C_CPP(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, ADD_SUB_HP_TYPE funcType, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; bool NOT_HP = (!((funcType == ADD_SUB_HP_TYPE.HP) || (funcType == ADD_SUB_HP_TYPE.IHP))); StringBuilder SB= new StringBuilder(); SB.AppendLine("int aidx = 0, bidx = 0, cidx = 0;"); string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()"; string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()"; string bgu = (S.OutputC()) ? FAI[1].Name + "->gu" : FAI[1].Name + ".gu()"; string bc = (S.OutputC()) ? FAI[1].Name + "->c" : FAI[1].Name + ".getC()"; string resultCoordPtr = (S.OutputC()) ? resultName + "->c" : "c"; string guSymbol = (NOT_HP) ? "|" : "&"; if (S.OutputC()) { SB.AppendLine(resultName + "->gu = " + agu + " " + guSymbol + " " + bgu + ";"); } else { SB.AppendLine("int gu = " + agu + " " + guSymbol + " " + bgu + ";"); SB.AppendLine(FT.type + " c[" + (1 << S.m_dimension) + "];"); } // get number of groups, and possible assurances that a group is always present: int nbGroups = gmv.NbGroups; // for each group // test if present in both-> then add both, etc for (int g = 0; g < nbGroups; g++) { SB.AppendLine(""); string funcName1_1 = GetCopyPartFunctionName(S, FT, g); string funcName2 = null; string funcName1_2 = null; switch (funcType) { case ADD_SUB_HP_TYPE.ADD: funcName2 = GetAdd2PartFunctionName(S, FT, g); funcName1_2 = GetCopyPartFunctionName(S, FT, g); break; case ADD_SUB_HP_TYPE.SUB: funcName2 = GetSub2PartFunctionName(S, FT, g); funcName1_2 = GetNegPartFunctionName(S, FT, g); break; case ADD_SUB_HP_TYPE.HP: funcName2 = GetHadamardProductPartFunctionName(S, FT, g); funcName1_2 = null; break; case ADD_SUB_HP_TYPE.IHP: funcName2 = GetInverseHadamardProductPartFunctionName(S, FT, g); funcName1_2 = null; break; } SB.AppendLine("if (" + agu + " & " + (1 << g) + ") {"); SB.AppendLine("\tif (" + bgu + " & " + (1 << g) + ") {"); SB.AppendLine("\t\t" + funcName2 + "(" + ac + " + aidx, " + bc + " + bidx, " + resultCoordPtr + " + cidx);"); if (g < (nbGroups - 1)) { SB.AppendLine("\t\tbidx += " + gmv.Group(g).Length + ";"); if (!NOT_HP) SB.AppendLine("\t\tcidx += " + gmv.Group(g).Length + ";"); } SB.AppendLine("\t}"); if (NOT_HP) SB.AppendLine("\telse " + funcName1_1 + "(" + ac + " + aidx, " + resultCoordPtr + " + cidx);"); if (g < (nbGroups - 1)) SB.AppendLine("\taidx += " + gmv.Group(g).Length + ";"); if (NOT_HP) SB.AppendLine("\tcidx += " + gmv.Group(g).Length + ";"); SB.AppendLine("}"); SB.AppendLine("else if (" + bgu + " & " + (1 << g) + ") {"); if (NOT_HP) SB.AppendLine("\t" + funcName1_2 + "(" + bc + " + bidx, " + resultCoordPtr + " + cidx);"); if (g < (nbGroups - 1)) SB.AppendLine("\tbidx += " + gmv.Group(g).Length + ";"); if (NOT_HP) SB.AppendLine("\tcidx += " + gmv.Group(g).Length + ";"); SB.AppendLine("}"); } // return result if (S.m_outputLanguage != OUTPUT_LANGUAGE.C) { SB.AppendLine("return " + FT.GetMangledName(S, gmv.Name) + "(gu, c);"); } return SB.ToString(); }
/// <summary> /// Returns the name of a partial geometric product function. /// /// Does not check whether this /// combination of groups actually produces any results (i.e., it may be that <c>g1 X g2 -> g3 = 0</c>, /// but in that case a name will still be returned. /// </summary> /// <param name="FT">Float type (used to mangle the name).</param> /// <param name="M">The metric (used for the name).</param> /// <param name="g1">Grade/group of argument 1.</param> /// <param name="g2">Grade/group of argument 2.</param> /// <param name="g3">Grade/group of result.</param> /// <returns>name of a partial geometric product function.</returns> public static string GetGPpartFunctionName(Specification S, G25.FloatType FT, G25.Metric M, int g1, int g2, int g3) { return FT.GetMangledName(S, "gp") + "_" + M.m_name + "_" + g1 + "_" + g2 + "_" + g3; }
/// <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}"); } }
/// <summary> /// Returns the code for applying a versor <c>V</c>to some multivector <c>M</c> (V M / V). /// The code is composed of calls to functions generated by <c>WriteGmvGpParts()</c>. /// /// This function does not explicitly use the geometric product parts code, but makes calls /// to the geometric product and the reverse/versor inverse. As such it generates dependencies /// on <c>gp</c>, <c>reverse</c>, <c>versorInverse</c> and <c>grade</c>. /// /// Three types of code can be generated, depending on the value of /// argument <c>T</c>: /// - <c>REVERSE</c>: the versor is unit, so the reverse can be used. /// - <c>INVERSE</c>: the versor inverse is used to compute the inverse. /// - <c>EXPLICIT_INVERSE</c>: the inverse is explicitly provided. /// /// The returned code is only the body. The function declaration is not included. /// </summary> /// <param name="S">Specification of algebra (used for output language).</param> /// <param name="cgd">Used for resolving dependencies.</param> /// <param name="FT">Floating point type.</param> /// <param name="M">Metric type used in the geometric products.</param> /// <param name="T">The product (e.g., geometric, outer, etc).</param> /// <param name="FAI">Info about function arguments. All arguments must be general multivectors.</param> /// <param name="resultName">Name of variable where the result goes (in the generated code).</param> /// <returns>code for the requested product type.</returns> public static string GetVersorApplicationCode(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, ApplyVersorTypes T, G25.CG.Shared.FuncArgInfo[] FAI, String resultName) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); // get geometric product function string gpFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "gp", new String[] { gmv.Name, gmv.Name }, FT, M.m_name); // get reverse or inverse function string invFuncName = null; if ((T == ApplyVersorTypes.INVERSE) || (T == ApplyVersorTypes.REVERSE)) { string inputFuncName = (T == ApplyVersorTypes.INVERSE) ? "versorInverse" : "reverse"; invFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, inputFuncName, new string[] { gmv.Name }, FT, (T == ApplyVersorTypes.INVERSE) ? M.m_name : null); } // get grade function string gradeFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, G25.CG.Shared.CANSparts.EXTRACT_GRADE, new String[] { gmv.Name, G25.GroupBitmapType.GROUP_BITMAP }, FT, null); // get string to be used for grade extraction string gradeUsageString; string bgu; if (S.OutputC()) { bgu = FAI[1].Name + "->gu"; } else if (S.OutputCSharpOrJava()) { bgu = FAI[1].Name + ".to_" + FAI[1].MangledTypeName + "().gu()"; } else { bgu = FAI[1].Name + ".gu()"; } string groupBitmapType = (S.OutputCSharp() ? "GroupBitmap" : "int"); if (!gmv.IsGroupedByGrade(S.m_dimension)) { SB.AppendLine(groupBitmapType + " gradeUsageBitmap;"); gradeUsageString = "gradeUsageBitmap"; } else { gradeUsageString = bgu; /*if (S.OutputC()) gradeUsageString = FAI[1].Name + "->gu"; else gradeUsageString = FAI[1].Name + ".gu()";*/ } // select grade parts! StringBuilder gradeUsageCode = new StringBuilder(); if (!gmv.IsGroupedByGrade(S.m_dimension)) { string groupBitmapStr = (S.OutputCSharpOrJava() ? ("GroupBitmap.") : ""); gradeUsageCode.Append(gradeUsageString + " = "); for (int g = 0; g <= S.m_dimension; g++) { if (g > 0) gradeUsageCode.Append(" | "); gradeUsageCode.Append("(((" + bgu + " & " + groupBitmapStr + "GRADE_" + g + ") != 0) ? " + groupBitmapStr + "GRADE_" + g + " : 0)"); } gradeUsageCode.AppendLine(";"); } if (S.OutputC()) { // get name of inverse, decl tmp variable for inverse if required string inverseInputName; if (T == ApplyVersorTypes.EXPLICIT_INVERSE) inverseInputName = FAI[2].Name; else if (T == ApplyVersorTypes.INVERSE) { inverseInputName = "&inv"; SB.AppendLine(FT.GetMangledName(S, gmv.Name) + " inv; /* temp space for reverse */"); } else // (T == ApplyVersorTypes.REVERSE) { inverseInputName = "&rev"; SB.AppendLine(FT.GetMangledName(S, gmv.Name) + " rev; /* temp space for reverse */"); } // get temp space for input * object SB.AppendLine(FT.GetMangledName(S, gmv.Name) + " tmp, tmp2; /* temp variables */"); // compute inverse or reverse, if required if ((T == ApplyVersorTypes.INVERSE) || (T == ApplyVersorTypes.REVERSE)) { SB.AppendLine(invFuncName + "(" + inverseInputName + ", " + FAI[0].Name + "); /* compute inverse or reverse */"); } // compute input * object SB.AppendLine(gpFuncName + "(&tmp, " + FAI[0].Name + ", " + FAI[1].Name + "); /* compute geometric product " + FAI[0].Name + " " + FAI[1].Name + " */"); // compute (input * object) * inverse SB.AppendLine(gpFuncName + "(&tmp2, &tmp, " + inverseInputName + "); /* compute geometric product (" + FAI[0].Name + " " + FAI[1].Name + ") " + inverseInputName + " */"); // select grade parts! SB.AppendLine(gradeUsageCode.ToString()); SB.AppendLine(gradeFuncName + "(" + resultName + ", &tmp2, " + gradeUsageString + "); /* ditch grade parts which were not in " + FAI[1].Name + " */"); } // end of 'C' version else // C++ version { if (gradeUsageCode.Length > 0) SB.AppendLine(gradeUsageCode.ToString()); string inverseCode = ((T == ApplyVersorTypes.INVERSE) || (T == ApplyVersorTypes.REVERSE)) ? (invFuncName + "(" + FAI[0].Name + ")") : FAI[2].Name; SB.AppendLine("return " + gradeFuncName + "(" + gpFuncName + "(" + gpFuncName + "(" + FAI[0].Name + ", " + FAI[1].Name + "), " + inverseCode + "), " + gradeUsageString + ");"); } return SB.ToString(); }
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(); }
public static string GetCompressCode(Specification S, G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool resultIsScalar, string GUstr) { if ((GUstr == null) || (GUstr.Length == 0)) { GUstr = ((1 << S.m_GMV.NbGroups) - 1).ToString(); } StringBuilder SB = new StringBuilder(); if (resultIsScalar) { SB.AppendLine("return c[0];"); } else { string funcName = (S.OutputC()) ? FT.GetMangledName(S, "compress") : FT.GetMangledName(S, S.m_GMV.Name) + "_compress"; if (S.m_outputLanguage != OUTPUT_LANGUAGE.C) SB.Append("return "); SB.Append(funcName + "(c, "); if (S.OutputC()) SB.Append(resultName + "->c, &(" + resultName + "->gu), "); SB.AppendLine(FT.DoubleToString(S, 0.0) + ", " + GUstr + ");"); } return SB.ToString(); }
/// <summary> /// Returns the name of a partial GOM-GMV application function. /// </summary> /// <param name="FT">Float type (used for mangled name).</param> /// <param name="srcGroup">Grade/group of input.</param> /// <param name="dstGroup">Grade/group of output.</param> public static string GetGomPartFunctionName(Specification S, G25.FloatType FT, int srcGroup, int dstGroup) { return FT.GetMangledName(S, "applyGomGmv") + "_" + srcGroup + "_" + dstGroup; }