// Filter comments and ".file" entries from ptx code. // They spoil the git history. func filterptx(fname string) string { f, err := os.Open(fname) util.PanicErr(err) defer f.Close() in := bufio.NewReader(f) var out bytes.Buffer out.Write(([]byte)("`")) line, err := in.ReadBytes('\n') for err != io.EOF { util.PanicErr(err) if !bytes.HasPrefix(line, []byte("//")) && !bytes.HasPrefix(line, []byte(" .file")) { out.Write(line) } line, err = in.ReadBytes('\n') } out.Write(([]byte)("`")) return out.String() }
// generate cuda wrapper for file. func cuda2go(fname string) { // open cuda file f, err := os.Open(fname) util.PanicErr(err) defer f.Close() // read tokens var token []string var s scanner.Scanner s.Init(f) tok := s.Scan() for tok != scanner.EOF { if !filter(s.TokenText()) { token = append(token, s.TokenText()) } tok = s.Scan() } // find function name and arguments funcname := "" argstart, argstop := -1, -1 for i := 0; i < len(token); i++ { if token[i] == "__global__" { funcname = token[i+2] argstart = i + 4 } if argstart > 0 && token[i] == ")" { argstop = i + 1 break } } argl := token[argstart:argstop] // isolate individual arguments var args [][]string start := 0 for i, a := range argl { if a == "," || a == ")" { args = append(args, argl[start:i]) start = i + 1 } } // separate arg names/types and make pointers Go-style argn := make([]string, len(args)) argt := make([]string, len(args)) for i := range args { if args[i][1] == "*" { args[i] = []string{args[i][0] + "*", args[i][2]} } argt[i] = typemap(args[i][0]) argn[i] = args[i][1] } wrapgen(fname, funcname, argt, argn) }
// 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)) }
func atoi(a string) int { i, err := strconv.Atoi(a) util.PanicErr(err) return i }
// path to the executable. func procSelfExe() string { me, err := os.Readlink("/proc/self/exe") util.PanicErr(err) return me }