Exemple #1
0
        /// <param name="S"></param>
        /// <param name="FT"></param>
        /// <param name="M"></param>
        /// <param name="d">1 -> generate dual, d = 0 -> generate undual</param>
        /// <param name="g1"></param>
        /// <param name="gd"></param>
        /// <param name="name1"></param>
        /// <param name="name2"></param>
        /// <param name="name3"></param>
        /// <returns>The code to compute a (un)dual at runtime using the geometric product tables.</returns>
        public static string GetRuntimeDualCode(G25.Specification S, G25.FloatType FT, G25.Metric M,
                                                int d, int g1, int gd,
                                                string name1, string name2, string name3)
        {
            // get pseudoscalar
            RefGA.Multivector I = RefGA.Multivector.GetPseudoscalar(S.m_dimension);
            if (d == 1) // if dual: use inverse I
            {
                I = RefGA.Multivector.VersorInverse(I, M.m_metric);
            }

            // get grade/group of pseudoscalar in GMV
            int g2 = S.m_GMV.GetGroupIdx(I.BasisBlades[0]);

            // get sign of pseudo scalar basis blade in GMV:
            double IbladeSign = S.m_GMV.Group(g2)[0].scale;

            string tmpArrayCode;

            if (S.OutputCppOrC())
            {
                tmpArrayCode = "\t" + FT.type + " " + name2 + "[1] = {" + FT.DoubleToString(S, IbladeSign * I.BasisBlades[0].scale) + "};\n";
            }
            else
            {
                tmpArrayCode = "\t\t" + FT.type + "[] " + name2 + " = new " + FT.type + "[]{" + FT.DoubleToString(S, IbladeSign * I.BasisBlades[0].scale) + "};\n\t";
            }

            return
                (tmpArrayCode +
                 "\t" + GPparts.GetGPpartFunctionName(S, FT, M, g1, g2, gd) + "(" + name1 + ", " + name2 + ", " + name3 + ");\n");
        }
Exemple #2
0
        private static string GetDualCodeCppOrC(Specification S, G25.CG.Shared.CGdata cgd, G25.FloatType FT,
                                                G25.Metric M, G25.CG.Shared.FuncArgInfo[] FAI, string resultName, bool dual)
        {
            G25.GMV gmv = S.m_GMV;

            StringBuilder SB = new StringBuilder();

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

            // allocate memory to store result:
            SB.AppendLine("int idx = 0;");
            bool resultIsScalar   = false;
            bool initResultToZero = true; // must init to zero because of compression

            SB.Append(GPparts.GetExpandCode(S, cgd, FT, null, resultIsScalar, initResultToZero));

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

            // for each combination of groups, check if the dual goes from one to the other
            for (int gi = 0; gi < nbGroups; gi++)
            {
                SB.AppendLine("if (" + agu + " & " + (1 << gi) + ") {");
                for (int go = 0; go < nbGroups; go++)
                {
                    string funcName = (dual) ? GetDualPartFunctionName(S, FT, M, gi, go) : GetUndualPartFunctionName(S, FT, M, gi, go);
                    Tuple <string, string, string> key = new Tuple <string, string, string>(FT.type, M.m_name, funcName);
                    if (cgd.m_gmvDualPartFuncNames.ContainsKey(key) &&
                        cgd.m_gmvDualPartFuncNames[key])
                    {
                        SB.AppendLine("\t" + funcName + "(" + ac + " + idx, c + " + gmv.GroupStartIdx(go) + ");");
                    }
                }
                if (gi < (nbGroups - 1))
                {
                    SB.AppendLine("\tidx += " + gmv.Group(gi).Length + ";");
                }
                SB.AppendLine("}");
                SB.AppendLine("");
            }

            // compress result
            SB.Append(GPparts.GetCompressCode(S, FT, FAI, resultName, resultIsScalar));

            return(SB.ToString());
        } // end of GetDualCodeCppOrC()
Exemple #3
0
        } // 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()
Exemple #4
0
        } // 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()
Exemple #5
0
        private static string GetApplyGomCodeCppOrC(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("int idxB = 0, gu = 0, idxC = 0;");
            bool resultIsScalar   = false;
            bool initResultToZero = !groupedByGrade;

            SB.Append(GPparts.GetExpandCode(S, cgd, FT, null, resultIsScalar, initResultToZero));

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

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

            int dstGrade = 0;
            int srcGradeSizeAccumulator = 0;

            // for each combination of groups, check if the OM goes from one to the other
            for (int srcGroup = 0; srcGroup < nbGroups; srcGroup++)
            {
                // increment the index into 'C' when we switch grade
                int srcGrade = gmv.Group(srcGroup)[0].Grade();
                if (srcGrade != dstGrade)
                {
                    if (!groupedByGrade)
                    {
                        SB.AppendLine("idxC += " + srcGradeSizeAccumulator + ";");
                        SB.AppendLine("");
                    }
                    dstGrade = srcGrade;
                    srcGradeSizeAccumulator = 0;
                }
                srcGradeSizeAccumulator += gmv.Group(srcGroup).Length;

                SB.AppendLine("if (" + bgu + " & " + (1 << srcGroup) + ") {");
                int dstGradeSizeAccumulator = 0;
                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])
                    {
                        SB.AppendLine("\t" + funcName + "(" + FAI[0].Name + ", " + bc + " + idxB, c + idxC + " + dstGradeSizeAccumulator + ");");
                    }
                    if (gmv.Group(dstGroup)[0].Grade() == srcGrade)
                    {
                        dstGradeSizeAccumulator += gmv.Group(dstGroup).Length;
                    }
                }
                if (srcGroup < (nbGroups - 1))
                {
                    SB.AppendLine("\tidxB += " + gmv.Group(srcGroup).Length + ";");
                    if (groupedByGrade)
                    {
                        SB.AppendLine("\tidxC += " + gmv.Group(srcGroup).Length + ";");
                        SB.AppendLine("");
                    }
                }
                SB.AppendLine("}");
                SB.AppendLine("");
            }

            // generate code to compress result
            string cgu = (groupedByGrade) ? bgu : null;                                      // null means: all groups/grades are present

            SB.Append(GPparts.GetCompressCode(S, FT, FAI, resultName, resultIsScalar, cgu)); // todo: bgu should be 63 when not grouped by grade

            return(SB.ToString());
        } // end of GetApplyGomCodeCppOrC