Пример #1
0
        /// <summary>
        /// Creates a new instance of the <see cref="MetisOptions"/> class with default graph partitioning options.
        /// </summary>
        public static MetisOptions GraphPartitionDefault()
        {
            var opt = new MetisOptions();

            opt.Partitioning        = PartitioningType.KWAY;
            opt.Objective           = ObjectiveType.CUT;
            opt.Coarsening          = CoarseningType.SHEM;
            opt.InitialPartitioning = InitialPartitioningType.GROW;
            opt.Refinement          = RefinementType.GREEDY;

            opt.No2Hop     = false;
            opt.MinConnect = false;
            opt.Contiguous = false;

            opt.Cuts       = 1;
            opt.Seperators = 1;
            opt.Iterations = 10;

            opt.Seed       = -1;
            opt.DebugLevel = DebugLevel.NONE;

            opt.UFactor = -1;

            return(opt);
        }
Пример #2
0
        private MetisStatus Partition(int nparts, int[] part, MetisOptions options, bool kway)
        {
            int objval = 0;

            if (part == null || part.Length < this.nvtxs)
            {
                return(MetisStatus.ERROR_INPUT);
            }

            var handles = new List <GCHandle>();

            // Pin array data.
            var p_part   = InteropHelper.Pin(part, handles);
            var p_xadj   = InteropHelper.Pin(xadj, handles);
            var p_adjncy = InteropHelper.Pin(adjncy, handles);
            var p_vwgt   = InteropHelper.Pin(vwgt, handles);
            var p_ewgt   = InteropHelper.Pin(adjwgt, handles);
            var p_vsize  = InteropHelper.Pin(vsize, handles);

            var p_opts = options == null ? IntPtr.Zero : InteropHelper.Pin(options.raw, handles);

            int l_nv = nvtxs;
            int l_nw = ncon;

            int status = 0;

            try
            {
                if (kway)
                {
                    status = NativeMethods.PartGraphKway(ref l_nv, ref l_nw, p_xadj, p_adjncy,
                                                         p_vwgt, p_vsize, p_ewgt, ref nparts, IntPtr.Zero, IntPtr.Zero,
                                                         p_opts, ref objval, p_part);
                }
                else
                {
                    status = NativeMethods.PartGraphRecursive(ref l_nv, ref l_nw, p_xadj, p_adjncy,
                                                              p_vwgt, p_vsize, p_ewgt, ref nparts, IntPtr.Zero, IntPtr.Zero,
                                                              p_opts, ref objval, p_part);
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                InteropHelper.Free(handles);
            }

            return((MetisStatus)status);
        }
Пример #3
0
        /// <summary>
        /// Computes fill reducing orderings of sparse matrices using the multilevel nested dissection algorithm.
        /// </summary>
        /// <param name="perm">Target array storing the fill-reducing permutaion (size nvtxs).</param>
        /// <param name="iperm">Target array storing the fill-reducing inverse permutaion (size nvtxs).</param>
        /// <param name="options">Partitioning options.</param>
        /// <returns></returns>
        public MetisStatus NestedDissection(int[] perm, int[] iperm, MetisOptions options = null)
        {
            if (perm.Length != nvtxs || iperm.Length != nvtxs)
            {
                return(MetisStatus.ERROR_INPUT);
            }

            var handles = new List <GCHandle>();

            // Pin array data.
            var p_xadj   = InteropHelper.Pin(xadj, handles);
            var p_adjncy = InteropHelper.Pin(adjncy, handles);
            var p_vwgt   = InteropHelper.Pin(vwgt, handles);

            var p_opts = options == null ? IntPtr.Zero : InteropHelper.Pin(options.raw, handles);

            var p_perm  = InteropHelper.Pin(perm, handles);
            var p_iperm = InteropHelper.Pin(iperm, handles);

            int l_nv = nvtxs;

            int status = 0;

            try
            {
                status = NativeMethods.NodeND(ref l_nv, p_xadj, p_adjncy, p_vwgt, p_opts, p_perm, p_iperm);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                InteropHelper.Free(handles);
            }

            return((MetisStatus)status);
        }
Пример #4
0
        /// <summary>
        /// Creates a new instance of the <see cref="MetisOptions"/> class with default nested dissection ordering options.
        /// </summary>
        public static MetisOptions NestedDissectionDefault()
        {
            var opt = new MetisOptions();

            opt.Coarsening          = CoarseningType.SHEM;
            opt.InitialPartitioning = InitialPartitioningType.NODE;
            opt.Refinement          = RefinementType.SEP2SIDED;

            opt.UFactor        = 200;
            opt.PFactor        = 0;
            opt.Compress       = true;
            opt.ComponentOrder = false;
            opt.No2Hop         = false;

            opt.Cuts       = 1;
            opt.Seperators = 1;
            opt.Iterations = 10;

            opt.Seed       = -1;
            opt.DebugLevel = DebugLevel.NONE;

            return(opt);
        }
Пример #5
0
 /// <summary>
 /// Partition a graph into k parts using multilevel recursive bisection partitioning.
 /// </summary>
 /// <param name="k">The number of partitions.</param>
 /// <param name="part">Target array storing the partition of the graph (size nvtxs).</param>
 /// <param name="options">Partitioning options.</param>
 /// <returns></returns>
 public MetisStatus PartitionRecursive(int k, int[] part, MetisOptions options = null)
 {
     return(Partition(k, part, options, false));
 }
Пример #6
0
 /// <summary>
 /// Partition a graph into k parts using multilevel k-way partitioning.
 /// </summary>
 /// <param name="k">The number of partitions.</param>
 /// <param name="part">Target array storing the partition of the graph (size nvtxs).</param>
 /// <param name="options">Partitioning options.</param>
 /// <returns></returns>
 public MetisStatus PartitionKway(int k, int[] part, MetisOptions options = null)
 {
     return(Partition(k, part, options, true));
 }
Пример #7
0
        private MetisStatus Partition(int nparts, int[] epart, int[] npart, MetisOptions options, bool dual)
        {
            if (ne <= 0)
            {
                return(MetisStatus.ERROR_INPUT);
            }

            if (epart == null || epart.Length < ne)
            {
                return(MetisStatus.ERROR_INPUT);
            }

            if (npart == null || npart.Length < nn)
            {
                return(MetisStatus.ERROR_INPUT);
            }

            int objval  = 0;
            int ncommon = 2; // for triangles

            float[] tpwgts = GetWeights(nparts, ncon);

            var handles = new List <GCHandle>();

            // Pin array data and get pointers.
            var p_eptr   = InteropHelper.Pin(eptr, handles);
            var p_eind   = InteropHelper.Pin(eind, handles);
            var p_ewgt   = InteropHelper.Pin(ewgt, handles);
            var p_tpwgts = InteropHelper.Pin(tpwgts, handles);
            var p_epart  = InteropHelper.Pin(epart, handles);
            var p_npart  = InteropHelper.Pin(npart, handles);

            var p_opts = options == null ? IntPtr.Zero : InteropHelper.Pin(options.raw, handles);

            int l_ne = ne;
            int l_nn = nn;

            int status = 0;

            try
            {
                if (dual)
                {
                    status = NativeMethods.PartMeshDual(ref l_ne, ref l_nn, p_eptr, p_eind, p_ewgt, IntPtr.Zero,
                                                        ref ncommon, ref nparts, p_tpwgts, p_opts, ref objval, p_epart, p_npart);
                }
                else
                {
                    status = NativeMethods.PartMeshNodal(ref l_ne, ref l_nn, p_eptr, p_eind, IntPtr.Zero, IntPtr.Zero,
                                                         ref nparts, p_tpwgts, p_opts, ref objval, p_epart, p_npart);
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                InteropHelper.Free(handles);
            }

            return((MetisStatus)status);
        }
Пример #8
0
 /// <summary>
 /// Partition a mesh into k parts based on a partitioning of the mesh's nodal graph.
 /// </summary>
 /// <param name="k">The number of partitions.</param>
 /// <param name="epart">Target array storing the element partition (size ne).</param>
 /// <param name="npart">Target array storing the node partition (size nn).</param>
 /// <param name="options">Partitioning options.</param>
 /// <returns></returns>
 public MetisStatus PartitionNodal(int k, int[] epart, int[] npart, MetisOptions options = null)
 {
     return(Partition(k, epart, npart, options, false));
 }