Commit 4558a3aa authored by Kirk Webb's avatar Kirk Webb

Merge of ipassign stuff from commvirtsig-branch into main trunk.

parent 6d7ed565
......@@ -1438,7 +1438,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/plab/plabdist tbsetup/plab/plabhttpd \
tbsetup/plab/etc/netbed_files/GNUmakefile \
tbsetup/ipassign/GNUmakefile tbsetup/ipassign/src/GNUmakefile \
tbsetup/assign_prepass \
tbsetup/ipassign/ipassign_wrapper tbsetup/assign_prepass \
tip/GNUmakefile \
tmcd/GNUmakefile tmcd/freebsd/GNUmakefile tmcd/openbsd/GNUmakefile \
tmcd/linux/GNUmakefile tmcd/ron/GNUmakefile tmcd/common/GNUmakefile \
......
......@@ -483,7 +483,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/plab/plabdist tbsetup/plab/plabhttpd \
tbsetup/plab/etc/netbed_files/GNUmakefile \
tbsetup/ipassign/GNUmakefile tbsetup/ipassign/src/GNUmakefile \
tbsetup/assign_prepass \
tbsetup/ipassign/ipassign_wrapper tbsetup/assign_prepass \
tip/GNUmakefile \
tmcd/GNUmakefile tmcd/freebsd/GNUmakefile tmcd/openbsd/GNUmakefile \
tmcd/linux/GNUmakefile tmcd/ron/GNUmakefile tmcd/common/GNUmakefile \
......
......@@ -13,7 +13,7 @@ PLABSUPPORT = @PLABSUPPORT@
include $(OBJDIR)/Makeconf
SUBDIRS = checkpass ns2ir nseparse
SUBDIRS = checkpass ns2ir ipassign nseparse
BIN_STUFF = power snmpit tbend tbprerun tbreport \
os_load startexp endexp batchexp swapexp \
......@@ -36,7 +36,7 @@ SBIN_STUFF = resetvlans console_setup.proxy sched_reload named_setup \
LIBEXEC_STUFF = rmproj wanlinksolve wanlinkinfo \
os_setup mkexpdir console_setup webnscheck webreport \
webstartexp webendexp webbatchexp \
assign_wrapper ptopgen webnodeupdate \
assign_wrapper assign_prepass ptopgen webnodeupdate \
webdelay_config \
webrmgroup webswapexp webnodecontrol \
webmkgroup websetgroups webmkproj \
......@@ -65,7 +65,7 @@ wanlinksolve: wanlinksolve.cc
routecalc: routecalc.cc
${CXX} $< ${CXXFLAGS} -o $@ ${LIBS} -lm -lstdc++ ${LDFLAGS}
.PHONY: checkpass ns2ir plab
.PHONY: checkpass ns2ir plab ipassign
checkpass:
@$(MAKE) -C checkpass all
......@@ -78,6 +78,9 @@ nseparse:
plab:
@$(MAKE) -C plab all
ipassign:
@$(MAKE) -C ipassign all
install: all script-install subdir-install
@echo "Don't forget to do a post-install as root"
......@@ -100,6 +103,7 @@ subdir-install:
@$(MAKE) -C ns2ir install
@$(MAKE) -C nseparse install
$(PLAB_INSTALL)
@$(MAKE) -C ipassign install
script-install: $(addprefix $(INSTALL_BINDIR)/, $(BIN_STUFF)) \
$(addprefix $(INSTALL_SBINDIR)/, $(SBIN_STUFF)) \
......@@ -111,6 +115,7 @@ post-install:
@$(MAKE) -C ns2ir post-install
@$(MAKE) -C nseparse post-install
$(PLAB_POST_INSTALL)
@$(MAKE) -C ipassign post-install
chmod 775 $(INSTALL_BINDIR)
chmod 775 $(INSTALL_SBINDIR)
chmod 775 $(INSTALL_LIBDIR)
......@@ -184,6 +189,7 @@ subdir-clean:
@$(MAKE) -C ns2ir clean
@$(MAKE) -C nseparse clean
# @$(MAKE) -C plab clean
@$(MAKE) -C ipassign clean
distclean: subdir-distclean
......@@ -192,6 +198,7 @@ subdir-distclean:
@$(MAKE) -C ns2ir distclean
@$(MAKE) -C nseparse distclean
@$(MAKE) -C plab distclean
@$(MAKE) -C ipassign distclean
#
# XXX Create non .tcl files.
#
......
......@@ -12,26 +12,29 @@ UNIFIED = @UNIFIED_BOSS_AND_OPS@
include $(OBJDIR)/Makeconf
SUBDIRS =
# src
IPASSIGN_SCRIPTS = ipassign_wrapper
#
# Force dependencies on the scripts so that they will be rerun through
# configure if the .in file is changed.
#
all: $(SUBDIRS)
all: src $(IPASSIGN_SCRIPTS)
include $(TESTBED_SRCDIR)/GNUmakerules
.PHONY: src
src:
@$(MAKE) -C src all
install: all subdir-install
install: all subdir-install script-install
#
# Automate this part at some point.
#
script-install: $(addprefix $(INSTALL_LIBEXECDIR)/, $(IPASSIGN_SCRIPTS))
subdir-install:
@$(MAKE) -C src install
......@@ -39,6 +42,7 @@ post-install:
@$(MAKE) -C src post-install
clean: subdir-clean
-rm -f $(IPASSIGN_SCRIPTS)
subdir-clean:
@$(MAKE) -C src clean
......
......@@ -16,15 +16,23 @@ Example: "bin/ipassign -c -s -h < graph/smalltern.graph"
Use conservative bitspace allocation for square root of the # of LANs
partitions with host-host routing on the smalltern graph
'-p#', '-s', '-b', and '-g' modify the same behaviour. If more than one is
used, the last one used takes precedence.
'-p#' When calculating assignment for ip addresses, # is used to set how
many partitions to create. Example: '-p20' would create 20 partitions.
'-s' When calculating the number of partitions to use for ip assignment,
use the square root of the number of LANs. (default)
'-ps' Search for the proper number of partitions by running METIS repeatedly
and scoring the result.
'-pq' Use the square root of the number of LANs as the number of partitions.
(default)
'-c', '-b', and '-g' modify the same behaviour. If more than one is
used, the last one used takes precedence.
!!! Always use this for now. Dynamic bitspace allocation is not yet
implemented !!!
'-c' Use conservative bitspace allocation. Each level of the hierarchy
is allocated a fixed number of bits. Only takes effect alongside
of -p or -s
#'-b' Instead of using a single level of hierachy in which a set number
# of partitions are used, cut the graph in half assigning each
# half a zero or one, cut each of the resulting subgraphs in half,
......@@ -34,11 +42,6 @@ used, the last one used takes precedence.
# METIS.
# -- NOT IMPLEMENTED --
!!! Always use this for now. Dynamic bitspace allocation is not yet
implemented !!!
'-c' Use conservative bitspace allocation. Each level of the hierarchy
is allocated a fixed number of bits. Only takes effect alongside
of -p or -s
'-h', '-l', and '-n' modify the same behaviour. If more than one is used, the
......
......@@ -3,16 +3,16 @@
export EXTRA_LIB_PATH=/home/duerig/metis/metis-4.0
export EXTRA_INCLUDE_PATH=/home/duerig/metis/metis-4.0/Lib/
g++ -O3 -c -o tmp/ipassign.o -I${EXTRA_INCLUDE_PATH} src/ipassign.cc
g++ -O3 -c -o tmp/bitmath.o -I${EXTRA_INCLUDE_PATH} src/bitmath.cc
g++ -O3 -c -o tmp/Assigner.o -I${EXTRA_INCLUDE_PATH} src/Assigner.cc
g++ -O3 -c -o tmp/ConservativeAssigner.o -I${EXTRA_INCLUDE_PATH} src/ConservativeAssigner.cc
g++ -O3 -c -o tmp/Framework.o -I${EXTRA_INCLUDE_PATH} src/Framework.cc
g++ -O3 -c -o tmp/HostRouter.o -I${EXTRA_INCLUDE_PATH} src/HostRouter.cc
g++ -O3 -c -o tmp/Router.o -I${EXTRA_INCLUDE_PATH} src/Router.cc
g++ -O3 -c -o tmp/LanRouter.o -I${EXTRA_INCLUDE_PATH} src/LanRouter.cc
g++ -O3 -c -o tmp/NetRouter.o -I${EXTRA_INCLUDE_PATH} src/NetRouter.cc
g++ -O3 -c -o tmp/coprocess.o -I${EXTRA_INCLUDE_PATH} src/coprocess.cc
g++ -O3 -c -o tmp/ipassign.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/ipassign.cc
g++ -O3 -c -o tmp/bitmath.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/bitmath.cc
g++ -O3 -c -o tmp/Assigner.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/Assigner.cc
g++ -O3 -c -o tmp/ConservativeAssigner.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/ConservativeAssigner.cc
g++ -O3 -c -o tmp/Framework.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/Framework.cc
g++ -O3 -c -o tmp/HostRouter.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/HostRouter.cc
g++ -O3 -c -o tmp/Router.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/Router.cc
g++ -O3 -c -o tmp/LanRouter.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/LanRouter.cc
g++ -O3 -c -o tmp/NetRouter.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/NetRouter.cc
g++ -O3 -c -o tmp/coprocess.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/coprocess.cc
g++ -O3 -o bin/ipassign -L${EXTRA_LIB_PATH}/ tmp/ipassign.o tmp/bitmath.o tmp/Assigner.o tmp/ConservativeAssigner.o tmp/Framework.o tmp/HostRouter.o tmp/Router.o tmp/LanRouter.o tmp/NetRouter.o tmp/coprocess.o -lmetis -lm
g++ -O3 -c -o tmp/routestat.o -I${EXTRA_INCLUDE_PATH} src/routestat.cc
......
# Lines starting with a '#' are comments and are ignored.
# Lines starting with '=' mark a divider. A horizontal line is written at
# that point. Anything else on the line is ignored.
# Lines starting with a '$' define a variable. Paths and filenames are
# relative to the working directory of autocheck. Slashes are
# automatically converted to be compatible with your os.
# All of the paths default to '.'
# Where to put the output generated by the script. This output file is
# checked against the output file with the same name in $keyOutputPath.
$trialOutputPath tmp/result/
# This is the path where the test scripts are held.
$scriptPath graph/
# This is where the master copies of the script output files are held.
$keyOutputPath result/
### The three command variables must have a value.
# This is the command that is used to execute scripts.
$runCommand bin/ipassign
# This is the command that is used to compare two output or two program files.
$compareCommand bin/boolcmp
# Every other line must contain a word, some whitespace, then a number.
# For example (if the next line didn't have the '#'):
# word 15
# For each value from 1 to the number, a test will be run and the following
# files will be created (relative to the current directory):
# $trialOutputPath/word1.result
# And so on for 2..14
# $trialOutputPath/word14-output.txt
# After those files are created, then comparisons are made to determine
# whether the test passes or failed.
# If '$trialOutputPath/word?.result' is identical to
# '$keyOutputPath/word?.result', then the output test passes.
# Where ? means the number of the test (between 1 and 15 in this case)
# Note that this means that both word and number should only contain
# characters that can be put in a filename. And the number should
# be an integer.
# Note if the 'zero index' flag is set, then the number range would be
# 0..14 in this example.
# word number
# ---- ------
=
kgraph 5
=
torus-real 1
=
narrows 9
=
tree 3
=
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
use Socket;
use IO::Handle; # thousands of lines just for autoflush :-(
#
# usage: ipassign_wrapper <pid> <eid>
#
sub usage()
{
print("Usage: ipassign_wrapper [-n [-s|-b|-l]] [-d] [-f] <pid> <eid>\n".
" Use -n to print routes, but leave the DB alone.\n".
" Use -s (with -n) to print routes in NS format.\n".
" Use -b (with -n) to print routes in Freebsd format.\n".
" Use -l (with -n) to print routes in Linux format.\n".
" Use -d to turn on debugging output.\n".
" Use -f to force route calculation; ignore 'static' flag.\n".
" Use -H to specift host-host routing in ipassign\n".
" Use -L to specift host-lan routing in ipassign\n".
" Use -N to specift host-net routing in ipassign\n".
" Use -p to specify the # of partitions\n");
exit(-1);
}
my $optlist = "nsbldfHLNp:";
#
# Configure variables
#
my $TB = "@prefix@";
my $debug = 0;
my $ipassign = "$TB/libexec/ipassign";
my $ipassign_args = " -c";
my $impotent = 0;
my $force = 0;
my $format = "";
my $routetype = "host2net";
my $partitions = 0;
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Turn off line buffering on output
#
$| = 1;
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (@ARGV != 2) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"n"})) {
$impotent = 1;
}
if (defined($options{"f"})) {
$force = 1;
}
if (defined($options{"s"})) {
$format = "ns";
}
if (defined($options{"b"})) {
$format = "bsd";
}
if (defined($options{"l"})) {
$format = "suxs";
}
if (defined($options{"p"})) {
$partitions = $options{"p"};
$ipassign_args .= " -p$partitions";
} else {
$ipassign_args .= " -s";
}
if (defined($options{"H"})) {
$routetype = "host2host";
$ipassign_args .= " -h";
}
if (defined($options{"L"})) {
$routetype = "host2lan";
$ipassign_args .= " -l";
}
if (defined($options{"N"})) {
$routetype = "host2net";
$ipassign_args .= " -n";
}
if ($format && !$impotent) {
usage();
}
my $pid = $ARGV[0];
my $eid = $ARGV[1];
#
# Untaint args.
#
if ($pid =~ /^([-\@\w]+)$/) {
$pid = $1;
}
else {
die("Bad data in pid: $pid.");
}
if ($eid =~ /^([-\@\w]+)$/) {
$eid = $1;
}
else {
die("Bad data in eid: $eid.");
}
#
# Are we doing Static routing?
#
my $query_result =
DBQueryFatal("select routertype from virt_nodes ".
"where pid='$pid' and eid='$eid' limit 1");
if (!$query_result->numrows) {
warn("*** $0:\n".
" No nodes in experiment $pid/$eid!\n");
exit(0);
} else {
my $routertype = $query_result->fetchrow_array;
if (!$force && $routertype ne "static") {
warn("Static routing not requested in $pid/$eid. This is okay!\n");
exit(0);
}
}
#
# Grab virtual lan configuration from the DB
#
$query_result =
DBQueryFatal("select vname,member,cost,mask " .
"from virt_lans where pid='$pid' and eid='$eid'");
if (!$query_result->numrows) {
warn("*** $0:\n".
" No links or lans in experiment $pid/$eid!\n");
exit(0);
}
my $vindex = 0;
my %lans = ();
my %costs = ();
my %masks = ();
my %lan2iface = ();
while (my ($vlan,$member,$cost,$mask) = $query_result->fetchrow_array) {
if (! defined($lans{$vlan})) {
$lans{$vlan} = [];
}
my($vnode, $iface) = split(":", $member);
if (! defined($vnode2index{$vnode})) {
$vnode2index{$vnode} = $vindex;
$index2vnode{$vindex} = $vnode;
$vindex++;
}
push(@{$lans{$vlan}},$vnode2index{$vnode});
$lan2iface{$vlan}->{$vnode} = $iface;
$costs{$vlan} = int($cost);
$masks{$vlan} = inet_aton($mask);
}
#
# We use perl IPC goo to create a child we can both write to and read from
# (normal perl I/O provides just unidirectional I/O to a process).
#
if (! socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC)) {
die("*** $0:\n".
" socketpair failed: $!\n");
}
CHILD->autoflush(1);
PARENT->autoflush(1);
my $childpid = fork();
if (! $childpid) {
close CHILD;
#
# Dup our descriptors to the parent, and exec the program.
# The parent then talks to it read/write.
#
open(STDIN, "<&PARENT") || die "Can't redirect stdin";
open(STDOUT, ">&PARENT") || die "Can't redirect stdout";
open(STDERR, ">/dev/null") || die "Can't redirect stderr";
exec($ipassign . $ipassign_args);
die("*** $0:\n".
" exec $ipassign $ipassign_args failed: $!\n");
}
close PARENT;
my $lindex = 0;
my %lan2index = ();
my %index2lan = ();
while (my ($vlan, $membptr) = each %lans) {
my @members = @{$membptr};
$index2lan{$lindex} = $vlan;
$lan2index{$vlan} = $lindex;
$lindex++;
print CHILD "8 $costs{$vlan} @members\n";
if ($debug) {
print "8 $costs{$vlan} @members\n";
}
}
shutdown(CHILD,1);
my %CIDR2dotquad = ();
$CIDR2dotquad{'8'} = "255.0.0.0";
$CIDR2dotquad{'16'} = "255.255.0.0";
$CIDR2dotquad{'24'} = "255.255.255.0";
$CIDR2dotquad{'32'} = "255.255.255.255";
my %vnodetab = ();
my $vnode = "";
my $mode = "ip";
while(<CHILD>) {
if ($debug) {
print $_;
}
if (/%%/) {
if ($mode eq "ip") {
$mode = "route";
}
next;
}
if ($mode eq "ip") {
my ($lindex, $vindex, $ip) = /^\s*(\d+)\s+(\d+)\s+([\d\.]+)/;
my $lan = $index2lan{$lindex};
my $vn = $index2vnode{$vindex};
push (@{$vnodetab{$vn}->{'IPS'}},
[$ip, $masks{$lan}, $lan2iface{$lan}->{$vn}]);
}
elsif ($mode eq "route") {
if (/^\s*Routing table for node:\s+(\d+)/) {
$vnode = $index2vnode{$1};
}
elsif (/^\s*Destination:\s+([\d\.]+)\/(\d+)\s+FirstHop:\s+([\d\.]+)/) {
my $type;
if ($2 == 32) {
$type = "host";
}
else {
$type = "net";
}
push(@{$vnodetab{$vnode}->{'routes'}},
[$type, $1, $CIDR2dotquad{$2}, $3]);
}
else {
die "Junk in ipassign output.";
}
}
}
close CHILD;
if (wait() != $childpid) {
die "problem encountered in wait()";
}
my $childstatus = $?;
my $retval = $childstatus >> 8;
if ($childstatus) {
die "ipassign failed. No routes or IPs have been added to the DB.";
}
#
# Clean the routes.
#
if (! $impotent) {
DBQueryFatal("delete from virt_routes where ".
"pid='$pid' and eid='$eid'");
}
while (my ($vnode, $valhash) = each %vnodetab) {
my @ipinfo = @{$valhash->{'IPS'}};
my @routes = @{$valhash->{'routes'}};
my @ipifaces = map { @{$_}[2] . ":" . @{$_}[0] } @ipinfo;
if (!$impotent) {
DBQueryFatal("update virt_nodes set ips='@ipifaces' ".
"where vname='$vnode' and pid='$pid' and eid='$eid'");
}
if ($debug) {
print "Info for $vnode:\n".
"IPS: @ipifaces\n";
}
foreach $routeptr (@routes) {
my ($type, $dstip, $mask, $hopip) = @{$routeptr};
my $srcip;
foreach my $ipdatum (@ipinfo) {
my ($src, $srcmask, $iface) = @{$ipdatum};
if ((inet_aton($src) & $srcmask) eq
(inet_aton($hopip) & $srcmask)) {
$srcip = $src;
last;
}
}
if ($debug) {
print "route: type: $type src: $srcip dst: $dstip mask: $mask ".
"nexthop: $hopip\n";
}
if ($impotent) {
if ($format eq "bsd") {
if ($type eq "host") {
print "route add -host $dstip $hopip\n";
}
else {
print "route add -net $dstip $hopip $mask\n";
}
}
elsif ($format eq "suxs") {
if ($type eq "host") {
print "route add -host $dstip gw $hopip\n";
}
else {
print "route add -net $dstip netmask ".
"$mask gw $hopip\n";
}
}
}
else {
DBQueryFatal("insert into virt_routes ".
" (pid,eid,vname,src,dst,nexthop,dst_type,".
" dst_mask) ".
" values ('$pid', '$eid', '$vnode', '$srcip', ".
" '$dstip', '$hopip', '$type', '$mask')");
}
}
}
exit 0;
......@@ -13,7 +13,3 @@
Assigner::~Assigner()
{
}
void Assigner::setPartitionCount(size_t)
{
}
......@@ -12,6 +12,8 @@
#ifndef ASSIGNER_H_IP_ASSIGN_2
#define ASSIGNER_H_IP_ASSIGN_2
#include "Partition.h"
class Assigner
{
public:
......@@ -23,9 +25,7 @@ public:
virtual ~Assigner();
virtual std::auto_ptr<Assigner> clone(void) const=0;
// Determines how many partitions to divide the graph into.
// Should only affect NumberAssigner and ConservativeAssigner
virtual void setPartitionCount(size_t);
virtual void setPartition(Partition & newPartition)=0;
// This is called repeatedly to form the graph. Raw parsing
// of the command line is done outside.
// Any numbers between [0..MaxNodeNumber] that are unused
......
......@@ -13,11 +13,12 @@
using namespace std;
ConservativeAssigner::ConservativeAssigner()
ConservativeAssigner::ConservativeAssigner(Partition & newPartition)
: m_partitionCount(0)
, m_largestLan(0)
, m_lanMaskSize(0)
, m_netMaskSize(0)
, m_partition(newPartition)
{
}
......@@ -30,9 +31,8 @@ auto_ptr<Assigner> ConservativeAssigner::clone(void) const
return auto_ptr<Assigner>(new ConservativeAssigner(*this));
}
void ConservativeAssigner::setPartitionCount(size_t newCount)
void ConservativeAssigner::setPartition(Partition & newPartition)
{
m_partitionCount = newCount;
}
void ConservativeAssigner::addLan(int bits, int weight, vector<size_t> nodes)
......@@ -65,66 +65,13 @@ void ConservativeAssigner::ipAssign(void)
std::vector<int> graphNeighborArray;
std::vector<int> weightArray;
//////////////////////////////////////////////////////
// convert to METIS graph
//////////////////////////////////////////////////////
convert(graphIndexArray, graphNeighborArray, weightArray);
partitionArray.resize(graphIndexArray.size() - 1);
fill(partitionArray.begin(), partitionArray.end(), 0);
//////////////////////////////////////////////////////
// partition the graph
//////////////////////////////////////////////////////
int numVertices = graphIndexArray.size() - 1;
int weightOption = 1; // Weights on edges only
int indexOption = 0; // 0-based index
int numPartitions = max(0, m_partitionCount);
int options[5];
int edgesCut = 0;
if (numPartitions > 1 && numPartitions <= 8)
{
options[0] = 0; // use defaults. Ignore other options.
options[1] = 3; // (default) Sorted Heavy-Edge matching
options[2] = 1; // (default) Region Growing
options[3] = 1; // (default) Early-Exit Boundary FM refinement
options[4] = 0; // (default) Always set to 0
METIS_PartGraphRecursive(
&numVertices, // # of vertices in graph
&(graphIndexArray[0]), // xadj
&(graphNeighborArray[0]), // adjncy
NULL, // vertex weights
&(weightArray[0]), // edge weights
&weightOption, // Weights on edges only
&indexOption, // 0-based index
&numPartitions,