88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package runtime
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/cheggaaa/pb"
|
|
"github.com/jjdekker/chronozinc/settings"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
// RunAll runs every instance on every solver
|
|
func RunAll(solvers []settings.Solver, instances []settings.Instance) {
|
|
work := make(chan func())
|
|
wait := govern(work)
|
|
|
|
fmt.Println("Running solving instances:")
|
|
bar := pb.StartNew(len(solvers) * len(instances))
|
|
for i := range solvers {
|
|
for j := range instances {
|
|
work <- func() {
|
|
RunInstance(&solvers[i], &instances[j])
|
|
bar.Increment()
|
|
}
|
|
}
|
|
}
|
|
close(work)
|
|
|
|
wait.Wait()
|
|
bar.FinishPrint("Finished!")
|
|
}
|
|
|
|
func govern(work <-chan func()) *sync.WaitGroup {
|
|
var wg sync.WaitGroup
|
|
procs := viper.GetInt("processes")
|
|
|
|
wg.Add(procs)
|
|
for i := 0; i < procs; i++ {
|
|
go func() {
|
|
for f := range work {
|
|
f()
|
|
}
|
|
wg.Done()
|
|
}()
|
|
}
|
|
|
|
return &wg
|
|
}
|
|
|
|
// RunInstance runs an instance on a Solver using mzn-fzn
|
|
func RunInstance(solver *settings.Solver, instance *settings.Instance) {
|
|
args := []string{
|
|
"--solver", solver.Binary,
|
|
"--flatzinc-flag", solver.Flags,
|
|
instance.Model,
|
|
}
|
|
if solver.Globals != "" {
|
|
args = append(args, "--globals-dir", solver.Globals)
|
|
}
|
|
if instance.Data != "" {
|
|
args = append(args, "--data", instance.Data)
|
|
}
|
|
if solver.OverrideFlags != "" {
|
|
args = append(args, strings.Split(solver.OverrideFlags, " ")...)
|
|
} else {
|
|
args = append(args, strings.Split(viper.GetString("flags"), " ")...)
|
|
}
|
|
proc := exec.Command(viper.GetString("mznfzn"), args...)
|
|
|
|
if out, err := proc.CombinedOutput(); err != nil {
|
|
log.Printf("Instance %s ended with error %s", instance, err)
|
|
} else {
|
|
path := instance.OutPath(solver.Name)
|
|
os.MkdirAll(filepath.Dir(path), os.ModePerm)
|
|
err := ioutil.WriteFile(path, out, 0644)
|
|
if err != nil {
|
|
log.Printf("Saving results for instance %s ended with error %s",
|
|
instance, err)
|
|
}
|
|
}
|
|
}
|