github.com/wzzhu/tensor@v0.9.24/genlib2/body.go (about)

     1  package main
     2  
     3  import "text/template"
     4  
     5  // generic loop templates
     6  
     7  type LoopBody struct {
     8  	TypedOp
     9  	Range string
    10  	Left  string
    11  	Right string
    12  
    13  	Index0, Index1, Index2 string
    14  
    15  	IterName0, IterName1, IterName2 string
    16  }
    17  
    18  const (
    19  	genericLoopRaw = `for i := range {{.Range}} {
    20  		{{template "check" . -}}
    21  		{{template "loopbody" . -}}
    22  	}`
    23  
    24  	genericUnaryIterLoopRaw = `var {{.Index0}} int
    25  	var valid{{.Index0}} bool
    26  	for {
    27  		if {{.Index0}}, valid{{.Index0}}, err = {{.IterName0}}.NextValidity(); err != nil {
    28  			err = handleNoOp(err)
    29  			break
    30  		}
    31  		if valid{{.Index0}} {
    32  			{{template "check" . -}}
    33  			{{template "loopbody" . -}}
    34  		}
    35  	}`
    36  
    37  	genericBinaryIterLoopRaw = `var {{.Index0}}, {{.Index1}} int
    38  	var valid{{.Index0}}, valid{{.Index1}} bool
    39  	for {
    40  		if {{.Index0}}, valid{{.Index0}}, err = {{.IterName0}}.NextValidity(); err != nil {
    41  			err = handleNoOp(err)
    42  			break
    43  		}
    44  		if {{.Index1}}, valid{{.Index1}}, err = {{.IterName1}}.NextValidity(); err != nil {
    45  			err = handleNoOp(err)
    46  			break
    47  		}
    48  		if valid{{.Index0}} && valid{{.Index1}} {
    49  			{{template "check" . -}}
    50  			{{template "loopbody" . -}}
    51  		}
    52  	}`
    53  
    54  	genericTernaryIterLoopRaw = `var {{.Index0}}, {{.Index1}}, {{.Index2}} int
    55  	var valid{{.Index0}}, valid{{.Index1}}, valid{{.Index2}} bool
    56  	for {
    57  		if {{.Index0}}, valid{{.Index0}}, err = {{.IterName0}}.NextValidity(); err != nil {
    58  			err = handleNoOp(err)
    59  			break
    60  		}
    61  		if {{.Index1}}, valid{{.Index1}}, err = {{.IterName1}}.NextValidity(); err != nil {
    62  			err = handleNoOp(err)
    63  			break
    64  		}
    65  		if {{.Index2}}, valid{{.Index2}}, err = {{.IterName2}}.NextValidity(); err != nil {
    66  			err = handleNoOp(err)
    67  			break
    68  		}
    69  		if valid{{.Index0}} && valid{{.Index1}} && valid{{.Index2}} {
    70  			{{template "check" . -}}
    71  			{{template "loopbody" . -}}
    72  		}
    73  	}`
    74  
    75  	// ALL THE SYNTACTIC ABSTRACTIONS!
    76  	// did I mention how much I hate C-style macros? Now I'm doing them instead
    77  
    78  	basicSet = `{{if .IsFunc -}}
    79  			{{.Range}}[i] = {{ template "callFunc" . -}}
    80  		{{else -}}
    81  			{{.Range}}[i] = {{template "opDo" . -}}
    82  		{{end -}}`
    83  
    84  	basicIncr = `{{if .IsFunc -}}
    85  			{{.Range}}[i] += {{template "callFunc" . -}}
    86  		{{else -}}
    87  			{{.Range}}[i] += {{template "opDo" . -}}
    88  		{{end -}}`
    89  
    90  	iterIncrLoopBody = `{{if .IsFunc -}}
    91  			{{.Range}}[k] += {{template "callFunc" . -}}
    92  		{{else -}}
    93  			{{.Range}}[k] += {{template "opDo" . -}}
    94  		{{end -}}`
    95  
    96  	sameSet = `if {{template "opDo" . }} {
    97  		{{.Range}}[i] = {{trueValue .Kind}}
    98  	}else{
    99  		{{.Range}}[i] = {{falseValue .Kind}}
   100  	}`
   101  
   102  	clampBody = `if {{.Range}}[i] < min {{if eq .Kind.String "float64"}}|| math.IsInf({{.Range}}[i], -1){{else if eq .Kind.String "float32"}}|| math32.IsInf({{.Range}}[i], -1){{end}}  {
   103  		{{.Range}}[i] = min
   104  		continue
   105  	}
   106  	if {{.Range}}[i] > max {{if eq .Kind.String "float64"}}|| math.IsInf({{.Range}}[i], 1){{else if eq .Kind.String "float32"}}|| math32.IsInf({{.Range}}[i], 1){{end}} {
   107  		{{.Range}}[i] = max
   108  	}
   109  	`
   110  
   111  	ternaryIterSet = `{{.Range}}[k] = {{template "opDo" . -}}`
   112  
   113  	binOpCallFunc = `{{if eq "complex64" .Kind.String -}}
   114  		complex64({{template "symbol" .Kind}}(complex128({{.Left}}), complex128({{.Right}}))){{else -}}
   115  		{{template "symbol" .Kind}}({{.Left}}, {{.Right}}){{end -}}`
   116  
   117  	binOpDo = `{{.Left}} {{template "symbol" .Kind}} {{.Right}}`
   118  
   119  	unaryOpDo = `{{template "symbol" .}}{{.Left}}[{{.Index0}}]`
   120  
   121  	unaryOpCallFunc = `{{if eq "complex64" .Kind.String -}}
   122  		complex64({{template "symbol" .}}(complex128({{.Left}}[{{.Index0}}]))){{else -}}
   123  		{{template "symbol" .}}({{.Left}}[{{.Index0}}]){{end -}}
   124  		`
   125  
   126  	check0 = `if {{.Right}} == 0 {
   127  		errs = append(errs, i)
   128  		{{.Range}}[i] = 0
   129  		continue
   130  	}
   131  	`
   132  
   133  	maskCheck = `if mask[i] {
   134  		continue
   135  	}
   136  	`
   137  
   138  	genericArgmaxVarDeclRaw = `var set bool
   139  	var f {{asType .Kind}}
   140  	var {{.ArgX | lower}} int
   141  	`
   142  )
   143  
   144  // renamed
   145  const (
   146  	vvLoopRaw         = genericLoopRaw
   147  	vvIncrLoopRaw     = genericLoopRaw
   148  	vvIterLoopRaw     = genericBinaryIterLoopRaw
   149  	vvIterIncrLoopRaw = genericTernaryIterLoopRaw
   150  
   151  	mixedLoopRaw         = genericLoopRaw
   152  	mixedIncrLoopRaw     = genericLoopRaw
   153  	mixedIterLoopRaw     = genericUnaryIterLoopRaw
   154  	mixedIterIncrLoopRaw = genericBinaryIterLoopRaw
   155  )
   156  
   157  var genericArgmaxVarDecl *template.Template
   158  
   159  func init() {
   160  	genericArgmaxVarDecl = template.Must(template.New("genericArgmaxVarDecl").Funcs(funcs).Parse(genericArgmaxVarDeclRaw))
   161  }