예제 #1
0
 public static void GenerateBasisElementsArray(Specification S, G25.CG.Shared.CGdata cgd, StringBuilder SB)
 {
     G25.GMV gmv = S.m_GMV;
     // basis vectors in basis elements
     SB.AppendLine("const int " + S.m_namespace + "_basisElements[" + (1 << S.m_dimension) + "][" + (S.m_dimension + 1) + "] = {");
     {
         bool comma = false;
         for (int i = 0; i < gmv.NbGroups; i++)
         {
             for (int j = 0; j < gmv.Group(i).Length; j++)
             {
                 if (comma)
                 {
                     SB.Append(",\n");
                 }
                 RefGA.BasisBlade B = gmv.Group(i)[j];
                 SB.Append("\t{");
                 for (int k = 0; k < S.m_dimension; k++)
                 {
                     if ((B.bitmap & (1 << k)) != 0)
                     {
                         SB.Append(k + ", ");
                     }
                 }
                 SB.Append("-1}");
                 comma = true;
             }
         }
     }
     SB.AppendLine("");
     SB.AppendLine("};");
 }
예제 #2
0
        } // end of GetAccessStr()

        /// <summary>
        /// Returns an array of 'access strings' for a specific group of the general multivector.
        /// Access strings are source code expressions that can be
        /// used to access the coordinates of one specific group of coordinates of <c>gmv</c>.
        /// </summary>
        /// <param name="S">Used for basis blade names, language, COORD_STORAGE , etc.</param>
        /// <param name="gmv">The specialized multivector for which access strings are generated.</param>
        /// <param name="gmvName">The variable name of the _array_ of float to be used in the access strings.
        /// For example, specify <c>"A"</c> to get <c>"A[0]"</c> and so on.</param>
        /// <param name="groupIdx">Specifies for that group index the access strings should be generated.</param>
        /// <param name="baseIdx">Index of first coordinate of group (required for C# and Java)</param>
        /// <returns>Array of strings that can be used to access the coordinates of group <c>groupIdx</c> of the <c>gmv</c>.</returns>
        public static string[] GetAccessStr(Specification S, G25.GMV gmv, String gmvName, int groupIdx, int baseIdx)
        {
            string[] AL = new String[gmv.Group(groupIdx).Length];

            for (int i = 0; i < gmv.Group(groupIdx).Length; i++)
            {
                AL[i] = gmvName + "[" + (baseIdx + i) + "]";
            }

            return(AL);
        } // end of GetAccessStr()
예제 #3
0
        public static void GenerateMultivectorSizeArray(Specification S, G25.CG.Shared.CGdata cgd, StringBuilder SB)
        {
            G25.GMV gmv = S.m_GMV;

            // size of multivector based on grade usage bitmap
            SB.AppendLine("const int " + S.m_namespace + "_mvSize[" + (1 << gmv.NbGroups) + "] = {");
            SB.Append("\t");
            for (int i = 0; i < (1 << gmv.NbGroups); i++)
            {
                int s = 0;
                for (int j = 0; j < gmv.NbGroups; j++)
                {
                    if ((i & (1 << j)) != 0)
                    {
                        s += gmv.Group(j).Length;
                    }
                }
                SB.Append(s);
                if (i != ((1 << gmv.NbGroups) - 1))
                {
                    SB.Append(", ");
                }
                if ((i % 20) == 19)
                {
                    SB.AppendLine("");
                    SB.Append("\t");
                }
            }

            SB.AppendLine("};");
        }
예제 #4
0
        private static void GenerateMultivectorSizeArrayInit(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd)
        {
            string accessModifierArr = Keywords.ConstArrayAccessModifier(S);

            G25.GMV gmv = S.m_GMV;

            // size of multivector based on grade usage bitmap
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] MvSize = new int[] {");
            SB.Append("\t\t");
            for (int i = 0; i < (1 << gmv.NbGroups); i++)
            {
                int s = 0;
                for (int j = 0; j < gmv.NbGroups; j++)
                {
                    if ((i & (1 << j)) != 0)
                    {
                        s += gmv.Group(j).Length;
                    }
                }
                SB.Append(s);
                if (i != ((1 << gmv.NbGroups) - 1))
                {
                    SB.Append(", ");
                }
                if ((i % 20) == 19)
                {
                    SB.AppendLine("");
                    SB.Append("\t\t");
                }
            }

            SB.AppendLine("\t};");
        }
예제 #5
0
        /// <summary>
        /// Takes a general multivector specification (G25.GMV) and converts it into a one symbolic multivector per group/grade part.
        ///
        /// The symbolic weights of the multivector are the coordinates of the GMV, labelled according to 'gmvName'.
        /// Currently, the indices start at zero for each group.
        /// </summary>
        /// <param name="S">Specification of the algebra. Used for the access convention (. or ->) and for how to name the coordinates ([0] or e1, e2, e3).</param>
        /// <param name="gmv">The specification of the general multivector.</param>
        /// <param name="gmvName">Name the variable should have.</param>
        /// <param name="ptr">Is 'gmvName' a pointer? (not used currently)</param>
        /// <param name="groupIdx">Index of group/grade to convert (use -1 for all groups)</param>
        /// <returns></returns>
        public static RefGA.Multivector[] GMVtoSymbolicMultivector(Specification S, G25.GMV gmv, String gmvName, bool ptr, int groupIdx)
        {
            RefGA.Multivector[] R = new RefGA.Multivector[gmv.NbGroups];

            //String accessStr = (ptr) ? "->" : ".";

            for (int g = 0; g < gmv.NbGroups; g++)
            {
                if ((groupIdx >= 0) && (g != groupIdx))
                {
                    continue;                                     // only one group requested?
                }
                RefGA.BasisBlade[] B = gmv.Group(g);
                RefGA.BasisBlade[] L = new RefGA.BasisBlade[B.Length];
                for (int i = 0; i < B.Length; i++)
                {
                    RefGA.BasisBlade b             = B[i];
                    String           fullCoordName = gmvName + "[" + i + "]";
                    // merge
                    L[i] = new RefGA.BasisBlade(b.bitmap, b.scale, fullCoordName);
                }
                R[g] = new RefGA.Multivector(L);
            }

            return(R);
        } // end of function GMVtoSymbolicMultivector()
예제 #6
0
        public static void GenerateBasisElementsArray(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd)
        {
            string accessModifierArr = Keywords.ConstArrayAccessModifier(S);

            G25.GMV gmv = S.m_GMV;
            // basis vectors in basis elements
            new G25.CG.Shared.Comment("This array of integers contains the order of basis elements in the general multivector.\n" +
                                      "Use it to answer: 'what basis vectors are in the basis element at position [x]?").Write(SB, S, 1);
            SB.Append("\tpublic " + accessModifierArr + " int[][] BasisElements = ");
            if (S.m_gmvCodeGeneration == GMV_CODE.EXPAND)
            {
                SB.AppendLine("new int[][] {");
                {
                    bool comma = false;
                    for (int i = 0; i < gmv.NbGroups; i++)
                    {
                        for (int j = 0; j < gmv.Group(i).Length; j++)
                        {
                            if (comma)
                            {
                                SB.Append(",\n");
                            }
                            RefGA.BasisBlade B = gmv.Group(i)[j];
                            SB.Append("\t\tnew int[] {");
                            for (int k = 0; k < S.m_dimension; k++)
                            {
                                if ((B.bitmap & (1 << k)) != 0)
                                {
                                    SB.Append(k + ", ");
                                }
                            }
                            SB.Append("-1}");
                            comma = true;
                        }
                    }
                }
                SB.AppendLine("");
                SB.AppendLine("\t};");
            }
            else
            {
                SB.AppendLine(G25.CG.CSJ.Util.GetFunctionName(S, "initBasisElementsArray") + "();");
                SB.AppendLine();

                cgd.m_cog.EmitTemplate(SB, "initBasisElementsArray", "S=", S);
            }
        }
예제 #7
0
        } // end of GenerateSMVassignmentCode

        /// <summary>
        /// Generates the code to assign a multivector value (which may have symbolic coordinates) to one specific coordinate group of a multivector.
        /// </summary>
        /// <param name="S">Specification of algebra. Used to known names of basis vector, output language, access strings, etc.</param>
        /// <param name="FT">Floating point type of destination.</param>
        /// <param name="mustCast">set to true if a cast to 'FT' must be performed before assigned to 'dstName'.</param>
        /// <param name="dstGmv">Type of general multivector assigned to.</param>
        /// <param name="dstName">Name of specialized multivector assigned to.</param>
        /// <param name="dstGroupIdx">Write to which group in destination type?</param>
        /// <param name="dstBaseIdx">Base index of coordinate 0 of group (needed for C# and Java)</param>
        /// <param name="value">Multivector value to assign to the GMV. Must not contain basis blades inside the symbolic scalars.</param>
        /// <param name="nbTabs">Number of tabs to put before the code.</param>
        /// <param name="writeZeros">Some callers want to skip "= 0.0" assignments because they would be redundant. So they set this argument to true.</param>
        /// <returns>String of code for dstName = value;</returns>
        public static string GenerateGMVassignmentCode(Specification S, FloatType FT, bool mustCast,
                                                       G25.GMV dstGmv, string dstName, int dstGroupIdx, int dstBaseIdx, RefGA.Multivector value, int nbTabs, bool writeZeros)
        {
            RefGA.BasisBlade[] BL          = dstGmv.Group(dstGroupIdx);
            string[]           accessStr   = GetAccessStr(S, dstGmv, dstName, dstGroupIdx, dstBaseIdx);
            string[]           assignedStr = GetAssignmentStrings(S, FT, mustCast, BL, value, writeZeros);

            return(GenerateAssignmentCode(S, accessStr, assignedStr, nbTabs, writeZeros));
        } // end of GenerateSMVassignmentCode
예제 #8
0
        /// <summary>
        /// Returns the comment for a GMV class.
        /// </summary>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param>
        /// <param name="FT">Float point type of 'GMV'.</param>
        /// <param name="gmv">The general multivector for which the class should be written.</param>
        public static Comment GetGmvComment(Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.GMV gmv)
        {
            StringBuilder SB = new StringBuilder();

            SB.AppendLine("This class can hold a general multivector.");
            SB.AppendLine("");

            SB.AppendLine("The coordinates are stored in type " + FT.type + ".");
            SB.AppendLine("");

            SB.AppendLine("There are " + gmv.NbGroups + " coordinate groups:");
            for (int g = 0; g < gmv.NbGroups; g++)
            {
                SB.Append("group " + g + ":");
                for (int i = 0; i < gmv.Group(g).Length; i++)
                {
                    if (i > 0) SB.Append(", ");
                    SB.Append(gmv.Group(g)[i].ToString(S.m_basisVectorNames));

                }
                if (gmv.Group(g).Length > 0)
                    SB.Append("  (grade " + gmv.Group(g)[0].Grade() + ")");

                SB.AppendLine(".");
            }
            SB.AppendLine("");

            switch (S.m_GMV.MemoryAllocationMethod)
            {
                case G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE:
                    SB.AppendLine("" + (gmv.NbCoordinates / 2) + " " + FT.type + "s are allocated inside the struct ('parity pure').");
                    SB.AppendLine("Hence creating a multivector which needs more than that number of coordinates ");
                    SB.AppendLine("will result in unpredictable behaviour (buffer overflow).");
                    break;
                case G25.GMV.MEM_ALLOC_METHOD.FULL:
                    SB.AppendLine("" + gmv.NbCoordinates + " " + FT.type + "s are allocated inside the struct.");
                    break;
            }

            return new Comment(SB.ToString());
        } // end of GetGmvComment()
예제 #9
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(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]);
                }
            }
        }
예제 #10
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;}");
        }
예제 #11
0
        /// <summary>
        /// Writes functions to reserve a coordinate group
        /// </summary>
        /// <param name="S"></param>
        /// <param name="cgd"></param>
        public static void WriteReserveGroups(Specification S, G25.CG.Shared.CGdata cgd)
        {
            //StringBuilder declSB = cgd.m_declSB;
            //StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            G25.GMV gmv = S.m_GMV;
            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                string typeName = FT.GetMangledName(S, gmv.Name);

                for (int groupIdx = 0; groupIdx < gmv.NbGroups; groupIdx++)
                {
                    WriteReserveGroup(S, cgd, FT, typeName, groupIdx, gmv.Group(groupIdx).Length);
                }
            }
        }
예제 #12
0
 public static void GenerateGroupSizeArray(Specification S, G25.CG.Shared.CGdata cgd, StringBuilder SB)
 { // group size
     G25.GMV gmv = S.m_GMV;
     SB.AppendLine("const int " + S.m_namespace + "_groupSize[" + gmv.NbGroups + "] = {");
     SB.Append("\t");
     for (int i = 0; i < gmv.NbGroups; i++)
     {
         if (i > 0)
         {
             SB.Append(", ");
         }
         SB.Append(gmv.Group(i).Length);
     }
     SB.AppendLine("");
     SB.AppendLine("};");
 }
예제 #13
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()
예제 #14
0
        public static void GenerateGroupSizeArray(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd)
        { // group size
            string accessModifierArr = Keywords.ConstArrayAccessModifier(S);

            G25.GMV gmv = S.m_GMV;
            new G25.CG.Shared.Comment("This array can be used to lookup the number of coordinates for a group part of a general multivector.").Write(SB, S, 1);
            SB.Append("\tpublic " + accessModifierArr + " int[] GroupSize = { ");
            for (int i = 0; i < gmv.NbGroups; i++)
            {
                if (i > 0)
                {
                    SB.Append(", ");
                }
                SB.Append(gmv.Group(i).Length);
            }
            SB.AppendLine(" };");
        }
예제 #15
0
        /// <summary>
        /// Writes functions to copy GMVs from one float type to another.
        /// </summary>
        /// <param name="SB">Where the output goes.</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="dstFT"></param>
        public static void WriteGMVtoGMVcopy(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType dstFT)
        {
            G25.GMV gmv = S.m_GMV;
            foreach (G25.FloatType srcFT in S.m_floatTypes)
            {
                string srcClassName = srcFT.GetMangledName(S, gmv.Name);

                //string dstClassName = dstFT.GetMangledName(S, gmv.Name);

                string funcName = GetSetFuncName(S);

                string funcDecl = "\tpublic void " + funcName + "(" + srcClassName + " src)";

                int nbTabs = 1;
                new G25.CG.Shared.Comment("sets this to multivector value.").Write(SB, S, nbTabs);

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

                SB.AppendLine("\t\t" + GetAllocateGroupsString(S) + "(src.gu());");

                for (int g = 0; g < gmv.NbGroups; g++)
                {
                    SB.AppendLine("\t\tif (m_c[" + g + "] != null) {");
                    if (dstFT == srcFT)
                    {
                        SB.Append("\t\t\t" + G25.CG.Shared.Util.GetCopyCode(S, dstFT, "src.m_c[" + g + "]", "m_c[" + g + "]", gmv.Group(g).Length));
                    }
                    else
                    {
                        SB.AppendLine("\t\t\tfor (int i = 0; i < " + gmv.Group(g).Length + "; i++)");
                        SB.AppendLine("\t\t\t\tm_c[" + g + "][i] = (" + dstFT.type + ")src.m_c[" + g + "][i];");
                    }

                    SB.AppendLine("\t\t}");
                }

                if (S.m_reportUsage)
                {
                    SB.AppendLine("\t\tm_t = src.m_t;");
                }

                SB.AppendLine("\t}");
            }
        }
예제 #16
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>
        public static void WriteCoordAccess(Specification S, G25.CG.Shared.CGdata cgd)
        {
            //StringBuilder declSB = cgd.m_declSB;
            //StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            G25.GMV gmv = S.m_GMV;
            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                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++)
                    {
                        WriteCoordExtractFunction(S, cgd, FT, typeName, groupIdx, elementIdx, gmv.Group(groupIdx)[elementIdx]);
                        WriteCoordSetFunction(S, cgd, FT, typeName, groupIdx, elementIdx, gmv.Group(groupIdx).Length, gmv.Group(groupIdx)[elementIdx]);
                    }
                }
            }
        }
예제 #17
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()
예제 #18
0
        /// <summary>
        /// Generates functions which compute the dual or undual of general multivectors, on a group by group basis.
        ///
        /// This function should be called early on in the code generation process, at least
        /// before any of the <c>GetDualCode()</c> functions is called.
        /// </summary>
        /// <param name="S">Specification (used for output language, GMV).</param>
        /// <param name="cgd">Where the result goes.</param>
        public static void WriteDualParts(Specification S, CGdata cgd)
        {
            G25.GMV gmv = S.m_GMV;

            string name1      = "A";
            string name2      = "B";
            string name3      = "C";
            bool   ptr        = true;
            int    allGroups  = -1;
            bool   mustCast   = false;
            int    nbBaseTabs = (S.OutputCSharpOrJava()) ? 1 : 0;
            int    nbCodeTabs = nbBaseTabs + 1;
            bool   writeZeros = false;

            // get symbolic multivectors
            RefGA.Multivector[] M1 = null;
            if (S.m_gmvCodeGeneration == GMV_CODE.EXPAND)
            {
                M1 = G25.CG.Shared.Symbolic.GMVtoSymbolicMultivector(S, gmv, name1, ptr, allGroups);
            }

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                // map from code fragment to name of function
                Dictionary <string, string> generatedCode = new Dictionary <string, string>();

                foreach (G25.Metric M in S.m_metric)
                {
                    if (M.m_metric.IsDegenerate())
                    {
                        continue;                            // do not generate code for degenerate metrics
                    }
                    for (int g1 = 0; g1 < gmv.NbGroups; g1++)
                    {
                        for (int d = 1; d >= 0; d--) // d = 1 -> generate dual, d = 0 -> generate undual
                        {
                            // get value of operation, name of function:
                            RefGA.Multivector value = null;
                            if (S.m_gmvCodeGeneration == GMV_CODE.EXPAND)
                            {
                                try
                                {
                                    value = (d == 0) ? RefGA.Multivector.Undual(M1[g1], M.m_metric) : RefGA.Multivector.Dual(M1[g1], M.m_metric);
                                }
                                catch (Exception)
                                {
                                    cgd.AddError(new G25.UserException("Non-invertable pseudoscalar. Do not generate (un)dual functions for degenerate metrics."));
                                    return;
                                }
                                if (M.m_round)
                                {
                                    value = value.Round(1e-14);
                                }
                            }


                            int grade     = gmv.Group(g1)[0].Grade();
                            int dualGrade = S.m_dimension - grade;
                            for (int g3 = 0; g3 < gmv.NbGroups; g3++)
                            {
                                if (gmv.Group(g3)[0].Grade() == dualGrade)
                                {
                                    string funcName = (d == 0) ? GetUndualPartFunctionName(S, FT, M, g1, g3) : GetDualPartFunctionName(S, FT, M, g1, g3);

                                    // get assignment code
                                    string code = "";

                                    if (S.m_gmvCodeGeneration == GMV_CODE.EXPAND)
                                    { // full code expansion
                                        int dstBaseIdx = 0;
                                        code = G25.CG.Shared.CodeUtil.GenerateGMVassignmentCode(S, FT, mustCast, gmv, name3, g3, dstBaseIdx, value, nbCodeTabs, writeZeros);
                                    }
                                    else if (S.m_gmvCodeGeneration == GMV_CODE.RUNTIME)
                                    { // runtime code
                                        code = GetRuntimeDualCode(S, FT, M, d, g1, g3, name1, name2, name3);
                                    }

                                    cgd.m_gmvDualPartFuncNames[new Tuple <string, string, string>(FT.type, M.m_name, funcName)] = (code.Length > 0);

                                    if (code.Length == 0)
                                    {
                                        continue;                   // only if code is non-empty
                                    }
                                    // is the following ever required: (i.e. the dual of a basis blade wrt to the full space is not a single basis blade?)
                                    //if (!M.m_metric.IsDiagonal())
                                    //    code = code.Replace("=", "+=");

                                    // check if code was already generated, and, if so, reuse it
                                    if (generatedCode.ContainsKey(code))
                                    {
                                        // ready generated: call that function
                                        code = new string('\t', nbCodeTabs) + generatedCode[code] + "(" + name1 + ", " + name3 + ");\n";
                                    }
                                    else
                                    {
                                        // not generated yet: remember code -> function
                                        generatedCode[code] = funcName;
                                    }

                                    // write comment
                                    string comment = "Computes the partial " + ((d == 0) ? "un" : "") + "dual (w.r.t. full space) of a multivector.";

                                    string ACCESS = "";
                                    if (S.OutputJava())
                                    {
                                        ACCESS = "protected final static ";
                                    }
                                    else if (S.OutputCSharp())
                                    {
                                        ACCESS = "protected internal static ";
                                    }
                                    string ARR   = (S.OutputCSharpOrJava()) ? "[] " : " *";
                                    string CONST = (S.OutputCSharpOrJava()) ? "" : "const ";

                                    string funcDecl = ACCESS + "void " + funcName + "(" + CONST + FT.type + ARR + name1 + ", " + FT.type + ARR + name3 + ")";

                                    if (S.OutputCppOrC())
                                    {
                                        new Comment(comment).Write(cgd.m_declSB, S, nbBaseTabs);
                                        cgd.m_declSB.Append(funcDecl); cgd.m_declSB.AppendLine(";");
                                    }
                                    else
                                    {
                                        new Comment(comment).Write(cgd.m_defSB, S, nbBaseTabs);
                                    }

                                    // emit def
                                    cgd.m_defSB.Append('\t', nbBaseTabs);
                                    cgd.m_defSB.Append(funcDecl);
                                    cgd.m_defSB.AppendLine(" {");
                                    cgd.m_defSB.Append(code);
                                    cgd.m_defSB.Append('\t', nbBaseTabs);
                                    cgd.m_defSB.AppendLine("}");
                                }
                            } // end of loop over all output groups
                        }     // end of loop over undual (0) and dual(1)
                    }         // end of loop over all input groups
                }             // end of loop over all metric
            }                 // end of loop over all float types
        }                     // end of function WriteDualParts()
예제 #19
0
        public static void GenerateBasisElementArrays(Specification S, G25.CG.Shared.CGdata cgd, StringBuilder SB)
        {
            G25.GMV gmv = S.m_GMV;

            double[] s             = new double[1 << S.m_dimension];
            int[]    IndexByBitmap = new int[1 << S.m_dimension];
            int[]    BitmapByIndex = new int[1 << S.m_dimension];
            int[]    GradeByBitmap = new int[1 << S.m_dimension];
            int[]    GroupByBitmap = new int[1 << S.m_dimension];
            SB.AppendLine("const double " + S.m_namespace + "_basisElementSignByIndex[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                bool comma = false;
                int  idx   = 0;
                for (int i = 0; i < gmv.NbGroups; i++)
                {
                    for (int j = 0; j < gmv.Group(i).Length; j++)
                    {
                        if (comma)
                        {
                            SB.Append(", ");
                        }
                        RefGA.BasisBlade B = gmv.Group(i)[j];
                        s[gmv.Group(i)[j].bitmap] = B.scale;
                        IndexByBitmap[B.bitmap]   = idx;
                        BitmapByIndex[idx]        = (int)B.bitmap;
                        GradeByBitmap[B.bitmap]   = B.Grade();
                        GroupByBitmap[B.bitmap]   = i;
                        SB.Append(B.scale);
                        comma = true;
                        idx++;
                    }
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const double " + S.m_namespace + "_basisElementSignByBitmap[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(s[i]);
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const int " + S.m_namespace + "_basisElementIndexByBitmap[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(IndexByBitmap[i]);
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const int " + S.m_namespace + "_basisElementBitmapByIndex[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(BitmapByIndex[i]);
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const int " + S.m_namespace + "_basisElementGradeByBitmap[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(GradeByBitmap[i]);
                }
            }
            SB.AppendLine("};");

            SB.AppendLine("const int " + S.m_namespace + "_basisElementGroupByBitmap[" + (1 << S.m_dimension) + "] =");
            SB.Append("\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(GroupByBitmap[i]);
                }
            }
            SB.AppendLine("};");
        } // end of GenerateBasisElementArrays()
예제 #20
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()
예제 #21
0
        public static void GenerateBasisElementArrays(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd)
        {
            string accessModifierArr = Keywords.ConstArrayAccessModifier(S);

            G25.GMV gmv = S.m_GMV;

            double[] s             = new double[1 << S.m_dimension];
            int[]    IndexByBitmap = new int[1 << S.m_dimension];
            int[]    BitmapByIndex = new int[1 << S.m_dimension];
            int[]    GradeByBitmap = new int[1 << S.m_dimension];
            int[]    GroupByBitmap = new int[1 << S.m_dimension];
            new G25.CG.Shared.Comment("This array of integers contains the 'sign' (even/odd permutation of canonical order) of basis elements in the general multivector.\n" +
                                      "Use it to answer 'what is the permutation of the coordinate at index [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " double[] BasisElementSignByIndex = new double[]");
            SB.Append("\t\t{");
            {
                bool comma = false;
                int  idx   = 0;
                for (int i = 0; i < gmv.NbGroups; i++)
                {
                    for (int j = 0; j < gmv.Group(i).Length; j++)
                    {
                        if (comma)
                        {
                            SB.Append(", ");
                        }
                        RefGA.BasisBlade B = gmv.Group(i)[j];
                        s[gmv.Group(i)[j].bitmap] = B.scale;
                        IndexByBitmap[B.bitmap]   = idx;
                        BitmapByIndex[idx]        = (int)B.bitmap;
                        GradeByBitmap[B.bitmap]   = B.Grade();
                        GroupByBitmap[B.bitmap]   = i;
                        SB.Append(B.scale);
                        comma = true;
                        idx++;
                    }
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of integers contains the 'sign' (even/odd permutation of canonical order) of basis elements in the general multivector.\n" +
                                      "Use it to answer 'what is the permutation of the coordinate of bitmap [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " double[] BasisElementSignByBitmap = new double[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(s[i]);
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of integers contains the order of basis elements in the general multivector.\n" +
                                      "Use it to answer: 'at what index do I find basis element [x] (x = basis vector bitmap)?'").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] BasisElementIndexByBitmap = new int[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(IndexByBitmap[i]);
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of integers contains the indices of basis elements in the general multivector.\n" +
                                      "Use it to answer: 'what basis element do I find at index [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] BasisElementBitmapByIndex = new int[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(BitmapByIndex[i]);
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of grade of each basis elements in the general multivector.\n" +
                                      "Use it to answer: 'what is the grade of basis element bitmap [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] BasisElementGradeByBitmap = new int[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(GradeByBitmap[i]);
                }
            }
            SB.AppendLine("};");

            new G25.CG.Shared.Comment("This array of group of each basis elements in the general multivector.\n" +
                                      "Use it to answer: 'what is the group of basis element bitmap [x]'?").Write(SB, S, 1);
            SB.AppendLine("\tpublic " + accessModifierArr + " int[] BasisElementGroupByBitmap = new int[]");
            SB.Append("\t\t{");
            {
                for (int i = 0; i < s.Length; i++)
                {
                    if (i > 0)
                    {
                        SB.Append(", ");
                    }
                    SB.Append(GroupByBitmap[i]);
                }
            }
            SB.AppendLine("};");
        } // end of GenerateBasisElementArrays()
예제 #22
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)
        {
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            G25.GMV gmv = S.m_GMV;
            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                string srcClassName = FT.GetMangledName(S, gmv.Name);
                for (int s = 0; s < S.m_SMV.Count; s++)
                {
                    G25.SMV smv          = S.m_SMV[s];
                    string  dstClassName = FT.GetMangledName(S, smv.Name);

                    bool     dstPtr       = true;
                    String[] smvAccessStr = G25.CG.Shared.CodeUtil.GetAccessStr(S, smv, G25.CG.Shared.SmvUtil.THIS, dstPtr);

                    string funcName = "set";

                    // do we inline this func?
                    string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");

                    string funcDecl = inlineStr + "void " + dstClassName + "::" + funcName + "(const " + srcClassName + " &src)";

                    defSB.Append(funcDecl);
                    {
                        defSB.AppendLine(" {");
                        defSB.AppendLine("\tconst " + FT.type + " *ptr = src.getC();\n");

                        // get a dictionary which tells you for each basis blade of 'smv' where it is in 'gmv'
                        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)
                            {
                                if (KVP.Value.Value1 == g)
                                {
                                    groupIsUsedBySMV = true;
                                    break;
                                }
                            }

                            // if group is present in GMV:
                            defSB.AppendLine("\tif (src.gu() & " + (1 << g) + ") {");
                            if (groupIsUsedBySMV)
                            {
                                bool mustCast             = false;
                                bool srcPtr               = true;
                                int  nbTabs               = 2;
                                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);
                            }
                            if ((g + 1) <= highestGroup)
                            {
                                defSB.AppendLine("\t\tptr += " + gmv.Group(g).Length + ";");
                            }
                            defSB.AppendLine("\t}");

                            // else, if group is not present in GMV:
                            if (groupIsUsedBySMV)
                            {
                                defSB.AppendLine("\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" + smvAccessStr[bladeIdx] + " = " + FT.DoubleToString(S, 0.0) + ";");
                                    }
                                }
                                defSB.AppendLine("\t}");
                            }
                        }
                        defSB.AppendLine("}");
                    }
                } // end of loop over all SMVs
            }     // end of loop over all float types
        }         // end of WriteGMVtoSMVcopy()
예제 #23
0
        /// <summary>
        /// Writes the definition of an GMV struct to 'SB' (including comments).
        /// </summary>
        /// <param name="SB">Where the code goes.</param>
        /// <param name="S">Used for basis vector names and output language.</param>
        /// <param name="cgd">Intermediate data for code generation. Also contains plugins and cog.</param>
        /// <param name="FT">Float point type of 'SMV'.</param>
        /// <param name="gmv">The general multivector for which the struct should be written.</param>
        public static void WriteGMVstruct(StringBuilder SB, Specification S, G25.CG.Shared.CGdata cgd, FloatType FT, G25.GMV gmv)
        {
            SB.AppendLine("");

            { // comments for type:
                SB.AppendLine("/**");
                SB.AppendLine(" * This struct can hold a general multivector.");
                SB.AppendLine(" * ");

                SB.AppendLine(" * The coordinates are stored in type " + FT.type + ".");
                SB.AppendLine(" * ");

                SB.AppendLine(" * There are " + gmv.NbGroups + " coordinate groups:");
                for (int g = 0; g < gmv.NbGroups; g++)
                {
                    SB.Append(" * group " + g + ":");
                    for (int i = 0; i < gmv.Group(g).Length; i++)
                    {
                        if (i > 0)
                        {
                            SB.Append(", ");
                        }
                        SB.Append(gmv.Group(g)[i].ToString(S.m_basisVectorNames));
                    }
                    if (gmv.Group(g).Length > 0)
                    {
                        SB.Append("  (grade " + gmv.Group(g)[0].Grade() + ")");
                    }

                    SB.AppendLine(".");
                }
                SB.AppendLine(" * ");

                switch (S.m_GMV.MemoryAllocationMethod)
                {
                case G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE:
                    SB.AppendLine(" * " + (gmv.NbCoordinates / 2) + " " + FT.type + "s are allocated inside the struct ('parity pure').");
                    SB.AppendLine(" * Hence creating a multivector which needs more than that number of coordinates ");
                    SB.AppendLine(" * will result in unpredictable behaviour (buffer overflow).");
                    break;

                case G25.GMV.MEM_ALLOC_METHOD.FULL:
                    SB.AppendLine(" * " + gmv.NbCoordinates + " " + FT.type + "s are allocated inside the struct.");
                    break;
                }

                SB.AppendLine(" */");
            } // end of comment

            // typedef
            SB.AppendLine("typedef struct ");
            SB.AppendLine("{");
            // group/grade usage
            SB.AppendLine("\t/** group/grade usage (a bitmap which specifies which groups/grades are stored in 'c', below). */");
            SB.AppendLine("\tint gu;");

            // coordinates
            switch (S.m_GMV.MemoryAllocationMethod)
            {
//                        case G25.GMV.MEM_ALLOC_METHOD.DYNAMIC:
//                          SB.AppendLine("\t" + FT.type + " *c; ///< the coordinates (array is allocated using realloc())");
//                        break;
            case G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE:
                SB.AppendLine("\t/** The coordinates (note: parity pure). */");
                SB.AppendLine("\t" + FT.type + " c[" + (gmv.NbCoordinates / 2) + "];");
                break;

            case G25.GMV.MEM_ALLOC_METHOD.FULL:
                SB.AppendLine("\t/** The coordinates (full). */");
                SB.AppendLine("\t" + FT.type + " c[" + (gmv.NbCoordinates) + "];");
                break;
            }

            // If we report non-optimized function usage, we need to know original type of GMVs:
            if (S.m_reportUsage)
            {
                SB.AppendLine("\t/** Specialized multivector type. Used to report about non-optimized function usage. */");
                SB.AppendLine("\tint t;");
            }

            SB.AppendLine("} " + FT.GetMangledName(S, gmv.Name) + ";");
        }
예제 #24
0
        }         // end of WriteGMVtoSMVcopy()

        /// <summary>
        /// Writes functions to copy SMVs to GMVs
        /// </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 WriteSMVtoGMVcopy(Specification S, G25.CG.Shared.CGdata cgd)
        {
            StringBuilder defSB = (S.m_inlineSet) ? cgd.m_inlineDefSB : cgd.m_defSB;

            G25.GMV gmv           = S.m_GMV;
            Boolean gmvParityPure = (S.m_GMV.MemoryAllocationMethod == G25.GMV.MEM_ALLOC_METHOD.PARITY_PURE);

            foreach (G25.FloatType FT in S.m_floatTypes)
            {
                String dstClassName = FT.GetMangledName(S, gmv.Name);
                for (int s = 0; s < S.m_SMV.Count; s++)
                {
                    G25.SMV smv = S.m_SMV[s];

                    // do not generate converter if the GMV cannot hold the type
                    if (gmvParityPure && (!smv.IsParityPure()))
                    {
                        continue;
                    }

                    string srcClassName = FT.GetMangledName(S, smv.Name);

                    string funcName = "set";

                    // do we inline this func?
                    string inlineStr = G25.CG.Shared.Util.GetInlineString(S, S.m_inlineSet, " ");

                    string funcDecl = inlineStr + "void " + dstClassName + "::" + funcName + "(const " + srcClassName + " &src)";

                    defSB.Append(funcDecl);

                    {
                        defSB.AppendLine(" {");

                        // get a dictionary which tells you for each basis blade of 'gmv' where it is in 'smv'
                        Dictionary <Tuple <int, int>, Tuple <int, int> > D = G25.MV.GetCoordMap(smv, gmv);

                        // convert SMV to symbolic Multivector:
                        bool smvPtr             = false;
                        RefGA.Multivector value = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(S, smv, "src", smvPtr);

                        // find out which groups are present
                        int gu = 0;
                        foreach (KeyValuePair <Tuple <int, int>, Tuple <int, int> > KVP in D)
                        {
                            gu |= 1 << KVP.Value.Value1;
                        }

                        // generate the code to set group usage:
                        defSB.AppendLine("\t" + SET_GROUP_USAGE + "(" + gu + ");");

                        // a helper pointer which is incremented
                        string dstArrName = "ptr";
                        defSB.AppendLine("\t" + FT.type + " *" + dstArrName + " = m_c;");


                        // for each used group, generate the assignment code
                        for (int g = 0; (1 << g) <= gu; g++)
                        {
                            if (((1 << g) & gu) != 0)
                            {
                                bool   mustCast   = false;
                                int    nbTabs     = 1;
                                bool   writeZeros = true;
                                String str        = G25.CG.Shared.CodeUtil.GenerateGMVassignmentCode(S, FT, mustCast, gmv, dstArrName, g, value, nbTabs, writeZeros);
                                defSB.Append(str);

                                if ((1 << (g + 1)) <= gu)
                                {
                                    defSB.AppendLine("\tptr += " + gmv.Group(g).Length + ";");
                                }
                            }
                        }

                        if (S.m_reportUsage)
                        {
                            defSB.AppendLine("\tm_t = " + G25.CG.Shared.ReportUsage.GetSpecializedConstantName(S, smv.Name) + ";");
                        }

                        defSB.AppendLine("}");
                    }
                } // end of loop over all SMVs
            }     // end of loop over all float types
        }         // end of WriteGMVtoSMVcopy()
예제 #25
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