| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7913f95 commit 9033377
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1018,6 +1018,7 @@ tf_kernel_libraries( | |||
| 1018 | 1018 | tf_kernel_libraries( | |
| 1019 | 1019 | name = "sparse", | |
| 1020 | 1020 | prefixes = [ | |
| 1021 | + "sparse_add_grad_op", | ||
| 1021 | 1022 | "sparse_add_op", | |
| 1022 | 1023 | "sparse_concat_op", | |
| 1023 | 1024 | "sparse_reorder_op", | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,144 @@ | |||
| 1 | + /* Copyright 2016 Google Inc. All Rights Reserved. | ||
| 2 | + | ||
| 3 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | + you may not use this file except in compliance with the License. | ||
| 5 | + You may obtain a copy of the License at | ||
| 6 | + | ||
| 7 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | + | ||
| 9 | + Unless required by applicable law or agreed to in writing, software | ||
| 10 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | + See the License for the specific language governing permissions and | ||
| 13 | + limitations under the License. | ||
| 14 | + ==============================================================================*/ | ||
| 15 | + | ||
| 16 | + #include "tensorflow/core/framework/op_kernel.h" | ||
| 17 | + #include "tensorflow/core/framework/register_types.h" | ||
| 18 | + #include "tensorflow/core/framework/tensor.h" | ||
| 19 | + #include "tensorflow/core/framework/tensor_util.h" | ||
| 20 | + #include "tensorflow/core/framework/types.h" | ||
| 21 | + #include "tensorflow/core/util/sparse/sparse_tensor.h" | ||
| 22 | + | ||
| 23 | + namespace tensorflow { | ||
| 24 | + | ||
| 25 | + template <typename T> | ||
| 26 | + class SparseAddGradOp : public OpKernel { | ||
| 27 | + public: | ||
| 28 | + explicit SparseAddGradOp(OpKernelConstruction *ctx) : OpKernel(ctx) {} | ||
| 29 | + | ||
| 30 | + void Compute(OpKernelContext *ctx) override { | ||
| 31 | + // Gradient for op: SparseAdd(a, b) == sum. | ||
| 32 | + const Tensor *backprop_val_grad, *a_indices, *b_indices, *sum_indices; | ||
| 33 | + OP_REQUIRES_OK(ctx, ctx->input("backprop_val_grad", &backprop_val_grad)); | ||
| 34 | + OP_REQUIRES_OK(ctx, ctx->input("a_indices", &a_indices)); | ||
| 35 | + OP_REQUIRES_OK(ctx, ctx->input("b_indices", &b_indices)); | ||
| 36 | + OP_REQUIRES_OK(ctx, ctx->input("sum_indices", &sum_indices)); | ||
| 37 | + | ||
| 38 | + OP_REQUIRES(ctx, TensorShapeUtils::IsMatrix(a_indices->shape()) && | ||
| 39 | + TensorShapeUtils::IsMatrix(b_indices->shape()) && | ||
| 40 | + TensorShapeUtils::IsMatrix(sum_indices->shape()), | ||
| 41 | + errors::InvalidArgument( | ||
| 42 | + "Input indices should be matrices but received shapes: ", | ||
| 43 | + a_indices->shape().DebugString(), " and ", | ||
| 44 | + b_indices->shape().DebugString(), " and ", | ||
| 45 | + sum_indices->shape().DebugString())); | ||
| 46 | + OP_REQUIRES( | ||
| 47 | + ctx, TensorShapeUtils::IsVector(backprop_val_grad->shape()), | ||
| 48 | + errors::InvalidArgument( | ||
| 49 | + "Input backprop_val_grad should be a vector but received shape: ", | ||
| 50 | + backprop_val_grad->shape().DebugString())); | ||
| 51 | + OP_REQUIRES( | ||
| 52 | + ctx, a_indices->dim_size(1) == b_indices->dim_size(1) && | ||
| 53 | + b_indices->dim_size(1) == sum_indices->dim_size(1), | ||
| 54 | + errors::InvalidArgument("The densified operands should have the same " | ||
| 55 | + "ndims; for A, B, sum got: ", | ||
| 56 | + a_indices->dim_size(1), b_indices->dim_size(1), | ||
| 57 | + sum_indices->dim_size(1))); | ||
| 58 | + OP_REQUIRES( | ||
| 59 | + ctx, backprop_val_grad->NumElements() == sum_indices->dim_size(0), | ||
| 60 | + errors::InvalidArgument("# elements of backprop_val_grad and # rows of " | ||
| 61 | + "sum_indices should match (#nnz of sum): got ", | ||
| 62 | + backprop_val_grad->NumElements(), " and ", | ||
| 63 | + sum_indices->dim_size(0))); | ||
| 64 | + | ||
| 65 | + const int num_dims = a_indices->dim_size(1); | ||
| 66 | + const int64 a_nnz = a_indices->dim_size(0); | ||
| 67 | + const int64 b_nnz = b_indices->dim_size(0); | ||
| 68 | + const int64 sum_nnz = backprop_val_grad->NumElements(); | ||
| 69 | + | ||
| 70 | + const auto a_indices_mat = a_indices->matrix<int64>(); | ||
| 71 | + const auto b_indices_mat = b_indices->matrix<int64>(); | ||
| 72 | + const auto sum_indices_mat = sum_indices->matrix<int64>(); | ||
| 73 | + | ||
| 74 | + Tensor *a_val_grad, *b_val_grad; | ||
| 75 | + OP_REQUIRES_OK(ctx, | ||
| 76 | + ctx->allocate_output(0, TensorShape({a_nnz}), &a_val_grad)); | ||
| 77 | + OP_REQUIRES_OK(ctx, | ||
| 78 | + ctx->allocate_output(1, TensorShape({b_nnz}), &b_val_grad)); | ||
| 79 | + | ||
| 80 | + T *a_val_grad_flat = a_val_grad->flat<T>().data(); | ||
| 81 | + T *b_val_grad_flat = b_val_grad->flat<T>().data(); | ||
| 82 | + const T *backprop_val_grad_flat = backprop_val_grad->flat<T>().data(); | ||
| 83 | + memset(a_val_grad_flat, 0, sizeof(T) * a_nnz); | ||
| 84 | + memset(b_val_grad_flat, 0, sizeof(T) * b_nnz); | ||
| 85 | + | ||
| 86 | + #define COMPARE(a_or_b, idx) \ | ||
| 87 | + switch (sparse::DimComparator::cmp(a_or_b##_indices_mat, sum_indices_mat, \ | ||
| 88 | + idx, k, num_dims)) { \ | ||
| 89 | + case 0: \ | ||
| 90 | + a_or_b##_val_grad_flat[idx] = backprop_val_grad_flat[k]; \ | ||
| 91 | + ++idx; \ | ||
| 92 | + break; \ | ||
| 93 | + case -1: \ | ||
| 94 | + ++idx; \ | ||
| 95 | + a_or_b##_idx_geq = false; \ | ||
| 96 | + break; \ | ||
| 97 | + case 1: \ | ||
| 98 | + break; \ | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + // Set-intersect the indices; fill in grads for positions in the | ||
| 102 | + // intersection. | ||
| 103 | + int64 i = 0, j = 0, k = 0; | ||
| 104 | + bool a_idx_geq, b_idx_geq; | ||
| 105 | + while (i < a_nnz && j < b_nnz && k < sum_nnz) { | ||
| 106 | + a_idx_geq = b_idx_geq = true; | ||
| 107 | + COMPARE(a, i); | ||
| 108 | + COMPARE(b, j); | ||
| 109 | + // increment pointer into sum_indices iff both the current A, B indices >= | ||
| 110 | + // the current sum index. | ||
| 111 | + if (a_idx_geq && b_idx_geq) ++k; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + // at most one loop below will run | ||
| 115 | + while (i < a_nnz && k < sum_nnz) { | ||
| 116 | + a_idx_geq = true; | ||
| 117 | + COMPARE(a, i); | ||
| 118 | + if (a_idx_geq) ++k; | ||
| 119 | + } | ||
| 120 | + while (j < b_nnz && k < sum_nnz) { | ||
| 121 | + b_idx_geq = true; | ||
| 122 | + COMPARE(b, j); | ||
| 123 | + if (b_idx_geq) ++k; | ||
| 124 | + } | ||
| 125 | + #undef COMPARE | ||
| 126 | + } | ||
| 127 | + }; | ||
| 128 | + | ||
| 129 | + #define REGISTER_KERNELS(type) \ | ||
| 130 | + REGISTER_KERNEL_BUILDER( \ | ||
| 131 | + Name("SparseAddGrad").Device(DEVICE_CPU).TypeConstraint<type>("T"), \ | ||
| 132 | + SparseAddGradOp<type>) | ||
| 133 | + | ||
| 134 | + // This op should work for any T that SparseAdd is registered with. | ||
| 135 | + REGISTER_KERNELS(float); | ||
| 136 | + REGISTER_KERNELS(double); | ||
| 137 | + REGISTER_KERNELS(int64); | ||
| 138 | + REGISTER_KERNELS(int32); | ||
| 139 | + REGISTER_KERNELS(int16); | ||
| 140 | + REGISTER_KERNELS(int8); | ||
| 141 | + REGISTER_KERNELS(complex64); | ||
| 142 | + REGISTER_KERNELS(complex128); | ||
| 143 | + #undef REGISTER_KERNELS | ||
| 144 | + } // namespace tensorflow | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -95,7 +95,7 @@ class SparseAddOp : public OpKernel { | |||
| 95 | 95 | std::vector<std::pair<bool, int64>> entries_to_copy; // from_a?, idx | |
| 96 | 96 | entries_to_copy.reserve(a_nnz + b_nnz); | |
| 97 | 97 | std::vector<T> out_values; | |
| 98 | - const int64 num_dims = a_shape->dim_size(0); | ||
| 98 | + const int num_dims = a_shape->dim_size(0); | ||
| 99 | 99 | ||
| 100 | 100 | // The input and output sparse tensors are assumed to be ordered along | |
| 101 | 101 | // increasing dimension number. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14681,6 +14681,55 @@ op { | |||
| 14681 | 14681 | } | |
| 14682 | 14682 | } | |
| 14683 | 14683 | } | |
| 14684 | + op { | ||
| 14685 | + name: "SparseAddGrad" | ||
| 14686 | + input_arg { | ||
| 14687 | + name: "backprop_val_grad" | ||
| 14688 | + type_attr: "T" | ||
| 14689 | + } | ||
| 14690 | + input_arg { | ||
| 14691 | + name: "a_indices" | ||
| 14692 | + type: DT_INT64 | ||
| 14693 | + } | ||
| 14694 | + input_arg { | ||
| 14695 | + name: "b_indices" | ||
| 14696 | + type: DT_INT64 | ||
| 14697 | + } | ||
| 14698 | + input_arg { | ||
| 14699 | + name: "sum_indices" | ||
| 14700 | + type: DT_INT64 | ||
| 14701 | + } | ||
| 14702 | + output_arg { | ||
| 14703 | + name: "a_val_grad" | ||
| 14704 | + type_attr: "T" | ||
| 14705 | + } | ||
| 14706 | + output_arg { | ||
| 14707 | + name: "b_val_grad" | ||
| 14708 | + type_attr: "T" | ||
| 14709 | + } | ||
| 14710 | + attr { | ||
| 14711 | + name: "T" | ||
| 14712 | + type: "type" | ||
| 14713 | + allowed_values { | ||
| 14714 | + list { | ||
| 14715 | + type: DT_FLOAT | ||
| 14716 | + type: DT_DOUBLE | ||
| 14717 | + type: DT_INT64 | ||
| 14718 | + type: DT_INT32 | ||
| 14719 | + type: DT_UINT8 | ||
| 14720 | + type: DT_UINT16 | ||
| 14721 | + type: DT_INT16 | ||
| 14722 | + type: DT_INT8 | ||
| 14723 | + type: DT_COMPLEX64 | ||
| 14724 | + type: DT_COMPLEX128 | ||
| 14725 | + type: DT_QINT8 | ||
| 14726 | + type: DT_QUINT8 | ||
| 14727 | + type: DT_QINT32 | ||
| 14728 | + type: DT_HALF | ||
| 14729 | + } | ||
| 14730 | + } | ||
| 14731 | + } | ||
| 14732 | + } | ||
| 14684 | 14733 | op { | |
| 14685 | 14734 | name: "SparseApplyAdadelta" | |
| 14686 | 14735 | input_arg { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9446,7 +9446,7 @@ op { | |||
| 9446 | 9446 | name: "SparseAdd" | |
| 9447 | 9447 | input_arg { | |
| 9448 | 9448 | name: "a_indices" | |
| 9449 | - description: "2-D. The `indices` of the first `SparseTensor`, size `[nnz, 2]` Matrix." | ||
| 9449 | + description: "2-D. The `indices` of the first `SparseTensor`, size `[nnz, ndims]` Matrix." | ||
| 9450 | 9450 | type: DT_INT64 | |
| 9451 | 9451 | } | |
| 9452 | 9452 | input_arg { | |
@@ -9456,12 +9456,12 @@ op { | |||
| 9456 | 9456 | } | |
| 9457 | 9457 | input_arg { | |
| 9458 | 9458 | name: "a_shape" | |
| 9459 | - description: "1-D. The `shape` of the first `SparseTensor`, size `[2]` Vector." | ||
| 9459 | + description: "1-D. The `shape` of the first `SparseTensor`, size `[ndims]` Vector." | ||
| 9460 | 9460 | type: DT_INT64 | |
| 9461 | 9461 | } | |
| 9462 | 9462 | input_arg { | |
| 9463 | 9463 | name: "b_indices" | |
| 9464 | - description: "2-D. The `indices` of the second `SparseTensor`, size `[nnz, 2]` Matrix." | ||
| 9464 | + description: "2-D. The `indices` of the second `SparseTensor`, size `[nnz, ndims]` Matrix." | ||
| 9465 | 9465 | type: DT_INT64 | |
| 9466 | 9466 | } | |
| 9467 | 9467 | input_arg { | |
@@ -9471,7 +9471,7 @@ op { | |||
| 9471 | 9471 | } | |
| 9472 | 9472 | input_arg { | |
| 9473 | 9473 | name: "b_shape" | |
| 9474 | - description: "1-D. The `shape` of the second `SparseTensor`, size `[2]` Vector." | ||
| 9474 | + description: "1-D. The `shape` of the second `SparseTensor`, size `[ndims]` Vector." | ||
| 9475 | 9475 | type: DT_INT64 | |
| 9476 | 9476 | } | |
| 9477 | 9477 | input_arg { | |
@@ -9533,6 +9533,63 @@ op { | |||
| 9533 | 9533 | summary: "Adds two `SparseTensor` objects to produce another `SparseTensor`." | |
| 9534 | 9534 | description: "The input `SparseTensor` objects\' indices are assumed ordered in standard\nlexicographic order. If this is not the case, before this step run\n`SparseReorder` to restore index ordering.\n\nBy default, if two values sum to zero at some index, the output `SparseTensor`\nwould still include that particular location in its index, storing a zero in the\ncorresponding value slot. To override this, callers can specify `thresh`,\nindicating that if the sum has a magnitude strictly smaller than `thresh`, its\ncorresponding value and index would then not be included. In particular,\n`thresh == 0` (default) means everything is kept and actual thresholding happens\nonly for a positive value.\n\nIn the following shapes, `nnz` is the count after taking `thresh` into account." | |
| 9535 | 9535 | } | |
| 9536 | + op { | ||
| 9537 | + name: "SparseAddGrad" | ||
| 9538 | + input_arg { | ||
| 9539 | + name: "backprop_val_grad" | ||
| 9540 | + description: "1-D with shape `[nnz(sum)]`. The gradient with respect to\nthe non-empty values of the sum." | ||
| 9541 | + type_attr: "T" | ||
| 9542 | + } | ||
| 9543 | + input_arg { | ||
| 9544 | + name: "a_indices" | ||
| 9545 | + description: "2-D. The `indices` of the `SparseTensor` A, size `[nnz(A), ndims]`." | ||
| 9546 | + type: DT_INT64 | ||
| 9547 | + } | ||
| 9548 | + input_arg { | ||
| 9549 | + name: "b_indices" | ||
| 9550 | + description: "2-D. The `indices` of the `SparseTensor` B, size `[nnz(B), ndims]`." | ||
| 9551 | + type: DT_INT64 | ||
| 9552 | + } | ||
| 9553 | + input_arg { | ||
| 9554 | + name: "sum_indices" | ||
| 9555 | + description: "2-D. The `indices` of the sum `SparseTensor`, size\n`[nnz(sum), ndims]`." | ||
| 9556 | + type: DT_INT64 | ||
| 9557 | + } | ||
| 9558 | + output_arg { | ||
| 9559 | + name: "a_val_grad" | ||
| 9560 | + description: "1-D with shape `[nnz(A)]`. The gradient with respect to the\nnon-empty values of A." | ||
| 9561 | + type_attr: "T" | ||
| 9562 | + } | ||
| 9563 | + output_arg { | ||
| 9564 | + name: "b_val_grad" | ||
| 9565 | + description: "1-D with shape `[nnz(B)]`. The gradient with respect to the\nnon-empty values of B." | ||
| 9566 | + type_attr: "T" | ||
| 9567 | + } | ||
| 9568 | + attr { | ||
| 9569 | + name: "T" | ||
| 9570 | + type: "type" | ||
| 9571 | + allowed_values { | ||
| 9572 | + list { | ||
| 9573 | + type: DT_FLOAT | ||
| 9574 | + type: DT_DOUBLE | ||
| 9575 | + type: DT_INT64 | ||
| 9576 | + type: DT_INT32 | ||
| 9577 | + type: DT_UINT8 | ||
| 9578 | + type: DT_UINT16 | ||
| 9579 | + type: DT_INT16 | ||
| 9580 | + type: DT_INT8 | ||
| 9581 | + type: DT_COMPLEX64 | ||
| 9582 | + type: DT_COMPLEX128 | ||
| 9583 | + type: DT_QINT8 | ||
| 9584 | + type: DT_QUINT8 | ||
| 9585 | + type: DT_QINT32 | ||
| 9586 | + type: DT_HALF | ||
| 9587 | + } | ||
| 9588 | + } | ||
| 9589 | + } | ||
| 9590 | + summary: "The gradient operator for the SparseAdd op." | ||
| 9591 | + description: "The SparseAdd op calculates A + B, where A, B, and the sum are all represented\nas `SparseTensor` objects. This op takes in the upstream gradient w.r.t.\nnon-empty values of the sum, and outputs the gradients w.r.t. the non-empty\nvalues of A and B." | ||
| 9592 | + } | ||
| 9536 | 9593 | op { | |
| 9537 | 9594 | name: "SparseApplyAdadelta" | |
| 9538 | 9595 | input_arg { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,6 +17,34 @@ limitations under the License. | |||
| 17 | 17 | ||
| 18 | 18 | namespace tensorflow { | |
| 19 | 19 | ||
| 20 | + REGISTER_OP("SparseAddGrad") | ||
| 21 | + .Input("backprop_val_grad: T") | ||
| 22 | + .Input("a_indices: int64") | ||
| 23 | + .Input("b_indices: int64") | ||
| 24 | + .Input("sum_indices: int64") | ||
| 25 | + .Output("a_val_grad: T") | ||
| 26 | + .Output("b_val_grad: T") | ||
| 27 | + .Attr("T: numbertype") | ||
| 28 | + .Doc(R"doc( | ||
| 29 | + The gradient operator for the SparseAdd op. | ||
| 30 | + | ||
| 31 | + The SparseAdd op calculates A + B, where A, B, and the sum are all represented | ||
| 32 | + as `SparseTensor` objects. This op takes in the upstream gradient w.r.t. | ||
| 33 | + non-empty values of the sum, and outputs the gradients w.r.t. the non-empty | ||
| 34 | + values of A and B. | ||
| 35 | + | ||
| 36 | + backprop_val_grad: 1-D with shape `[nnz(sum)]`. The gradient with respect to | ||
| 37 | + the non-empty values of the sum. | ||
| 38 | + a_indices: 2-D. The `indices` of the `SparseTensor` A, size `[nnz(A), ndims]`. | ||
| 39 | + b_indices: 2-D. The `indices` of the `SparseTensor` B, size `[nnz(B), ndims]`. | ||
| 40 | + sum_indices: 2-D. The `indices` of the sum `SparseTensor`, size | ||
| 41 | + `[nnz(sum), ndims]`. | ||
| 42 | + a_val_grad: 1-D with shape `[nnz(A)]`. The gradient with respect to the | ||
| 43 | + non-empty values of A. | ||
| 44 | + b_val_grad: 1-D with shape `[nnz(B)]`. The gradient with respect to the | ||
| 45 | + non-empty values of B. | ||
| 46 | + )doc"); | ||
| 47 | + | ||
| 20 | 48 | REGISTER_OP("SparseAdd") | |
| 21 | 49 | .Input("a_indices: int64") | |
| 22 | 50 | .Input("a_values: T") | |
@@ -47,12 +75,12 @@ only for a positive value. | |||
| 47 | 75 | ||
| 48 | 76 | In the following shapes, `nnz` is the count after taking `thresh` into account. | |
| 49 | 77 | ||
| 50 | - a_indices: 2-D. The `indices` of the first `SparseTensor`, size `[nnz, 2]` Matrix. | ||
| 78 | + a_indices: 2-D. The `indices` of the first `SparseTensor`, size `[nnz, ndims]` Matrix. | ||
| 51 | 79 | a_values: 1-D. The `values` of the first `SparseTensor`, size `[nnz]` Vector. | |
| 52 | - a_shape: 1-D. The `shape` of the first `SparseTensor`, size `[2]` Vector. | ||
| 53 | - b_indices: 2-D. The `indices` of the second `SparseTensor`, size `[nnz, 2]` Matrix. | ||
| 80 | + a_shape: 1-D. The `shape` of the first `SparseTensor`, size `[ndims]` Vector. | ||
| 81 | + b_indices: 2-D. The `indices` of the second `SparseTensor`, size `[nnz, ndims]` Matrix. | ||
| 54 | 82 | b_values: 1-D. The `values` of the second `SparseTensor`, size `[nnz]` Vector. | |
| 55 | - b_shape: 1-D. The `shape` of the second `SparseTensor`, size `[2]` Vector. | ||
| 83 | + b_shape: 1-D. The `shape` of the second `SparseTensor`, size `[ndims]` Vector. | ||
| 56 | 84 | thresh: 0-D. The magnitude threshold that determines if an output value/index | |
| 57 | 85 | pair takes space. | |
| 58 | 86 | )doc"); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -704,6 +704,7 @@ tf_gen_op_wrapper_py( | |||
| 704 | 704 | "SerializeManySparse", | |
| 705 | 705 | "SerializeSparse", | |
| 706 | 706 | "SparseAdd", | |
| 707 | + "SparseAddGrad", | ||
| 707 | 708 | "SparseConcat", | |
| 708 | 709 | "SparseSplit", | |
| 709 | 710 | "SparseSelectLastK", | |
| Back | FazBrowse Home | New Git URL |
0 commit comments