github.com/wzzhu/tensor@v0.9.24/defaultengine_arith.go (about) 1 // Code generated by genlib2. DO NOT EDIT. 2 3 package tensor 4 5 import ( 6 "github.com/pkg/errors" 7 "github.com/wzzhu/tensor/internal/storage" 8 ) 9 10 // Add performs a + b elementwise. Both a and b must have the same shape. 11 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 12 func (e StdEng) Add(a Tensor, b Tensor, opts ...FuncOpt) (retVal Tensor, err error) { 13 if err = binaryCheck(a, b, numberTypes); err != nil { 14 return nil, errors.Wrapf(err, "Add failed") 15 } 16 17 var reuse DenseTensor 18 var safe, toReuse, incr bool 19 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(a.Shape(), a.Dtype(), a.DataOrder(), true, opts...); err != nil { 20 return nil, errors.Wrap(err, "Unable to handle funcOpts") 21 } 22 typ := a.Dtype().Type 23 var dataA, dataB, dataReuse *storage.Header 24 var ait, bit, iit Iterator 25 var useIter, swap bool 26 if dataA, dataB, dataReuse, ait, bit, iit, useIter, swap, err = prepDataVV(a, b, reuse); err != nil { 27 return nil, errors.Wrapf(err, "StdEng.Add") 28 } 29 if useIter { 30 switch { 31 case incr: 32 err = e.E.AddIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 33 retVal = reuse 34 case toReuse: 35 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 36 ait.Reset() 37 iit.Reset() 38 err = e.E.AddIter(typ, dataReuse, dataB, iit, bit) 39 retVal = reuse 40 case !safe: 41 err = e.E.AddIter(typ, dataA, dataB, ait, bit) 42 retVal = a 43 default: 44 if swap { 45 retVal = b.Clone().(Tensor) 46 } else { 47 retVal = a.Clone().(Tensor) 48 } 49 err = e.E.AddIter(typ, retVal.hdr(), dataB, ait, bit) 50 } 51 return 52 } 53 switch { 54 case incr: 55 err = e.E.AddIncr(typ, dataA, dataB, dataReuse) 56 retVal = reuse 57 case toReuse: 58 err = e.E.AddRecv(typ, dataA, dataB, dataReuse) 59 retVal = reuse 60 case !safe: 61 err = e.E.Add(typ, dataA, dataB) 62 retVal = a 63 default: 64 if swap { 65 retVal = b.Clone().(Tensor) 66 } else { 67 retVal = a.Clone().(Tensor) 68 } 69 err = e.E.Add(typ, retVal.hdr(), dataB) 70 } 71 return 72 } 73 74 // Sub performs a - b elementwise. Both a and b must have the same shape. 75 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 76 func (e StdEng) Sub(a Tensor, b Tensor, opts ...FuncOpt) (retVal Tensor, err error) { 77 if err = binaryCheck(a, b, numberTypes); err != nil { 78 return nil, errors.Wrapf(err, "Sub failed") 79 } 80 81 var reuse DenseTensor 82 var safe, toReuse, incr bool 83 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(a.Shape(), a.Dtype(), a.DataOrder(), true, opts...); err != nil { 84 return nil, errors.Wrap(err, "Unable to handle funcOpts") 85 } 86 typ := a.Dtype().Type 87 var dataA, dataB, dataReuse *storage.Header 88 var ait, bit, iit Iterator 89 var useIter, swap bool 90 if dataA, dataB, dataReuse, ait, bit, iit, useIter, swap, err = prepDataVV(a, b, reuse); err != nil { 91 return nil, errors.Wrapf(err, "StdEng.Sub") 92 } 93 if useIter { 94 switch { 95 case incr: 96 err = e.E.SubIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 97 retVal = reuse 98 case toReuse: 99 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 100 ait.Reset() 101 iit.Reset() 102 err = e.E.SubIter(typ, dataReuse, dataB, iit, bit) 103 retVal = reuse 104 case !safe: 105 err = e.E.SubIter(typ, dataA, dataB, ait, bit) 106 retVal = a 107 default: 108 if swap { 109 retVal = b.Clone().(Tensor) 110 } else { 111 retVal = a.Clone().(Tensor) 112 } 113 err = e.E.SubIter(typ, retVal.hdr(), dataB, ait, bit) 114 } 115 return 116 } 117 switch { 118 case incr: 119 err = e.E.SubIncr(typ, dataA, dataB, dataReuse) 120 retVal = reuse 121 case toReuse: 122 err = e.E.SubRecv(typ, dataA, dataB, dataReuse) 123 retVal = reuse 124 case !safe: 125 err = e.E.Sub(typ, dataA, dataB) 126 retVal = a 127 default: 128 if swap { 129 retVal = b.Clone().(Tensor) 130 } else { 131 retVal = a.Clone().(Tensor) 132 } 133 err = e.E.Sub(typ, retVal.hdr(), dataB) 134 } 135 return 136 } 137 138 // Mul performs a × b elementwise. Both a and b must have the same shape. 139 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 140 func (e StdEng) Mul(a Tensor, b Tensor, opts ...FuncOpt) (retVal Tensor, err error) { 141 if err = binaryCheck(a, b, numberTypes); err != nil { 142 return nil, errors.Wrapf(err, "Mul failed") 143 } 144 145 var reuse DenseTensor 146 var safe, toReuse, incr bool 147 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(a.Shape(), a.Dtype(), a.DataOrder(), true, opts...); err != nil { 148 return nil, errors.Wrap(err, "Unable to handle funcOpts") 149 } 150 typ := a.Dtype().Type 151 var dataA, dataB, dataReuse *storage.Header 152 var ait, bit, iit Iterator 153 var useIter, swap bool 154 if dataA, dataB, dataReuse, ait, bit, iit, useIter, swap, err = prepDataVV(a, b, reuse); err != nil { 155 return nil, errors.Wrapf(err, "StdEng.Mul") 156 } 157 if useIter { 158 switch { 159 case incr: 160 err = e.E.MulIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 161 retVal = reuse 162 case toReuse: 163 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 164 ait.Reset() 165 iit.Reset() 166 err = e.E.MulIter(typ, dataReuse, dataB, iit, bit) 167 retVal = reuse 168 case !safe: 169 err = e.E.MulIter(typ, dataA, dataB, ait, bit) 170 retVal = a 171 default: 172 if swap { 173 retVal = b.Clone().(Tensor) 174 } else { 175 retVal = a.Clone().(Tensor) 176 } 177 err = e.E.MulIter(typ, retVal.hdr(), dataB, ait, bit) 178 } 179 return 180 } 181 switch { 182 case incr: 183 err = e.E.MulIncr(typ, dataA, dataB, dataReuse) 184 retVal = reuse 185 case toReuse: 186 err = e.E.MulRecv(typ, dataA, dataB, dataReuse) 187 retVal = reuse 188 case !safe: 189 err = e.E.Mul(typ, dataA, dataB) 190 retVal = a 191 default: 192 if swap { 193 retVal = b.Clone().(Tensor) 194 } else { 195 retVal = a.Clone().(Tensor) 196 } 197 err = e.E.Mul(typ, retVal.hdr(), dataB) 198 } 199 return 200 } 201 202 // Div performs a ÷ b elementwise. Both a and b must have the same shape. 203 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 204 func (e StdEng) Div(a Tensor, b Tensor, opts ...FuncOpt) (retVal Tensor, err error) { 205 if err = binaryCheck(a, b, numberTypes); err != nil { 206 return nil, errors.Wrapf(err, "Div failed") 207 } 208 209 var reuse DenseTensor 210 var safe, toReuse, incr bool 211 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(a.Shape(), a.Dtype(), a.DataOrder(), true, opts...); err != nil { 212 return nil, errors.Wrap(err, "Unable to handle funcOpts") 213 } 214 typ := a.Dtype().Type 215 var dataA, dataB, dataReuse *storage.Header 216 var ait, bit, iit Iterator 217 var useIter, swap bool 218 if dataA, dataB, dataReuse, ait, bit, iit, useIter, swap, err = prepDataVV(a, b, reuse); err != nil { 219 return nil, errors.Wrapf(err, "StdEng.Div") 220 } 221 if useIter { 222 switch { 223 case incr: 224 err = e.E.DivIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 225 retVal = reuse 226 case toReuse: 227 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 228 ait.Reset() 229 iit.Reset() 230 err = e.E.DivIter(typ, dataReuse, dataB, iit, bit) 231 retVal = reuse 232 case !safe: 233 err = e.E.DivIter(typ, dataA, dataB, ait, bit) 234 retVal = a 235 default: 236 if swap { 237 retVal = b.Clone().(Tensor) 238 } else { 239 retVal = a.Clone().(Tensor) 240 } 241 err = e.E.DivIter(typ, retVal.hdr(), dataB, ait, bit) 242 } 243 return 244 } 245 switch { 246 case incr: 247 err = e.E.DivIncr(typ, dataA, dataB, dataReuse) 248 retVal = reuse 249 case toReuse: 250 err = e.E.DivRecv(typ, dataA, dataB, dataReuse) 251 retVal = reuse 252 case !safe: 253 err = e.E.Div(typ, dataA, dataB) 254 retVal = a 255 default: 256 if swap { 257 retVal = b.Clone().(Tensor) 258 } else { 259 retVal = a.Clone().(Tensor) 260 } 261 err = e.E.Div(typ, retVal.hdr(), dataB) 262 } 263 return 264 } 265 266 // Pow performs a ^ b elementwise. Both a and b must have the same shape. 267 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 268 func (e StdEng) Pow(a Tensor, b Tensor, opts ...FuncOpt) (retVal Tensor, err error) { 269 if err = binaryCheck(a, b, numberTypes); err != nil { 270 return nil, errors.Wrapf(err, "Pow failed") 271 } 272 273 var reuse DenseTensor 274 var safe, toReuse, incr bool 275 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(a.Shape(), a.Dtype(), a.DataOrder(), true, opts...); err != nil { 276 return nil, errors.Wrap(err, "Unable to handle funcOpts") 277 } 278 typ := a.Dtype().Type 279 var dataA, dataB, dataReuse *storage.Header 280 var ait, bit, iit Iterator 281 var useIter, swap bool 282 if dataA, dataB, dataReuse, ait, bit, iit, useIter, swap, err = prepDataVV(a, b, reuse); err != nil { 283 return nil, errors.Wrapf(err, "StdEng.Pow") 284 } 285 if useIter { 286 switch { 287 case incr: 288 err = e.E.PowIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 289 retVal = reuse 290 case toReuse: 291 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 292 ait.Reset() 293 iit.Reset() 294 err = e.E.PowIter(typ, dataReuse, dataB, iit, bit) 295 retVal = reuse 296 case !safe: 297 err = e.E.PowIter(typ, dataA, dataB, ait, bit) 298 retVal = a 299 default: 300 if swap { 301 retVal = b.Clone().(Tensor) 302 } else { 303 retVal = a.Clone().(Tensor) 304 } 305 err = e.E.PowIter(typ, retVal.hdr(), dataB, ait, bit) 306 } 307 return 308 } 309 switch { 310 case incr: 311 err = e.E.PowIncr(typ, dataA, dataB, dataReuse) 312 retVal = reuse 313 case toReuse: 314 err = e.E.PowRecv(typ, dataA, dataB, dataReuse) 315 retVal = reuse 316 case !safe: 317 err = e.E.Pow(typ, dataA, dataB) 318 retVal = a 319 default: 320 if swap { 321 retVal = b.Clone().(Tensor) 322 } else { 323 retVal = a.Clone().(Tensor) 324 } 325 err = e.E.Pow(typ, retVal.hdr(), dataB) 326 } 327 return 328 } 329 330 // Mod performs a % b elementwise. Both a and b must have the same shape. 331 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 332 func (e StdEng) Mod(a Tensor, b Tensor, opts ...FuncOpt) (retVal Tensor, err error) { 333 if err = binaryCheck(a, b, numberTypes); err != nil { 334 return nil, errors.Wrapf(err, "Mod failed") 335 } 336 337 var reuse DenseTensor 338 var safe, toReuse, incr bool 339 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(a.Shape(), a.Dtype(), a.DataOrder(), true, opts...); err != nil { 340 return nil, errors.Wrap(err, "Unable to handle funcOpts") 341 } 342 typ := a.Dtype().Type 343 var dataA, dataB, dataReuse *storage.Header 344 var ait, bit, iit Iterator 345 var useIter, swap bool 346 if dataA, dataB, dataReuse, ait, bit, iit, useIter, swap, err = prepDataVV(a, b, reuse); err != nil { 347 return nil, errors.Wrapf(err, "StdEng.Mod") 348 } 349 if useIter { 350 switch { 351 case incr: 352 err = e.E.ModIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 353 retVal = reuse 354 case toReuse: 355 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 356 ait.Reset() 357 iit.Reset() 358 err = e.E.ModIter(typ, dataReuse, dataB, iit, bit) 359 retVal = reuse 360 case !safe: 361 err = e.E.ModIter(typ, dataA, dataB, ait, bit) 362 retVal = a 363 default: 364 if swap { 365 retVal = b.Clone().(Tensor) 366 } else { 367 retVal = a.Clone().(Tensor) 368 } 369 err = e.E.ModIter(typ, retVal.hdr(), dataB, ait, bit) 370 } 371 return 372 } 373 switch { 374 case incr: 375 err = e.E.ModIncr(typ, dataA, dataB, dataReuse) 376 retVal = reuse 377 case toReuse: 378 err = e.E.ModRecv(typ, dataA, dataB, dataReuse) 379 retVal = reuse 380 case !safe: 381 err = e.E.Mod(typ, dataA, dataB) 382 retVal = a 383 default: 384 if swap { 385 retVal = b.Clone().(Tensor) 386 } else { 387 retVal = a.Clone().(Tensor) 388 } 389 err = e.E.Mod(typ, retVal.hdr(), dataB) 390 } 391 return 392 } 393 394 // AddScalar performs t + s elementwise. The leftTensor parameter indicates if the tensor is the left operand. Only scalar types are accepted in s. 395 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 396 func (e StdEng) AddScalar(t Tensor, s interface{}, leftTensor bool, opts ...FuncOpt) (retVal Tensor, err error) { 397 if err = unaryCheck(t, numberTypes); err != nil { 398 return nil, errors.Wrapf(err, "Add failed") 399 } 400 401 if err = scalarDtypeCheck(t, s); err != nil { 402 return nil, errors.Wrap(err, "Add failed") 403 } 404 405 var reuse DenseTensor 406 var safe, toReuse, incr bool 407 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(t.Shape(), t.Dtype(), t.DataOrder(), true, opts...); err != nil { 408 return nil, errors.Wrap(err, "Unable to handle funcOpts") 409 } 410 a := t 411 typ := t.Dtype().Type 412 var ait, bit, iit Iterator 413 var dataA, dataB, dataReuse, scalarHeader *storage.Header 414 var useIter, newAlloc bool 415 416 if leftTensor { 417 if dataA, dataB, dataReuse, ait, iit, useIter, newAlloc, err = prepDataVS(t, s, reuse); err != nil { 418 return nil, errors.Wrapf(err, opFail, "StdEng.Add") 419 } 420 scalarHeader = dataB 421 } else { 422 if dataA, dataB, dataReuse, bit, iit, useIter, newAlloc, err = prepDataSV(s, t, reuse); err != nil { 423 return nil, errors.Wrapf(err, opFail, "StdEng.Add") 424 } 425 scalarHeader = dataA 426 } 427 428 if useIter { 429 switch { 430 case incr: 431 err = e.E.AddIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 432 retVal = reuse 433 case toReuse && leftTensor: 434 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 435 ait.Reset() 436 iit.Reset() 437 err = e.E.AddIter(typ, dataReuse, dataB, iit, bit) 438 retVal = reuse 439 case toReuse && !leftTensor: 440 storage.CopyIter(typ, dataReuse, dataB, iit, bit) 441 iit.Reset() 442 bit.Reset() 443 err = e.E.AddIter(typ, dataA, dataReuse, ait, iit) 444 retVal = reuse 445 case !safe: 446 err = e.E.AddIter(typ, dataA, dataB, ait, bit) 447 retVal = a 448 default: 449 retVal = a.Clone().(Tensor) 450 if leftTensor { 451 err = e.E.AddIter(typ, retVal.hdr(), dataB, ait, bit) 452 } else { 453 err = e.E.AddIter(typ, dataA, retVal.hdr(), ait, bit) 454 } 455 } 456 if newAlloc { 457 freeScalar(scalarHeader.Raw) 458 } 459 returnHeader(scalarHeader) 460 return 461 } 462 switch { 463 case incr: 464 err = e.E.AddIncr(typ, dataA, dataB, dataReuse) 465 retVal = reuse 466 case toReuse && leftTensor: 467 storage.Copy(typ, dataReuse, dataA) 468 err = e.E.Add(typ, dataReuse, dataB) 469 retVal = reuse 470 case toReuse && !leftTensor: 471 storage.Copy(typ, dataReuse, dataB) 472 err = e.E.Add(typ, dataA, dataReuse) 473 if t.Shape().IsScalarEquiv() { 474 storage.Copy(typ, dataReuse, dataA) 475 } 476 retVal = reuse 477 case !safe: 478 err = e.E.Add(typ, dataA, dataB) 479 if t.Shape().IsScalarEquiv() && !leftTensor { 480 storage.Copy(typ, dataB, dataA) 481 } 482 retVal = a 483 default: 484 retVal = a.Clone().(Tensor) 485 if !leftTensor { 486 storage.Fill(typ, retVal.hdr(), dataA) 487 } 488 err = e.E.Add(typ, retVal.hdr(), dataB) 489 } 490 if newAlloc { 491 freeScalar(scalarHeader.Raw) 492 } 493 returnHeader(scalarHeader) 494 return 495 } 496 497 // SubScalar performs t - s elementwise. The leftTensor parameter indicates if the tensor is the left operand. Only scalar types are accepted in s. 498 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 499 func (e StdEng) SubScalar(t Tensor, s interface{}, leftTensor bool, opts ...FuncOpt) (retVal Tensor, err error) { 500 if err = unaryCheck(t, numberTypes); err != nil { 501 return nil, errors.Wrapf(err, "Sub failed") 502 } 503 504 if err = scalarDtypeCheck(t, s); err != nil { 505 return nil, errors.Wrap(err, "Sub failed") 506 } 507 508 var reuse DenseTensor 509 var safe, toReuse, incr bool 510 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(t.Shape(), t.Dtype(), t.DataOrder(), true, opts...); err != nil { 511 return nil, errors.Wrap(err, "Unable to handle funcOpts") 512 } 513 a := t 514 typ := t.Dtype().Type 515 var ait, bit, iit Iterator 516 var dataA, dataB, dataReuse, scalarHeader *storage.Header 517 var useIter, newAlloc bool 518 519 if leftTensor { 520 if dataA, dataB, dataReuse, ait, iit, useIter, newAlloc, err = prepDataVS(t, s, reuse); err != nil { 521 return nil, errors.Wrapf(err, opFail, "StdEng.Sub") 522 } 523 scalarHeader = dataB 524 } else { 525 if dataA, dataB, dataReuse, bit, iit, useIter, newAlloc, err = prepDataSV(s, t, reuse); err != nil { 526 return nil, errors.Wrapf(err, opFail, "StdEng.Sub") 527 } 528 scalarHeader = dataA 529 } 530 531 if useIter { 532 switch { 533 case incr: 534 err = e.E.SubIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 535 retVal = reuse 536 case toReuse && leftTensor: 537 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 538 ait.Reset() 539 iit.Reset() 540 err = e.E.SubIter(typ, dataReuse, dataB, iit, bit) 541 retVal = reuse 542 case toReuse && !leftTensor: 543 storage.CopyIter(typ, dataReuse, dataB, iit, bit) 544 iit.Reset() 545 bit.Reset() 546 err = e.E.SubIter(typ, dataA, dataReuse, ait, iit) 547 retVal = reuse 548 case !safe: 549 err = e.E.SubIter(typ, dataA, dataB, ait, bit) 550 retVal = a 551 default: 552 retVal = a.Clone().(Tensor) 553 if leftTensor { 554 err = e.E.SubIter(typ, retVal.hdr(), dataB, ait, bit) 555 } else { 556 err = e.E.SubIter(typ, dataA, retVal.hdr(), ait, bit) 557 } 558 } 559 if newAlloc { 560 freeScalar(scalarHeader.Raw) 561 } 562 returnHeader(scalarHeader) 563 return 564 } 565 switch { 566 case incr: 567 err = e.E.SubIncr(typ, dataA, dataB, dataReuse) 568 retVal = reuse 569 case toReuse && leftTensor: 570 storage.Copy(typ, dataReuse, dataA) 571 err = e.E.Sub(typ, dataReuse, dataB) 572 retVal = reuse 573 case toReuse && !leftTensor: 574 storage.Copy(typ, dataReuse, dataB) 575 err = e.E.Sub(typ, dataA, dataReuse) 576 if t.Shape().IsScalarEquiv() { 577 storage.Copy(typ, dataReuse, dataA) 578 } 579 retVal = reuse 580 case !safe: 581 err = e.E.Sub(typ, dataA, dataB) 582 if t.Shape().IsScalarEquiv() && !leftTensor { 583 storage.Copy(typ, dataB, dataA) 584 } 585 retVal = a 586 default: 587 retVal = a.Clone().(Tensor) 588 if !leftTensor { 589 storage.Fill(typ, retVal.hdr(), dataA) 590 } 591 err = e.E.Sub(typ, retVal.hdr(), dataB) 592 } 593 if newAlloc { 594 freeScalar(scalarHeader.Raw) 595 } 596 returnHeader(scalarHeader) 597 return 598 } 599 600 // MulScalar performs t × s elementwise. The leftTensor parameter indicates if the tensor is the left operand. Only scalar types are accepted in s. 601 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 602 func (e StdEng) MulScalar(t Tensor, s interface{}, leftTensor bool, opts ...FuncOpt) (retVal Tensor, err error) { 603 if err = unaryCheck(t, numberTypes); err != nil { 604 return nil, errors.Wrapf(err, "Mul failed") 605 } 606 607 if err = scalarDtypeCheck(t, s); err != nil { 608 return nil, errors.Wrap(err, "Mul failed") 609 } 610 611 var reuse DenseTensor 612 var safe, toReuse, incr bool 613 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(t.Shape(), t.Dtype(), t.DataOrder(), true, opts...); err != nil { 614 return nil, errors.Wrap(err, "Unable to handle funcOpts") 615 } 616 a := t 617 typ := t.Dtype().Type 618 var ait, bit, iit Iterator 619 var dataA, dataB, dataReuse, scalarHeader *storage.Header 620 var useIter, newAlloc bool 621 622 if leftTensor { 623 if dataA, dataB, dataReuse, ait, iit, useIter, newAlloc, err = prepDataVS(t, s, reuse); err != nil { 624 return nil, errors.Wrapf(err, opFail, "StdEng.Mul") 625 } 626 scalarHeader = dataB 627 } else { 628 if dataA, dataB, dataReuse, bit, iit, useIter, newAlloc, err = prepDataSV(s, t, reuse); err != nil { 629 return nil, errors.Wrapf(err, opFail, "StdEng.Mul") 630 } 631 scalarHeader = dataA 632 } 633 634 if useIter { 635 switch { 636 case incr: 637 err = e.E.MulIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 638 retVal = reuse 639 case toReuse && leftTensor: 640 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 641 ait.Reset() 642 iit.Reset() 643 err = e.E.MulIter(typ, dataReuse, dataB, iit, bit) 644 retVal = reuse 645 case toReuse && !leftTensor: 646 storage.CopyIter(typ, dataReuse, dataB, iit, bit) 647 iit.Reset() 648 bit.Reset() 649 err = e.E.MulIter(typ, dataA, dataReuse, ait, iit) 650 retVal = reuse 651 case !safe: 652 err = e.E.MulIter(typ, dataA, dataB, ait, bit) 653 retVal = a 654 default: 655 retVal = a.Clone().(Tensor) 656 if leftTensor { 657 err = e.E.MulIter(typ, retVal.hdr(), dataB, ait, bit) 658 } else { 659 err = e.E.MulIter(typ, dataA, retVal.hdr(), ait, bit) 660 } 661 } 662 if newAlloc { 663 freeScalar(scalarHeader.Raw) 664 } 665 returnHeader(scalarHeader) 666 return 667 } 668 switch { 669 case incr: 670 err = e.E.MulIncr(typ, dataA, dataB, dataReuse) 671 retVal = reuse 672 case toReuse && leftTensor: 673 storage.Copy(typ, dataReuse, dataA) 674 err = e.E.Mul(typ, dataReuse, dataB) 675 retVal = reuse 676 case toReuse && !leftTensor: 677 storage.Copy(typ, dataReuse, dataB) 678 err = e.E.Mul(typ, dataA, dataReuse) 679 if t.Shape().IsScalarEquiv() { 680 storage.Copy(typ, dataReuse, dataA) 681 } 682 retVal = reuse 683 case !safe: 684 err = e.E.Mul(typ, dataA, dataB) 685 if t.Shape().IsScalarEquiv() && !leftTensor { 686 storage.Copy(typ, dataB, dataA) 687 } 688 retVal = a 689 default: 690 retVal = a.Clone().(Tensor) 691 if !leftTensor { 692 storage.Fill(typ, retVal.hdr(), dataA) 693 } 694 err = e.E.Mul(typ, retVal.hdr(), dataB) 695 } 696 if newAlloc { 697 freeScalar(scalarHeader.Raw) 698 } 699 returnHeader(scalarHeader) 700 return 701 } 702 703 // DivScalar performs t ÷ s elementwise. The leftTensor parameter indicates if the tensor is the left operand. Only scalar types are accepted in s. 704 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 705 func (e StdEng) DivScalar(t Tensor, s interface{}, leftTensor bool, opts ...FuncOpt) (retVal Tensor, err error) { 706 if err = unaryCheck(t, numberTypes); err != nil { 707 return nil, errors.Wrapf(err, "Div failed") 708 } 709 710 if err = scalarDtypeCheck(t, s); err != nil { 711 return nil, errors.Wrap(err, "Div failed") 712 } 713 714 var reuse DenseTensor 715 var safe, toReuse, incr bool 716 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(t.Shape(), t.Dtype(), t.DataOrder(), true, opts...); err != nil { 717 return nil, errors.Wrap(err, "Unable to handle funcOpts") 718 } 719 a := t 720 typ := t.Dtype().Type 721 var ait, bit, iit Iterator 722 var dataA, dataB, dataReuse, scalarHeader *storage.Header 723 var useIter, newAlloc bool 724 725 if leftTensor { 726 if dataA, dataB, dataReuse, ait, iit, useIter, newAlloc, err = prepDataVS(t, s, reuse); err != nil { 727 return nil, errors.Wrapf(err, opFail, "StdEng.Div") 728 } 729 scalarHeader = dataB 730 } else { 731 if dataA, dataB, dataReuse, bit, iit, useIter, newAlloc, err = prepDataSV(s, t, reuse); err != nil { 732 return nil, errors.Wrapf(err, opFail, "StdEng.Div") 733 } 734 scalarHeader = dataA 735 } 736 737 if useIter { 738 switch { 739 case incr: 740 err = e.E.DivIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 741 retVal = reuse 742 case toReuse && leftTensor: 743 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 744 ait.Reset() 745 iit.Reset() 746 err = e.E.DivIter(typ, dataReuse, dataB, iit, bit) 747 retVal = reuse 748 case toReuse && !leftTensor: 749 storage.CopyIter(typ, dataReuse, dataB, iit, bit) 750 iit.Reset() 751 bit.Reset() 752 err = e.E.DivIter(typ, dataA, dataReuse, ait, iit) 753 retVal = reuse 754 case !safe: 755 err = e.E.DivIter(typ, dataA, dataB, ait, bit) 756 retVal = a 757 default: 758 retVal = a.Clone().(Tensor) 759 if leftTensor { 760 err = e.E.DivIter(typ, retVal.hdr(), dataB, ait, bit) 761 } else { 762 err = e.E.DivIter(typ, dataA, retVal.hdr(), ait, bit) 763 } 764 } 765 if newAlloc { 766 freeScalar(scalarHeader.Raw) 767 } 768 returnHeader(scalarHeader) 769 return 770 } 771 switch { 772 case incr: 773 err = e.E.DivIncr(typ, dataA, dataB, dataReuse) 774 retVal = reuse 775 case toReuse && leftTensor: 776 storage.Copy(typ, dataReuse, dataA) 777 err = e.E.Div(typ, dataReuse, dataB) 778 retVal = reuse 779 case toReuse && !leftTensor: 780 storage.Copy(typ, dataReuse, dataB) 781 err = e.E.Div(typ, dataA, dataReuse) 782 if t.Shape().IsScalarEquiv() { 783 storage.Copy(typ, dataReuse, dataA) 784 } 785 retVal = reuse 786 case !safe: 787 err = e.E.Div(typ, dataA, dataB) 788 if t.Shape().IsScalarEquiv() && !leftTensor { 789 storage.Copy(typ, dataB, dataA) 790 } 791 retVal = a 792 default: 793 retVal = a.Clone().(Tensor) 794 if !leftTensor { 795 storage.Fill(typ, retVal.hdr(), dataA) 796 } 797 err = e.E.Div(typ, retVal.hdr(), dataB) 798 } 799 if newAlloc { 800 freeScalar(scalarHeader.Raw) 801 } 802 returnHeader(scalarHeader) 803 return 804 } 805 806 // PowScalar performs t ^ s elementwise. The leftTensor parameter indicates if the tensor is the left operand. Only scalar types are accepted in s. 807 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 808 func (e StdEng) PowScalar(t Tensor, s interface{}, leftTensor bool, opts ...FuncOpt) (retVal Tensor, err error) { 809 if err = unaryCheck(t, numberTypes); err != nil { 810 return nil, errors.Wrapf(err, "Pow failed") 811 } 812 813 if err = scalarDtypeCheck(t, s); err != nil { 814 return nil, errors.Wrap(err, "Pow failed") 815 } 816 817 var reuse DenseTensor 818 var safe, toReuse, incr bool 819 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(t.Shape(), t.Dtype(), t.DataOrder(), true, opts...); err != nil { 820 return nil, errors.Wrap(err, "Unable to handle funcOpts") 821 } 822 a := t 823 typ := t.Dtype().Type 824 var ait, bit, iit Iterator 825 var dataA, dataB, dataReuse, scalarHeader *storage.Header 826 var useIter, newAlloc bool 827 828 if leftTensor { 829 if dataA, dataB, dataReuse, ait, iit, useIter, newAlloc, err = prepDataVS(t, s, reuse); err != nil { 830 return nil, errors.Wrapf(err, opFail, "StdEng.Pow") 831 } 832 scalarHeader = dataB 833 } else { 834 if dataA, dataB, dataReuse, bit, iit, useIter, newAlloc, err = prepDataSV(s, t, reuse); err != nil { 835 return nil, errors.Wrapf(err, opFail, "StdEng.Pow") 836 } 837 scalarHeader = dataA 838 } 839 840 if useIter { 841 switch { 842 case incr: 843 err = e.E.PowIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 844 retVal = reuse 845 case toReuse && leftTensor: 846 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 847 ait.Reset() 848 iit.Reset() 849 err = e.E.PowIter(typ, dataReuse, dataB, iit, bit) 850 retVal = reuse 851 case toReuse && !leftTensor: 852 storage.CopyIter(typ, dataReuse, dataB, iit, bit) 853 iit.Reset() 854 bit.Reset() 855 err = e.E.PowIter(typ, dataA, dataReuse, ait, iit) 856 retVal = reuse 857 case !safe: 858 err = e.E.PowIter(typ, dataA, dataB, ait, bit) 859 retVal = a 860 default: 861 retVal = a.Clone().(Tensor) 862 if leftTensor { 863 err = e.E.PowIter(typ, retVal.hdr(), dataB, ait, bit) 864 } else { 865 err = e.E.PowIter(typ, dataA, retVal.hdr(), ait, bit) 866 } 867 } 868 if newAlloc { 869 freeScalar(scalarHeader.Raw) 870 } 871 returnHeader(scalarHeader) 872 return 873 } 874 switch { 875 case incr: 876 err = e.E.PowIncr(typ, dataA, dataB, dataReuse) 877 retVal = reuse 878 case toReuse && leftTensor: 879 storage.Copy(typ, dataReuse, dataA) 880 err = e.E.Pow(typ, dataReuse, dataB) 881 retVal = reuse 882 case toReuse && !leftTensor: 883 storage.Copy(typ, dataReuse, dataB) 884 err = e.E.Pow(typ, dataA, dataReuse) 885 if t.Shape().IsScalarEquiv() { 886 storage.Copy(typ, dataReuse, dataA) 887 } 888 retVal = reuse 889 case !safe: 890 err = e.E.Pow(typ, dataA, dataB) 891 if t.Shape().IsScalarEquiv() && !leftTensor { 892 storage.Copy(typ, dataB, dataA) 893 } 894 retVal = a 895 default: 896 retVal = a.Clone().(Tensor) 897 if !leftTensor { 898 storage.Fill(typ, retVal.hdr(), dataA) 899 } 900 err = e.E.Pow(typ, retVal.hdr(), dataB) 901 } 902 if newAlloc { 903 freeScalar(scalarHeader.Raw) 904 } 905 returnHeader(scalarHeader) 906 return 907 } 908 909 // ModScalar performs t % s elementwise. The leftTensor parameter indicates if the tensor is the left operand. Only scalar types are accepted in s. 910 // Acceptable FuncOpts are: UseUnsafe(), WithReuse(T), WithIncr(T) 911 func (e StdEng) ModScalar(t Tensor, s interface{}, leftTensor bool, opts ...FuncOpt) (retVal Tensor, err error) { 912 if err = unaryCheck(t, numberTypes); err != nil { 913 return nil, errors.Wrapf(err, "Mod failed") 914 } 915 916 if err = scalarDtypeCheck(t, s); err != nil { 917 return nil, errors.Wrap(err, "Mod failed") 918 } 919 920 var reuse DenseTensor 921 var safe, toReuse, incr bool 922 if reuse, safe, toReuse, incr, _, err = handleFuncOpts(t.Shape(), t.Dtype(), t.DataOrder(), true, opts...); err != nil { 923 return nil, errors.Wrap(err, "Unable to handle funcOpts") 924 } 925 a := t 926 typ := t.Dtype().Type 927 var ait, bit, iit Iterator 928 var dataA, dataB, dataReuse, scalarHeader *storage.Header 929 var useIter, newAlloc bool 930 931 if leftTensor { 932 if dataA, dataB, dataReuse, ait, iit, useIter, newAlloc, err = prepDataVS(t, s, reuse); err != nil { 933 return nil, errors.Wrapf(err, opFail, "StdEng.Mod") 934 } 935 scalarHeader = dataB 936 } else { 937 if dataA, dataB, dataReuse, bit, iit, useIter, newAlloc, err = prepDataSV(s, t, reuse); err != nil { 938 return nil, errors.Wrapf(err, opFail, "StdEng.Mod") 939 } 940 scalarHeader = dataA 941 } 942 943 if useIter { 944 switch { 945 case incr: 946 err = e.E.ModIterIncr(typ, dataA, dataB, dataReuse, ait, bit, iit) 947 retVal = reuse 948 case toReuse && leftTensor: 949 storage.CopyIter(typ, dataReuse, dataA, iit, ait) 950 ait.Reset() 951 iit.Reset() 952 err = e.E.ModIter(typ, dataReuse, dataB, iit, bit) 953 retVal = reuse 954 case toReuse && !leftTensor: 955 storage.CopyIter(typ, dataReuse, dataB, iit, bit) 956 iit.Reset() 957 bit.Reset() 958 err = e.E.ModIter(typ, dataA, dataReuse, ait, iit) 959 retVal = reuse 960 case !safe: 961 err = e.E.ModIter(typ, dataA, dataB, ait, bit) 962 retVal = a 963 default: 964 retVal = a.Clone().(Tensor) 965 if leftTensor { 966 err = e.E.ModIter(typ, retVal.hdr(), dataB, ait, bit) 967 } else { 968 err = e.E.ModIter(typ, dataA, retVal.hdr(), ait, bit) 969 } 970 } 971 if newAlloc { 972 freeScalar(scalarHeader.Raw) 973 } 974 returnHeader(scalarHeader) 975 return 976 } 977 switch { 978 case incr: 979 err = e.E.ModIncr(typ, dataA, dataB, dataReuse) 980 retVal = reuse 981 case toReuse && leftTensor: 982 storage.Copy(typ, dataReuse, dataA) 983 err = e.E.Mod(typ, dataReuse, dataB) 984 retVal = reuse 985 case toReuse && !leftTensor: 986 storage.Copy(typ, dataReuse, dataB) 987 err = e.E.Mod(typ, dataA, dataReuse) 988 if t.Shape().IsScalarEquiv() { 989 storage.Copy(typ, dataReuse, dataA) 990 } 991 retVal = reuse 992 case !safe: 993 err = e.E.Mod(typ, dataA, dataB) 994 if t.Shape().IsScalarEquiv() && !leftTensor { 995 storage.Copy(typ, dataB, dataA) 996 } 997 retVal = a 998 default: 999 retVal = a.Clone().(Tensor) 1000 if !leftTensor { 1001 storage.Fill(typ, retVal.hdr(), dataA) 1002 } 1003 err = e.E.Mod(typ, retVal.hdr(), dataB) 1004 } 1005 if newAlloc { 1006 freeScalar(scalarHeader.Raw) 1007 } 1008 returnHeader(scalarHeader) 1009 return 1010 }