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  }