gorgonia.org/gorgonia@v0.9.17/debug.go (about) 1 // +build debug 2 3 package gorgonia 4 5 import ( 6 "bytes" 7 "fmt" 8 "log" 9 "os" 10 "strings" 11 "sync/atomic" 12 ) 13 14 // DEBUG is a global flag that activates various debugging functions 15 const DEBUG = true 16 17 func init() { 18 log.Printf("DEBUG") 19 } 20 21 // these constants are used during development time - mainly on tracing statements to see the values of certain things. 22 // I use these instead of say, Delve because most of the time, the larger picture has to be known. Delve tends to give small picture views 23 var ( 24 compileDev = false 25 shapeInferenceDev = false 26 typeSystemDev = false 27 symdiffDev = false 28 autodiffDev = false 29 machineDev = false 30 stabilizationDev = false 31 solverDev = false 32 cudaDev = false 33 allocatorDev = false 34 ) 35 36 // TABCOUNT is a global flag used when debugging 37 var TABCOUNT uint32 38 39 var logger = log.New(os.Stderr, "", 0) 40 var replacement = "\n" 41 42 func tabcount() int { 43 return int(atomic.LoadUint32(&TABCOUNT)) 44 } 45 46 func enterLogScope() { 47 atomic.AddUint32(&TABCOUNT, 1) 48 tabcount := tabcount() 49 logger.SetPrefix(strings.Repeat("\t", tabcount)) 50 replacement = "\n" + strings.Repeat("\t", tabcount) 51 } 52 53 func leaveLogScope() { 54 tabcount := tabcount() 55 tabcount-- 56 57 if tabcount < 0 { 58 atomic.StoreUint32(&TABCOUNT, 0) 59 tabcount = 0 60 } else { 61 atomic.StoreUint32(&TABCOUNT, uint32(tabcount)) 62 } 63 logger.SetPrefix(strings.Repeat("\t", tabcount)) 64 replacement = "\n" + strings.Repeat("\t", tabcount) 65 } 66 67 func logf(format string, others ...interface{}) { 68 if DEBUG { 69 // format = strings.Replace(format, "\n", replacement, -1) 70 s := fmt.Sprintf(format, others...) 71 s = strings.Replace(s, "\n", replacement, -1) 72 logger.Println(s) 73 // logger.Printf(format, others...) 74 } 75 } 76 77 func compileLogf(format string, attrs ...interface{}) { 78 if compileDev { 79 logf(format, attrs...) 80 } 81 } 82 83 func shapeLogf(format string, attrs ...interface{}) { 84 if shapeInferenceDev { 85 logf(format, attrs...) 86 } 87 } 88 89 func typeSysLogf(format string, attrs ...interface{}) { 90 if typeSystemDev { 91 logf(format, attrs...) 92 } 93 } 94 95 func symdiffLogf(format string, attrs ...interface{}) { 96 if symdiffDev { 97 logf(format, attrs...) 98 } 99 } 100 101 func autodiffLogf(format string, attrs ...interface{}) { 102 if autodiffDev { 103 logf(format, attrs...) 104 } 105 } 106 107 func machineLogf(format string, attrs ...interface{}) { 108 if machineDev { 109 logf(format, attrs...) 110 } 111 } 112 113 func stabLogf(format string, attrs ...interface{}) { 114 if stabilizationDev { 115 logf(format, attrs...) 116 } 117 } 118 119 func solverLogf(format string, attrs ...interface{}) { 120 if solverDev { 121 logf(format, attrs...) 122 } 123 } 124 125 func cudaLogf(format string, attrs ...interface{}) { 126 if cudaDev { 127 logf(format, attrs...) 128 } 129 } 130 131 func allocatorLogf(format string, attrs ...interface{}) { 132 if allocatorDev { 133 logf(format, attrs...) 134 } 135 } 136 137 func recoverFrom(format string, attrs ...interface{}) { 138 if r := recover(); r != nil { 139 logger.Printf(format, attrs...) 140 panic(r) 141 } 142 } 143 144 /* Graph Collision related debugging code */ 145 var nnc, cc, ec int64 146 147 func incrNN() { 148 atomic.AddInt64(&nnc, 1) 149 } 150 151 func incrCC() { 152 atomic.AddInt64(&cc, 1) 153 } 154 155 func incrEC() { 156 atomic.AddInt64(&ec, 1) 157 } 158 159 // GraphCollisionStats ... 160 func GraphCollisionStats() (int, int, int) { 161 return int(atomic.LoadInt64(&nnc)), int(atomic.LoadInt64(&cc)), int(atomic.LoadInt64(&ec)) 162 } 163 164 /* Compilation related debug utility functions/methods*/ 165 func logCompileState(name string, g *ExprGraph, df *dataflow) { 166 var fname string 167 if name == "" { 168 fname = "TotallyRandomName.csv" 169 } else { 170 fname = name + ".csv" 171 } 172 f, err := os.OpenFile(fname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 173 if err != nil { 174 panic(err) 175 } 176 defer f.Close() 177 178 compileState(f, g, df) 179 compileLogf("Written Compile State to %v", fname) 180 } 181 182 /* Analysis Debug Utility Functions/Methods */ 183 func (df *dataflow) debugIntervals(sorted Nodes) { 184 var buf bytes.Buffer 185 buf.Write([]byte("Intervals:\n")) 186 for _, n := range sorted { 187 fmt.Fprintf(&buf, "\t%v:\t%v\n", n, df.intervals[n]) 188 } 189 compileLogf(buf.String()) 190 }