rbmetis 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +32 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +7 -0
- data/README.md +63 -0
- data/Rakefile +2 -0
- data/ext/extconf.rb +56 -0
- data/lib/rbmetis.rb +5 -0
- data/lib/rbmetis/lib.rb +135 -0
- data/lib/rbmetis/main.rb +259 -0
- data/lib/rbmetis/version.rb +3 -0
- data/rbmetis.gemspec +25 -0
- data/setup.rb +1585 -0
- data/spec/matcher.rb +15 -0
- data/spec/mcpart_spec.rb +40 -0
- data/spec/part_spec.rb +72 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fbae1487ebf509c40e38f3f8faf4215cf990aeb2
|
4
|
+
data.tar.gz: c72a1b49ba3d6b7546fafbd0cf8c6d212056d316
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e580d9355397280750f1643e5d112ffd8d175bd1a6f2787bfa8d0767110d8144c4b077c201425a377ad9eed35cc0277b223b4ce2c212450ccd940180bda8d2f4
|
7
|
+
data.tar.gz: 17def092502f7ec8cd3a55dce354151b4bb7f4afea8e1b641fac5bb9f07283c0b093385ef4a6b94bcb160549419c4f06f710097bfe4c9dbd9f00b7517f5a9369
|
data/.gitignore
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
.config
|
19
|
+
*~
|
20
|
+
*/*~
|
21
|
+
*/*/*~
|
22
|
+
*.bak
|
23
|
+
*/*.bak
|
24
|
+
*/*/*.bak
|
25
|
+
.#*
|
26
|
+
*/.#*
|
27
|
+
*/*/.#*
|
28
|
+
rhosts
|
29
|
+
spec/*/*.dat
|
30
|
+
spec/*/*.csv
|
31
|
+
ext/Makefile
|
32
|
+
lib/rbmetis/config.rb
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# RbMetis
|
2
|
+
|
3
|
+
FFI wrapper of [METIS graph partitioning library](http://glaros.dtc.umn.edu/gkhome/metis/metis/overview)
|
4
|
+
|
5
|
+
* [GitHub](https://github.com/masa16/rbmetis)
|
6
|
+
* [RubyGems](https://rubygems.org/gems/rbmetis)
|
7
|
+
* [Class Documentation](http://rubydoc.info/gems/rbmetis/frames/)
|
8
|
+
|
9
|
+
## Requirement
|
10
|
+
|
11
|
+
* [METIS version 5.1.0](http://glaros.dtc.umn.edu/gkhome/metis/metis/overview)
|
12
|
+
* [Ruby-FFI](https://rubygems.org/gems/ffi)
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Install from RubyGems:
|
17
|
+
|
18
|
+
$ gem install rbmetis
|
19
|
+
|
20
|
+
Or download source tree from [releases](https://github.com/masa16/rbmetis/releases),
|
21
|
+
cd to tree top and run:
|
22
|
+
|
23
|
+
$ ruby setup.rb
|
24
|
+
|
25
|
+
### Installation Option
|
26
|
+
|
27
|
+
* Required METIS files:
|
28
|
+
* C header: metis.h
|
29
|
+
* Library: libmetis.so or libmetis.a
|
30
|
+
|
31
|
+
* option for extconf.rb
|
32
|
+
|
33
|
+
--with-metis-dir=path
|
34
|
+
--with-metis-include=path
|
35
|
+
--with-metis-lib=path
|
36
|
+
|
37
|
+
* How to pass option to extconf.rb
|
38
|
+
|
39
|
+
$ gem install rbmetis -- --with-metis-dir=/opt/metis
|
40
|
+
$ ruby setup.rb -- --with-metis-dir=/opt/metis
|
41
|
+
|
42
|
+
## Usage
|
43
|
+
|
44
|
+
Loading RbMeits:
|
45
|
+
|
46
|
+
require 'rbmetis'
|
47
|
+
|
48
|
+
Currently implemented APIs:
|
49
|
+
|
50
|
+
RbMetis.part_graph_recursive(xadj, adjncy, npart, opts = {})
|
51
|
+
RbMetis.part_graph_kway(xadj, adjncy, npart, opts = {})
|
52
|
+
RbMetis.default_options
|
53
|
+
|
54
|
+
See also [RbMeits API document](http://rubydoc.info/gems/rbmetis/frames)
|
55
|
+
and [METIS manual](http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/manual.pdf)
|
56
|
+
|
57
|
+
## Contributing
|
58
|
+
|
59
|
+
1. Fork it ( https://github.com/[my-github-username]/rbmetis/fork )
|
60
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
61
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
62
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
63
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/ext/extconf.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
|
3
|
+
# configure options:
|
4
|
+
# --with-metis-dir=path
|
5
|
+
# --with-metis-include=path
|
6
|
+
# --with-metis-lib=path
|
7
|
+
|
8
|
+
dir_config("metis")
|
9
|
+
|
10
|
+
libdirs = $LIBPATH.dup
|
11
|
+
libdirs |= %w[/usr/lib64 /usr/lib /usr/local/lib]
|
12
|
+
incdirs = $CPPFLAGS.scan(/(?<=^-I|\s-I)\S+/)
|
13
|
+
incdirs |= %w[/usr/include /usr/local/include]
|
14
|
+
|
15
|
+
libmetis = %w[libmetis.so libmetis.a]
|
16
|
+
|
17
|
+
libdirs.each do |dir|
|
18
|
+
libmetis.each do |name|
|
19
|
+
path = File.join(dir,name)
|
20
|
+
if File.exist?(path)
|
21
|
+
$libmetis = path
|
22
|
+
break
|
23
|
+
end
|
24
|
+
end
|
25
|
+
break if $libmetis
|
26
|
+
end
|
27
|
+
|
28
|
+
incdirs.each do |dir|
|
29
|
+
path = File.join(dir,'metis.h')
|
30
|
+
if File.exist?(path)
|
31
|
+
puts "reading #{path}"
|
32
|
+
open(path,'r').each do |line|
|
33
|
+
case line
|
34
|
+
when /^\s*#define\s+IDXTYPEWIDTH\s+(\d+)/
|
35
|
+
$idxtypewidth = $1.to_i
|
36
|
+
when /^\s*#define\s+REALTYPEWIDTH\s+(\d+)/
|
37
|
+
$realtypewidth = $1.to_i
|
38
|
+
end
|
39
|
+
end
|
40
|
+
break
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
conf_file = File.join("..","lib","rbmetis","config.rb")
|
45
|
+
print "creating #{conf_file}\n"
|
46
|
+
open(conf_file, "w") do |f|
|
47
|
+
f.puts <<EOL
|
48
|
+
module RbMetis
|
49
|
+
IDXTYPEWIDTH=#{$idxtypewidth}
|
50
|
+
REALTYPEWIDTH=#{$realtypewidth}
|
51
|
+
LIBMETIS='#{$libmetis}'
|
52
|
+
end
|
53
|
+
EOL
|
54
|
+
end
|
55
|
+
|
56
|
+
create_makefile("rbmetis")
|
data/lib/rbmetis.rb
ADDED
data/lib/rbmetis/lib.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
module RbMetis
|
2
|
+
|
3
|
+
# @visibility private
|
4
|
+
module Lib
|
5
|
+
|
6
|
+
extend FFI::Library
|
7
|
+
ffi_lib LIBMETIS
|
8
|
+
attach_function :METIS_PartGraphRecursive, [:pointer]*13, :int
|
9
|
+
attach_function :METIS_PartGraphKway, [:pointer]*13, :int
|
10
|
+
attach_function :METIS_SetDefaultOptions, [:pointer], :int
|
11
|
+
|
12
|
+
case IDXTYPEWIDTH
|
13
|
+
when 32
|
14
|
+
def alloc_idx_ary(ary)
|
15
|
+
a = FFI::MemoryPointer.new(:int32, ary.size)
|
16
|
+
a.write_array_of_int32(ary)
|
17
|
+
a
|
18
|
+
end
|
19
|
+
def alloc_idx(num)
|
20
|
+
a = FFI::MemoryPointer.new(:int32)
|
21
|
+
a.write_int32(num)
|
22
|
+
a
|
23
|
+
end
|
24
|
+
def read_idx_ary(a,n)
|
25
|
+
a.read_array_of_int32(n)
|
26
|
+
end
|
27
|
+
def read_idx(a)
|
28
|
+
a.read_int32
|
29
|
+
end
|
30
|
+
when 64
|
31
|
+
def alloc_idx_ary(ary)
|
32
|
+
a = FFI::MemoryPointer.new(:int64, ary.size)
|
33
|
+
a.write_array_of_int64(ary)
|
34
|
+
a
|
35
|
+
end
|
36
|
+
def alloc_idx(num)
|
37
|
+
a = FFI::MemoryPointer.new(:int64)
|
38
|
+
a.write_int64(num)
|
39
|
+
a
|
40
|
+
end
|
41
|
+
def read_idx_ary(a,n)
|
42
|
+
a.read_array_of_int64(n)
|
43
|
+
end
|
44
|
+
def read_idx(a)
|
45
|
+
a.read_int64
|
46
|
+
end
|
47
|
+
end
|
48
|
+
module_function :alloc_idx
|
49
|
+
module_function :alloc_idx_ary
|
50
|
+
module_function :read_idx
|
51
|
+
module_function :read_idx_ary
|
52
|
+
|
53
|
+
case REALTYPEWIDTH
|
54
|
+
when 32
|
55
|
+
def alloc_real_ary(ary)
|
56
|
+
a = FFI::MemoryPointer.new(4, ary.size)
|
57
|
+
a.put_array_of_float32(0, ary)
|
58
|
+
a
|
59
|
+
end
|
60
|
+
when 64
|
61
|
+
def alloc_real_ary(ary)
|
62
|
+
a = FFI::MemoryPointer.new(8, ary.size)
|
63
|
+
a.put_array_of_float64(0, ary)
|
64
|
+
a
|
65
|
+
end
|
66
|
+
end
|
67
|
+
module_function :alloc_real_ary
|
68
|
+
|
69
|
+
def check_idx_array(args,name,size=nil,sizename=nil)
|
70
|
+
arg = args[name]
|
71
|
+
if arg
|
72
|
+
if !(Array===arg)
|
73
|
+
raise ArgumentError, "#{name} must be an array"
|
74
|
+
end
|
75
|
+
if size && arg.size != size
|
76
|
+
raise ArgumentError, "the size of #{name} must be #{sizename||size}"
|
77
|
+
end
|
78
|
+
alloc_idx_ary(arg)
|
79
|
+
else
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
module_function :check_idx_array
|
84
|
+
|
85
|
+
def check_real_array(args,name,size=nil,sizename=nil)
|
86
|
+
arg = args[name]
|
87
|
+
if arg
|
88
|
+
if !(Array===arg)
|
89
|
+
raise ArgumentError, "#{name} must be an array"
|
90
|
+
end
|
91
|
+
if size && arg.size != size
|
92
|
+
raise ArgumentError, "the size of #{name} must be #{sizename||size}"
|
93
|
+
end
|
94
|
+
alloc_real_ary(arg)
|
95
|
+
else
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
module_function :check_real_array
|
100
|
+
|
101
|
+
def check_idx(args,name,default_value=nil)
|
102
|
+
arg = args[name]
|
103
|
+
if arg
|
104
|
+
if !(Integer===arg)
|
105
|
+
raise ArgumentError, "#{name} must be an integer"
|
106
|
+
end
|
107
|
+
alloc_idx(arg)
|
108
|
+
else
|
109
|
+
if default_value
|
110
|
+
alloc_idx(default_value)
|
111
|
+
else
|
112
|
+
nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
module_function :check_idx
|
117
|
+
|
118
|
+
def postprocess(retval)
|
119
|
+
case retval
|
120
|
+
when METIS_OK
|
121
|
+
"that the function returned normally."
|
122
|
+
when METIS_ERROR_INPUT
|
123
|
+
raise MetisError, "input error"
|
124
|
+
when METIS_ERROR_MEMORY
|
125
|
+
raise MetisError, "memory allocation error"
|
126
|
+
when METIS_ERROR
|
127
|
+
raise MetisError, "other type of error"
|
128
|
+
else
|
129
|
+
raise MetisError, "unknown return code"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
module_function :postprocess
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
data/lib/rbmetis/main.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
module RbMetis
|
2
|
+
class MetisError < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
# Returned normally
|
6
|
+
METIS_OK = 1
|
7
|
+
# Returned due to erroneous inputs and/or options
|
8
|
+
METIS_ERROR_INPUT = -2
|
9
|
+
# Returned due to insufficient memory
|
10
|
+
METIS_ERROR_MEMORY = -3
|
11
|
+
# Some other errors
|
12
|
+
METIS_ERROR = -4
|
13
|
+
|
14
|
+
NOPTIONS = 40
|
15
|
+
|
16
|
+
#/*! Operation type codes */
|
17
|
+
OP_PMETIS,
|
18
|
+
OP_KMETIS,
|
19
|
+
OP_OMETIS = 0..2
|
20
|
+
|
21
|
+
#/*! Options codes (i.e., options[]) */
|
22
|
+
OPTION_PTYPE,
|
23
|
+
OPTION_OBJTYPE,
|
24
|
+
OPTION_CTYPE,
|
25
|
+
OPTION_IPTYPE,
|
26
|
+
OPTION_RTYPE,
|
27
|
+
OPTION_DBGLVL,
|
28
|
+
OPTION_NITER,
|
29
|
+
OPTION_NCUTS,
|
30
|
+
OPTION_SEED,
|
31
|
+
OPTION_NO2HOP,
|
32
|
+
OPTION_MINCONN,
|
33
|
+
OPTION_CONTIG,
|
34
|
+
OPTION_COMPRESS,
|
35
|
+
OPTION_CCORDER,
|
36
|
+
OPTION_PFACTOR,
|
37
|
+
OPTION_NSEPS,
|
38
|
+
OPTION_UFACTOR,
|
39
|
+
OPTION_NUMBERING,
|
40
|
+
#/* Used for command-line parameter purposes */
|
41
|
+
OPTION_HELP,
|
42
|
+
OPTION_TPWGTS,
|
43
|
+
OPTION_NCOMMON,
|
44
|
+
OPTION_NOOUTPUT,
|
45
|
+
OPTION_BALANCE,
|
46
|
+
OPTION_GTYPE,
|
47
|
+
OPTION_UBVEC = 0..25
|
48
|
+
|
49
|
+
# /*! Partitioning Schemes */
|
50
|
+
PTYPE_RB,
|
51
|
+
PTYPE_KWAY = 0..1
|
52
|
+
|
53
|
+
# /*! Graph types for meshes */
|
54
|
+
GTYPE_DUAL,
|
55
|
+
GTYPE_NODAL = 0..1
|
56
|
+
|
57
|
+
# /*! Coarsening Schemes */
|
58
|
+
CTYPE_RM,
|
59
|
+
CTYPE_SHEM = 0..1
|
60
|
+
|
61
|
+
# /*! Initial partitioning schemes */
|
62
|
+
IPTYPE_GROW,
|
63
|
+
IPTYPE_RANDOM,
|
64
|
+
IPTYPE_EDGE,
|
65
|
+
IPTYPE_NODE,
|
66
|
+
IPTYPE_METISRB = 0..4
|
67
|
+
|
68
|
+
# /*! Refinement schemes */
|
69
|
+
RTYPE_FM,
|
70
|
+
RTYPE_GREEDY,
|
71
|
+
RTYPE_SEP2SIDED,
|
72
|
+
RTYPE_SEP1SIDED = 0..3
|
73
|
+
|
74
|
+
# /*! Debug Levels */
|
75
|
+
DBG_INFO = 1
|
76
|
+
DBG_TIME = 2
|
77
|
+
DBG_COARSEN = 4
|
78
|
+
DBG_REFINE = 8
|
79
|
+
DBG_IPART = 16
|
80
|
+
DBG_MOVEINFO = 32
|
81
|
+
DBG_SEPINFO = 64
|
82
|
+
DBG_CONNINFO = 128
|
83
|
+
DBG_CONTIGINFO = 256
|
84
|
+
DBG_MEMORY = 2048
|
85
|
+
|
86
|
+
# /* Types of objectives */
|
87
|
+
OBJTYPE_CUT,
|
88
|
+
OBJTYPE_VOL,
|
89
|
+
OBJTYPE_NODE = 0..2
|
90
|
+
|
91
|
+
# @visibility private
|
92
|
+
module Lib
|
93
|
+
def part_graph_preprocess(xadj_arg, adjncy_arg, np, args={})
|
94
|
+
nv = xadj_arg.size - 1
|
95
|
+
|
96
|
+
# The number of vertices in the graph.
|
97
|
+
nvtxs = alloc_idx(nv)
|
98
|
+
# The adjacency structure of the graph as described in Section 5.5.
|
99
|
+
xadj = alloc_idx_ary(xadj_arg)
|
100
|
+
adjncy = alloc_idx_ary(adjncy_arg)
|
101
|
+
# The number of parts to partition the graph.
|
102
|
+
nparts = alloc_idx(np)
|
103
|
+
|
104
|
+
ncon = check_idx(args, :ncon, 1)
|
105
|
+
nc = read_idx(ncon)
|
106
|
+
|
107
|
+
# The weights of the vertices as described in Section 5.5.
|
108
|
+
vwgt = check_idx_array(args, :vwgt, nv*nc, "nvtxs*ncon")
|
109
|
+
|
110
|
+
# The number of balancing constraints. It should be at least 1.
|
111
|
+
ncon = alloc_idx(nc)
|
112
|
+
|
113
|
+
# The size of the vertices for computing the total communication
|
114
|
+
# volume as described in Section 5.7.
|
115
|
+
vsize = check_idx(args, :vsize, 1)
|
116
|
+
|
117
|
+
# The weights of the edges as described in Section 5.5.
|
118
|
+
adjwgt = check_idx_array(args, :adjwgt, adjncy_arg.size, "size of adjncy")
|
119
|
+
|
120
|
+
# This is an array of size nparts*ncon that specifies the desired
|
121
|
+
# weight for each partition and constraint.
|
122
|
+
# The target partition weight for the ith partition and jth
|
123
|
+
# constraint is specified at tpwgts[i*ncon+j]
|
124
|
+
# For each constraint, the sum of the tpwgts[] entries must be 1.0.
|
125
|
+
tpwgts = check_real_array(args, :tpwgts, np*nc, "nparts*ncon")
|
126
|
+
|
127
|
+
# This is an array of size ncon that specifies the allowed load
|
128
|
+
# imbalance tolerance for each constraint.
|
129
|
+
# For the ith partition and jth constraint the allowed weight is
|
130
|
+
# the ubvec[j]*tpwgts[i*ncon+j] fraction of the jth’s constraint
|
131
|
+
# total weight. The load imbalances must be greater than 1.0.
|
132
|
+
# A NULL value can be passed indicating that the load imbalance
|
133
|
+
# tolerance for each constraint should be 1.001 (for ncon=1) or
|
134
|
+
# 1.01 (for ncon>1).
|
135
|
+
ubvec = check_real_array(args, :ubvec, nc, "ncon")
|
136
|
+
|
137
|
+
# This is the array of options as described in Section 5.4.
|
138
|
+
options = check_idx_array(args, :options, 40)
|
139
|
+
|
140
|
+
# Upon successful completion, this variable stores the edge-cut or
|
141
|
+
# the total communication volume of the partitioning solution. The
|
142
|
+
# value returned depends on the partitioning’s objective
|
143
|
+
# function.
|
144
|
+
objval = alloc_idx(0)
|
145
|
+
|
146
|
+
# This is a vector of size nvtxs that upon successful completion
|
147
|
+
# stores the partition vector of the graph. The numbering of this
|
148
|
+
# vector starts from either 0 or 1, depending on the value of
|
149
|
+
# options[METIS OPTION NUMBERING].
|
150
|
+
part = alloc_idx_ary([0]*nv)
|
151
|
+
|
152
|
+
return [nvtxs, ncon, xadj, adjncy, vwgt, vsize, adjwgt, nparts,
|
153
|
+
tpwgts, ubvec, options, objval, part]
|
154
|
+
end
|
155
|
+
module_function :part_graph_preprocess
|
156
|
+
end
|
157
|
+
|
158
|
+
# partition a graph into k parts using multilevel recursive bisection.
|
159
|
+
# @overload part_graph_recursive(xadj, adjncy, npart, opts={})
|
160
|
+
# @param [Array] xadj adjacency structure of the graph
|
161
|
+
# @param [Array] adjncy adjacency structure of the graph
|
162
|
+
# @param [Integer] npart the number of partitions
|
163
|
+
# @option opts [Array] :vwgt (nil) The weights of the vertices.
|
164
|
+
# @option opts [Array] :ncon (1) The number of balancing
|
165
|
+
# constraints. It should be at least 1.
|
166
|
+
# @option opts [Array] :vsize (nil) The size of the vertices for
|
167
|
+
# computing the total communication volume.
|
168
|
+
# @option opts [Array] :adjwgt (nil) The weights of the edges.
|
169
|
+
# @option opts [Array] :tpwgts (nil) an array of size nparts*ncon
|
170
|
+
# that specifies the desired weight for each partition and
|
171
|
+
# constraint. The target partition weight for the ith partition
|
172
|
+
# and jth constraint is specified at tpwgts[i*ncon+j] For each
|
173
|
+
# constraint, the sum of the tpwgts[] entries must be 1.0.
|
174
|
+
# @option opts [Array] :ubvec (nil) an array of size ncon that
|
175
|
+
# specifies the allowed load imbalance tolerance for each
|
176
|
+
# constraint. For the ith partition and jth constraint the allowed
|
177
|
+
# weight is the ubvec[j]*tpwgts[i*ncon+j] fraction of the jth’s
|
178
|
+
# constraint total weight. The load imbalances must be greater than
|
179
|
+
# 1.0. A NULL value can be passed indicating that the load
|
180
|
+
# imbalance tolerance for each constraint should be 1.001 (for
|
181
|
+
# ncon=1) or 1.01 (for ncon>1).
|
182
|
+
# @option opts [Array] :options (nil) the array of options.
|
183
|
+
# The following options are valid for METIS PartGraphRecursive:
|
184
|
+
# METIS_OPTION_CTYPE, METIS_OPTION_IPTYPE, METIS_OPTION_RTYPE,
|
185
|
+
# METIS_OPTION_NO2HOP, METIS_OPTION_NCUTS, METIS_OPTION_NITER,
|
186
|
+
# METIS_OPTION_SEED, METIS_OPTION_UFACTOR, METIS_OPTION_NUMBERING,
|
187
|
+
# METIS_OPTION_DBGLVL
|
188
|
+
# @return [Array] an array that stores the partition of the graph.
|
189
|
+
# @raise [RbMetis::MetisError]
|
190
|
+
def part_graph_recursive(xadj, adjncy, npart, opts={})
|
191
|
+
# args = [ nvtxs, ncon, xadj, adjncy, vwgt, vsize, adjwgt, nparts,
|
192
|
+
# tpwgts, ubvec, options, objval, part ]
|
193
|
+
args = Lib.part_graph_preprocess(xadj, adjncy, npart, opts)
|
194
|
+
retval = Lib.METIS_PartGraphRecursive(*args)
|
195
|
+
Lib.postprocess(retval)
|
196
|
+
part = args.last
|
197
|
+
nv = xadj.size - 1
|
198
|
+
#p read_idx(objval)
|
199
|
+
return Lib.read_idx_ary(part,nv)
|
200
|
+
end
|
201
|
+
module_function :part_graph_recursive
|
202
|
+
|
203
|
+
|
204
|
+
# partition a graph into k parts using multilevel k-way partitioning.
|
205
|
+
# @overload part_graph_kway(xadj, adjncy, npart, opts={})
|
206
|
+
# @param [Array] xadj adjacency structure of the graph
|
207
|
+
# @param [Array] adjncy adjacency structure of the graph
|
208
|
+
# @param [Integer] npart the number of partitions
|
209
|
+
# @option opts [Array] :vwgt (nil) The weights of the vertices.
|
210
|
+
# @option opts [Array] :ncon (1) The number of balancing
|
211
|
+
# constraints. It should be at least 1.
|
212
|
+
# @option opts [Array] :vsize (nil) The size of the vertices for
|
213
|
+
# computing the total communication volume.
|
214
|
+
# @option opts [Array] :adjwgt (nil) The weights of the edges.
|
215
|
+
# @option opts [Array] :tpwgts (nil) an array of size nparts*ncon
|
216
|
+
# that specifies the desired weight for each partition and
|
217
|
+
# constraint. The target partition weight for the ith partition
|
218
|
+
# and jth constraint is specified at tpwgts[i*ncon+j] For each
|
219
|
+
# constraint, the sum of the tpwgts[] entries must be 1.0.
|
220
|
+
# @option opts [Array] :ubvec (nil) an array of size ncon that
|
221
|
+
# specifies the allowed load imbalance tolerance for each
|
222
|
+
# constraint. For the ith partition and jth constraint the allowed
|
223
|
+
# weight is the ubvec[j]*tpwgts[i*ncon+j] fraction of the jth’s
|
224
|
+
# constraint total weight. The load imbalances must be greater than
|
225
|
+
# 1.0. A NULL value can be passed indicating that the load
|
226
|
+
# imbalance tolerance for each constraint should be 1.001 (for
|
227
|
+
# ncon=1) or 1.01 (for ncon>1).
|
228
|
+
# @option opts [Array] :options (nil) the array of options.
|
229
|
+
# The following options are valid for METIS PartGraphKway:
|
230
|
+
# METIS_OPTION_OBJTYPE, METIS_OPTION_CTYPE, METIS_OPTION_IPTYPE,
|
231
|
+
# METIS_OPTION_RTYPE, METIS_OPTION_NO2HOP, METIS_OPTION_NCUTS,
|
232
|
+
# METIS_OPTION_NITER, METIS_OPTION_UFACTOR, METIS_OPTION_MINCONN,
|
233
|
+
# METIS_OPTION_CONTIG, METIS_OPTION_SEED, METIS_OPTION_NUMBERING,
|
234
|
+
# METIS_OPTION_DBGLVL
|
235
|
+
# @return [Array] an array that stores the partition of the graph.
|
236
|
+
# @raise [RbMetis::MetisError]
|
237
|
+
def part_graph_kway(xadj, adjncy, npart, opts={})
|
238
|
+
# args = [ nvtxs, ncon, xadj, adjncy, vwgt, vsize, adjwgt, nparts,
|
239
|
+
# tpwgts, ubvec, options, objval, part ]
|
240
|
+
args = Lib.part_graph_preprocess(xadj, adjncy, npart, opts)
|
241
|
+
retval = Lib.METIS_PartGraphKway(*args)
|
242
|
+
Lib.postprocess(retval)
|
243
|
+
part = args.last
|
244
|
+
nv = xadj.size - 1
|
245
|
+
#p read_idx(objval)
|
246
|
+
return Lib.read_idx_ary(part,nv)
|
247
|
+
end
|
248
|
+
module_function :part_graph_kway
|
249
|
+
|
250
|
+
# Initializes the options array into its default values.
|
251
|
+
# @return [Array] The array of options that will be initialized.
|
252
|
+
# It’s size is METIS_NOPTIONS.
|
253
|
+
def default_options
|
254
|
+
options = Lib.alloc_idx_ary([0]*40)
|
255
|
+
Lib.METIS_SetDefaultOptions(options)
|
256
|
+
Lib.read_idx_ary(options,40)
|
257
|
+
end
|
258
|
+
module_function :default_options
|
259
|
+
end
|