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()); }
} // end of GenerateSMVassignmentCode public static string GenerateReturnCode(Specification S, G25.SMV smv, G25.FloatType FT, String[] valueStr, int nbTabs, bool writeZeros) { StringBuilder SB = new StringBuilder(); string smvName = FT.GetMangledName(S, smv.Name); string STATIC_MEMBER_ACCESS = (S.OutputCpp()) ? "::" : "."; SB.Append('\t', nbTabs); SB.Append("return "); if (S.OutputCSharpOrJava()) { SB.Append("new "); } SB.Append(smvName); SB.Append("("); if (valueStr.Length > 0) { SB.AppendLine(smvName + STATIC_MEMBER_ACCESS + SmvUtil.GetCoordinateOrderConstant(S, smv) + ","); } for (int i = 0; i < valueStr.Length; i++) { SB.Append('\t', nbTabs + 2); SB.Append(valueStr[i]); if (i < (valueStr.Length - 1)) { SB.Append(","); } SB.AppendLine(" // " + smv.NonConstBasisBlade(i).ToLangString(S.m_basisVectorNames)); } SB.Append('\t', nbTabs + 1); SB.Append(");"); return(SB.ToString()); }
/// <summary> /// Returns the name of a generated function (for example <c>gp_mv_mv</c>). /// If the function is not found, a DependencyException is thrown. /// /// The function is found by looking through all G25.FGS in the specification. /// </summary> /// <param name="S">The spec.</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 GetFunctionName(Specification S, string functionName, string[] argumentTypes, string returnTypeName, G25.FloatType FT, string metricName) { fgs F = S.FindFunctionEx(functionName, argumentTypes, returnTypeName, new String[] { FT.type }, metricName); if (F == null) // error: function not found { string exStr = "G25.CG.Shared.Util.GetFunctionName(): cannot find function " + functionName + " with arguments ("; for (int i = 0; i < argumentTypes.Length; i++) { if (i > 0) { exStr = exStr + ", "; } exStr = exStr + argumentTypes[i]; } exStr = exStr + ") and using floating point type " + FT.type; if (metricName != null) { exStr = exStr + " and using metric " + metricName; } throw new DependencyException(exStr); } else { argumentTypes = F.ArgumentTypeNames; string mangledFuncName = F.OutputName; if (S.OutputC()) { // add mangled argument types to function name string[] mangledArgumentTypes = new string[argumentTypes.Length]; for (int i = 0; i < argumentTypes.Length; i++) { if (Util.DontAppendTypename(argumentTypes[i])) { continue; } mangledArgumentTypes[i] = (S.IsFloatType(argumentTypes[i])) ? FT.type : FT.GetMangledName(S, argumentTypes[i]); } mangledFuncName = Util.AppendTypenameToFuncName(S, FT, F.OutputName, mangledArgumentTypes); //mangledFuncName = FT.GetMangledName(S, mangledFuncName); } else if (argumentTypes.Length == 0) { // test to apply mangling when no arguments are present. mangledFuncName = FT.GetMangledName(S, mangledFuncName); } return(mangledFuncName); } } // end of GetFunctionName()
/// <summary> /// Writes functions to set coordinates of the GMV /// </summary> /// <param name="S"></param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> /// <param name="FT"></param> /// <param name="SB"></param> public static void WriteSetCoord(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, StringBuilder SB) { G25.GMV gmv = S.m_GMV; string typeName = FT.GetMangledName(S, gmv.Name); for (int groupIdx = 0; groupIdx < gmv.NbGroups; groupIdx++) { for (int elementIdx = 0; elementIdx < gmv.Group(groupIdx).Length; elementIdx++) { WriteSetCoordFunction(S, cgd, FT, SB, typeName, groupIdx, elementIdx, gmv.Group(groupIdx).Length, gmv.Group(groupIdx)[elementIdx]); } } }
/// <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> /// Appends the non-mangled typenames of the type of all arguments to the name of 'F'. /// Also appends the float type. /// </summary> /// <param name="S">Specification (used for output language).</param> /// <param name="FT">Float type of function.</param> /// <param name="funcName">The function name.</param> /// <param name="typeNames">Typenames of function arguments. Some entries may be null.</param> /// <returns>new name.</returns> public static string AppendTypenameToFuncName(Specification S, G25.FloatType FT, string funcName, string[] typeNames) { StringBuilder SB = new StringBuilder(funcName); if (!funcName.Contains(G25.Specification.DONT_MANGLE)) // for the auto-dependency system to work, we should not mangle when this string is present! { foreach (string tn in typeNames) { if (tn != null) { SB.Append("_"); SB.Append(tn); } } } return(FT.GetMangledName(S, SB.ToString())); }
} // end of WriteSetIdentity() /// <summary> /// Writes a function to copy an GOM class. /// </summary> /// <param name="SB">Where the code goes.</param> /// <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 point type of 'GOM'.</param> public static void WriteSetCopy(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT) { SB.AppendLine(); string srcName = "src"; string matrixName = "m_m"; // todo: centralize this name string className = FT.GetMangledName(S, S.m_GOM.Name); string funcName = Util.GetFunctionName(S, "set");; SB.AppendLine("\tvoid " + funcName + "(" + className + " " + srcName + ") {"); for (int g = 1; g < S.m_GOM.Domain.Length; g++) { int s = S.m_GOM.Domain[g].Length * S.m_GOM.Range[g].Length; SB.AppendLine("\t\t" + G25.CG.Shared.Util.GetCopyCode(S, FT, srcName + "." + matrixName + g, matrixName + g, s)); } // end of loop over all grades of the OM SB.AppendLine("\t}"); } // end of WriteCopy()
} // end of GetApplyGomCodeCppOrC private static string GetApplyGomCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, string resultName) { G25.GMV gmv = S.m_GMV; bool groupedByGrade = gmv.IsGroupedByGrade(S.m_dimension); StringBuilder SB = new StringBuilder(); // allocate memory to store result: SB.AppendLine(FT.type + "[][] bc = " + FAI[1].Name + ".to_" + FAI[1].MangledTypeName + "().c();"); bool resultIsScalar = false; bool initResultToZero = !groupedByGrade; SB.Append(GPparts.GetExpandCode(S, cgd, FT, null, resultIsScalar, initResultToZero)); // get number of groups: int nbGroups = gmv.NbGroups; // for each combination of groups, check if the OM goes from one to the other for (int srcGroup = 0; srcGroup < nbGroups; srcGroup++) { SB.AppendLine("if (bc[" + srcGroup + "] != null) {"); for (int dstGroup = 0; dstGroup < nbGroups; dstGroup++) { string funcName = GetGomPartFunctionName(S, FT, srcGroup, dstGroup); Tuple <string, string> key = new Tuple <string, string>(FT.type, funcName); if (cgd.m_gmvGomPartFuncNames.ContainsKey(key) && cgd.m_gmvGomPartFuncNames[key]) { string allocCcode = "if (cc[" + dstGroup + "] == null) cc[" + dstGroup + "] = new " + FT.type + "[" + gmv.Group(dstGroup).Length + "];"; SB.AppendLine("\t" + allocCcode); SB.AppendLine("\t" + funcName + "(" + FAI[0].Name + ", bc[" + srcGroup + "], cc[" + dstGroup + "]);"); } } SB.AppendLine("}"); SB.AppendLine(""); } SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return(SB.ToString()); } // end of GetApplyGomCodeCSharpOrJava()
} // end of WriteDeclaration() /// <summary> /// Writes generic function based on Instructions. /// /// This version automatically figures out the return type (so it is recommended over the other WriteFunction()). /// </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="functionName">Name of generated function.</param> /// <param name="arguments">Arguments of function (any 'return argument' used for the C language is automatically setup correctly).</param> /// <param name="instructions">List of GA-instructions which make up the function.</param> /// <param name="comment">Comment to go into generated declration code.</param> public static void WriteFunction( Specification S, G25.CG.Shared.CGdata cgd, G25.fgs F, bool inline, bool staticFunc, string functionName, FuncArgInfo[] arguments, List <Instruction> instructions, Comment comment) { List <G25.VariableType> returnTypes = new List <G25.VariableType>(); List <G25.FloatType> returnTypeFT = new List <G25.FloatType>(); // floating point types of return types Instruction.GetReturnType(instructions, returnTypes, returnTypeFT); // for now, assume only one return type is used? string returnType = "void"; G25.CG.Shared.FuncArgInfo returnArgument = null; if (returnTypes.Count > 0) { G25.VariableType returnVT = returnTypes[0]; G25.FloatType returnFT = returnTypeFT[0]; if (returnVT is G25.FloatType) { returnVT = returnFT; } string returnTypeName = (returnVT is G25.MV) ? (returnVT as G25.MV).Name : (returnVT as FloatType).type; returnType = returnFT.GetMangledName(S, returnTypeName); if (S.OutputC()) { if (!(returnVT is G25.FloatType)) { returnArgument = new G25.CG.Shared.FuncArgInfo(S, F, -1, returnFT, returnTypeName, false); // false = compute value } } } WriteFunction(S, cgd, F, inline, staticFunc, returnType, functionName, returnArgument, arguments, instructions, comment); } // end of WriteFunction()
} // end of GetDualCodeCppOrC() private static string GetDualCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool dual) { G25.GMV gmv = S.m_GMV; StringBuilder SB = new StringBuilder(); bool resultIsScalar = false; bool initResultToZero = true; // must init to zero because of compression SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero)); // get number of groups: int nbGroups = gmv.NbGroups; // for each combination of groups, check if the dual goes from one to the other for (int gi = 0; gi < nbGroups; gi++) { SB.AppendLine("if (ac[" + gi + "] != null) {"); for (int go = 0; go < nbGroups; go++) { string funcName = (dual) ? GetDualPartFunctionName(S, FT, M, gi, go) : GetUndualPartFunctionName(S, FT, M, gi, go); Tuple <string, string, string> key = new Tuple <string, string, string>(FT.type, M.m_name, funcName); if (cgd.m_gmvDualPartFuncNames.ContainsKey(key) && cgd.m_gmvDualPartFuncNames[key]) { SB.AppendLine("\tif (cc[" + go + "] == null) cc[" + go + "] = new " + FT.type + "[" + gmv.Group(go).Length + "];"); SB.AppendLine("\t" + funcName + "(ac[" + gi + "], cc[" + go + "]);"); } } SB.AppendLine("}"); SB.AppendLine(""); } SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);"); return(SB.ToString()); } // end of GetDualCodeCppOrC()
} // end of GetDependency() /// <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))); }
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 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); }
/// <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); }
/// <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); }
/// <summary> /// Writes the declaration/definitions of 'F' to StringBuffer 'SB', taking into account parameters specified in specification 'S'. /// </summary> public override void WriteFunction() { StringBuilder declSB = m_cgd.m_declSB; StringBuilder defSB = (m_specification.m_inlineFunctions) ? m_cgd.m_inlineDefSB : m_cgd.m_defSB; string inlineStr = G25.CG.Shared.Util.GetInlineString(m_specification, m_specification.m_inlineFunctions, " "); G25.FloatType FT = m_specification.GetFloatType(m_functionNameFloatType); string funcName = FT.GetMangledName(m_specification, m_fgs.OutputName); // what random number generator is being used (for the comment) string generatorType = " unknown method"; if (m_specification.OutputCSharp()) { generatorType = "System.Random class"; } else if (m_specification.OutputJava()) { generatorType = "java.util.Random"; } else if (m_generatorType == PRGtype.LIBC) { generatorType = "c library rand() function"; } else if (m_generatorType == PRGtype.LIBC) { generatorType = "mersenne twister method"; } // get comment string comment = "Generates a random " + m_functionNameFloatType + " in [0.0 1.0) interval using the " + generatorType; // emit declaration / comment if (m_specification.OutputCppOrC()) { new Comment(comment).Write(declSB, m_specification, 0); declSB.Append(m_functionNameFloatType + " " + funcName + "();\n"); } else { new Comment(comment).Write(defSB, m_specification, 0); } // get access modifier string ACCESS = ""; if (m_specification.OutputCSharp()) { ACCESS = "public static "; } else if (m_specification.OutputJava()) { ACCESS = "public final static "; } // emit definition { defSB.Append(inlineStr + ACCESS + m_functionNameFloatType + " " + funcName + "() {\n"); // emit actual code if (m_specification.OutputCSharpOrJava()) { defSB.Append("\treturn (" + m_functionNameFloatType + ")NextRandomDouble();\n"); } else if (m_generatorType == PRGtype.LIBC) { // write template to file? if (m_functionNameFloatType == "float") { defSB.Append("\treturn (" + m_functionNameFloatType + ")(rand() & 0x7FFF) / 32768.0f + (" + m_functionNameFloatType + ")(rand() & 0x7FFF) / (32768.0f * 32768.0f);\n"); } else { defSB.Append("return (" + m_functionNameFloatType + ")((double)(rand() & 0x7FFF) / 32768.0) + \n"); defSB.Append("\t(" + m_functionNameFloatType + ")((double)(rand() & 0x7FFF) / (32768.0 * 32768.0)) + \n"); defSB.Append("\t(" + m_functionNameFloatType + ")((double)(rand() & 0x7FFF) / (32768.0 * 32768.0 * 32768.0)) + \n"); defSB.Append("\t(" + m_functionNameFloatType + ")((double)(rand() & 0x7FFF) / (32768.0 * 32768.0 * 32768.0 * 32768.0)); \n"); } } else if (m_generatorType == PRGtype.MT) { if (m_functionNameFloatType == "float") { defSB.Append("\treturn (" + m_functionNameFloatType + ")genrand_real2();\n"); } else { defSB.Append("\treturn (" + m_functionNameFloatType + ")genrand_res53();\n"); } } defSB.Append("}\n"); // seeder decls: string seedComment = "Seeds the random number generator for " + m_functionNameFloatType; string timeSeedComment = "Seeds the random number generator for " + m_functionNameFloatType + " with the current time"; if (m_specification.OutputCppOrC()) { new Comment(seedComment).Write(declSB, m_specification, 0); declSB.AppendLine("void " + funcName + "_seed(unsigned int seed);"); new Comment(timeSeedComment).Write(declSB, m_specification, 0); declSB.AppendLine("void " + funcName + "_timeSeed();"); } string SEED_TYPE = (m_specification.OutputCppOrC()) ? "unsigned int" : "int"; // seeder defs: if (m_specification.OutputCSharpOrJava()) { new Comment(seedComment).Write(declSB, m_specification, 0); } defSB.AppendLine(inlineStr + ACCESS + "void " + funcName + "_seed(" + SEED_TYPE + " seed) {"); if (m_specification.OutputCSharp()) { defSB.AppendLine("\ts_randomGenerator = new System.Random(seed);"); } else if (m_specification.OutputJava()) { defSB.AppendLine("\ts_randomGenerator.setSeed(seed);"); } else { if (m_generatorType == PRGtype.LIBC) { defSB.AppendLine("\tsrand(seed);"); } else if (m_generatorType == PRGtype.MT) { defSB.AppendLine("\tinit_genrand(seed);"); } } defSB.AppendLine("}\n"); if (m_specification.OutputCSharpOrJava()) { new Comment(timeSeedComment).Write(declSB, m_specification, 0); } defSB.AppendLine(inlineStr + ACCESS + "void " + funcName + "_timeSeed() {"); if (m_specification.OutputCSharp()) { defSB.AppendLine("\t" + funcName + "_seed((int)DateTime.Now.Ticks);"); } else if (m_specification.OutputJava()) { defSB.AppendLine("\t" + funcName + "_seed((int)System.currentTimeMillis());"); } else { defSB.AppendLine("\t" + funcName + "_seed((unsigned int)time(NULL));"); } defSB.AppendLine("}\n"); } // end of WriteFunction
/// <summary> /// Returns the name of a partial undual function. /// </summary> /// <param name="FT">Float type (used for mangled name).</param> /// <param name="M">Metric of dual.</param> /// <param name="gi">Grade/group of input.</param> /// <param name="go">Grade/group of output.</param> /// <returns>name of a partial geometric product function.</returns> public static string GetUndualPartFunctionName(Specification S, G25.FloatType FT, G25.Metric M, int gi, int go) { return(FT.GetMangledName(S, "undual") + "_" + M.m_name + "_" + gi + "_" + go); }
/// <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); }
} // end of WriteSetCopyCrossFloat() /// <summary> /// Writes functions to copy GMVs to SMVs /// </summary> /// <param name="S"></param> /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param> public static void WriteGMVtoSMVcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.SMV smv) { StringBuilder defSB = cgd.m_defSB; G25.GMV gmv = S.m_GMV; string srcClassName = FT.GetMangledName(S, gmv.Name); //string dstClassName = FT.GetMangledName(S, smv.Name); bool dstPtr = false; string[] smvAccessStr = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr); string funcName = GMV.GetSetFuncName(S); string FINAL = (S.OutputJava()) ? "final " : ""; string funcDecl = "\tpublic " + FINAL + "void " + funcName + "(" + FINAL + srcClassName + " src)"; defSB.Append(funcDecl); { defSB.AppendLine(" {"); // get a dictionary which tells you for each basis blade of 'smv' where it is in 'gmv' // A dictionary from <smv group, smv element> to <gmv group, gmv element> Dictionary <Tuple <int, int>, Tuple <int, int> > D = G25.MV.GetCoordMap(smv, gmv); // what is the highest group of the 'gmv' that must be (partially) copied to the 'smv' int highestGroup = -1; foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { if (KVP.Value.Value1 > highestGroup) { highestGroup = KVP.Value.Value1; } } // generate code for each group for (int g = 0; g <= highestGroup; g++) { // determine if group 'g' is to be copied to smv: bool groupIsUsedBySMV = false; foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { // KVP.Key = SMV<group, element> // KVP.Value = GMV<group, element> if (KVP.Value.Value1 == g) { if (!smv.IsCoordinateConstant(KVP.Key.Value2)) { groupIsUsedBySMV = true; break; } } } // if group is present in GMV: if (groupIsUsedBySMV) { defSB.AppendLine("\t\tif (src.c()[" + g + "] != null) {"); defSB.AppendLine("\t\t\t" + FT.type + "[] ptr = src.c()[" + g + "];"); bool mustCast = false; bool srcPtr = true; int nbTabs = 3; RefGA.Multivector[] value = G25.CG.Shared.Symbolic.GMVtoSymbolicMultivector(S, gmv, "ptr", srcPtr, g); bool writeZeros = false; string str = G25.CG.Shared.CodeUtil.GenerateSMVassignmentCode(S, FT, mustCast, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr, value[g], nbTabs, writeZeros); defSB.Append(str); defSB.AppendLine("\t\t}"); defSB.AppendLine("\t\telse {"); foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D) { if ((KVP.Value.Value1 == g) && (!smv.IsCoordinateConstant(KVP.Key.Value2))) { // translate KVP.Key.Value2 to non-const idx, because the accessStrs are only about non-const blades blades! int bladeIdx = smv.BladeIdxToNonConstBladeIdx(KVP.Key.Value2); defSB.AppendLine("\t\t\t" + smvAccessStr[bladeIdx] + " = " + FT.DoubleToString(S, 0.0) + ";"); } } defSB.AppendLine("\t\t}"); } } defSB.AppendLine("\t}"); } } // end of WriteGMVtoSMVcopy()
} // end of WriteSetVectorImages() private 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); // write comment declSB.AppendLine("/** Copies a " + srcTypeName + " to a " + dstTypeName); declSB.AppendLine(" * Warning 1: coordinates which cannot be represented are silenty lost"); declSB.AppendLine(" * Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'."); declSB.AppendLine(" */"); string funcName = srcTypeName + "_to_" + dstTypeName; // do we inline this func? string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " "); string funcDecl = inlineStr + "void " + funcName + "(" + dstTypeName + " *dst, const " + srcTypeName + " *src)"; declSB.Append(funcDecl); declSB.AppendLine(";"); 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>(); // 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 = "dst->m" + 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->m" + 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> /// Constructs a new FuncArgInfo class for a specific argument 'argIdx' of function 'F'. /// </summary> /// <param name="S">Used for retrieving the G25.VariableType of 'm_typeName'.</param> /// <param name="F">Function for which this FuncArgInfo describes an argument.</param> /// <param name="argIdx">Index of argument. Use -1 for artificial 'return argument' used for the C language.</param> /// <param name="FT">Floating point type of the type of the argument.</param> /// <param name="defaultTypeName">Name of the type of the argument.</param> /// <param name="computeMultivectorValue">Set to true to convert the type into symbolic code. Uses 'F' to obtain the actual name of the variable to use inside the symbolic multivector.</param> public FuncArgInfo(G25.Specification S, G25.fgs F, int argIdx, G25.FloatType FT, string defaultTypeName, bool computeMultivectorValue) { m_mvInterface = true; m_name = F.GetArgumentName(argIdx); m_typeName = F.GetArgumentTypeName(argIdx, defaultTypeName); m_type = S.GetType(m_typeName); m_varType = m_type.GetVariableType(); if (m_varType != VARIABLE_TYPE.FLOAT) { m_floatType = FT; } else { m_floatType = S.GetFloatType(m_typeName); } // set mangled type name (depends on whether type is scalar or not) if ((m_varType == VARIABLE_TYPE.FLOAT) || (m_varType == VARIABLE_TYPE.ENUM)) { m_mangledTypeName = m_typeName; } else { m_mangledTypeName = FT.GetMangledName(S, m_typeName); // temp (currently disabled) test for C# and Java // if (S.OutputCSharpOrJava() && (m_varType == VARIABLE_TYPE.GMV)) // m_mangledTypeName = m_mangledTypeName + G25.CG.Shared.Main.IF_SUFFIX; } // set pointer / non pointer flag m_pointer = F.GetArgumentPtr(S, argIdx); // set array flag m_array = F.GetArgumentArr(S, argIdx); m_constant = (argIdx >= 0); if (computeMultivectorValue) { if (m_varType == VARIABLE_TYPE.SMV) { m_multivectorValue = new RefGA.Multivector[1] { Symbolic.SMVtoSymbolicMultivector(S, (G25.SMV)m_type, m_name, m_pointer) }; } else if (m_varType == VARIABLE_TYPE.GMV) { m_multivectorValue = Symbolic.GMVtoSymbolicMultivector(S, (G25.GMV)m_type, m_name, m_pointer, -1); // -1 = sym mv for all groups } else if (m_varType == VARIABLE_TYPE.FLOAT) { m_multivectorValue = new RefGA.Multivector[1] { Symbolic.ScalarToSymbolicMultivector(S, (G25.FloatType)m_type, m_name) } } ; else { // OM: do nothing? m_multivectorValue = null; } } }