// Read a magnetization state from .dump file. func LoadFile(fname string) *data.Slice { in, err := httpfs.Open(fname) util.FatalErr(err) var s *data.Slice if path.Ext(fname) == ".dump" { s, _, err = dump.Read(in) } else { s, _, err = oommf.Read(in) } util.FatalErr(err) return s }
// Runs a script file. func runFileAndServe(fname string) { outDir := util.NoExt(fname) + ".out" if *flag_od != "" { outDir = *flag_od } engine.InitIO(fname, outDir, *flag_forceclean) fname = engine.InputFile var code *script.BlockStmt var err2 error if fname != "" { // first we compile the entire file into an executable tree code, err2 = engine.CompileFile(fname) util.FatalErr(err2) } // now the parser is not used anymore so it can handle web requests goServeGUI() if *flag_interactive { openbrowser("http://127.0.0.1" + *flag_port) } // start executing the tree, possibly injecting commands from web gui engine.EvalFile(code) if *flag_interactive { engine.RunInteractive() } }
// open writer and write header func (t *DataTable) init() { if t.inited() { return } f, err := httpfs.Create(OD() + t.name + ".txt") util.FatalErr(err) t.output = f // write header fprint(t, "# t (s)") for _, o := range t.outputs { if o.NComp() == 1 { fprint(t, "\t", o.Name(), " (", o.Unit(), ")") } else { for c := 0; c < o.NComp(); c++ { fprint(t, "\t", o.Name()+string('x'+c), " (", o.Unit(), ")") } } } fprintln(t) t.Flush() // periodically flush so GUI shows graph, // but don't flush after every output for performance // (httpfs flush is expensive) go func() { for { time.Sleep(TableAutoflushRate * time.Second) Table.flush() } }() }
func main() { flag.Parse() IPs = parseIPs() MinPort, MaxPort = parsePorts() thisAddr = canonicalAddr(*flag_addr, IPs) var err error thisHost, _, err = net.SplitHostPort(thisAddr) util.FatalErr(err) DetectMumax() DetectGPUs() LoadJobs() http.HandleFunc("/do/", HandleRPC) http.HandleFunc("/", HandleStatus) httpfs.RegisterHandlers() // Listen and serve on all interfaces go func() { log.Println("serving at", thisAddr) // try to listen and serve on all interfaces other than thisAddr // this is for convenience, errors are not fatal. _, p, err := net.SplitHostPort(thisAddr) Fatal(err) ips := util.InterfaceAddrs() for _, ip := range ips { addr := net.JoinHostPort(ip, p) if addr != thisAddr { // skip thisAddr, will start later and is fatal on error go func() { err := http.ListenAndServe(addr, nil) if err != nil { log.Println("info:", err, "(but still serving other interfaces)") } }() } } // only on thisAddr, this server's unique address, // we HAVE to be listening. Fatal(http.ListenAndServe(thisAddr, nil)) }() ProbePeer(thisAddr) // make sure we have ourself as peer go FindPeers(IPs, MinPort, MaxPort) go RunComputeService() go LoopWatchdog() go RunShareDecay() // re-load jobs every hour so we don't stall on very exceptional circumstances go func() { for { time.Sleep(1 * time.Hour) LoadJobs() } }() <-make(chan struct{}) // wait forever }
// Append msg to file. Used to write aggregated output of many simulations in one file. func Fprintln(filename string, msg ...interface{}) { if !path.IsAbs(filename) { filename = OD() + filename } httpfs.Touch(filename) err := httpfs.Append(filename, []byte(fmt.Sprintln(myFmt(msg)...))) util.FatalErr(err) }
func InitCPU(OD string) { // start CPU profile to file fname := OD + "cpu.pprof" f, err := os.Create(fname) util.FatalErr(err) err = pprof.StartCPUProfile(f) util.FatalErr(err) log.Println("writing CPU profile to", fname) // at exit: exec go tool pprof to generate SVG output AtExit(func() { pprof.StopCPUProfile() me := procSelfExe() outfile := fname + ".svg" saveCmdOutput(outfile, "go", "tool", "pprof", "-svg", me, fname) }) }
// cu.Init(), but error is fatal and does not dump stack. func tryCuInit() { defer func() { err := recover() if err == cu.ERROR_UNKNOWN { log.Println("\n Try running: sudo nvidia-modprobe -u \n") } util.FatalErr(err) }() cu.Init(0) }
func parseSize(arg string) (size [3]int) { words := strings.Split(arg, "x") if len(words) != 3 { log.Fatal("resize: need N0xN1xN2 argument") } for i, w := range words { v, err := strconv.Atoi(w) util.FatalErr(err) size[i] = v } return }
func initLog() { if logfile != nil { panic("log already inited") } // open log file and flush what was logged before the file existed var err error logfile, err = httpfs.Create(OD() + "log.txt") if err != nil { panic(err) } util.FatalErr(err) logfile.Write(([]byte)(hist)) logfile.Write([]byte{'\n'}) }
func (t *DataTable) Flush() error { if t.output == nil { return nil } if cuda.Synchronous { timer.Start("io") } err := t.output.Flush() if cuda.Synchronous { timer.Stop("io") } util.FatalErr(err) return err }
// check all input files for errors, don't run. func vet() { status := 0 for _, f := range flag.Args() { src, ioerr := ioutil.ReadFile(f) util.FatalErr(ioerr) engine.World.EnterScope() // avoid name collisions between separate files _, err := engine.World.Compile(string(src)) engine.World.ExitScope() if err != nil { fmt.Println(f, ":", err) status = 1 } else { fmt.Println(f, ":", "OK") } } os.Exit(status) }
// synchronous save func saveAs_sync(fname string, s *data.Slice, info data.Meta, format OutputFormat) { f, err := httpfs.Create(fname) util.FatalErr(err) defer f.Close() switch format { case OVF1_TEXT: oommf.WriteOVF1(f, s, info, "text") case OVF1_BINARY: oommf.WriteOVF1(f, s, info, "binary 4") case OVF2_TEXT: oommf.WriteOVF2(f, s, info, "text") case OVF2_BINARY: oommf.WriteOVF2(f, s, info, "binary 4") case DUMP: dump.Write(f, s, info) default: panic("invalid output format") } }
func (t *DataTable) Write(p []byte) (int, error) { n, err := t.output.Write(p) util.FatalErr(err) return n, err }
// Write the slice to file in binary format, panic on error. func MustWriteFile(fname string, s *data.Slice, info data.Meta) { err := WriteFile(fname, s, info) util.FatalErr(err) }
// synchronous snapshot func snapshot_sync(fname string, output *data.Slice) { f, err := httpfs.Create(fname) util.FatalErr(err) defer f.Close() draw.RenderFormat(f, output, "auto", "auto", arrowSize, path.Ext(fname)) }
func MustReadFile(fname string) (*data.Slice, data.Meta) { s, t, err := ReadFile(fname) util.FatalErr(err) return s, t }
// Safe fmt.Fprintln, will fail on error func fprintln(out io.Writer, x ...interface{}) { _, err := fmt.Fprintln(out, x...) util.FatalErr(err) }
// Writes a header key/value pair to out: // # Key: Value func hdr(out io.Writer, key string, value ...interface{}) { _, err := fmt.Fprint(out, "# ", key, ": ") util.FatalErr(err) _, err = fmt.Fprintln(out, value...) util.FatalErr(err) }