Пример #1
0
        /// <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));
        }
Пример #2
0
        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();
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        private static string GetGradeCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
            int gradeIdx,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName, string groupBitmapName)
        {
            G25.GMV gmv = S.m_GMV;
            if (gradeIdx >= 0)
            {  // if a specific grade is requested, convert it into a group bitmap, and call the grade(A, groupBitmap) function
                // get name of grade function
                //bool returnTrueName = false;
                string gradeFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, EXTRACT_GRADE, new string[] { gmv.Name, G25.GroupBitmapType.GROUP_BITMAP }, FT, null);

                // turn grade into group
                int groupBitmap = gmv.GradeToGroupBitmap(gradeIdx);

                if (S.OutputC())
                {
                    return gradeFuncName + "(" + resultName + ", " + FAI[0].Name + ", " + groupBitmap + ");";
                }
                else
                {
                    return "return " + gradeFuncName + "(" + FAI[0].Name + ", " + groupBitmap + ");";
                }
            }
            else
            {
                StringBuilder SB = new StringBuilder();

                // get indices into coordinates for input and output
                SB.AppendLine("int aidx = 0, cidx = 0;");

                string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()";
                string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()";

                if (S.OutputC())
                {
                    SB.AppendLine(resultName + "->gu = " + agu +" & " + groupBitmapName + ";");
                }
                else
                {
                    SB.AppendLine("int gu =  " + agu + " & " + groupBitmapName + ";");
                    SB.AppendLine(FT.type + " c[" + (1 << S.m_dimension) + "];");
                }

                string resultCoordPtr = (S.OutputC()) ? resultName + "->c" : "c";

                // for each group, test if present
                int nbGroups = gmv.NbGroups;
                for (int g = 0; g < nbGroups; g++)
                {
                    SB.AppendLine("");

                    string funcName = GetCopyPartFunctionName(S, FT, g);

                    SB.AppendLine("if (" + agu + " & " + (1 << g) + ") {");
                    SB.AppendLine("\tif (" + groupBitmapName + " & " + (1 << g) + ") {");
                    SB.AppendLine("\t\t" + funcName + "(" + ac + " + aidx, " + resultCoordPtr + " + cidx);");
                    if (g < (nbGroups - 1)) SB.AppendLine("\t\tcidx += " + gmv.Group(g).Length + ";");
                    SB.AppendLine("\t}");
                    if (g < (nbGroups - 1)) SB.AppendLine("\taidx += " + gmv.Group(g).Length + ";");
                    SB.AppendLine("}");
                }

                // return result
                if (S.m_outputLanguage != OUTPUT_LANGUAGE.C)
                {
                    SB.AppendLine("return " + FT.GetMangledName(S, gmv.Name) + "(gu, c);");
                }

                return SB.ToString();
            }
        }
Пример #5
0
        /// <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;}");
        }
Пример #6
0
        /// <summary>
        /// Returns the code for a inverse geometric product. 
        /// 
        /// The returned code is only the body. The function declaration is not included.
        /// </summary>
        /// <param name="S">Specification of algebra (used for output language and to obtain general multivector type).</param>
        /// <param name="cgd">Used for <c>m_gmvGPpartFuncNames</c>.</param>
        /// <param name="FT">Floating point type.</param>
        /// <param name="M">Metric type.</param>
        /// <param name="T">The product (e.g., geometric, outer, etc)</param>
        /// <param name="FAI">Info about function arguments. Used to know whether arguments are general multivectors or scalars.</param>
        /// <param name="resultName">Name of variable where the result goes (in the generated code).</param>
        /// <returns>code for the requested product type.</returns>
        public static string GetIGPcode(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

            string divFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "div", new String[] { gmv.Name, FT.type }, FT, null);

            System.Collections.Hashtable argTable = new System.Collections.Hashtable();
            argTable["S"] = S;
            argTable["gmvName"] = FT.GetMangledName(S, gmv.Name);
            argTable["FT"] = FT;
            argTable["arg1name"] = FAI[0].Name;
            argTable["arg2name"] = FAI[1].Name;
            argTable["divFuncName"] = divFuncName;

            if (S.OutputC())
                argTable["dstName"] = resultName;

            bool arg1isGmv = FAI[0].Type is G25.GMV;
            bool arg2isGmv = FAI[1].Type is G25.GMV;
            if (arg2isGmv)
            {
                string norm2FuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "norm2", new String[] { gmv.Name }, FT, M.m_name) + CANSparts.RETURNS_SCALAR;
                string reverseFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "reverse", new String[] { gmv.Name }, FT, null);
                argTable["reverseFuncName"] = reverseFuncName;
                argTable["norm2FuncName"] = norm2FuncName;

                if (arg1isGmv)
                {
                    string gpFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "gp", new String[] { gmv.Name, gmv.Name }, FT, M.m_name);
                    argTable["gpFuncName"] = gpFuncName;
                    cgd.m_cog.EmitTemplate(SB, "igp_GMV_GMV_body", argTable);
                }
                else
                {
                    string gpFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "gp", new String[] { gmv.Name, FT.type }, FT, M.m_name);
                    argTable["mulFuncName"] = gpFuncName;
                    cgd.m_cog.EmitTemplate(SB, "igp_float_GMV_body", argTable);
                }
            }
            else if (arg1isGmv)
            {
                cgd.m_cog.EmitTemplate(SB, "igp_GMV_float_body", argTable);
            }

            return SB.ToString();
        }
Пример #7
0
        private static string GetExpandCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, 
            G25.FloatType FT, G25.CG.Shared.FuncArgInfo[] FAI, bool resultIsScalar, bool initResultToZero)
        {
            StringBuilder SB = new StringBuilder();

            // result coordinates code:
            int nbCoords = (resultIsScalar) ? 1 : (1 << S.m_dimension);
            SB.AppendLine(FT.type + " c[" + nbCoords + "];");

            // expand code
            if (FAI != null)
            {
                for (int i = 0; i < FAI.Length; i++)
                {
                    if (FAI[i].IsScalar())
                    {
                        // 'expand' scalar
                        SB.AppendLine("const " + FAI[i].FloatType.type + "* _" + FAI[i].Name + "[1] = {&" + FAI[i].Name + "};");
                    }
                    else
                    {
                        // expand general multivector
            //                                SB.AppendLine("const " + FAI[i].FloatType.type + "* _" + FAI[i].Name + "[" + (S.m_dimension + 1) + "];");
                        SB.AppendLine("const " + FAI[i].FloatType.type + "* _" + FAI[i].Name + "[" + (S.m_GMV.NbGroups) + "];");
                    }
                }
                for (int i = 0; i < FAI.Length; i++)
                {
                    if (!FAI[i].IsScalar())
                    {
                        if (S.OutputC())
                            SB.AppendLine(FT.GetMangledName(S, "expand") + "(_" + FAI[i].Name + ", " + FAI[i].Name + ");");
                        else SB.AppendLine(FAI[i].Name + ".expand(_" + FAI[i].Name + ");");
                    }
                }
            }

            // set coordinates of 'c' to zero
            if (initResultToZero)
            {
                SB.Append(Util.GetSetToZeroCode(S, FT, "c", nbCoords));
            }

            return SB.ToString();
        }
Пример #8
0
 /// <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);
 }
Пример #9
0
        private static string GetSAScodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

            SB.AppendLine("int idxa = 0, idxc = 0;");

            string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()";
            string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()";
            string resultCoordPtr = (S.OutputC()) ? resultName + "->c" : "C";

            // copy group usage / allocate memory for result
            if (S.OutputC())
            {
                SB.AppendLine(resultName + "->gu = " + agu + " | ((" + FAI[2].Name + " != 0.0) ? GRADE_0 : 0); /* '| GRADE_0' to make sure the scalar part is included */");
            }
            else
            {
                SB.AppendLine("int gu = " + agu + " | ((" + FAI[2].Name + " != 0.0) ? GRADE_0 : 0); // '| GRADE_0' to make sure the scalar part is included");
                SB.AppendLine(FT.type + " C[" + (1 << S.m_dimension) + "];");
            }

            int nbGroups = gmv.NbGroups;
            for (int g = 0; g < nbGroups; g++)
            {
                SB.AppendLine("");

                // get func name
                string funcName = GetCopyMulPartFunctionName(S, FT, g);

                SB.AppendLine("if (" + agu + " & " + (1 << g) + ") {");
                SB.AppendLine("\t" + funcName + "(" + ac + " + idxa, " + resultCoordPtr + " + idxc, " + FAI[1].Name + ");");
                if (g == 0)
                { // also add scalar
                    SB.AppendLine("\tif (" + FAI[2].Name + " != 0.0) " + resultCoordPtr + "[idxc] += " + FAI[2].Name + ";");
                }
                if (g < (nbGroups - 1))
                {
                    SB.AppendLine("\tidxa += " + gmv.Group(g).Length + ";");
                    SB.AppendLine("\tidxc += " + gmv.Group(g).Length + ";");
                }
                SB.AppendLine("}");

                if (g == 0)
                { // always add the scalar:
                    SB.AppendLine("else if (" + FAI[2].Name + " != 0.0) {");
                    SB.AppendLine("\t" + resultCoordPtr + "[idxc] = " + FAI[2].Name + ";");
                    SB.AppendLine("\tidxc += " + gmv.Group(g).Length + ";");
                    SB.AppendLine("}");
                }
            }

            // return result
            if (S.m_outputLanguage != OUTPUT_LANGUAGE.C)
            {
                SB.AppendLine("return " + FT.GetMangledName(S, gmv.Name) + "(gu, C);");
            }

            return SB.ToString();
        }
Пример #10
0
 /// <summary>
 /// Returns the name of a partial subtraction function.
 /// </summary>
 /// <param name="FT">Float type (used for mangled name).</param>
 /// <param name="g">Grade/group of arguments.</param>
 /// <returns>name of a partial subtraction function.</returns>
 public static string GetSubPartFunctionName(Specification S, G25.FloatType FT, int g)
 {
     return FT.GetMangledName(S, "sub") + "_" + g;
 }
Пример #11
0
 /// <summary>
 /// Returns the name of a partial is-zero function 
 /// </summary>
 /// <param name="FT">Float type (used for mangled name).</param>
 /// <param name="g">Grade/group of arguments.</param>
 /// <returns>name of a partial Hadamard product function.</returns>
 public static string GetZeroPartFunctionName(Specification S, G25.FloatType FT, int g)
 {
     return FT.GetMangledName(S, "zeroGroup") + "_" + g;
 }
Пример #12
0
 /// <summary>
 /// Returns the name of a partial equality function 
 /// </summary>
 /// <param name="FT">Float type (used for mangled name).</param>
 /// <param name="g">Grade/group of arguments.</param>
 /// <returns>name of a partial Hadamard product function.</returns>
 public static string GetEqualsPartFunctionName(Specification S, G25.FloatType FT, int g)
 {
     return FT.GetMangledName(S, "equals") + "_" + g + "_" + g;
 }
Пример #13
0
 /// <summary>
 /// Returns the name of a partial Hadamard product function 
 /// </summary>
 /// <param name="FT">Float type (used for mangled name).</param>
 /// <param name="g">Grade/group of arguments.</param>
 /// <returns>name of a partial Hadamard product function.</returns>
 public static string GetInverseHadamardProductPartFunctionName(Specification S, G25.FloatType FT, int g)
 {
     return FT.GetMangledName(S, "ihp") + "_" + g + "_" + g;
 }
Пример #14
0
        private static string GetUnaryToggleSignCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
            UnaryToggleSignType T,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

            // get number of groups:
            int nbGroups = gmv.NbGroups;

            bool resultIsScalar = false , initResultToZero = false;
            SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero));

            // for each group
            // test if present, then code / negate, etc

            for (int g = 0; g < nbGroups; g++)
            {
                SB.AppendLine("");

                // do we need to negate this group?
                bool neg = NeedToNegate(gmv, g, T);

                string funcName = (neg) ? GetNegPartFunctionName(S, FT, g) : GetCopyPartFunctionName(S, FT, g);

                SB.AppendLine("if (ac[" + g + "] != null) {");
                SB.AppendLine("\tcc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];");
                SB.AppendLine("\t" + funcName + "(ac[" + g + "], cc[" + g + "]);");
                SB.AppendLine("}");
            }

            SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);");

            return SB.ToString();
        }
Пример #15
0
        private static string GetUnaryToggleSignCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, 
            UnaryToggleSignType T,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB=  new StringBuilder();

            string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()";
            string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()";
            string resultCoordPtr = (S.OutputC()) ? resultName + "->c" : "c";

            SB.AppendLine("int idx = 0;");

            if (S.OutputC())
            {
                SB.AppendLine(resultName + "->gu = " + agu + ";");
            }
            else
            {
                SB.AppendLine("int gu = " + agu + ";");
                SB.AppendLine(FT.type + " c[" + (1 << S.m_dimension) + "];");
            }

            // get number of groups:
            int nbGroups = gmv.NbGroups;

            // for each group
            // test if present, then code / negate, etc

            for (int g = 0; g < nbGroups; g++)
            {
                SB.AppendLine("");

                // do we need to negate this group?
                bool neg = NeedToNegate(gmv, g, T);

                string funcName = (neg) ? GetNegPartFunctionName(S, FT, g) : GetCopyPartFunctionName(S, FT, g);

                SB.AppendLine("if (" + agu + " & " + (1 << g) + ") {");
                SB.AppendLine("\t" + funcName + "(" + ac + " + idx, " + resultCoordPtr + " + idx);");

                if (g < (nbGroups - 1)) SB.AppendLine("\tidx += " + gmv.Group(g).Length + ";");

                SB.AppendLine("}");
            }

            // return result
            if (S.m_outputLanguage != OUTPUT_LANGUAGE.C)
            {
                SB.AppendLine("return " + FT.GetMangledName(S, gmv.Name) + "(gu, c);");
            }

            return SB.ToString();
        }
Пример #16
0
        private static string GetSAScodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
            G25.CG.Shared.FuncArgInfo[] FAI, String resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

            bool resultIsScalar = false, initResultToZero = false;
            SB.Append(GPparts.GetExpandCode(S, cgd, FT, new FuncArgInfo[] { FAI[0] }, resultIsScalar, initResultToZero));

            //SB.AppendLine("cc[0] = new " + FT.type + "[" + gmv
            // string allocCcode = "cc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];";

            int nbGroups = gmv.NbGroups;
            for (int g = 0; g < nbGroups; g++)
            {
                SB.AppendLine("");

                // get func name
                string funcName = GetCopyMulPartFunctionName(S, FT, g);

                SB.AppendLine("if (ac[" + g + "] != null) {");
                SB.AppendLine("\tcc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];");
                SB.AppendLine("\t" + funcName + "(ac[" + g + "], cc[" + g + "], " + FAI[1].Name + ");");
                if (g == 0)
                { // also add scalar
                    SB.AppendLine("\tcc[" + g + "][0] += " + FAI[2].Name + ";");
                }
                SB.AppendLine("}");

                if (g == 0)
                { // always add the scalar:
                    SB.AppendLine("else if (" + FAI[2].Name + " != 0.0) {");
                    SB.AppendLine("\tcc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];");
                    SB.AppendLine("cc[" + g + "][0] = " + FAI[2].Name + ";");
                    SB.AppendLine("}");
                }
            }

            // return result
            SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);");

            return SB.ToString();
        }
Пример #17
0
 /// <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);
 }
Пример #18
0
        public static void WriteOMtoOMcopy(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, OM srcOm, OM dstOm)
        {
            StringBuilder declSB = cgd.m_declSB;
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;
            string srcTypeName = FT.GetMangledName(S, srcOm.Name);
            string dstTypeName = FT.GetMangledName(S, dstOm.Name);
            bool writeDecl = S.OutputC();

            string funcName = GetFunctionName(S, (S.OutputC() ? "" : dstTypeName), "set", srcTypeName + "_to_" + dstTypeName);

            // do we inline this func?
            string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");
            string dstArgStr = (S.OutputC()) ? (dstTypeName + " *dst, ") : "";
            string refStr = (S.OutputC()) ? "*" : ((S.OutputCpp()) ? "&" : "");
            string CONST = (S.OutputCppOrC()) ? "const " : "";

            string funcDecl = inlineStr + "void " + funcName + "(" + dstArgStr + CONST + srcTypeName + " " + refStr + "src)";

            // write comment, function declaration
            Comment comment = new Comment("Copies a " + srcTypeName + " to a " + dstTypeName + "\n" +
                "Warning 1: coordinates which cannot be represented are silenty lost.\n" +
                "Warning 2: coordinates which are not present in 'src' are set to zero in 'dst'.\n");
            if (writeDecl)
            {
                comment.Write(declSB, S, 0);
                declSB.Append(funcDecl);
                declSB.AppendLine(";");
            }

            if (S.OutputCSharpOrJava())
                comment.Write(defSB, S, 0);

            defSB.Append(funcDecl);
            {
                defSB.AppendLine(" {");

                Dictionary<Tuple<int, int, int>, Tuple<int, int, double>> D = dstOm.getMapping(srcOm);

                StringBuilder copySB = new StringBuilder();
                List<string> setToZero = new List<string>();

                string matrixStr = (S.OutputC()) ? "m" : "m_m";
                string dstMatrixStr = (S.OutputC()) ? "dst->" + matrixStr : matrixStr;
                string ptrStr = (S.OutputC()) ? "->" : ".";

                // For all grades of som, for all columns, for all rows, check D, get entry, set; otherwise set to null
                // Do not use foreach() on D because we want to fill in coordinates in their proper order.
                for (int gradeIdx = 1; gradeIdx < dstOm.Domain.Length; gradeIdx++)
                {
                    for (int somRangeIdx = 0; somRangeIdx < dstOm.Range[gradeIdx].Length; somRangeIdx++)
                    {
                        for (int somDomainIdx = 0; somDomainIdx < dstOm.Domain[gradeIdx].Length; somDomainIdx++)
                        {
                            Tuple<int, int, int> key = new Tuple<int, int, int>(gradeIdx, somDomainIdx, somRangeIdx);

                            int somMatrixIdx = dstOm.getCoordinateIndex(gradeIdx, somDomainIdx, somRangeIdx);
                            string dstString = dstMatrixStr + gradeIdx + "[" + somMatrixIdx + "] = ";
                            if (D.ContainsKey(key))
                            {
                                Tuple<int, int, double> value = D[key];
                                int gomMatrixIdx = srcOm.getCoordinateIndex(gradeIdx, value.Value1, value.Value2);
                                double multiplier = value.Value3;
                                string multiplierString = (multiplier == 1.0) ? "" : (FT.DoubleToString(S, multiplier) + " * ");

                                copySB.AppendLine("\t" + dstString + multiplierString + " src" + ptrStr + matrixStr + gradeIdx + "[" + gomMatrixIdx + "];");
                            }
                            else
                            {
                                setToZero.Add(dstString);
                            }
                        }
                    }
                }

                // append copy statements
                defSB.Append(copySB);

                // append statements to set coordinates to zero
                if (setToZero.Count > 0)
                {
                    int cnt = 0;
                    defSB.Append("\t");
                    foreach (string str in setToZero)
                    {
                        defSB.Append(str);
                        cnt++;
                        if (cnt > 8)
                        {
                            cnt = 0;
                            defSB.AppendLine("");
                            defSB.Append("\t\t");
                        }
                    }
                    defSB.AppendLine(FT.DoubleToString(S, 0.0) + ";");
                }

                defSB.AppendLine("}");
            }
        }
Пример #19
0
        /// <summary>
        /// Writes functions to set coordinates of the GMV.
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd">Results go here. Also intermediate data for code generation. Also contains plugins and cog.</param>
        /// <param name="FT"></param>
        /// <param name="SB"></param>
        public static void WriteSetCoord(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT)
        {
            G25.GMV gmv = S.m_GMV;
            string typeName = FT.GetMangledName(S, gmv.Name);

            for (int groupIdx = 0; groupIdx < gmv.NbGroups; groupIdx++)
            {
                for (int elementIdx = 0; elementIdx < gmv.Group(groupIdx).Length; elementIdx++)
                {
                    WriteSetCoordFunction(SB, S, cgd, FT, typeName, groupIdx, elementIdx, gmv.Group(groupIdx).Length, gmv.Group(groupIdx)[elementIdx]);
                }
            }
        }
Пример #20
0
        private static string GetGPcodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, G25.Metric M,
            ProductTypes T,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();
            bool resultIsScalar = (T == ProductTypes.SCALAR_PRODUCT);
            bool initResultToZero = true;
            SB.Append(GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero));

            // get number of groups
            int nbGroups1 = (FAI[0].IsScalar()) ? 1 : gmv.NbGroups;
            int nbGroups2 = (FAI[1].IsScalar()) ? 1 : gmv.NbGroups;
            bool[] GroupAlwaysPresent1 = new bool[nbGroups1];
            bool[] GroupAlwaysPresent2 = new bool[nbGroups2];
            if (FAI[0].IsScalar()) GroupAlwaysPresent1[0] = true;
            if (FAI[1].IsScalar()) GroupAlwaysPresent2[0] = true;

            if (resultIsScalar)
            {
                // make sure scalar part is present in result
                SB.AppendLine("cc[0] = new " + FT.type + "[" + gmv.Group(0).Length + "];");
            }

            int g1Cond = -1; // grade 1 conditional which is open (-1 = none)
            int g2Cond = -1; // grade 2 conditional which is open (-1 = none)

            for (int g1 = 0; g1 < nbGroups1; g1++)
            {
                for (int g2 = 0; g2 < nbGroups2; g2++)
                {
                    for (int g3 = 0; g3 < gmv.NbGroups; g3++)
                    {
                        if (!zero(S, cgd, FT, M, g1, g2, g3, T))
                        {
                            // close conditionals if required
                            if ((((g1Cond != g1) && (g1Cond >= 0)) || (g2Cond != g2)) && (g2Cond >= 0))
                            {
                                SB.AppendLine("\t}");
                                g2Cond = -1;
                            }
                            if ((g1Cond != g1) && (g1Cond >= 0))
                            {
                                SB.AppendLine("}");
                                g1Cond = -1;
                            }

                            // open conditionals if required (group not currently open, and not guaranteed to be present)
                            if ((!GroupAlwaysPresent1[g1]) && (g1Cond != g1))
                            {
                                SB.AppendLine("if (ac[" + g1 + "] != null) {");
                                g1Cond = g1;
                            }
                            if ((!GroupAlwaysPresent2[g2]) && (g2Cond != g2))
                            {
                                SB.AppendLine("\tif (bc[" + g2+ "] != null) {");
                                g2Cond = g2;
                            }

                            if (!(resultIsScalar && (g3 == 0))) // grade 0 is always allocated for scalar result
                                SB.AppendLine("\t\tif (cc[" + g3 + "] == null) cc[" + g3 + "] = new " + FT.type + "[" + gmv.Group(g3).Length + "];");

                            // get function name
                            string funcName = GetGPpartFunctionName(S, FT, M, g1, g2, g3);

                            SB.AppendLine("\t\t" + funcName + "(ac[" + g1 + "], bc[" + g2 + "], cc[" + g3 + "]);");
                        }
                    }
                }
            }

            // close any open conditionals
            if (g2Cond >= 0)
            {
                SB.AppendLine("\t}");
                g2Cond = -1;
            }
            if (g1Cond >= 0)
            {
                SB.AppendLine("}");
                g1Cond = -1;
            }

            if (resultIsScalar)
                SB.AppendLine("return cc[0][0];");
            else SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);");

            return SB.ToString();
        }
Пример #21
0
        private static string GetAddSubtractHpCode_CSharp_Java(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, 
            ADD_SUB_HP_TYPE funcType,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            bool NOT_HP = (!((funcType == ADD_SUB_HP_TYPE.HP) || (funcType == ADD_SUB_HP_TYPE.IHP)));

            StringBuilder SB= new StringBuilder();

            // get number of groups, and possible assurances that a group is always present:
            int nbGroups = gmv.NbGroups;

            bool resultIsScalar = false, initResultToZero = false;
            SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero));

            // for each group
            // test if present in both-> then add both, etc
            for (int g = 0; g < nbGroups; g++)
            {
                SB.AppendLine("");

                string funcName1_1 = GetCopyPartFunctionName(S, FT, g);
                string funcName2 = null;
                string funcName1_2 = null;
                switch (funcType)
                {
                    case ADD_SUB_HP_TYPE.ADD:
                        funcName2 = GetAdd2PartFunctionName(S, FT, g);
                        funcName1_2 = GetCopyPartFunctionName(S, FT, g);
                        break;
                    case ADD_SUB_HP_TYPE.SUB:
                        funcName2 = GetSub2PartFunctionName(S, FT, g);
                        funcName1_2 = GetNegPartFunctionName(S, FT, g);
                        break;
                    case ADD_SUB_HP_TYPE.HP:
                        funcName2 = GetHadamardProductPartFunctionName(S, FT, g);
                        funcName1_2 = null;
                        break;
                    case ADD_SUB_HP_TYPE.IHP:
                        funcName2 = GetInverseHadamardProductPartFunctionName(S, FT, g);
                        funcName1_2 = null;
                        break;
                }

                string allocCcode = "cc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];";

                SB.AppendLine("if (ac[" + g + "] != null) {");
                if (NOT_HP)
                    SB.AppendLine("\t" + allocCcode);

                SB.AppendLine("\tif (bc[" + g + "] != null) {");

                if (!NOT_HP)
                    SB.AppendLine("\t\t" + allocCcode);

                SB.AppendLine("\t\t" + funcName2 + "(ac[" + g + "], bc[" + g + "], cc[" + g + "]);");
                SB.AppendLine("\t}");

                if (NOT_HP)
                    SB.AppendLine("\telse " + funcName1_1 + "(ac[" + g + "], cc[" + g + "]);");

                SB.AppendLine("}");
                if (NOT_HP)
                {
                    SB.AppendLine("else if (bc[" + g + "] != null) {");

                    SB.AppendLine("\t" + allocCcode);
                    SB.AppendLine("\t" + funcName1_2 + "(bc[" + g + "], cc[" + g + "]);");

                    SB.AppendLine("}");
                }

            }

            // return result
            SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);");

            return SB.ToString();
        }
Пример #22
0
        private static string GetGradeCodeCSharpOrJava(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
            int gradeIdx,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName, string groupBitmapName)
        {
            G25.GMV gmv = S.m_GMV;
            if (gradeIdx >= 0)
            {  // if a specific grade is requested, convert it into a group bitmap, and call the grade(A, groupBitmap) function
                // get name of grade function
                string gradeFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, EXTRACT_GRADE, new string[] { gmv.Name, G25.GroupBitmapType.GROUP_BITMAP }, FT, null);

                // turn grade into group
                int groupBitmap = gmv.GradeToGroupBitmap(gradeIdx);
                string castToGroupBitmap = (S.OutputCSharp()) ? "(GroupBitmap)" : "";
                return "return " + gradeFuncName + "(" + FAI[0].Name + ", " + castToGroupBitmap + groupBitmap + ");";
            }
            else
            {
                StringBuilder SB = new StringBuilder();

                int nbGroups = gmv.NbGroups;

                string GroupBitmapType = (S.OutputCSharp()) ? "GroupBitmap" : "int";
                SB.AppendLine(GroupBitmapType + " gu = " + FAI[0].Name + ".to_" + FAI[0].MangledTypeName + "().gu() & " + groupBitmapName + ";");
                bool resultIsScalar = false, initResultToZero = false;
                SB.Append(GPparts.GetExpandCode(S, cgd, FT, FAI, resultIsScalar, initResultToZero));

                // for each group, test if present
                for (int g = 0; g < nbGroups; g++)
                {
                    SB.AppendLine("");

                    string funcName = GetCopyPartFunctionName(S, FT, g);

                    SB.AppendLine("if ((gu & GroupBitmap.GROUP_" + g + ") != 0) {");
                    SB.AppendLine("\tcc[" + g + "] = new " + FT.type + "[" + gmv.Group(g).Length + "];");
                    SB.AppendLine("\t" + funcName + "(ac[" + g + "], cc[" + g + "]);");
                    SB.AppendLine("}");
                }

                SB.AppendLine("return new " + FT.GetMangledName(S, gmv.Name) + "(cc);");

                return SB.ToString();
            }
        }
Пример #23
0
        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);
        }
Пример #24
0
        private static string GetAddSubtractHpCode_C_CPP(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT, 
            ADD_SUB_HP_TYPE funcType,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName)
        {
            G25.GMV gmv = S.m_GMV;

            bool NOT_HP = (!((funcType == ADD_SUB_HP_TYPE.HP) || (funcType == ADD_SUB_HP_TYPE.IHP)));

            StringBuilder SB= new StringBuilder();

            SB.AppendLine("int aidx = 0, bidx = 0, cidx = 0;");

            string agu = (S.OutputC()) ? FAI[0].Name + "->gu" : FAI[0].Name + ".gu()";
            string ac = (S.OutputC()) ? FAI[0].Name + "->c" : FAI[0].Name + ".getC()";
            string bgu = (S.OutputC()) ? FAI[1].Name + "->gu" : FAI[1].Name + ".gu()";
            string bc = (S.OutputC()) ? FAI[1].Name + "->c" : FAI[1].Name + ".getC()";
            string resultCoordPtr = (S.OutputC()) ? resultName + "->c" : "c";

            string guSymbol = (NOT_HP) ? "|" : "&";
            if (S.OutputC())
            {
                SB.AppendLine(resultName + "->gu = " + agu + " " + guSymbol + " " + bgu + ";");
            }
            else
            {
                SB.AppendLine("int gu = " + agu + " " + guSymbol + " " + bgu + ";");
                SB.AppendLine(FT.type + " c[" + (1 << S.m_dimension) + "];");
            }

            // get number of groups, and possible assurances that a group is always present:
            int nbGroups = gmv.NbGroups;

            // for each group
            // test if present in both-> then add both, etc
            for (int g = 0; g < nbGroups; g++)
            {
                SB.AppendLine("");

                string funcName1_1 = GetCopyPartFunctionName(S, FT, g);
                string funcName2 = null;
                string funcName1_2 = null;
                switch (funcType)
                {
                    case ADD_SUB_HP_TYPE.ADD:
                        funcName2 = GetAdd2PartFunctionName(S, FT, g);
                        funcName1_2 = GetCopyPartFunctionName(S, FT, g);
                        break;
                    case ADD_SUB_HP_TYPE.SUB:
                        funcName2 = GetSub2PartFunctionName(S, FT, g);
                        funcName1_2 = GetNegPartFunctionName(S, FT, g);
                        break;
                    case ADD_SUB_HP_TYPE.HP:
                        funcName2 = GetHadamardProductPartFunctionName(S, FT, g);
                        funcName1_2 = null;
                        break;
                    case ADD_SUB_HP_TYPE.IHP:
                        funcName2 = GetInverseHadamardProductPartFunctionName(S, FT, g);
                        funcName1_2 = null;
                        break;
                }

                SB.AppendLine("if (" + agu + " & " + (1 << g) + ") {");
                SB.AppendLine("\tif (" + bgu + " & " + (1 << g) + ") {");

                SB.AppendLine("\t\t" + funcName2 + "(" + ac + " + aidx, " + bc + " + bidx, " + resultCoordPtr + " + cidx);");
                if (g < (nbGroups - 1))
                {
                    SB.AppendLine("\t\tbidx += " + gmv.Group(g).Length + ";");
                    if (!NOT_HP) SB.AppendLine("\t\tcidx += " + gmv.Group(g).Length + ";");
                }
                SB.AppendLine("\t}");

                if (NOT_HP)
                    SB.AppendLine("\telse " + funcName1_1 + "(" + ac + " + aidx, " + resultCoordPtr + " + cidx);");

                if (g < (nbGroups - 1)) SB.AppendLine("\taidx += " + gmv.Group(g).Length + ";");

                if (NOT_HP)
                    SB.AppendLine("\tcidx += " + gmv.Group(g).Length + ";");

                SB.AppendLine("}");
                SB.AppendLine("else if (" + bgu + " & " + (1 << g) + ") {");

                if (NOT_HP)
                    SB.AppendLine("\t" + funcName1_2 + "(" + bc + " + bidx, " + resultCoordPtr + " + cidx);");

                if (g < (nbGroups - 1)) SB.AppendLine("\tbidx += " + gmv.Group(g).Length + ";");

                if (NOT_HP)
                    SB.AppendLine("\tcidx += " + gmv.Group(g).Length + ";");

                SB.AppendLine("}");

            }

            // return result
            if (S.m_outputLanguage != OUTPUT_LANGUAGE.C)
            {
                SB.AppendLine("return " + FT.GetMangledName(S, gmv.Name) + "(gu, c);");
            }

            return SB.ToString();
        }
Пример #25
0
 /// <summary>
 /// Returns the name of a partial geometric product function. 
 /// 
 /// Does not check whether this
 /// combination of groups actually produces any results (i.e., it may be that <c>g1 X g2 -> g3 = 0</c>,
 /// but in that case a name will still be returned.
 /// </summary>
 /// <param name="FT">Float type (used to mangle the name).</param>
 /// <param name="M">The metric (used for the name).</param>
 /// <param name="g1">Grade/group of argument 1.</param>
 /// <param name="g2">Grade/group of argument 2.</param>
 /// <param name="g3">Grade/group of result.</param>
 /// <returns>name of a partial geometric product function.</returns>
 public static string GetGPpartFunctionName(Specification S, G25.FloatType FT, G25.Metric M, int g1, int g2, int g3)
 {
     return FT.GetMangledName(S, "gp") + "_" + M.m_name + "_" + g1 + "_" + g2 + "_" + g3;
 }
Пример #26
0
        /// <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}");
            }
        }
Пример #27
0
        /// <summary>
        /// Returns the code for applying a versor <c>V</c>to some multivector <c>M</c> (V M / V).
        /// The code is composed of calls to functions generated by <c>WriteGmvGpParts()</c>.
        /// 
        /// This function does not explicitly use the geometric product parts code, but makes calls
        /// to the geometric product and the reverse/versor inverse. As such it generates dependencies
        /// on <c>gp</c>, <c>reverse</c>, <c>versorInverse</c> and <c>grade</c>.
        /// 
        /// Three types of code can be generated, depending on the value of 
        /// argument <c>T</c>:
        ///   - <c>REVERSE</c>: the versor is unit, so the reverse can be used.
        ///   - <c>INVERSE</c>: the versor inverse is used to compute the inverse.
        ///   - <c>EXPLICIT_INVERSE</c>: the inverse is explicitly provided.
        /// 
        /// The returned code is only the body. The function declaration is not included.
        /// </summary>
        /// <param name="S">Specification of algebra (used for output language).</param>
        /// <param name="cgd">Used for resolving dependencies.</param>
        /// <param name="FT">Floating point type.</param>
        /// <param name="M">Metric type used in the geometric products.</param>
        /// <param name="T">The product (e.g., geometric, outer, etc).</param>
        /// <param name="FAI">Info about function arguments. All arguments must be general multivectors.</param>
        /// <param name="resultName">Name of variable where the result goes (in the generated code).</param>
        /// <returns>code for the requested product type.</returns>
        public static string GetVersorApplicationCode(Specification S, G25.CG.Shared.CGdata cgd, 
            G25.FloatType FT, G25.Metric M, ApplyVersorTypes T,
            G25.CG.Shared.FuncArgInfo[] FAI, String resultName)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

            // get geometric product function
            string gpFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, "gp", new String[] { gmv.Name, gmv.Name }, FT, M.m_name);

            // get reverse or inverse function
            string invFuncName = null;
            if ((T == ApplyVersorTypes.INVERSE) || (T == ApplyVersorTypes.REVERSE))
            {
                string inputFuncName = (T == ApplyVersorTypes.INVERSE) ? "versorInverse" : "reverse";

                invFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd,
                     inputFuncName, new string[] { gmv.Name }, FT, (T == ApplyVersorTypes.INVERSE) ? M.m_name : null);
            }

            // get grade function
            string gradeFuncName = G25.CG.Shared.Dependencies.GetDependency(S, cgd, G25.CG.Shared.CANSparts.EXTRACT_GRADE, new String[] { gmv.Name, G25.GroupBitmapType.GROUP_BITMAP }, FT, null);

            // get string to be used for grade extraction
            string gradeUsageString;
            string bgu;
            if (S.OutputC()) {
                bgu = FAI[1].Name + "->gu";
            }
            else if (S.OutputCSharpOrJava()) {
                bgu = FAI[1].Name + ".to_" + FAI[1].MangledTypeName + "().gu()";
            }
            else {
                bgu = FAI[1].Name + ".gu()";
            }

            string groupBitmapType = (S.OutputCSharp() ? "GroupBitmap" : "int");
            if (!gmv.IsGroupedByGrade(S.m_dimension))
            {
                SB.AppendLine(groupBitmapType + " gradeUsageBitmap;");
                gradeUsageString = "gradeUsageBitmap";
            }
            else
            {
                gradeUsageString = bgu;
                /*if (S.OutputC())
                    gradeUsageString = FAI[1].Name + "->gu";
                else gradeUsageString = FAI[1].Name + ".gu()";*/
            }

            // select grade parts!
            StringBuilder gradeUsageCode = new StringBuilder();
            if (!gmv.IsGroupedByGrade(S.m_dimension))
            {
                string groupBitmapStr = (S.OutputCSharpOrJava() ? ("GroupBitmap.") : "");
                gradeUsageCode.Append(gradeUsageString + " = ");
                for (int g = 0; g <= S.m_dimension; g++)
                {
                    if (g > 0) gradeUsageCode.Append(" | ");
                    gradeUsageCode.Append("(((" + bgu + " & " + groupBitmapStr + "GRADE_" + g + ") != 0) ? " + groupBitmapStr + "GRADE_" + g + " : 0)");
                }
                gradeUsageCode.AppendLine(";");
            }

            if (S.OutputC())
            {
                // get name of inverse, decl tmp variable for inverse if required
                string inverseInputName;
                if (T == ApplyVersorTypes.EXPLICIT_INVERSE) inverseInputName = FAI[2].Name;
                else if (T == ApplyVersorTypes.INVERSE)
                {
                    inverseInputName = "&inv";
                    SB.AppendLine(FT.GetMangledName(S, gmv.Name) + " inv; /* temp space for reverse */");
                }
                else // (T == ApplyVersorTypes.REVERSE)
                {
                    inverseInputName = "&rev";
                    SB.AppendLine(FT.GetMangledName(S, gmv.Name) + " rev; /* temp space for reverse */");
                }

                // get temp space for input * object
                SB.AppendLine(FT.GetMangledName(S, gmv.Name) + " tmp, tmp2; /* temp variables */");

                // compute inverse or reverse, if required
                if ((T == ApplyVersorTypes.INVERSE) || (T == ApplyVersorTypes.REVERSE))
                {
                    SB.AppendLine(invFuncName + "(" + inverseInputName + ", " + FAI[0].Name + "); /* compute inverse or reverse */");
                }

                // compute input * object
                SB.AppendLine(gpFuncName + "(&tmp, " + FAI[0].Name + ", " + FAI[1].Name + "); /* compute geometric product " + FAI[0].Name + " " + FAI[1].Name + " */");

                // compute (input * object) * inverse
                SB.AppendLine(gpFuncName + "(&tmp2, &tmp, " + inverseInputName + "); /* compute geometric product (" + FAI[0].Name + " " + FAI[1].Name + ") " + inverseInputName + " */");

                // select grade parts!
                SB.AppendLine(gradeUsageCode.ToString());
                SB.AppendLine(gradeFuncName + "(" + resultName + ", &tmp2, " + gradeUsageString + "); /* ditch grade parts which were not in " + FAI[1].Name + " */");
            } // end of 'C' version
            else // C++ version
            {
                if (gradeUsageCode.Length > 0)
                    SB.AppendLine(gradeUsageCode.ToString());
                string inverseCode = ((T == ApplyVersorTypes.INVERSE) || (T == ApplyVersorTypes.REVERSE))
                    ? (invFuncName + "(" + FAI[0].Name + ")")
                    : FAI[2].Name;

                SB.AppendLine("return " + gradeFuncName + "(" + gpFuncName + "(" + gpFuncName + "(" + FAI[0].Name + ", " + FAI[1].Name + "), " + inverseCode + "), " + gradeUsageString + ");");
            }

            return SB.ToString();
        }
Пример #28
0
        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();
        }
Пример #29
0
        public static string GetCompressCode(Specification S, G25.FloatType FT,
            G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool resultIsScalar, string GUstr)
        {
            if ((GUstr == null) || (GUstr.Length == 0))
            {
                GUstr = ((1 << S.m_GMV.NbGroups) - 1).ToString();
            }

            StringBuilder SB = new StringBuilder();
            if (resultIsScalar)
            {
                SB.AppendLine("return c[0];");
            }
            else
            {
                string funcName = (S.OutputC())
                    ? FT.GetMangledName(S, "compress")
                    : FT.GetMangledName(S, S.m_GMV.Name) + "_compress";

                if (S.m_outputLanguage != OUTPUT_LANGUAGE.C)
                    SB.Append("return ");

                SB.Append(funcName + "(c, ");
                if (S.OutputC())
                    SB.Append(resultName + "->c, &(" + resultName + "->gu), ");
                SB.AppendLine(FT.DoubleToString(S, 0.0) + ", " + GUstr + ");");
            }
            return SB.ToString();
        }
Пример #30
0
 /// <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;
 }