gorgonia.org/gorgonia@v0.9.17/templates.go (about) 1 package gorgonia 2 3 import ( 4 "fmt" 5 "strings" 6 "text/template" 7 ) 8 9 const exprNodeTemplText = `< 10 <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" PORT="anchor" {{if isLeaf .}} COLOR="#00FF00;"{{else if isRoot . }} COLOR="#FF0000;" {{else if isMarked .}} COLOR="#0000FF;" {{end}}{{if isInput .}} BGCOLOR="lightyellow"{{else if isStmt .}} BGCOLOR="lightblue"{{end}}> 11 12 <TR><TD>{{printf "%x" .ID}}</TD><TD>{{printf "%v" .Name | html | dotEscape}} :: {{nodeType . | html | dotEscape }}</TD></TR> 13 {{if printOp . }}<TR><TD>Op</TD><TD>{{ opStr . | html | dotEscape }} :: {{ opType . | html | dotEscape }}</TD></TR>{{end}} 14 {{if hasShape .}}<TR><TD>Shape</TD><TD>{{ getShape .}}</TD></TR>{{end}} 15 <TR><TD>Overwrites Input {{overwritesInput . }}</TD><TD>Data On: {{.Device}}</TD></TR> 16 {{if hasGrad .}}<TR><TD>Value</TD><TD>Grad</TD></TR> 17 <TR><TD>{{printf "%+3.3s" .Value | dotEscape}}</TD><TD>{{getGrad . | dotEscape }} </TD></TR> 18 <TR><TD>Ptr: {{getValPtr . | dotEscape}} </TD><TD>Ptr: {{getGradPtr . | dotEscape}} </TD></TR> 19 {{else}} 20 <TR><TD>Value</TD><TD>{{printf "%+3.3s" .Value | dotEscape}}</TD></TR> 21 {{end}} 22 23 </TABLE> 24 >` 25 26 func dotEscape(s string) string { 27 s = strings.Replace(s, "\n", "<BR />", -1) 28 s = strings.Replace(s, "<nil>", "NIL", -1) 29 return s 30 } 31 32 func printOp(n *Node) bool { return n.op != nil && !n.isStmt } 33 func isLeaf(n *Node) bool { return len(n.children) == 0 } 34 func isInput(n *Node) bool { return n.isInput() } 35 func isMarked(n *Node) bool { return n.ofInterest } 36 func isRoot(n *Node) bool { return n.isRoot() } 37 func isStmt(n *Node) bool { return n.isStmt } 38 func hasShape(n *Node) bool { return n.shape != nil } 39 func hasGrad(n *Node) bool { _, err := n.Grad(); return err == nil } 40 func opStr(n *Node) string { return n.op.String() } 41 func opType(n *Node) string { return n.op.Type().String() } 42 43 func nodeType(n *Node) string { 44 if n.t == nil { 45 return "NIL" 46 } 47 return n.t.String() 48 } 49 50 func overwritesInput(n *Node) int { 51 if n.op == nil { 52 return -1 53 } 54 return n.op.OverwritesInput() 55 } 56 57 func getShape(n *Node) string { 58 if !n.inferredShape { 59 return fmt.Sprintf("%v", n.shape) 60 } 61 return fmt.Sprintf("<U>%v</U>", n.shape) // graphviz 2.38+ only supports <O> 62 } 63 64 func getGrad(n *Node) string { 65 grad, err := n.Grad() 66 if err == nil { 67 return fmt.Sprintf("%+3.3s", grad) 68 } 69 return "" 70 } 71 72 func getGradPtr(n *Node) string { 73 grad, err := n.Grad() 74 if err == nil && grad != nil { 75 return fmt.Sprintf("0x%x", grad.Uintptr()) 76 } 77 return "" 78 } 79 80 func getValPtr(n *Node) string { 81 if n.Value() == nil { 82 return "<nil>" 83 } 84 return fmt.Sprintf("0x%dx", n.Value().Uintptr()) 85 } 86 87 var funcMap = template.FuncMap{ 88 "dotEscape": dotEscape, 89 "printOp": printOp, 90 "isRoot": isRoot, 91 "isLeaf": isLeaf, 92 "isInput": isInput, 93 "isStmt": isStmt, 94 "isMarked": isMarked, 95 "hasShape": hasShape, 96 "hasGrad": hasGrad, 97 "getShape": getShape, 98 "getValPtr": getValPtr, 99 "getGrad": getGrad, 100 "getGradPtr": getGradPtr, 101 "overwritesInput": overwritesInput, 102 "opStr": opStr, 103 "opType": opType, 104 "nodeType": nodeType, 105 } 106 107 var ( 108 exprNodeTempl *template.Template 109 exprNodeJSONTempl *template.Template 110 ) 111 112 func init() { 113 exprNodeTempl = template.Must(template.New("node").Funcs(funcMap).Parse(exprNodeTemplText)) 114 }