public Converter(Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F) { m_specification = S; m_cgd = cgd; m_fgs = F; m_fgs.InitArgumentPtrFromTypeNames(S); }
} // end of WriteSetCopy() /// <summary> /// Writes a function to copy the value of one SMV struct to another with a different floating point type, for all combinations of floating point types. /// </summary> /// <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> public static void WriteSetCopyCrossFloat(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType dstFT, G25.SMV smv) { foreach (G25.FloatType srcFT in S.m_floatTypes) { if (srcFT.type == dstFT.type) { continue; } cgd.m_defSB.AppendLine(""); //string srcClassName = srcFT.GetMangledName(smv.Name); //string dstClassName = dstFT.GetMangledName(S, smv.Name); string funcName = GMV.GetSetFuncName(S); bool mustCast = dstFT.MustCastIfAssigned(S, srcFT); G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { smv.Name }, null, new String[] { srcFT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; int nbArgs = 1; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, srcFT, null, computeMultivectorValue); RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, FAI[0].Name, FAI[0].Pointer); string dstName = G25.CG.Shared.SmvUtil.THIS; bool dstPtr = false; bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, null, FAI, dstFT, mustCast, smv, dstName, dstPtr, value); } } // end of WriteSetCopyCrossFloat()
private static string GetComment(Specification S, bool declOnly, G25.fgs FGS, G25.Operator op, G25.FloatType FT, bool assign) { StringBuilder SB = new StringBuilder(); if ((S.OutputCpp()) && op.IsUnaryInPlace()) { if (op.IsPrefix) { SB.Append("returns (" + FGS.ArgumentVariableNames[0] + " = " + FGS.OutputName + "(" + FGS.ArgumentVariableNames[0] + "))"); } else { SB.Append("returns input value of " + FGS.ArgumentVariableNames[0] + ", but sets " + FGS.ArgumentVariableNames[0] + " to " + FGS.OutputName + "(" + FGS.ArgumentVariableNames[0] + ")"); } } else if (assign) { SB.Append("returns (" + FGS.ArgumentVariableNames[0] + " = " + FGS.OutputName + "(" + FGS.ArgumentVariableNames[0]); SB.Append(", " + FGS.ArgumentVariableNames[1]); SB.Append("))"); } else { SB.Append("returns " + FGS.OutputName + "(" + FGS.ArgumentVariableNames[0]); if (op.IsBinary()) { SB.Append(", " + FGS.ArgumentVariableNames[1]); } SB.Append(")"); } return(SB.ToString()); }
private static string GetXMLstring(Specification S, G25.fgs F, FuncArgInfo[] FAI) { // no return forced type in XML string returnTypeName = null; // get placeholder arguments for XML string[] argumentTypeNames = new string[FAI.Length]; for (int i = 0; i < FAI.Length; i++) { argumentTypeNames[i] = GetPlaceHolderString(i); } // use a single float type only in XML string[] floatNames = new string[1] { FAI[0].FloatType.type }; // get a copy of F, but put insert placeholders for the typenames G25.fgs tmpF = new G25.fgs(F.Name, F.OutputName, returnTypeName, argumentTypeNames, F.ArgumentVariableNames, floatNames, F.MetricName, F.Comment, F.Options); string XMLstr = XML.FunctionToXmlString(S, tmpF); return(XMLstr); }
protected Dictionary <string, string> m_funcName = new Dictionary <string, string>(); ///< generated function name with full mangling, etc /// <summary> /// Checks if this FunctionGenerator can implement a certain function. /// </summary> /// <param name="S">The specification of the algebra.</param> /// <param name="F">The function to be implemented.</param> /// <returns>true if 'F' can be implemented</returns> public override bool CanImplement(Specification S, G25.fgs F) { //String type F.GetArgumentTypeName(0, S.m_GMV.Name); return((F.Name == "equals") && (F.MatchNbArguments(NB_ARGS)) && G25.CG.Shared.Functions.NotMixSmvGmv(S, F, NB_ARGS, S.m_GMV.Name) && G25.CG.Shared.Functions.NotUseOm(S, F, NB_ARGS, S.m_GMV.Name)); }
/// <summary> /// Prints out a report of all the missing dependencies recorded in m_missingDependencies. /// /// The report consists of XML that can be added directly to the specification XML. /// </summary> /// <param name="S"></param> public void PrintMissingDependencies(Specification S) { lock (m_missingDependencies) { if (m_missingDependencies.Count != 0) { System.Console.WriteLine(""); System.Console.WriteLine("Missing dependencies detected."); System.Console.WriteLine("Add the following XML to the specification to fix them:"); System.Console.WriteLine(""); // sort missing deps (this is nicer for the user who pastes them into the specification XML G25.fgs[] D = new G25.fgs[m_missingDependencies.Count]; { int idx = 0; foreach (KeyValuePair<G25.fgs, G25.fgs> KVP in m_missingDependencies) D[idx++] = KVP.Key; Array.Sort(D); } // print deps to console: for (int i = 0; i < D.Length; i++) { System.Console.WriteLine(XML.FunctionToXmlString(S, D[i])); } } } } // end of PrintMissingDependencies
/// <summary> /// Writes a function to set an SMV struct to zero, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</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; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) { continue; } string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setZero"; bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", null, null, new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to zero */"); string returnVarName = null; bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", returnVarName, funcName, returnArgument, null, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, new RefGA.Multivector(0.0)); } } } // end of WriteSetZero()
/// <summary> /// Write the declaration/definition of 'F' to 'm_declSB', 'm_defSB' and 'm_inlineDefSB', /// taking into account parameters specified in specification 'S'. /// </summary> public override void WriteFunction() { foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); bool computeMultivectorValue = true; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, m_specification.m_GMV.Name, computeMultivectorValue); // comment Comment comment = new Comment(m_fgs.AddUserComment("Returns " + FAI[0].TypeName + (IsAdd(m_fgs) ? " + " : " - ") + FAI[1].TypeName + ".")); // if scalar or specialized: generate specialized function if (m_gmvFunc) { m_funcName[FT.type] = G25.CG.Shared.GmvCASNparts.WriteAddSubHpFunction(m_specification, m_cgd, FT, FAI, m_fgs, comment, IsAdd(m_fgs) ? G25.CG.Shared.CANSparts.ADD_SUB_HP_TYPE.ADD : G25.CG.Shared.CANSparts.ADD_SUB_HP_TYPE.SUB); } else { // write simple specialized function: // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, m_fgs, FAI); m_funcName[FT.type] = CF.OutputName; // write out the function: G25.CG.Shared.Functions.WriteSpecializedFunction(m_specification, m_cgd, CF, FT, FAI, m_returnValue, comment); } } } // end of WriteFunction
} // end of CompleteFGS() /// <summary> /// Writes the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'. /// </summary> public override void WriteFunction() { foreach (String floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); bool computeMultivectorValue = true; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, m_specification.m_GMV.Name, computeMultivectorValue); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, m_fgs, FAI); m_funcName[FT.type] = CF.OutputName; Comment comment; if (IsDistance(m_fgs)) { comment = new Comment(m_fgs.AddUserComment("Returns distance of two conformal points.")); } else { comment = new Comment(m_fgs.AddUserComment("Returns distance squared of two conformal points.")); } // write out the function: G25.CG.Shared.Functions.WriteSpecializedFunction(m_specification, m_cgd, CF, FT, FAI, m_returnValue, comment); } } // end of WriteFunction
/// <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)); }
} // end of WriteSetArray() /// <summary> /// Writes a function to copy the value of one SMV struct to another, for all floating point types. /// </summary> /// <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> public static void WriteCopy(Specification S, G25.CG.Shared.CGdata cgd) { //StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { // if (smv.NbNonConstBasisBlade == 0) continue; string className = FT.GetMangledName(S, smv.Name); string funcName = className + "::set"; bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { smv.Name }, null, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; int nbArgs = 1; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue); RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, FAI[0].Name, FAI[0].Pointer); string dstName = G25.CG.Shared.SmvUtil.THIS; bool dstPtr = true; bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, value); } } } // end of WriteCopy()
/// <summary> /// Writes a function to copy the value of one SMV struct to another, for all floating point types. /// </summary> /// <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> public static void WriteCopy(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; String typeName = FT.GetMangledName(S, smv.Name); String funcName = typeName + "_copy"; bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { smv.Name }, null, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); int nbArgs = 1; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue); declSB.AppendLine("/** Copies " + typeName + ": " + FAI[0].Name + " = " + returnArgument.Name + " */"); RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, FAI[0].Name, FAI[0].Pointer); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, value); } } }
/// <summary> /// Writes the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'. /// </summary> public override void WriteFunction() { foreach (String floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); bool computeMultivectorValue = true; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, m_specification.m_GMV.Name, computeMultivectorValue); // comment Comment comment = new Comment( m_fgs.AddUserComment("Returns outer product of " + FAI[0].TypeName + " and " + FAI[1].TypeName + ".")); // if scalar or specialized: generate specialized function if (m_gmvFunc) { m_funcName[FT.type] = G25.CG.Shared.GmvGpParts.WriteGMVgpFunction(m_specification, m_cgd, FT, m_specification.GetMetric(XML.XML_DEFAULT), FAI, m_fgs, comment, G25.CG.Shared.GPparts.ProductTypes.OUTER_PRODUCT); } else {// write simple specialized function: // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, m_fgs, FAI); m_funcName[FT.type] = CF.OutputName; // write out the function: G25.CG.Shared.Functions.WriteSpecializedFunction(m_specification, m_cgd, CF, FT, FAI, m_returnValue, comment); } } } // end of WriteFunction
/// <summary> /// Returns the name of a generated function (for example <c>gp_mv_mv</c>). /// The function is found by looking through all G25.FGS in the Specification. /// /// If the function is not found, a fictional name is returned, i.e. "missingFunction_" + functionName. /// This name will then show up in the generated code, which will not compile as a result. /// /// 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="functionName">Basic name of the function to be found.</param> /// <param name="argumentTypes">Names of the arguments types (not mangled).</param> /// <param name="returnTypeName">Name of the return type (can be null or "" for default return type).</param> /// <param name="FT">Floating point type.</param> /// <param name="metricName">(optional, can be null for don't care)</param> /// <returns>The mangled name of the function.</returns> public static string GetDependency(Specification S, CGdata cgd, string functionName, string[] argumentTypes, string returnTypeName, G25.FloatType FT, string metricName) { // bool returnTrueName = dependent on cgd.mode try { return(GetFunctionName(S, functionName, argumentTypes, returnTypeName, FT, metricName)); } catch (DependencyException) { // function not found, return a fictional name, and remember dependency G25.fgs F = null; { // get name of dep, and make sure it does not get mangled string outputName = functionName + cgd.GetDontMangleUniqueId(); if (returnTypeName != null) { outputName = outputName + "_returns_" + returnTypeName; } // add dependency to list of missing deps: string[] argVarNames = null; Dictionary <String, String> options = null; string comment = null; G25.fgs tmpF = new G25.fgs(functionName, outputName, returnTypeName, argumentTypes, argVarNames, new String[] { FT.type }, metricName, comment, options); F = cgd.AddMissingDependency(S, tmpF); } return(cgd.m_dependencyPrefix + F.OutputName); } } // end of GetDependency()
/// <summary> /// Checks if this FunctionGenerator can implement a certain function. /// </summary> /// <param name="S">The specification of the algebra.</param> /// <param name="F">The function to be implemented.</param> /// <returns>true if 'F' can be implemented</returns> public override bool CanImplement(Specification S, G25.fgs F) { return(((F.Name == "hp") || (F.Name == "ihp")) && (F.MatchNbArguments(NB_ARGS)) && G25.CG.Shared.Functions.NotMixScalarGmv(S, F, NB_ARGS, S.m_GMV.Name) && G25.CG.Shared.Functions.NotMixSmvGmv(S, F, NB_ARGS, S.m_GMV.Name) && G25.CG.Shared.Functions.NotUseOm(S, F, NB_ARGS, S.m_GMV.Name)); }
/// <summary> /// Writes a shortcut for 'type', 'fgs'. /// </summary> /// <param name="SB">Where the code goes.</param> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Not used yet.</param> /// <param name="FT">Float point type of 'type'.</param> /// <param name="type">The type for which shortcuts should be written.</param> /// <param name="fgs"></param> /// <param name="FAI"></param> public static void WriteFunctionShortcut(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.VariableType type, G25.fgs fgs, FuncArgInfo[] FAI) { int nbTabs = 1; FuncArgInfo[] tailFAI = getTail(FAI); string shortcutCall = getShortcutCall(S, fgs, tailFAI); SB.AppendLine(""); // output comment new Comment("shortcut to " + shortcutCall).Write(SB, S, nbTabs); bool inline = false; bool staticFunc = false; string returnType = FT.GetMangledName(S, fgs.ReturnTypeName); FuncArgInfo returnArgument = null; SB.Append('\t', nbTabs); Functions.WriteDeclaration(SB, S, cgd, inline, staticFunc, returnType, fgs.OutputName, returnArgument, tailFAI); SB.AppendLine(" {"); SB.Append('\t', nbTabs + 1); SB.Append("return "); SB.Append(shortcutCall); SB.AppendLine(";"); SB.Append('\t', nbTabs); SB.AppendLine("}"); }
/// <summary> /// Checks if this FunctionGenerator can implement a certain function. /// </summary> /// <param name="S">The specification of the algebra.</param> /// <param name="F">The function to be implemented.</param> /// <returns>true if 'F' can be implemented</returns> public override bool CanImplement(Specification S, G25.fgs F) { string arg1Type = F.GetArgumentTypeName(0, S.m_GMV.Name); return((IsIncrement(F) || IsDecrement(F)) && (F.MatchNbArguments(1) && (S.IsSpecializedMultivectorName(arg1Type) || (arg1Type == S.m_GMV.Name)))); }
/// <summary> /// Writes a increment or decrement function. /// (not based on CASN parts code, but put here anyway). /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="increment"></param> public static string WriteIncrementFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, bool increment) { // setup instructions System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = G25.CG.Shared.CANSparts.GetIncrementCode(S, cgd, FT, FAI, fgs.RETURN_ARG_NAME, increment); // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = FT.GetMangledName(S, S.m_GMV.Name); G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, CF, -1, FT, S.m_GMV.Name, false); // false = compute value } // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); return(CF.OutputName); }
/// <summary> /// Writes the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'. /// </summary> public override void WriteFunction() { const int nbArgs = 1; foreach (string floatName in m_fgs.FloatNames) { FloatType FT = m_specification.GetFloatType(floatName); bool computeMultivectorValue = true; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, nbArgs, FT, m_specification.m_GMV.Name, computeMultivectorValue); // comment Comment comment = new Comment( m_fgs.AddUserComment("Returns " + m_fgs.Name + " of " + FAI[0].TypeName + " using " + m_G25M.m_name + " metric.")); // if scalar or specialized: generate specialized function if (m_gmvFunc) { bool dual = IsDual(m_fgs); m_funcName[FT.type] = G25.CG.Shared.GmvDualParts.WriteDualFunction(m_specification, m_cgd, FT, m_G25M, FAI, m_fgs, comment, dual); } else {// write simple specialized function: // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, m_fgs, FAI); m_funcName[FT.type] = CF.OutputName; // write out the function: G25.CG.Shared.Functions.WriteSpecializedFunction(m_specification, m_cgd, CF, FT, FAI, m_returnValue, comment); } } } // end of WriteFunction
/// <summary> /// Converts the name of the function to a RefGA.BasisBlade.InnerProductType. /// </summary> /// <param name="S"></param> /// <param name="F">Function (used for <c>F.name</c>).</param> /// <returns>identifier for inner product type.</returns> public static RefGA.BasisBlade.InnerProductType GetIpType(Specification S, G25.fgs F) { if (IsHip(F)) { return(RefGA.BasisBlade.InnerProductType.HESTENES_INNER_PRODUCT); } else if (IsMHip(F)) { return(RefGA.BasisBlade.InnerProductType.MODIFIED_HESTENES_INNER_PRODUCT); } else if (IsLc(F)) { return(RefGA.BasisBlade.InnerProductType.LEFT_CONTRACTION); } else if (IsRc(F)) { return(RefGA.BasisBlade.InnerProductType.RIGHT_CONTRACTION); } else if (IsSp(F)) { return(RefGA.BasisBlade.InnerProductType.SCALAR_PRODUCT); } else { throw new G25.UserException("Unknown inner product type: " + F.Name, XML.FunctionToXmlString(S, F)); } }
/// <summary> /// Converts the name of the function to a human readable name. /// </summary> /// <param name="S"></param> /// <param name="F">Function (used for <c>F.name</c>).</param> /// <returns>Human readable version of Function <c>F.name</c>.</returns> public static String GetIpName(Specification S, G25.fgs F) { if (IsHip(F)) { return("Hestenes inner product"); } else if (IsMHip(F)) { return("Modified Hestenes inner product"); } else if (IsLc(F)) { return("left contraction"); } else if (IsRc(F)) { return("right contraction"); } else if (IsSp(F)) { return("scalar product"); } else { throw new G25.UserException("G25.CG.C.IP.GetIpName(): unknown inner product type: " + F.Name, XML.FunctionToXmlString(S, F)); } }
/// <summary> /// Writes a zero or equality test function for general multivectors, /// based on CASN parts code. /// </summary> /// <param name="S"></param> /// <param name="cgd"></param> /// <param name="FT"></param> /// <param name="FAI"></param> /// <param name="F"></param> /// <param name="comment"></param> /// <param name="writeZero">When true, a function to test for zero is written.</param> /// <returns>full (mangled) name of generated function</returns> public static string WriteEqualsOrZeroOrGradeBitmapFunction(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, G25.fgs F, Comment comment, G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE funcType) { // setup instructions System.Collections.Generic.List <G25.CG.Shared.Instruction> I = new System.Collections.Generic.List <G25.CG.Shared.Instruction>(); int nbTabs = 1; // write this function: string code = ""; if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.EQUALS) { code = G25.CG.Shared.CANSparts.GetEqualsCode(S, cgd, FT, FAI); } else if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.ZERO) { code = G25.CG.Shared.CANSparts.GetZeroCode(S, cgd, FT, FAI); } else if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.GRADE_BITMAP) { code = G25.CG.Shared.CANSparts.GetGradeBitmapCode(S, cgd, FT, FAI); } // add one instruction (verbatim code) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, code)); // because of lack of overloading, function names include names of argument types G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(S, FT, F, FAI); // setup return type and argument: string returnTypeName = null; if (S.OutputC()) { returnTypeName = G25.IntegerType.INTEGER; } else { if (funcType == G25.CG.Shared.CANSparts.EQUALS_ZERO_GRADEBITMAP_TYPE.GRADE_BITMAP) { returnTypeName = G25.IntegerType.INTEGER; } else { returnTypeName = CodeUtil.GetBoolType(S); } } G25.CG.Shared.FuncArgInfo returnArgument = null; // write function bool inline = false; // never inline GMV functions bool staticFunc = Functions.OutputStaticFunctions(S); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, returnTypeName, CF.OutputName, returnArgument, FAI, I, comment); return(CF.OutputName); }
/// <summary> /// Return true if argument 'argIdx' in 'F' is a multivector type. /// </summary> /// <param name="S">Specification of algebra</param> /// <param name="F">Function specification</param> /// <param name="argIdx">Index of argument. If out of range, false is returned.</param> /// <returns>true if argument 'argIdx' in 'F' is an multivector type.</returns> public static bool IsSmv(Specification S, G25.fgs F, int argIdx) { if (argIdx >= F.NbArguments) { return(false); } return(S.IsSpecializedMultivectorName(F.GetArgumentTypeName(argIdx, ""))); }
/// <summary> /// Return true if argument 'argIdx' in 'F' is a specialized outermorphism type. /// </summary> /// <param name="S">Specification of algebra</param> /// <param name="F">Function specification</param> /// <param name="argIdx">Index of argument. If out of range, false is returned.</param> /// <returns>true if argument 'argIdx' in 'F' is an outermorphism type.</returns> public static bool IsSom(Specification S, G25.fgs F, int argIdx) { if (argIdx >= F.NbArguments) { return(false); } return(S.IsSpecializedOutermorphismName(F.GetArgumentTypeName(argIdx, ""))); }
} // end of WriteSet() /// <summary> /// Writes a function to set an SMV struct to an array of specified coordinates, for all floating point types. /// </summary> /// <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> 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; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) { continue; } string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setArray"; bool mustCast = false; string[] argTypename = new string[1] { FT.type }; string[] argName = new string[1] { "A" }; System.Collections.ArrayList L = new System.Collections.ArrayList(); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); //argTypename[i] = FT.type; String coordStr = argName[0] + "[" + i + "]"; //argName[i] = coordStr; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr)); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); F.SetArgumentPtr(0, true); // first argument is a pointer to array bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); int nbArgs = 1; // one array of coordinates G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to specified coordinates */"); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, mvValue); } } } // end of WriteSetArray()
/// <summary> /// Constructs an array of func arg info for all arguments of an G25.fgs. /// </summary> /// <param name="S">Used for retrieving the G25.VariableType of 'm_typeName'.</param> /// <param name="F">Function for which you want an array of FuncArgInfo.</param> /// <param name="nbArgs">Default number of arguments. (the user may not specified arguments and then a default is used).</param> /// <param name="FT">Floating point type of arguments.</param> /// <param name="defaultTypeName">When the user does not specify arguments, this is the default type used.</param> /// <param name="computeMultivectorValue">Set to true to expand all multivector values to symbolic RefGA.Multivectors.</param> /// <returns>Array of FuncArgInfo describing the arguments of 'F'.</returns> public static FuncArgInfo[] GetAllFuncArgInfo(G25.Specification S, G25.fgs F, int nbArgs, G25.FloatType FT, string defaultTypeName, bool computeMultivectorValue) { FuncArgInfo[] FAI = new FuncArgInfo[nbArgs]; for (int i = 0; i < nbArgs; i++) { FAI[i] = new FuncArgInfo(S, F, i, FT, defaultTypeName, computeMultivectorValue); } return(FAI); }
public static void WriteSetCopy(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) { declSB.AppendLine(); } defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_set"); bool mustCast = false; const int NB_ARGS = 1; string srcName = "src"; bool srcPtr = S.OutputC(); G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { som.Name }, new String[] { srcName }, 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>(); { int nbTabs = 1; mustCast = false; 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.Multivector srcValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, srcName, srcPtr); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, srcValue, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Copies " + typeName + ".");; bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
/// <summary> /// Checks if this FunctionGenerator can implement a certain function. /// </summary> /// <param name="S">The specification of the algebra.</param> /// <param name="F">The function to be implemented.</param> /// <returns>true if 'F' can be implemented.</returns> public override bool CanImplement(Specification S, G25.fgs F) { int NB_ARGS = 2; return((IsAdd(F) || IsSubtract(F)) && (F.MatchNbArguments(NB_ARGS)) && G25.CG.Shared.Functions.NotMixSmvGmv(S, F, NB_ARGS, S.m_GMV.Name) && G25.CG.Shared.Functions.NotMixScalarGmv(S, F, NB_ARGS, S.m_GMV.Name) && G25.CG.Shared.Functions.NotUseOm(S, F, NB_ARGS, S.m_GMV.Name)); }
protected RefGA.Multivector m_returnValue; ///< returned value (symbolic multivector) /// <summary> /// Checks if this FunctionGenerator can implement a certain function. /// </summary> /// <param name="S">The specification of the algebra.</param> /// <param name="F">The function to be implemented.</param> /// <returns>true if 'F' can be implemented</returns> public override bool CanImplement(Specification S, G25.fgs F) { String arg1Type = F.GetArgumentTypeName(0, S.m_GMV.Name); return((F.Name == "sas") && (F.MatchNbArguments(3) && (S.IsSpecializedMultivectorName(arg1Type) || (arg1Type == S.m_GMV.Name)) && S.IsFloatType(F.GetArgumentTypeName(1, S.m_GMV.Name)) && S.IsFloatType(F.GetArgumentTypeName(2, S.m_GMV.Name)))); }
/// <summary> /// Writes generic function based on Instructions. /// /// The other WriteFunction() can figure out the return type automatically, so /// it is preferred over this more verbose version. /// </summary> /// <param name="S">Specification of algebra.</param> /// <param name="cgd">Results go into cgd.m_defSB, and so on</param> /// <param name="F">Function specification.</param> /// <param name="inline">When true, the code is inlined.</param> /// <param name="staticFunc">Static function?</param> /// <param name="returnType">The type to return (String, can also be e.g. <c>"code"</c>.</param> /// <param name="functionName">Name of generated function.</param> /// <param name="returnArgument">For use with the 'C' language, an extra argument can be used to return results.</param> /// <param name="arguments">Arguments of function (any `return argument' used for the C language is automatically generated).</param> /// <param name="instructions">List of GA-instructions which make up the function.</param> /// <param name="comment">Comment to go into generated code (used for decl only).</param> /// <param name="writeDecl">When false, no declaration is written</param> public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, System.Collections.Generic.List <Instruction> instructions, Comment comment, bool writeDecl) { // where the definition goes: StringBuilder defSB = (inline) ? cgd.m_inlineDefSB : cgd.m_defSB; // declaration: if (writeDecl) { if (comment != null) { comment.Write(cgd.m_declSB, S, 0); } bool inlineDecl = false; // never put inline keywords in declaration WriteDeclaration(cgd.m_declSB, S, cgd, inlineDecl, staticFunc, returnType, functionName, returnArgument, arguments); cgd.m_declSB.AppendLine(";"); } if (S.OutputCSharpOrJava()) { comment.Write(defSB, S, 0); } WriteDeclaration(defSB, S, cgd, inline, staticFunc, returnType, functionName, returnArgument, arguments); // open function defSB.AppendLine(""); defSB.AppendLine("{"); // add extra instruction for reporting usage of SMVs if (S.m_reportUsage) { instructions.Insert(0, ReportUsage.GetReportInstruction(S, F, arguments)); } if (returnArgument != null) { int nbTabs = 1; instructions.Add(new VerbatimCodeInstruction(nbTabs, "return " + returnArgument.Name + ";")); } // write all instructions foreach (Instruction I in instructions) { I.Write(defSB, S, cgd); } // close function defSB.AppendLine("}"); } // end of WriteFunction()
/// <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; }
} // end of WriteFunction() public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string returnType, string functionName, FuncArgInfo returnArgument, FuncArgInfo[] arguments, System.Collections.Generic.List <Instruction> instructions, Comment comment) { bool writeDecl = S.OutputCppOrC(); WriteFunction(S, cgd, F, inline, staticFunc, returnType, functionName, returnArgument, arguments, instructions, comment, writeDecl); }
public static void WriteSetMatrix(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som, bool transpose) { int NB_ARGS = 1; string[] argTypes = new string[NB_ARGS]; string[] argNames = new string[NB_ARGS]; argTypes[0] = FT.type; argNames[0] = "M"; // construct image values RefGA.Multivector[] imageValue = new RefGA.Multivector[som.DomainVectors.Length]; for (int d = 0; d < som.DomainVectors.Length; d++) { //imageValue[d] = RefGA.Multivector.ZERO; RefGA.BasisBlade[] IV = new RefGA.BasisBlade[som.RangeVectors.Length]; for (int r = 0; r < som.RangeVectors.Length; r++) { int matrixIdx = (transpose) ? (d * som.RangeVectors.Length + r) : (r * som.DomainVectors.Length + d); string entryName = argNames[0] + "[" + matrixIdx + "]"; IV[r] = new RefGA.BasisBlade(som.RangeVectors[r].bitmap, 1.0, entryName); } imageValue[d] = new RefGA.Multivector(IV); } string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_setMatrix"); if (transpose) funcName = funcName + "Transpose"; //argNames[0] = "*" + argNames[0]; // quick hack: add pointer to name instead of type! 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); if (S.OutputCppOrC()) F.m_argumentPtr[0] = true; else F.m_argumentArr[0] = true; 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, imageValue[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 a " + (transpose ? "transposed " : "") + "matrix."); bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
/// <summary> /// Writes a function to set an SOM struct/class to identity /// </summary> /// <param name="S">Used for basis vector names and output language.</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="som"></param> public static void WriteSetIdentity(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) declSB.AppendLine(); defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "setIdentity", "_setIdentity"); bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", null, null, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; 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>(); { int nbTabs = 1; mustCast = false; string valueName = (S.OutputC()) ? G25.fgs.RETURN_ARG_NAME : SmvUtil.THIS; bool valuePtr = S.OutputCppOrC(); bool declareValue = 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]; I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, new RefGA.Multivector(som.DomainForGrade(g)[c]), valueName, valuePtr, declareValue)); } } } Comment comment = new Comment("Sets " + typeName + " to identity."); bool writeDecl = S.OutputC(); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, new G25.CG.Shared.FuncArgInfo[0], I, comment, writeDecl); }
public static void WriteSetCopy(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.SOM som) { StringBuilder declSB = cgd.m_declSB; StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; if (S.OutputC()) declSB.AppendLine(); defSB.AppendLine(); string typeName = FT.GetMangledName(S, som.Name); string funcName = GetFunctionName(S, typeName, "set", "_set"); bool mustCast = false; const int NB_ARGS = 1; string srcName = "src"; bool srcPtr = S.OutputC(); G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { som.Name }, new String[] { srcName }, 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>(); { int nbTabs = 1; mustCast = false; 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.Multivector srcValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, srcName, srcPtr); I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smvOM, FT, mustCast, srcValue, dstName, dstPtr, declareDst)); } } } Comment comment = new Comment("Copies " + typeName + "."); ; bool writeDecl = (S.OutputC()); bool staticFunc = false; G25.CG.Shared.Functions.WriteFunction(S, cgd, F, S.m_inlineSet, staticFunc, "void", funcName, returnArgument, FAI, I, comment, writeDecl); }
/// <summary> /// Writes a function to copy the value of one SMV struct to another, for all floating point types. /// </summary> /// <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> public static void WriteSetCopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv) { cgd.m_defSB.AppendLine(""); //string className = FT.GetMangledName(S, smv.Name); string funcName = GMV.GetSetFuncName(S); bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", new string[] { smv.Name }, null, new string[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; int nbArgs = 1; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue); RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, FAI[0].Name, FAI[0].Pointer); string dstName = G25.CG.Shared.SmvUtil.THIS; bool dstPtr = false; bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, value); }
/// <summary> /// Prints out a report of all the missing dependencies recorded in m_missingDependencies. /// /// The report consists of XML that can be added directly to the specification XML. /// </summary> /// <param name="S"></param> public void PrintMissingDependencies(Specification S) { lock (m_missingDependencies) { if (m_missingDependencies.Count != 0) { System.Console.WriteLine(""); System.Console.WriteLine("Missing dependencies detected."); System.Console.WriteLine("Add the following XML to the specification to fix them:"); System.Console.WriteLine(""); // sort missing deps (this is nicer for the user who pastes them into the specification XML G25.fgs[] D = new G25.fgs[m_missingDependencies.Count]; { int idx = 0; foreach (KeyValuePair<G25.fgs, G25.fgs> KVP in m_missingDependencies) D[idx++] = KVP.Key; Array.Sort(D); } // print deps to console: for (int i = 0; i < D.Length; i++) { System.Console.WriteLine(XML.FunctionToXmlString(S, D[i])); } } } }
/// <summary> /// Writes a function to set an SMV struct to a scalar coordinate, for all floating point types which have a non-constant scalar coordinate. /// </summary> /// <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> 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; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.GetElementIdx(RefGA.BasisBlade.ONE) < 0) continue; // if no scalar coordinate, continue string className = FT.GetMangledName(S, smv.Name); string funcName = className + "::set"; bool mustCast = false; System.Collections.ArrayList L = new System.Collections.ArrayList(); const int NB_COORDS = 1; string[] argTypename = new String[NB_COORDS]; string[] argName = new String[NB_COORDS]; { RefGA.BasisBlade B = RefGA.BasisBlade.ONE; argTypename[0] = FT.type; argName[0] = "scalarVal"; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, argName[0])); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; //G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_COORDS, FT, null, computeMultivectorValue); string dstName = G25.CG.Shared.SmvUtil.THIS; bool dstPtr = true; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, mvValue); } } }
/// <summary> /// Writes a function to set an SMV struct to an array of specified coordinates, for all floating point types. /// </summary> /// <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> public static void WriteSetArray(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; String className = FT.GetMangledName(S, smv.Name); String funcName = className + "::set"; bool mustCast = false; String[] argTypename = new String[2] { G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM, FT.type }; String[] argName = new String[2]{"co", "A"}; System.Collections.ArrayList L = new System.Collections.ArrayList(); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); String coordStr = argName[1] + "[" + i + "]"; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr)); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); F.SetArgumentPtr(1, true); // second argument is a pointer to array bool computeMultivectorValue = false; int NB_ARGS = 2; // enum + one array of coordinates G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, null, computeMultivectorValue); string dstName = G25.CG.Shared.SmvUtil.THIS; bool dstPtr = true; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, mvValue); } } }
/// <summary> /// Writes a function to set an SMV struct to specified coordinates, for all floating point types. /// </summary> /// <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> public static void WriteSet(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; string className = FT.GetMangledName(S, smv.Name); string funcName = className + "::set"; bool mustCast = false; System.Collections.ArrayList L = new System.Collections.ArrayList(); int NB_ARGS = 1 + smv.NbNonConstBasisBlade; string[] argTypename = new String[NB_ARGS]; string[] argName = new String[NB_ARGS]; argTypename[0] = G25.CG.Shared.SmvUtil.COORDINATE_ORDER_ENUM; argName[0] = "co"; for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); argTypename[i + 1] = FT.type; string coordStr = "_" + smv.GetCoordLangID(i, S, COORD_STORAGE.VARIABLES); argName[i + 1] = coordStr; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr)); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; //G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, null, computeMultivectorValue); string dstName = G25.CG.Shared.SmvUtil.THIS; bool dstPtr = true; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, "void", null, funcName, null, FAI, FT, mustCast, smv, dstName, dstPtr, mvValue); } } }
/// <summary> /// Writes a function to copy the value of one SMV struct to another with a different floating point type, for all combinations of floating point types. /// </summary> /// <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> public static void WriteCopyCrossFloat(Specification S, G25.CG.Shared.CGdata cgd) { StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB; defSB.AppendLine(""); foreach (G25.FloatType srcFT in S.m_floatTypes) { foreach (G25.FloatType dstFT in S.m_floatTypes) { if (srcFT.type == dstFT.type) continue; foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; //string srcClassName = srcFT.GetMangledName(smv.Name); string dstClassName = dstFT.GetMangledName(S, smv.Name); string funcName = dstClassName + "::set"; bool mustCast = dstFT.MustCastIfAssigned(S, srcFT); G25.fgs F = new G25.fgs(funcName, funcName, "", new String[] { smv.Name }, null, new String[] { srcFT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; int nbArgs = 1; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, srcFT, null, computeMultivectorValue); RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, FAI[0].Name, FAI[0].Pointer); string dstName = G25.CG.Shared.SmvUtil.THIS; bool dstPtr = true; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, "void", null, funcName, null, FAI, dstFT, mustCast, smv, dstName, dstPtr, value); } } } }
private static string GetXMLstring(Specification S, G25.fgs F, FuncArgInfo[] FAI) { // no return forced type in XML string returnTypeName = null; // get placeholder arguments for XML string[] argumentTypeNames = new string[FAI.Length]; for (int i = 0; i < FAI.Length; i++) { argumentTypeNames[i] = GetPlaceHolderString(i); } // use a single float type only in XML string[] floatNames = new string[1] { FAI[0].FloatType.type }; // get a copy of F, but put insert placeholders for the typenames G25.fgs tmpF = new G25.fgs(F.Name, F.OutputName, returnTypeName, argumentTypeNames, F.ArgumentVariableNames, floatNames, F.MetricName, F.Comment, F.Options); string XMLstr = XML.FunctionToXmlString(S, tmpF); return XMLstr; }
/// <summary> /// Writes a function to set a GOM struct according to vector images, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT">Float type.</param> /// <param name="matrixMode">When true, generates code for setting from matrix instead of vector images.</param> /// <param name="transpose">When this parameter is true and <c>matrixMode</c> is true, generates code for setting from transpose matrix.</param> public static void WriteSetVectorImages(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, bool matrixMode, bool transpose) { G25.GOM gom = S.m_GOM; // get the 'plan' on how to initialize all domain basis blades efficiently: uint[][][] plan = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsPlan(S, gom); double[][] signs = G25.CG.Shared.OMinit.ComputeOmInitFromVectorsSigns(S, gom, plan); // get range vector type G25.SMV rangeVectorType = G25.CG.Shared.OMinit.GetRangeVectorType(S, FT, cgd, gom); // setup array of arguments, function specification, etc int NB_ARGS = (matrixMode) ? 1 : gom.DomainVectors.Length; string[] argTypes = new string[NB_ARGS], argNames = new string[NB_ARGS]; RefGA.Multivector[] symbolicBBvalues = new RefGA.Multivector[1 << S.m_dimension]; // symbolic basis blade values go here if (matrixMode) { argTypes[0] = FT.type; argNames[0] = "M"; // convert matrix columns to symbolic Multivector values for (int d = 0; d < gom.DomainVectors.Length; d++) { RefGA.BasisBlade[] IV = new RefGA.BasisBlade[gom.RangeVectors.Length]; for (int r = 0; r < gom.RangeVectors.Length; r++) { int matrixIdx = (transpose) ? (d * gom.RangeVectors.Length + r) : (r * gom.DomainVectors.Length + d); string entryName = argNames[0] + "[" + matrixIdx + "]"; IV[r] = new RefGA.BasisBlade(gom.RangeVectors[r].bitmap, 1.0, entryName); } symbolicBBvalues[gom.DomainVectors[d].bitmap] = new RefGA.Multivector(IV); } } else { for (int d = 0; d < NB_ARGS; d++) { argTypes[d] = rangeVectorType.Name; argNames[d] = "i" + gom.DomainVectors[d].ToLangString(S.m_basisVectorNames); bool ptr = S.OutputC(); symbolicBBvalues[gom.DomainVectors[d].bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, rangeVectorType, argNames[d], ptr); } } // generate function names for all grades (basis blade names not included) string typeName = FT.GetMangledName(S, gom.Name); string[] funcNames = GetSetFromLowerGradeFunctionNames(S, FT, matrixMode); // setup instructions (for main function, and subfunctions for grades) List<G25.CG.Shared.Instruction> mainI = new List<G25.CG.Shared.Instruction>(); List<G25.CG.Shared.Instruction>[] bladeI = new List<G25.CG.Shared.Instruction>[1 << S.m_dimension]; { 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 < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { G25.SMVOM smvOM = gom.DomainSmvForGrade(g)[d]; RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d]; if (g > 1) { bladeI[domainBlade.bitmap] = new List<G25.CG.Shared.Instruction>(); string funcCallCode = funcNames[g] + "_" + d + "("; if (S.OutputC()) funcCallCode += G25.fgs.RETURN_ARG_NAME; funcCallCode += ");"; mainI.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, funcCallCode)); } // follow the plan RefGA.Multivector value = new RefGA.Multivector(signs[g][d]); uint[] P = plan[g][d]; for (int p = 0; p < P.Length; p++) value = RefGA.Multivector.op(value, symbolicBBvalues[P[p]]); // add instructions List<G25.CG.Shared.Instruction> I = (g == 1) ? mainI : bladeI[domainBlade.bitmap]; 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)); // store symbolic value symbolicBBvalues[domainBlade.bitmap] = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smvOM, dstName, dstPtr); } } } // output grade > 1 functions if (cgd.generateOmInitCode(FT.type)) { for (int g = 2; g < gom.Domain.Length; g++) { for (int d = 0; d < gom.DomainForGrade(g).Length; d++) { RefGA.BasisBlade domainBlade = gom.DomainForGrade(g)[d]; string funcName = funcNames[g] + "_" + d; G25.fgs F = new G25.fgs(funcName, funcName, "", new string[0], new string[0], new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options //F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue); int nbArgs = 0; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, S.m_GMV.Name, computeMultivectorValue); Comment comment; comment = new Comment("Sets grade " + g + " part of outermorphism matrix based on lower grade parts."); bool inline = false; // do not inline this potentially huge function bool staticFunc = false; bool writeDecl = S.OutputC(); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcName, returnArgument, FAI, bladeI[domainBlade.bitmap], comment, writeDecl); } } } { // output grade 1 function G25.fgs F = new G25.fgs(funcNames[1], funcNames[1], "", argTypes, argNames, new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); if (matrixMode) { F.m_argumentPtr[0] = S.OutputCppOrC(); F.m_argumentArr[0] = S.OutputCSharpOrJava(); } bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = null; if (S.OutputC()) returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, gom.Name, computeMultivectorValue); G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, NB_ARGS, FT, S.m_GMV.Name, computeMultivectorValue); Comment comment; if (!matrixMode) comment = new Comment("Sets " + typeName + " from images of the domain vectors."); else comment = new Comment("Sets " + typeName + " from a " + (transpose ? "transposed " : "") + "matrix"); bool inline = false; // do not inline this potentially huge function bool staticFunc = false; bool writeDecl = S.OutputC(); G25.CG.Shared.Functions.WriteFunction(S, cgd, F, inline, staticFunc, "void", funcNames[1], returnArgument, FAI, mainI, comment, writeDecl); } }
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); }
/// <summary> /// Writes a function to set an SMV struct to zero, for all floating point types. /// </summary> /// <param name="S">Used for basis vector names and output language.</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; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setZero"; bool mustCast = false; G25.fgs F = new G25.fgs(funcName, funcName, "", null, null, new string[] { FT.type }, null, null, null); // null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to zero */"); string returnVarName = null; bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", returnVarName, funcName, returnArgument, null, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, new RefGA.Multivector(0.0)); } } }
/// <summary> /// Writes the 'explicit' declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'. /// /// This function is called by the non-explicit version of the function. /// </summary> public void WriteExFunction(FloatType FT, string exFuncName) { G25.SMV smv = m_specification.GetSMV(m_SMVname); string randFuncCall = FT.DoubleToString(m_specification, -1.0) + " + " + FT.DoubleToString(m_specification, 2.0) + " * " + m_randomScalarFunc[FT.type] + "()"; // construct a explicit FGS string[] exArgumentTypeNames = new string[] { FT.type, FT.type, FT.type }; string[] exVariableNames = { m_fgs.ArgumentVariableNames[0], MINIMUM_NORM, LARGEST_COORDINATE }; fgs exFgs = new fgs(m_fgs.Name, m_fgs.OutputName, m_fgs.ReturnTypeName, exArgumentTypeNames, exVariableNames, m_fgs.FloatNames, m_fgs.MetricName, m_fgs.Comment, m_fgs.Options); exFgs.InitArgumentPtrFromTypeNames(m_specification); bool computeMultivectorValue = false; int nbArgs = 3; G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, exFgs, nbArgs, FT, FT.type, computeMultivectorValue); // because of lack of overloading, function names include names of argument types //G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, exFgs, FAI); G25.fgs CF = new G25.fgs(exFgs, exFuncName); //string exFuncName = funcName; // setup code to recursively call exFuncName string exFuncCall = ""; { StringBuilder exFuncCallSB = new StringBuilder(); if (!m_specification.OutputC()) exFuncCallSB.Append("return "); exFuncCallSB.Append(exFuncName); exFuncCallSB.Append("("); if (m_specification.OutputC()) { exFuncCallSB.Append(fgs.RETURN_ARG_NAME); exFuncCallSB.Append(", "); } for (int i = 0; i < exVariableNames.Length; i++) { if (i > 0) exFuncCallSB.Append(", "); exFuncCallSB.Append(exVariableNames[i]); } exFuncCallSB.AppendLine(");"); if (m_specification.OutputC()) { exFuncCallSB.AppendLine("return;"); } exFuncCall = exFuncCallSB.ToString(); } // generate a random SMV: RefGA.Multivector randomSMV = null; // get highest grade and bitmap of int hg = smv.HighestGrade(); // what is the highest non-zero grade of the type? uint bvBitmap = smv.BasisVectorBitmap(); // which basis vectors are used in the type? // setup random value to be returned if (InitWithRandomCoordinates(m_specification, smv)) { // set all coordinates to random values randomSMV = RefGA.Multivector.ZERO; for (int b = 0; b < smv.NbNonConstBasisBlade; b++) { randomSMV = RefGA.Multivector.Add(randomSMV, RefGA.Multivector.gp(new RefGA.Multivector(smv.NonConstBasisBlade(b)), new RefGA.Multivector("r" + smv.NonConstBasisBlade(b).ToLangString(m_specification.m_basisVectorNames)))); } } else { // set to geometric product of random vectors randomSMV = RefGA.Multivector.ONE; RefGA.Multivector randomVector; RefGA.BasisBlade[] B = new RefGA.BasisBlade[(int)RefGA.Bits.BitCount(bvBitmap)]; for (int g = 0; g < hg; g++) { int cnt = 0; for (int v = 0; v < m_specification.m_dimension; v++) { if ((bvBitmap & (uint)(1 << v)) != 0) { B[cnt] = new RefGA.BasisBlade((uint)(1 << v), 1.0, "r" + g + "_" + m_specification.m_basisVectorNames[v]); cnt++; } } randomVector = new RefGA.Multivector(B); randomSMV = RefGA.Multivector.gp(randomSMV, randomVector, m_G25M.m_metric); } // round value if required by metric if (m_G25M.m_round) randomSMV = randomSMV.Round(1e-14); } // setup instructions System.Collections.Generic.List<G25.CG.Shared.Instruction> I = new System.Collections.Generic.List<G25.CG.Shared.Instruction>(); { int nbTabs = 1; if (!smv.IsConstant()) { string smvTypeName = FT.GetMangledName(m_specification, m_SMVname); // SMV tmp; // double n, mul, lc; if (m_specification.OutputCppOrC()) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, smvTypeName + " tmp;")); else I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, smvTypeName + " tmp = new " + smvTypeName + "();")); I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, FT.type + " n, mul, lc;")); I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, CodeUtil.GetBoolType(m_specification) + " nullBlade;")); // double rCoord = randomValue(), ....; StringBuilder randSB = new StringBuilder(); randSB.Append(FT.type); randSB.Append(" "); if (InitWithRandomCoordinates(m_specification, smv)) { // random coordinates for (int b = 0; b < smv.NbNonConstBasisBlade; b++) { if (b > 0) randSB.Append(", "); randSB.Append("r" + smv.NonConstBasisBlade(b).ToLangString(m_specification.m_basisVectorNames)); randSB.Append(" = "); randSB.Append(randFuncCall); } } else { // random vectors bool first = true; for (int g = 0; g < hg; g++) { for (int v = 0; v < m_specification.m_dimension; v++) { if (!first) randSB.Append(", "); first = false; if ((g > 0) && (v == 0)) { randSB.AppendLine(""); // newline randSB.Append("\t\t"); } randSB.Append("r" + g + "_" + m_specification.m_basisVectorNames[v]); randSB.Append(" = "); randSB.Append(randFuncCall); } } } randSB.Append(";"); I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, randSB.ToString())); // SMV tmp = random; bool mustCast = false; bool randomPtr = false; bool declareRandom = false; I.Add(new G25.CG.Shared.AssignInstruction(nbTabs, smv, FT, mustCast, randomSMV, "tmp", randomPtr, declareRandom)); // n = norm_ret_scalar(tmp); string emp = (m_specification.OutputC()) ? "&" : ""; I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "n = " + m_normFunc[FT.type] + "(" + emp + "tmp);")); // lc = largestCoordinate(tmp); if (m_specification.OutputC()) { I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "lc = " + smvTypeName + "_largestCoordinate(&tmp);")); } else { string lcStr = "largestCoordinate"; if (m_specification.OutputCSharp()) lcStr = "LargestCoordinate"; I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "lc = tmp." + lcStr + "();")); } // null = (n == 0) && (lc ! 0) if ((m_smvType.MvType == SMV.MULTIVECTOR_TYPE.ROTOR) || (m_smvType.MvType == SMV.MULTIVECTOR_TYPE.VERSOR)) I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "nullBlade = " + (m_specification.OutputC() ? "0" : "false") + ";")); else I.Add(new G25.CG.Shared.VerbatimCodeInstruction(nbTabs, "nullBlade = ((n == " + FT.DoubleToString(m_specification, 0.0) + ") && (lc != " + FT.DoubleToString(m_specification, 0.0) + "));")); // test minimumNorm I.Add(new CommentInstruction(nbTabs, "Recurse if generated random value has a norm below user-supplied limit, unless this is a null blade")); I.Add(new G25.CG.Shared.IfElseInstruction(nbTabs, "(n < " + exVariableNames[1] + ") && (!nullBlade)", new List<Instruction>() {new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 1, exFuncCall)}, // if instructions new List<Instruction>())); // else instructions // compute multiplier string lcCondition = "(lc * " + CodeUtil.OpNameToLangString(m_specification, FT, "abs") + "(mul)) > largestCoordinate "; I.Add(new CommentInstruction(nbTabs, "Compute multiplier")); I.Add(new G25.CG.Shared.IfElseInstruction(nbTabs, "n < " + FT.DoubleToString(m_specification, 0.0001), new List<Instruction>() { new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 1, "mul = " + FT.DoubleToString(m_specification, 1.0) + ";") }, // if instructions new List<Instruction>() { // else instructions new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 1, "mul = " + exFgs.ArgumentVariableNames[0] + " * (" + randFuncCall + ") / n;"), new CommentInstruction(nbTabs+1, "Test largest coordinate"), new G25.CG.Shared.IfElseInstruction(nbTabs+1, lcCondition, new List<Instruction>() { new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 2, exFuncCall) }, // if instructions new List<Instruction>()) })); // test largest coordinate //I.Add(new CommentInstruction(nbTabs, "Test largest coordinate")); //I.Add(new G25.CG.Shared.IfElseInstruction(nbTabs, lcCondition, // new List<Instruction>() { new G25.CG.Shared.VerbatimCodeInstruction(nbTabs + 1, exFuncCall) }, // if instructions // new List<Instruction>())); // else instructions // return tmp*mul; I.Add(new CommentInstruction(nbTabs, "Apply multiplier, return")); RefGA.Multivector tmpValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(m_specification, smv, "tmp", false); RefGA.Multivector returnValue = RefGA.Multivector.gp(tmpValue, new RefGA.Multivector("mul")); I.Add(new G25.CG.Shared.ReturnInstruction(nbTabs, smv, FT, mustCast, returnValue)); } // end of '!IsConstant()'? else { // the user wants a 'random' constant: simply return the constant itself. RefGA.Multivector returnValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(m_specification, smv, "tmp", false); bool mustCast = false; I.Add(new G25.CG.Shared.ReturnInstruction(nbTabs, smv, FT, mustCast, returnValue)); } } // because of lack of overloading, function names include names of argument types //G25.fgs CF = G25.CG.Shared.Util.AppendTypenameToFuncName(m_specification, FT, exFgs, FAI); // generate comment Comment comment = new Comment(exFgs.AddUserComment("Returns random " + m_SMVname + " with a scale in the interval [0, scale)")); bool staticFunc = Functions.OutputStaticFunctions(m_specification); G25.CG.Shared.Functions.WriteFunction(m_specification, m_cgd, CF, m_specification.m_inlineFunctions, staticFunc, exFuncName, FAI, I, comment); }
/// <summary> /// Writes a function to set an SMV struct to an array of specified coordinates, for all floating point types. /// </summary> /// <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> 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; declSB.AppendLine(""); defSB.AppendLine(""); foreach (G25.FloatType FT in S.m_floatTypes) { foreach (G25.SMV smv in S.m_SMV) { if (smv.NbNonConstBasisBlade == 0) continue; string typeName = FT.GetMangledName(S, smv.Name); string funcName = typeName + "_setArray"; bool mustCast = false; string[] argTypename = new string[1] { FT.type }; string[] argName = new string[1] { "A" }; System.Collections.ArrayList L = new System.Collections.ArrayList(); for (int i = 0; i < smv.NbNonConstBasisBlade; i++) { RefGA.BasisBlade B = smv.NonConstBasisBlade(i); //argTypename[i] = FT.type; String coordStr = argName[0] + "[" + i + "]"; //argName[i] = coordStr; L.Add(new RefGA.BasisBlade(B.bitmap, B.scale, coordStr)); } RefGA.Multivector mvValue = new RefGA.Multivector(L); G25.fgs F = new G25.fgs(funcName, funcName, "", argTypename, argName, new String[] { FT.type }, null, null, null); // null, null, null = metricName, comment, options F.InitArgumentPtrFromTypeNames(S); F.SetArgumentPtr(0, true); // first argument is a pointer to array bool computeMultivectorValue = false; G25.CG.Shared.FuncArgInfo returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, FT, smv.Name, computeMultivectorValue); int nbArgs = 1; // one array of coordinates G25.CG.Shared.FuncArgInfo[] FAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(S, F, nbArgs, FT, null, computeMultivectorValue); declSB.AppendLine("/** Sets " + typeName + " to specified coordinates */"); bool staticFunc = false; G25.CG.Shared.Functions.WriteAssignmentFunction(S, cgd, S.m_inlineSet, staticFunc, "void", null, funcName, returnArgument, FAI, FT, mustCast, smv, returnArgument.Name, returnArgument.Pointer, mvValue); } } }
/// <summary> /// Returns the name of a generated function (for example <c>gp_mv_mv</c>). /// The function is found by looking through all G25.FGS in the Specification. /// /// If the function is not found, a fictional name is returned, i.e. "missingFunction_" + functionName. /// This name will then show up in the generated code, which will not compile as a result. /// /// 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="functionName">Basic name of the function to be found.</param> /// <param name="argumentTypes">Names of the arguments types (not mangled).</param> /// <param name="returnTypeName">Name of the return type (can be null or "" for default return type).</param> /// <param name="FT">Floating point type.</param> /// <param name="metricName">(optional, can be null for don't care)</param> /// <returns>The mangled name of the function.</returns> public static string GetDependency(Specification S, CGdata cgd, string functionName, string[] argumentTypes, string returnTypeName, G25.FloatType FT, string metricName) { // bool returnTrueName = dependent on cgd.mode try { return GetFunctionName(S, functionName, argumentTypes, returnTypeName, FT, metricName); } catch (DependencyException) { // function not found, return a fictional name, and remember dependency G25.fgs F = null; { // get name of dep, and make sure it does not get mangled string outputName = functionName + cgd.GetDontMangleUniqueId(); if (returnTypeName != null) outputName = outputName + "_returns_" + returnTypeName; // add dependency to list of missing deps: string[] argVarNames = null; Dictionary<String, String> options = null; string comment = null; G25.fgs tmpF = new G25.fgs(functionName, outputName, returnTypeName, argumentTypes, argVarNames, new String[] { FT.type }, metricName, comment, options); F = cgd.AddMissingDependency(S, tmpF); } return cgd.m_dependencyPrefix + F.OutputName; } }