obfunc load_balanced_create() {local host, gid, usx, sx, si, sb, c, cc, ptree \
  localobj cell, sr, s
	host = load_balance_.host.x[$1]
	gid = load_balance_.gid.x[$1]
	sx = load_balance_.splitx.x[$1]
	usx = load_balance_.unsplitx.x[$1]
	si = load_balance_.spliti.x[$1]
	sb = load_balance_.splitb.x[$1]

	s = new String()
	sprint(s.s, "pnm.cells.append(%s)", $s2)
	execute(s.s)
	cell = pnm.cells.object(pnm.cells.count-1)

	if (sx < 0) { // entirely on this cpu
		pc.set_gid2node(gid, pc.id)
		gidvec.append(gid)
	}else{
		c = load_balance_.cell_complexity(cell)
		load_balance_.compute_roots()
		sr = ldbal_reconnect(si, abs(sb))
// following tests must be carried out with point process complexities in mcomplex.dat = 0
//sr.sec printf("%d a split %s %g %g    %g %g   %d %d %d %d\n", pc.id, secname(), usx, c, sx, usx - sx, host, gid, si, sb)
		ptree = 0 if (sb < 0) { ptree = 1 }
		ldbal_split(sr, host, gid, ptree, cell)
//c = load_balance_.cell_complexity(cell)
//if (host == pc.id) { cc = sx } else { cc = usx - sx }
//ptree = 0 if (!pc.gid_exists(gid)) ptree = 1
//printf("%d split %s %d %d %g %g\n", pc.id, cell, gid, ptree, c, cc)
	}
	return cell
}

//reconnect so a split at the returned
// SectionRef corresponds to the complexity desired
// ptree = 1 means the parent tree will go on the host
obfunc ldbal_reconnect() {local i  localobj sp, bs, sr, sc
	ip = load_balance_.parent_vec_.x[$1]
	if (ip  == -1) {
		execerror("cannot split at original root", "")
	}
	sp = load_balance_.secref(ip)
	// the branch set (in the proper order)
	bs = load_balance_.parent_vec_.indvwhere("==", ip)
	// disconnect all the children
	// assume all children effectively connected at their 0 end to the trueparent
	// at the 1 end
	for i=0, bs.size-1 {
		sr = load_balance_.secref(bs.x[i])
		sr.sec { disconnect() }
	}
	if ($2 <= bs.size) { // is it an individual?
		// then all get connected to the trueparent and return
		// the individual
		for i=0, bs.size-1 {
			sr = load_balance_.secref(bs.x[i])
			sp.sec connect sr.sec (0), 1
		}
		sc = load_balance_.secref(bs.x[$2-1])
	}else{ // it is a sum
		sc = load_balance_.secref(bs.x[0])
		sp.sec connect sc.sec (0), 1
		n = $2 - bs.size // 1 means 0+1
		for i=1, n { // connect to the 0 child
			sr = load_balance_.secref(bs.x[i])
			sc.sec connect sr.sec (0), 0
		}
		for i=n+1, bs.size-1 { // connect to the trueparent
			sr = load_balance_.secref(bs.x[i])
			sp.sec connect sr.sec (0), 1
		}
	}
	return sc
}

proc ldbal_split() {localobj nc, sr, nil
	$o5.connect2target(nil, nc)
	nc.preloc() sr = new SectionRef() pop_section()
	if ($4 == 0) {
		$o1.sec pnm.splitcell($2, $2+1)
	}else{
		$o1.sec pnm.splitcell($2+1, $2)
	}
	if (sr.exists()) {
		pc.set_gid2node($3, pc.id)
		gidvec.append($3)
	}else{
		pc.set_gid2node($3 + splitbit, pc.id)
		gidvec.append($3 + splitbit)
		nc = nil
	}
}