chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
# Empty file to be replaced in https://github.com/tensorflow/tensorflow/pull/50934
+20
View File
@@ -0,0 +1,20 @@
/*
Copyright 2016 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//go:generate go generate ../genop
//go:generate go run ../genop/main.go -outfile wrappers.go -api_def_dirs ../../core/api_def/base_api/
package op
+49
View File
@@ -0,0 +1,49 @@
/*
Copyright 2016 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package op
import (
"fmt"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
)
// Gradients adds gradients computation ops to the graph according to scope.
//
// Arguments:
// y: output of the function to derive
// x: inputs of the function for which partial derivatives are computed
// dx: if not null, the partial derivatives of some loss function L w.r.t. y
//
// return the partial derivatives
func Gradients(scope *Scope, y []tf.Output, x []tf.Output, dx ...tf.Output) (output []tf.Output) {
if len(scope.controlDependencies) > 0 {
scope.UpdateErr("Gradients", fmt.Errorf("Gradients does not currently support control dependencies (via Scope.WithControlDependencies)."))
return
}
if scope.device != "" {
scope.UpdateErr("Gradients", fmt.Errorf("Gradients does not currently support device annotations (via Scope.WithDevice)."))
return
}
var err error
if output, err = scope.graph.AddGradients(scope.opName("Gradients"), y, x, dx); err != nil {
scope.UpdateErr("Gradients", err)
return
}
return output
}
+246
View File
@@ -0,0 +1,246 @@
/*
Copyright 2016 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package op
import (
"strings"
"testing"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
)
func TestAddGradients(t *testing.T) {
var (
s = NewScope()
x1 = Placeholder(s.SubScope("x1"), tf.Float)
x2 = Placeholder(s.SubScope("x2"), tf.Float)
y0 = Square(s.SubScope("y0"), x1)
y1 = Square(s.SubScope("y1"), y0)
y2 = AddN(s.SubScope("y2"), []tf.Output{y0, x2})
)
grads0 := Gradients(s, []tf.Output{y1}, []tf.Output{x1})
if err := s.Err(); err != nil {
t.Fatal(err)
}
if len(grads0) != 1 {
t.Fatal(len(grads0))
}
if grads0[0].DataType() != tf.Float {
t.Fatalf("Got DataType %v, wanted %v", grads0[0].DataType(), tf.Float)
}
sub := s.SubScope("sub")
grads1 := Gradients(sub, []tf.Output{y2}, []tf.Output{x1, x2})
if err := sub.Err(); err != nil {
t.Fatal(err)
}
if len(grads1) != 2 {
t.Fatal(len(grads1))
}
if grads1[0].DataType() != tf.Float {
t.Fatalf("Got DataType %v, wanted %v", grads1[0].DataType(), tf.Float)
}
if grads1[1].DataType() != tf.Float {
t.Fatalf("Got DataType %v, wanted %v", grads1[1].DataType(), tf.Float)
}
graph, err := sub.Finalize()
if err != nil {
t.Fatal(err)
}
sess, err := tf.NewSession(graph, nil)
if err != nil {
t.Fatal(err)
}
c1, _ := tf.NewTensor(float32(3.0))
c2, _ := tf.NewTensor(float32(3.0))
outputs, err := sess.Run(
map[tf.Output]*tf.Tensor{x1: c1, x2: c2},
[]tf.Output{grads0[0], grads1[0], grads1[1]},
nil)
if err != nil {
t.Fatal(err)
}
if len(outputs) != 3 {
t.Fatal(len(outputs))
}
if outputs[0].Value().(float32) != 108.0 {
t.Fatalf("Got %v, wanted float 108.0", outputs[0].Value())
}
if outputs[1].Value().(float32) != 6.0 {
t.Fatalf("Got %v, wanted float 6.0", outputs[1].Value())
}
if outputs[2].Value().(float32) != 1.0 {
t.Fatalf("Got %v, wanted float 1.0", outputs[2].Value())
}
}
func TestAddGradientsSums(t *testing.T) {
var (
s = NewScope()
x = Placeholder(s.SubScope("x"), tf.Float)
y0 = Square(s.SubScope("y0"), x)
y1 = Square(s.SubScope("y1"), y0)
)
grad := Gradients(s, []tf.Output{y0, y1}, []tf.Output{x})
if err := s.Err(); err != nil {
t.Fatal(err)
}
if len(grad) != 1 {
t.Fatal(len(grad))
}
if grad[0].DataType() != tf.Float {
t.Fatalf("Got DataType %v, wanted %v", grad[0].DataType(), tf.Float)
}
graph, err := s.Finalize()
if err != nil {
t.Fatal(err)
}
sess, err := tf.NewSession(graph, nil)
if err != nil {
t.Fatal(err)
}
c, _ := tf.NewTensor(float32(3.0))
outputs, err := sess.Run(
map[tf.Output]*tf.Tensor{x: c},
[]tf.Output{grad[0]},
nil)
if err != nil {
t.Fatal(err)
}
if outputs[0].Value().(float32) != 114.0 {
t.Fatalf("Got %v, wanted float 114.0", outputs[0].Value())
}
}
func TestAddGradientsWithInitialValues(t *testing.T) {
var (
s = NewScope()
x = Placeholder(s.SubScope("x1"), tf.Float)
y0 = Square(s.SubScope("y0"), x)
y1 = Square(s.SubScope("y1"), y0)
)
grads0 := Gradients(s, []tf.Output{y1}, []tf.Output{y0})
if err := s.Err(); err != nil {
t.Fatal(err)
}
if len(grads0) != 1 {
t.Fatal(len(grads0))
}
if grads0[0].DataType() != tf.Float {
t.Fatalf("Got DataType %v, wanted %v", grads0[0].DataType(), tf.Float)
}
sub := s.SubScope("sub")
grads1 := Gradients(sub, []tf.Output{y0}, []tf.Output{x}, grads0[0])
if err := sub.Err(); err != nil {
t.Fatal(err)
}
if len(grads1) != 1 {
t.Fatal(len(grads1))
}
if grads1[0].DataType() != tf.Float {
t.Fatalf("Got DataType %v, wanted %v", grads1[0].DataType(), tf.Float)
}
graph, err := sub.Finalize()
if err != nil {
t.Fatal(err)
}
sess, err := tf.NewSession(graph, nil)
if err != nil {
t.Fatal(err)
}
c, _ := tf.NewTensor(float32(3.0))
outputs, err := sess.Run(
map[tf.Output]*tf.Tensor{x: c},
[]tf.Output{grads1[0]},
nil)
if err != nil {
t.Fatal(err)
}
if outputs[0].Value().(float32) != 108.0 {
t.Fatalf("Got %v, wanted float 108.0", outputs[0].Value())
}
}
func TestValidateGradientsNames(t *testing.T) {
var (
s = NewScope()
x = Placeholder(s.SubScope("x"), tf.Float)
y0 = Square(s.SubScope("y0"), x)
)
grads0 := Gradients(s, []tf.Output{y0}, []tf.Output{x})
if err := s.Err(); err != nil {
t.Fatal(err)
}
if !strings.HasPrefix(grads0[0].Op.Name(), "Gradients/") {
t.Fatalf("Got name %v, wanted started with Gradients/", grads0[0].Op.Name())
}
sub := s.SubScope("sub")
grads1 := Gradients(sub, []tf.Output{y0}, []tf.Output{x})
if err := s.Err(); err != nil {
t.Fatal(err)
}
if !strings.HasPrefix(grads1[0].Op.Name(), "sub/Gradients/") {
t.Fatalf("Got name %v, wanted started with sub/Gradients/", grads1[0].Op.Name())
}
Gradients(sub, []tf.Output{y0}, []tf.Output{x})
if err := s.Err(); err == nil {
t.Error("Gradients should have failed if executed more than once for scope of the same namespace")
}
}
func TestAddGradientsWithControlDependencies(t *testing.T) {
var (
s = NewScope()
zero = Const(s.SubScope("zero"), int32(0))
x = Placeholder(s.SubScope("x"), tf.Float)
y0 = Square(s.SubScope("y0"), x)
variable = VarHandleOp(s, tf.Int32, tf.ScalarShape())
init = AssignVariableOp(s, variable, zero)
readDeps = []*tf.Operation{init}
)
s = s.WithControlDependencies(readDeps...)
Gradients(s, []tf.Output{y0}, []tf.Output{x})
if err := s.Err(); err == nil {
t.Error("Gradients should have failed when control dependencies are set")
}
}
func TestAddGradientsWithDevice(t *testing.T) {
var (
s = NewScope()
x = Placeholder(s.SubScope("x"), tf.Float)
y0 = Square(s.SubScope("y0"), x)
)
s = s.WithDevice("/device:GPU:0")
Gradients(s, []tf.Output{y0}, []tf.Output{x})
if err := s.Err(); err == nil {
t.Error("Gradients should have failed when device is set")
}
}
+51
View File
@@ -0,0 +1,51 @@
/*
Copyright 2016 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package op defines functions for adding TensorFlow operations to a Graph.
//
// Functions for adding an operation to a graph take a Scope object as the
// first argument. The Scope object encapsulates a graph and a set of
// properties (such as a name prefix) for all operations being added
// to the graph.
//
// WARNING: The API in this package has not been finalized and can
// change without notice.
package op
import (
tf "github.com/tensorflow/tensorflow/tensorflow/go"
)
// Const adds an operation to graph that produces value as output.
func Const(scope *Scope, value interface{}) (output tf.Output) {
if scope.Err() != nil {
return
}
t, ok := value.(*tf.Tensor)
if !ok {
var err error
if t, err = tf.NewTensor(value); err != nil {
scope.UpdateErr("Const", err)
return
}
}
return scope.AddOperation(tf.OpSpec{
Type: "Const",
Attrs: map[string]interface{}{
"dtype": t.DataType(),
"value": t,
}}).Output(0)
}
+133
View File
@@ -0,0 +1,133 @@
/*
Copyright 2016 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Tests for the generated code of some operations.
package op
import (
"strings"
"testing"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
)
func TestPlaceholder(t *testing.T) {
s := NewScope()
Placeholder(s.SubScope("x"), tf.Float, PlaceholderShape(tf.MakeShape(-1, 10)))
Placeholder(s.SubScope("y"), tf.Float, PlaceholderShape(tf.ScalarShape()))
Placeholder(s.SubScope("z"), tf.Float, PlaceholderShape(tf.Shape{}))
if _, err := s.Finalize(); err != nil {
t.Fatal(err)
}
}
func TestAddOperationFailure(t *testing.T) {
// Inspired from https://github.com/tensorflow/tensorflow/issues/9931
s := NewScope()
resize := ResizeArea(s, Placeholder(s, tf.Float), Const(s, []int64{80, 80}))
if err := s.Err(); err == nil {
t.Fatal("ResizeArea expects an int32 Tensor for size, should fail when an int64 is provided")
}
// And any use of resize should panic with an error message more informative than SIGSEGV
defer func() {
r := recover()
if r == nil {
return
}
s, ok := r.(string)
if ok && strings.Contains(s, "see Scope.Err() for details") {
return
}
t.Errorf("Expected panic string to Scope.Err(), found %T: %q", r, r)
}()
_ = resize.Shape()
t.Errorf("resize.Shape() should have paniced since the underlying Operation was not created")
}
func TestShapeAttribute(t *testing.T) {
s := NewScope()
x := Placeholder(s.SubScope("x"), tf.Int32, PlaceholderShape(tf.MakeShape(1)))
y := Placeholder(s.SubScope("y"), tf.Int32, PlaceholderShape(tf.Shape{}))
z := Add(s, x, y)
graph, err := s.Finalize()
if err != nil {
t.Fatal(err)
}
sess, err := tf.NewSession(graph, nil)
if err != nil {
t.Fatal(err)
}
value, err := tf.NewTensor([]int32{7})
if err != nil {
t.Fatal(err)
}
feeds := map[tf.Output]*tf.Tensor{
x: value,
y: value,
}
fetched, err := sess.Run(feeds, []tf.Output{z}, nil)
if err != nil {
t.Fatal(err)
}
if got, want := len(fetched), 1; got != want {
t.Fatalf("Fetched %d tensors, expected %d", got, want)
}
if got, want := fetched[0].Value().([]int32), []int32{14}; len(got) != len(want) || len(got) != 1 || got[0] != want[0] {
t.Fatalf("Got %v, want %v", got, want)
}
}
func TestDataset(t *testing.T) {
var (
s = NewScope()
// The use of a non-scalar here is inspired by
// https://github.com/tensorflow/tensorflow/issues/14891
c = Const(s, []int32{21718, 31415})
types = []tf.DataType{c.DataType()}
shapes = []tf.Shape{c.Shape()}
dataset = TensorDataset(s, []tf.Output{c}, shapes)
iterator = Iterator(s, "", "", types, shapes)
next = IteratorGetNext(s, iterator, types, shapes)
init = MakeIterator(s, dataset, iterator)
)
graph, err := s.Finalize()
if err != nil {
t.Fatal(err)
}
sess, err := tf.NewSession(graph, nil)
if err != nil {
t.Fatal(err)
}
if _, err := sess.Run(nil, nil, []*tf.Operation{init}); err != nil {
t.Fatal(err)
}
results, err := sess.Run(nil, next, nil)
if err != nil {
t.Fatal(err)
}
got := results[0].Value().([]int32)
if len(got) != 2 || got[0] != 21718 || got[1] != 31415 {
t.Errorf("Got %v, want {21718, 31415}", got)
}
if _, err := sess.Run(nil, next, nil); err == nil {
t.Errorf("Expected sess.Run() to fail since the iterator should have reached the end of the dataset")
}
}
+185
View File
@@ -0,0 +1,185 @@
/*
Copyright 2016 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package op
import (
"fmt"
"runtime/debug"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
)
// Scope encapsulates common operation properties when building a Graph.
//
// A Scope object (and its derivatives, e.g., obtained from Scope.SubScope)
// act as a builder for graphs. They allow common properties (such as
// a name prefix) to be specified for multiple operations being added
// to the graph.
//
// A Scope object and all its derivatives (e.g., obtained from Scope.SubScope)
// are not safe for concurrent use by multiple goroutines.
type Scope struct {
graph *tf.Graph
namemap map[string]int
namespace string
controlDependencies []*tf.Operation
device string
err *scopeErr
}
// scopeErr is used to share errors between all derivatives of a root scope.
type scopeErr struct {
err error
}
// NewScope creates a Scope initialized with an empty Graph.
func NewScope() *Scope {
return &Scope{graph: tf.NewGraph(), namemap: make(map[string]int), err: new(scopeErr)}
}
// NewScopeWithGraph creates a Scope initialized with the Graph thats passed in
func NewScopeWithGraph(g *tf.Graph) *Scope {
return &Scope{graph: g, namemap: make(map[string]int), err: new(scopeErr)}
}
// Finalize returns the Graph on which this scope operates on and renders s
// unusable. If there was an error during graph construction, that error is
// returned instead.
func (s *Scope) Finalize() (*tf.Graph, error) {
if err := s.Err(); err != nil {
return nil, err
}
s.err.err = fmt.Errorf("Scope has been finalized and is no longer usable")
return s.graph, nil
}
// AddOperation adds the operation to the Graph managed by s.
//
// If there is a name prefix associated with s (such as if s was created
// by a call to SubScope), then this prefix will be applied to the name
// of the operation being added. See also Graph.AddOperation.
func (s *Scope) AddOperation(args tf.OpSpec) *tf.Operation {
if s.Err() != nil {
return nil
}
if args.Name == "" {
args.Name = args.Type
}
if s.namespace != "" {
args.Name = s.namespace + "/" + args.Name
}
args.ControlDependencies = append(args.ControlDependencies, s.controlDependencies...)
args.Device = s.device
op, err := s.graph.AddOperation(args)
if err != nil {
s.UpdateErr(args.Type, err)
}
return op
}
// SubScope returns a new Scope which will cause all operations added to the
// graph to be namespaced with 'namespace'. If namespace collides with an
// existing namespace within the scope, then a suffix will be added.
func (s *Scope) SubScope(namespace string) *Scope {
namespace = s.uniqueName(namespace)
if s.namespace != "" {
namespace = s.namespace + "/" + namespace
}
return &Scope{
graph: s.graph,
namemap: make(map[string]int),
namespace: namespace,
controlDependencies: s.controlDependencies,
device: s.device,
err: s.err,
}
}
// WithControlDependencies returns a new Scope which will cause all operations
// added to the graph to execute only after all the provided operations have
// executed first (in addition to any other control dependencies in s).
func (s *Scope) WithControlDependencies(ops ...*tf.Operation) *Scope {
// Force a copy of the control dependencies into a new underlying array on
// every call. We cannot alias the same underlying array as `ops`, otherwise
// the user could modify that array after calling s.WithControlDependencies,
// which would be confusing. We cannot alias the same underlying array as the
// original `s.controlDependencies`, since Scopes form a logical tree, and
// other calls to s.WithControlDependencies could stomp on each other.
deps := make([]*tf.Operation, 0, len(s.controlDependencies)+len(ops))
deps = append(deps, s.controlDependencies...)
deps = append(deps, ops...)
return &Scope{
graph: s.graph,
namemap: s.namemap,
namespace: s.namespace,
controlDependencies: deps,
device: s.device,
err: s.err,
}
}
// WithDevice returns a new Scope which will cause all operations added to the
// graph to execute on devices that match the provided device specification.
//
// For example, WithDevice("/device:GPU:0") will cause operations added to
// the graph to execute on GPU #0.
//
// An empty string removes any device restrictions.
func (s *Scope) WithDevice(device string) *Scope {
return &Scope{
graph: s.graph,
namemap: s.namemap,
namespace: s.namespace,
controlDependencies: s.controlDependencies,
device: device,
err: s.err,
}
}
// Err returns the error, if any, encountered during the construction
// of the Graph managed by s.
//
// Once Err returns a non-nil error, all future calls will do the same,
// indicating that the scope should be discarded as the graph could not
// be constructed.
func (s *Scope) Err() error {
return s.err.err
}
// UpdateErr is used to notify Scope of any graph construction errors
// while creating the operation op.
func (s *Scope) UpdateErr(op string, err error) {
if s.err.err == nil {
s.err.err = fmt.Errorf("failed to add operation %q: %v (Stacktrace: %s)", op, err, debug.Stack())
}
}
func (s *Scope) uniqueName(name string) string {
count := s.namemap[name]
s.namemap[name]++
if count == 0 {
return name
}
return fmt.Sprint(name, "_", count)
}
func (s *Scope) opName(typ string) string {
if s.namespace == "" {
return typ
}
return s.namespace + "/" + typ
}
+201
View File
@@ -0,0 +1,201 @@
/*
Copyright 2016 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package op
import (
"fmt"
"testing"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
)
func TestScopeSubScope(t *testing.T) {
var (
root = NewScope()
sub1 = root.SubScope("x")
sub2 = root.SubScope("x")
sub1a = sub1.SubScope("y")
sub2a = sub2.SubScope("y")
)
testdata := []struct {
scope *Scope
name string
}{
{root, "Const"},
{sub1, "x/Const"},
{sub1a, "x/y/Const"},
{sub2, "x_1/Const"},
{sub2a, "x_1/y/Const"},
}
for _, test := range testdata {
c := Const(test.scope, int64(1))
if err := test.scope.Err(); err != nil {
t.Fatalf("%q: %v", test.name, err)
}
if got := c.Op.Name(); got != test.name {
t.Errorf("%q: Got %q", test.name, got)
}
}
}
func TestScopeSubScopeErrors(t *testing.T) {
var (
root = NewScope()
sub = root.SubScope("x")
)
// Error on the root, even after sub has been created should be propagated.
// Force an error by creating a Const which has a type that does not
// translate to the TensorFlow type system.
Const(root, int(1))
if err := root.Err(); err == nil {
t.Fatal("Expected error")
}
if err := sub.Err(); err == nil {
t.Errorf("Root scope had error [%v], but sub-scope did not", root.Err())
}
}
func TestControlDependencies(t *testing.T) {
var (
s = NewScope()
zero = Const(s.SubScope("zero"), int32(0))
one = Const(s.SubScope("one"), int32(1))
variable = VarHandleOp(s, tf.Int32, tf.ScalarShape())
init = AssignVariableOp(s, variable, zero)
update = AssignAddVariableOp(s, variable, one)
readDeps = []*tf.Operation{update}
)
// We intend for `read` to have a control dependency on `update`.
s = s.WithControlDependencies(readDeps...)
// Ensure that Scope.WithControlDependencies makes a copy of the underlying
// array, rather than just holding a slice reference to the same user-supplied
// underlying array. If the copy is correctly performed, overwriting
// readDeps[0] should have no effect on control dependencies for `read`.
readDeps[0] = init
read := ReadVariableOp(s, variable, tf.Int32)
graph, err := s.Finalize()
if err != nil {
t.Fatal(err)
}
sess, err := tf.NewSession(graph, nil)
if err != nil {
t.Fatal(err)
}
if _, err = sess.Run(nil, nil, []*tf.Operation{init}); err != nil {
t.Fatal(err)
}
// Without the control dependency, the read operation may not see the
// update.
for i := int32(0); i < 10; i++ {
out, err := sess.Run(nil, []tf.Output{read}, nil)
if err != nil {
t.Fatal(err)
}
if got, want := out[0].Value().(int32), i+1; got != want {
t.Errorf("Got %d, want %d", got, want)
}
}
}
func TestDevice(t *testing.T) {
s := NewScope()
matrix := Const(s, [][]float32{{3.0}})
s = s.WithDevice("/device:GPU:0")
square := MatMul(s.SubScope("square"), matrix, matrix)
s = s.WithDevice("")
cube := MatMul(s.SubScope("cube"), square, matrix)
if got, want := square.Op.Device(), "/device:GPU:0"; got != want {
t.Errorf("Got %q, want %q", got, want)
}
if got, want := cube.Op.Device(), ""; got != want {
t.Errorf("Got %q, want %q", got, want)
}
}
func TestScopeFinalize(t *testing.T) {
var (
root = NewScope()
sub1 = root.SubScope("x")
sub2 = sub1.SubScope("y")
)
if _, err := sub1.Finalize(); err != nil {
t.Fatal(err)
}
if err := root.Err(); err == nil {
t.Error("Root scope's Err() should be non-nil once Finalize has been called")
}
if err := sub2.Err(); err == nil {
t.Error("Sub scope's Err() should be non-nil once Finalize has been called")
}
}
func TestMultipleGeneratedOps(t *testing.T) {
s := NewScope()
Placeholder(s.SubScope("x"), tf.Float)
Placeholder(s.SubScope("y"), tf.Float)
if _, err := s.Finalize(); err != nil {
t.Fatal(err)
}
}
func TestScopeWithGraph(t *testing.T) {
s1 := NewScope()
Const(s1, "hello")
graph, err := s1.Finalize()
if err != nil {
t.Fatal(err)
}
s2 := NewScopeWithGraph(graph)
Const(s2.SubScope("addition"), "world")
if err := s2.Err(); err != nil {
t.Fatal(err)
}
}
func Example() {
// This example creates a Graph that multiplies a constant matrix with
// a matrix to be provided during graph execution (via
// tensorflow.Session).
s := NewScope()
input := Placeholder(s, tf.Float) // Matrix to be provided to Session.Run
output := MatMul(s,
Const(s, [][]float32{{10}, {20}}), // Constant 2x1 matrix
input,
MatMulTransposeB(true))
if s.Err() != nil {
panic(s.Err())
}
// Shape of the product: The number of rows is fixed by m1, but the
// number of columns will depend on m2, which is unknown.
fmt.Println(output.Shape())
// Output: [2, ?]
}
func ExampleScope_SubScope() {
var (
s = NewScope()
c1 = Const(s.SubScope("x"), int64(1))
c2 = Const(s.SubScope("x"), int64(1))
)
if s.Err() != nil {
panic(s.Err())
}
fmt.Println(c1.Op.Name(), c2.Op.Name())
// Output: x/Const x_1/Const
}
File diff suppressed because it is too large Load Diff