// 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() } }
// main loop for table input func mainTable() { // process files for _, f := range flag.Args() { outFname := util.NoExt(f) + "_fft" + path.Ext(f) processTable(f, outFname) } }
// generate wrapper code from template func wrapgen(filename, funcname string, argt, argn []string) { kernel := &Kernel{funcname, argt, argn, make(map[int]string)} // find corresponding .PTX files if ls == nil { dir, errd := os.Open(".") defer dir.Close() util.PanicErr(errd) var errls error ls, errls = dir.Readdirnames(-1) util.PanicErr(errls) } basename := util.NoExt(filename) for _, f := range ls { match, e := regexp.MatchString("^"+basename+"_*[0-9]..ptx", f) util.PanicErr(e) if match { cc, ei := strconv.Atoi(f[len(f)-len("00.ptx") : len(f)-len(".ptx")]) util.PanicErr(ei) fmt.Println(basename, cc) kernel.PTX[cc] = filterptx(f) } } if len(kernel.PTX) == 0 { log.Fatal("no PTX files for ", filename) } wrapfname := basename + "_wrapper.go" wrapout, err := os.OpenFile(wrapfname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) util.PanicErr(err) defer wrapout.Close() util.PanicErr(templ.Execute(wrapout, kernel)) }
// Usage: in every Go input file, write: // // func main(){ // defer InitAndClose()() // // ... // } // // This initialises the GPU, output directory, etc, // and makes sure pending output will get flushed. func InitAndClose() func() { flag.Parse() cuda.Init(*Flag_gpu) cuda.Synchronous = *Flag_sync od := *Flag_od if od == "" { od = path.Base(os.Args[0]) + ".out" } inFile := util.NoExt(od) InitIO(inFile, od, *Flag_forceclean) GoServe(*Flag_port) return func() { Close() } }
// Once Params/Quants have been declared and added, // initialize the GUI Page (pre-renders template) and register http handlers func (g *guistate) PrepareServer() { g.Page = gui.NewPage(templText, g) util.SetProgress(gui_.Prog) g.OnAnyEvent(func() { g.incCacheBreaker() }) http.Handle("/", g) http.HandleFunc("/render/", g.ServeRender) http.HandleFunc("/plot/", g.servePlot) g.Set("title", util.NoExt(OD()[:len(OD())-1])) g.prepareConsole() g.prepareMesh() g.prepareGeom() g.prepareM() g.prepareSolver() g.prepareDisplay() g.prepareParam() g.prepareOnUpdate() }
// prepare exec.Cmd to run mumax3 compute process func NewProcess(ID string, gpu int, webAddr string) *Process { // prepare command inputURL := "http://" + ID command := *flag_mumax gpuFlag := fmt.Sprint(`-gpu=`, gpu) httpFlag := fmt.Sprint(`-http=`, webAddr) cacheFlag := fmt.Sprint(`-cache=`, *flag_cachedir) forceFlag := `-f=0` cmd := exec.Command(command, gpuFlag, httpFlag, cacheFlag, forceFlag, inputURL) // Pipe stdout, stderr to log file over httpfs outDir := util.NoExt(inputURL) + ".out" errMkdir := httpfs.Mkdir(outDir) if errMkdir != nil { SetJobError(ID, errMkdir) log.Println("makeProcess", errMkdir) j := JobByName(ID) if j != nil { j.Reque() } return nil } out, errD := httpfs.Create(outDir + "/stdout.txt") if errD != nil { SetJobError(ID, errD) log.Println("makeProcess", errD) j := JobByName(ID) if j != nil { j.Reque() } return nil } cmd.Stderr = out cmd.Stdout = out return &Process{ID: ID, Cmd: cmd, Start: time.Now(), Out: out, OutputURL: OutputDir(inputURL), GUI: webAddr} }
func doFile(infname string, outp output) { // determine output file outfname := util.NoExt(infname) + outp.Ext if *flag_dir != "" { outfname = *flag_dir + "/" + path.Base(outfname) } msg := infname + "\t-> " + outfname defer func() { log.Println(msg) }() if infname == outfname { msg = fail(msg, "input and output file are the same") return } defer func() { if err := recover(); err != nil { msg = fail(msg, err) os.Remove(outfname) } }() if !(strings.HasPrefix(infname, "http://") || strings.HasPrefix(outfname, "http://")) { inStat, errS := os.Stat(infname) if errS != nil { panic(errS) } outStat, errO := os.Stat(outfname) if errO == nil && outStat.ModTime().Sub(inStat.ModTime()) > 0 { msg = "[skip] " + msg + ": skipped based on time stamps" skipped.Add(1) return } } var slice *data.Slice var info data.Meta var err error in, errI := httpfs.Open(infname) if errI != nil { msg = fail(msg, errI) return } defer in.Close() switch path.Ext(infname) { default: msg = fail(msg, ": skipping unsupported type: "+path.Ext(infname)) return case ".ovf", ".omf", ".ovf2": slice, info, err = oommf.Read(in) case ".dump": slice, info, err = dump.Read(in) } if err != nil { msg = fail(msg, err) return } out, err := httpfs.Create(outfname) if err != nil { msg = fail(msg, err) return } defer out.Close() preprocess(slice) outp.Convert(slice, info, panicWriter{out}) succeeded.Add(1) msg = "[ ok ] " + msg }
// renders page title for PrepareServer func (g *guistate) Title() string { return util.NoExt(path.Base(OD())) }
// output directory for input file func OutputDir(path string) string { return util.NoExt(path) + ".out/" }