diff --git a/tfjs-backend-wasm/src/cc/BUILD b/tfjs-backend-wasm/src/cc/BUILD index 6f4ead29a09..0ff565614c9 100644 --- a/tfjs-backend-wasm/src/cc/BUILD +++ b/tfjs-backend-wasm/src/cc/BUILD @@ -28,6 +28,12 @@ cc_binary( ], ) +test_suite( + name = "cc_tests" +) + +## Library + tfjs_cc_library( name = "backend", srcs = ["backend.cc"], @@ -39,45 +45,52 @@ tfjs_cc_library( ], ) -tfjs_cc_library( - name = "check_macros", - srcs = ["check_macros.h"], +tfjs_unit_test( + name = "backend_tests", + srcs = glob(["*_test.cc"]), deps = [ + ":backend", ":util", - ], + ":Prelu", + ] ) tfjs_cc_library( - name = "unary", - srcs = ["unary.h"], + name = "binary", + hdrs = ["binary.h"], + srcs = ["binary.cc"], deps = [ ":backend", ], ) tfjs_cc_library( - name = "binary", - hdrs = ["binary.h"], - srcs = ["binary.cc"], + name = "check_macros", + srcs = ["check_macros.h"], deps = [ - ":backend", + ":util", ], ) tfjs_cc_library( - name = "transpose_impl", - hdrs = ["transpose_impl.h"], - srcs = ["transpose_impl.cc"], - deps = [":util"], + name = "clamp_impl", + hdrs = ["clamp_impl.h"], + srcs = ["clamp_impl.cc"], + deps = [ + ":backend", + ":util" + ], ) tfjs_cc_library( - name = "prelu_impl", - hdrs = ["prelu_impl.h"], - srcs = ["prelu_impl.cc"], + name = "conv2d_impl", + hdrs = ["conv2d_impl.h"], + srcs = ["conv2d_impl.cc"], deps = [ ":backend", - ":util" + ":transpose_impl", + ":prelu_impl", + ":util", ], ) @@ -92,27 +105,38 @@ tfjs_cc_library( ) tfjs_cc_library( - name = "conv2d_impl", - hdrs = ["conv2d_impl.h"], - srcs = ["conv2d_impl.cc"], + name = "prelu_impl", + hdrs = ["prelu_impl.h"], + srcs = ["prelu_impl.cc"], deps = [ ":backend", - ":transpose_impl", - ":prelu_impl", - ":util", + ":util" ], ) tfjs_cc_library( - name = "clamp_impl", - hdrs = ["clamp_impl.h"], - srcs = ["clamp_impl.cc"], + name = "transpose_impl", + hdrs = ["transpose_impl.h"], + srcs = ["transpose_impl.cc"], + deps = [":util"], +) + +tfjs_cc_library( + name = "util", + hdrs = ["util.h"], + srcs = ["util.cc"], +) + +tfjs_cc_library( + name = "unary", + srcs = ["unary.h"], deps = [ ":backend", - ":util" ], ) +# Kernels + tfjs_cc_library( name = "all_kernels", deps = [ @@ -122,17 +146,21 @@ tfjs_cc_library( ":AddN", ":ArgMax", ":BatchMatMul", - ":MaxPool", + ":Div", ":ClipByValue", ":CropAndResize", ":Conv2D", ":DepthwiseConv2dNative", + ":Exp", ":FloorDiv", - ":Minimum", - ":Maximum", + ":FusedBatchNorm", ":FusedConv2D", ":FusedDepthwiseConv2D", - ":Div", + ":Max", + ":Maximum", + ":MaxPool", + ":Minimum", + ":Min", ":Mul", ":NonMaxSuppressionV3", ":PadV2", @@ -140,9 +168,6 @@ tfjs_cc_library( ":Relu", ":Relu6", ":ResizeBilinear", - ":FusedBatchNorm", - ":Max", - ":Min", ":Sigmoid", ":Sub", ":Transpose", @@ -150,28 +175,27 @@ tfjs_cc_library( ) tfjs_cc_library( - name = "MaxPool", - srcs = ["kernels/MaxPool.cc"], - hdrs = ["kernels/MaxPool.h"], + name = "Abs", + srcs = ["kernels/Abs.cc"], deps = [ ":backend", - ":util" - ] + ":unary", + ], ) tfjs_cc_library( - name = "AvgPool", - srcs = ["kernels/AvgPool.cc"], - hdrs = ["kernels/AvgPool.h"], + name = "Add", + srcs = ["kernels/Add.cc"], deps = [ ":backend", - ":util" - ] + ":binary", + ":util", + ], ) tfjs_cc_library( - name = "FusedBatchNorm", - srcs = ["kernels/FusedBatchNorm.cc"], + name = "AddN", + srcs = ["kernels/AddN.cc"], deps = [ ":backend", ":util", @@ -179,8 +203,8 @@ tfjs_cc_library( ) tfjs_cc_library( - name = "Max", - srcs = ["kernels/Max.cc"], + name = "ArgMax", + srcs = ["kernels/ArgMax.cc"], deps = [ ":backend", ":util", @@ -188,85 +212,135 @@ tfjs_cc_library( ) tfjs_cc_library( - name = "Min", - srcs = ["kernels/Min.cc"], + name = "AvgPool", + srcs = ["kernels/AvgPool.cc"], + hdrs = ["kernels/AvgPool.h"], deps = [ ":backend", - ":util", - ], + ":util" + ] +) + +tfjs_unit_test( + name = "AvgPool_test", + srcs = ["kernels/AvgPool_test.cc"], + deps = [ + ":AvgPool" + ] ) tfjs_cc_library( - name = "Abs", - srcs = ["kernels/Abs.cc"], + name = "BatchMatMul", + srcs = ["kernels/BatchMatMul.cc"], + hdrs = ["kernels/BatchMatMul.h"], deps = [ ":backend", - ":unary", + ":util", ], ) +tfjs_unit_test( + name = "BatchMatMul_test", + srcs = ["kernels/BatchMatMul_test.cc"], + deps = [ + ":BatchMatMul", + ] +) + tfjs_cc_library( - name = "Add", - srcs = ["kernels/Add.cc"], + name = "ClipByValue", + hdrs = ["kernels/ClipByValue.h"], + srcs = ["kernels/ClipByValue.cc"], deps = [ ":backend", - ":binary", ":util", ], ) +tfjs_unit_test( + name = "ClipByValue_test", + srcs = ["kernels/ClipByValue_test.cc"], + deps = [ + ":ClipByValue", + ] +) + tfjs_cc_library( - name = "AddN", - srcs = ["kernels/AddN.cc"], + name = "Conv2D", + srcs = ["kernels/Conv2D.cc"], + hdrs = ["kernels/Conv2D.h"], deps = [ - ":backend", - ":util", + ":conv2d_impl", ], ) +tfjs_unit_test( + name = "Conv2D_test", + srcs = ["kernels/Conv2D_test.cc"], + deps = [ + ":Conv2D", + ] +) + tfjs_cc_library( - name = "ArgMax", - srcs = ["kernels/ArgMax.cc"], + name = "CropAndResize", + srcs = ["kernels/CropAndResize.cc"], deps = [ ":backend", + ":interpolate_bilinear_impl", ":util", ], ) tfjs_cc_library( - name = "BatchMatMul", - srcs = ["kernels/BatchMatMul.cc"], - hdrs = ["kernels/BatchMatMul.h"], + name = "DepthwiseConv2dNative", + srcs = ["kernels/DepthwiseConv2dNative.cc"], + hdrs = ["kernels/DepthwiseConv2dNative.h"], + deps = [ + ":conv2d_impl", + ], +) + +tfjs_unit_test( + name = "DepthwiseConv2dNative_test", + srcs = ["kernels/DepthwiseConv2dNative_test.cc"], + deps = [ + ":DepthwiseConv2dNative", + ] +) + +tfjs_cc_library( + name = "Div", + srcs = ["kernels/Div.cc"], deps = [ ":backend", + ":binary", ":util", ], ) tfjs_cc_library( - name = "ClipByValue", - hdrs = ["kernels/ClipByValue.h"], - srcs = ["kernels/ClipByValue.cc"], + name = "Exp", + srcs = ["kernels/Exp.cc"], deps = [ ":backend", - ":util", + ":unary", ], ) tfjs_cc_library( - name = "CropAndResize", - srcs = ["kernels/CropAndResize.cc"], + name = "FloorDiv", + srcs = ["kernels/FloorDiv.cc"], deps = [ ":backend", - ":interpolate_bilinear_impl", + ":binary", ":util", ], ) tfjs_cc_library( - name = "ResizeBilinear", - srcs = ["kernels/ResizeBilinear.cc"], - hdrs = ["kernels/ResizeBilinear.h"], + name = "FusedBatchNorm", + srcs = ["kernels/FusedBatchNorm.cc"], deps = [ ":backend", ":util", @@ -274,30 +348,53 @@ tfjs_cc_library( ) tfjs_cc_library( - name = "Conv2D", - srcs = ["kernels/Conv2D.cc"], - hdrs = ["kernels/Conv2D.h"], + name = "FusedConv2D", + srcs = ["kernels/FusedConv2D.cc"], + hdrs = ["kernels/FusedConv2D.h"], deps = [ ":conv2d_impl", ], ) +tfjs_unit_test( + name = "FusedConv2D_test", + srcs = ["kernels/FusedConv2D_test.cc"], + deps = [ + ":FusedConv2D", + ] +) + tfjs_cc_library( - name = "FloorDiv", - srcs = ["kernels/FloorDiv.cc"], + name = "FusedDepthwiseConv2D", + srcs = ["kernels/FusedDepthwiseConv2D.cc"], + hdrs = ["kernels/FusedDepthwiseConv2D.h"], + deps = [ + ":conv2d_impl", + ], +) + +tfjs_unit_test( + name = "FusedDepthwiseConv2D_test", + srcs = ["kernels/FusedDepthwiseConv2D_test.cc"], + deps = [ + ":FusedDepthwiseConv2D", + ] +) + +tfjs_cc_library( + name = "Log", + srcs = ["kernels/Log.cc"], deps = [ ":backend", - ":binary", - ":util", + ":unary", ], ) tfjs_cc_library( - name = "Minimum", - srcs = ["kernels/Minimum.cc"], + name = "Max", + srcs = ["kernels/Max.cc"], deps = [ ":backend", - ":binary", ":util", ], ) @@ -313,35 +410,35 @@ tfjs_cc_library( ) tfjs_cc_library( - name = "FusedConv2D", - srcs = ["kernels/FusedConv2D.cc"], - hdrs = ["kernels/FusedConv2D.h"], + name = "MaxPool", + srcs = ["kernels/MaxPool.cc"], + hdrs = ["kernels/MaxPool.h"], deps = [ - ":conv2d_impl", - ], + ":backend", + ":util" + ] ) -tfjs_cc_library( - name = "FusedDepthwiseConv2D", - srcs = ["kernels/FusedDepthwiseConv2D.cc"], - hdrs = ["kernels/FusedDepthwiseConv2D.h"], +tfjs_unit_test( + name = "MaxPool_test", + srcs = ["kernels/MaxPool_test.cc"], deps = [ - ":conv2d_impl", - ], + ":MaxPool" + ] ) tfjs_cc_library( - name = "DepthwiseConv2dNative", - srcs = ["kernels/DepthwiseConv2dNative.cc"], - hdrs = ["kernels/DepthwiseConv2dNative.h"], + name = "Min", + srcs = ["kernels/Min.cc"], deps = [ - ":conv2d_impl", + ":backend", + ":util", ], ) tfjs_cc_library( - name = "Div", - srcs = ["kernels/Div.cc"], + name = "Minimum", + srcs = ["kernels/Minimum.cc"], deps = [ ":backend", ":binary", @@ -388,13 +485,12 @@ tfjs_cc_library( ], ) -tfjs_cc_library( - name = "Sigmoid", - srcs = ["kernels/Sigmoid.cc"], +tfjs_unit_test( + name = "Prelu_test", + srcs = ["kernels/Prelu_test.cc"], deps = [ - ":backend", - ":unary", - ], + ":Prelu", + ] ) tfjs_cc_library( @@ -418,37 +514,35 @@ tfjs_cc_library( ) tfjs_cc_library( - name = "Square", - srcs = ["kernels/Square.cc"], + name = "ResizeBilinear", + srcs = ["kernels/ResizeBilinear.cc"], + hdrs = ["kernels/ResizeBilinear.h"], deps = [ ":backend", - ":unary", + ":util", ], ) -tfjs_cc_library( - name = "Sub", - srcs = ["kernels/Sub.cc"], +tfjs_unit_test( + name = "ResizeBilinear_test", + srcs = ["kernels/ResizeBilinear_test.cc"], deps = [ - ":backend", - ":binary", - ":util", - ], + ":ResizeBilinear", + ] ) tfjs_cc_library( - name = "Transpose", - srcs = ["kernels/Transpose.cc"], + name = "Sigmoid", + srcs = ["kernels/Sigmoid.cc"], deps = [ ":backend", - ":util", - ":transpose_impl", + ":unary", ], ) tfjs_cc_library( - name = "Exp", - srcs = ["kernels/Exp.cc"], + name = "Square", + srcs = ["kernels/Square.cc"], deps = [ ":backend", ":unary", @@ -456,102 +550,21 @@ tfjs_cc_library( ) tfjs_cc_library( - name = "util", - hdrs = ["util.h"], - srcs = ["util.cc"], -) - -test_suite( - name = "cc_tests" -) - -tfjs_unit_test( - name = "backend_tests", - srcs = glob(["*_test.cc"]), + name = "Sub", + srcs = ["kernels/Sub.cc"], deps = [ ":backend", + ":binary", ":util", - ":Prelu", - ] -) - -tfjs_unit_test( - name = "BatchMatMul_test", - srcs = ["kernels/BatchMatMul_test.cc"], - deps = [ - ":BatchMatMul", - ] -) - -tfjs_unit_test( - name = "Prelu_test", - srcs = ["kernels/Prelu_test.cc"], - deps = [ - ":Prelu", - ] -) - -tfjs_unit_test( - name = "Conv2D_test", - srcs = ["kernels/Conv2D_test.cc"], - deps = [ - ":Conv2D", - ] -) - -tfjs_unit_test( - name = "DepthwiseConv2dNative_test", - srcs = ["kernels/DepthwiseConv2dNative_test.cc"], - deps = [ - ":DepthwiseConv2dNative", - ] -) - -tfjs_unit_test( - name = "FusedConv2D_test", - srcs = ["kernels/FusedConv2D_test.cc"], - deps = [ - ":FusedConv2D", - ] -) - -tfjs_unit_test( - name = "FusedDepthwiseConv2D_test", - srcs = ["kernels/FusedDepthwiseConv2D_test.cc"], - deps = [ - ":FusedDepthwiseConv2D", - ] -) - -tfjs_unit_test( - name = "AvgPool_test", - srcs = ["kernels/AvgPool_test.cc"], - deps = [ - ":AvgPool" - ] -) - -tfjs_unit_test( - name = "MaxPool_test", - srcs = ["kernels/MaxPool_test.cc"], - deps = [ - ":MaxPool" - ] -) - -tfjs_unit_test( - name = "ClipByValue_test", - srcs = ["kernels/ClipByValue_test.cc"], - deps = [ - ":ClipByValue", - ] + ], ) -tfjs_unit_test( - name = "ResizeBilinear_test", - srcs = ["kernels/ResizeBilinear_test.cc"], +tfjs_cc_library( + name = "Transpose", + srcs = ["kernels/Transpose.cc"], deps = [ - ":ResizeBilinear", - ] + ":backend", + ":util", + ":transpose_impl", + ], ) - diff --git a/tfjs-backend-wasm/src/cc/kernels/Log.cc b/tfjs-backend-wasm/src/cc/kernels/Log.cc new file mode 100644 index 00000000000..a333258bf47 --- /dev/null +++ b/tfjs-backend-wasm/src/cc/kernels/Log.cc @@ -0,0 +1,36 @@ +/* Copyright 2019 Google Inc. 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. + * ===========================================================================*/ + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include + +#include "src/cc/backend.h" +#include "src/cc/unary.h" + +namespace tfjs { +namespace wasm { +// We use C-style API to interface with Javascript. +extern "C" { + +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_KEEPALIVE +#endif +void Log(const int x_id, const int out_id) { unary(x_id, out_id, std::log); } + +} // extern "C" +} // namespace wasm +} // namespace tfjs diff --git a/tfjs-backend-wasm/src/kernels/Log.ts b/tfjs-backend-wasm/src/kernels/Log.ts new file mode 100644 index 00000000000..402abc04861 --- /dev/null +++ b/tfjs-backend-wasm/src/kernels/Log.ts @@ -0,0 +1,19 @@ +/** + * @license + * Copyright 2019 Google Inc. 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. + * ============================================================================= + */ + +import {registerUnaryKernel} from './unary_kernel'; +registerUnaryKernel('Log'); diff --git a/tfjs-backend-wasm/src/kernels/all_kernels.ts b/tfjs-backend-wasm/src/kernels/all_kernels.ts index 9bf8e7a36ae..d96f3151465 100644 --- a/tfjs-backend-wasm/src/kernels/all_kernels.ts +++ b/tfjs-backend-wasm/src/kernels/all_kernels.ts @@ -36,6 +36,7 @@ import './FloorDiv'; import './FusedBatchNorm'; import './FusedConv2D'; import './FusedDepthwiseConv2D'; +import './Log'; import './Max'; import './Maximum'; import './MaxPool'; diff --git a/tfjs-backend-wasm/src/setup_test.ts b/tfjs-backend-wasm/src/setup_test.ts index 2d922483d16..3b9a225b10b 100644 --- a/tfjs-backend-wasm/src/setup_test.ts +++ b/tfjs-backend-wasm/src/setup_test.ts @@ -198,19 +198,22 @@ const TEST_FILTERS: TestFilter[] = [ { include: 'minimum', excludes: [ - 'gradient', // Not yet implemented. - 'broadcasts 2x1 Tensor2D and 2x2 Tensor2D' // Broadcasting along inner - // dims not supported yet. + 'gradient', // Not yet implemented. + 'broadcasts 2x1 Tensor2D and 2x2 Tensor2D' // Broadcasting along inner + // dims not supported yet. ] }, { include: 'maximum', excludes: [ - 'gradient', // Not yet implemented. - 'broadcasts 2x1 Tensor2D and 2x2 Tensor2D' // Broadcasting along inner - // dims not supported yet. + 'gradient', // Not yet implemented. + 'broadcasts 2x1 Tensor2D and 2x2 Tensor2D' // Broadcasting along inner + // dims not supported yet. ] }, + { + include: 'log ', + } ]; const customInclude = (testName: string) => { diff --git a/tfjs-core/src/ops/unary_ops.ts b/tfjs-core/src/ops/unary_ops.ts index 3586397bc61..1e3cdbe3850 100644 --- a/tfjs-core/src/ops/unary_ops.ts +++ b/tfjs-core/src/ops/unary_ops.ts @@ -266,13 +266,17 @@ function log_(x: T|TensorLike): T { const grad = (dy: T, saved: Tensor[]) => { const [$x] = saved; - return {$x: () => dy.div($x.toFloat())} as {$x: () => T}; + return {x: () => dy.div($x.toFloat())} as {x: () => T}; }; + + const attrs = {}; + const inputsToSave = [$x]; + return ENGINE.runKernelFunc((backend, save) => { const res = backend.log($x); save([$x]); return res; - }, {$x}, grad); + }, {x: $x}, grad, 'Log', attrs, inputsToSave); } /**