From 5a9cd25aa9e2338887dc4b6fd4296b6bd26a7f14 Mon Sep 17 00:00:00 2001 From: Patrick Wieschollek Date: Sun, 23 Sep 2018 12:07:50 +0200 Subject: [PATCH] cherry pick files for public release --- .drone.yml | 10 + .github/flexconv.jpg | Bin 0 -> 344862 bytes .gitignore | 136 +++++ CPPLINT.cfg | 1 + LICENSE | 201 +++++++ README.md | 60 ++ example.py | 47 ++ layers.py | 215 +++++++ setup.cfg | 3 + user_ops/CMakeLists.txt | 40 ++ user_ops/FindTensorFlow.cmake | 273 +++++++++ user_ops/PointTestCase.py | 130 +++++ user_ops/__init__.py | 176 ++++++ user_ops/kernels/flex_conv_kernel.cc | 173 ++++++ user_ops/kernels/flex_conv_kernel_gpu.cu.cc | 532 ++++++++++++++++++ user_ops/kernels/flex_conv_op.cc | 122 ++++ user_ops/kernels/flex_conv_op.h | 53 ++ user_ops/kernels/flex_deconv_kernel.cc | 173 ++++++ user_ops/kernels/flex_deconv_kernel_gpu.cu.cc | 227 ++++++++ user_ops/kernels/flex_deconv_op.cc | 103 ++++ user_ops/kernels/flex_deconv_op.h | 53 ++ user_ops/kernels/flex_pool_kernel.cc | 102 ++++ user_ops/kernels/flex_pool_kernel_gpu.cu.cc | 171 ++++++ user_ops/kernels/flex_pool_op.cc | 113 ++++ user_ops/kernels/flex_pool_op.h | 50 ++ user_ops/ops/flex_conv.cc | 133 +++++ user_ops/ops/flex_deconv.cc | 129 +++++ user_ops/ops/flex_pool.cc | 93 +++ user_ops/profile_flexconv.py | 116 ++++ user_ops/test_flex_convolution.py | 109 ++++ user_ops/test_flex_convolution_transpose.py | 116 ++++ user_ops/test_flex_pooling.py | 87 +++ 32 files changed, 3947 insertions(+) create mode 100644 .drone.yml create mode 100644 .github/flexconv.jpg create mode 100644 .gitignore create mode 100644 CPPLINT.cfg create mode 100644 LICENSE create mode 100644 README.md create mode 100644 example.py create mode 100644 layers.py create mode 100644 setup.cfg create mode 100644 user_ops/CMakeLists.txt create mode 100644 user_ops/FindTensorFlow.cmake create mode 100644 user_ops/PointTestCase.py create mode 100644 user_ops/__init__.py create mode 100644 user_ops/kernels/flex_conv_kernel.cc create mode 100644 user_ops/kernels/flex_conv_kernel_gpu.cu.cc create mode 100644 user_ops/kernels/flex_conv_op.cc create mode 100644 user_ops/kernels/flex_conv_op.h create mode 100644 user_ops/kernels/flex_deconv_kernel.cc create mode 100644 user_ops/kernels/flex_deconv_kernel_gpu.cu.cc create mode 100644 user_ops/kernels/flex_deconv_op.cc create mode 100644 user_ops/kernels/flex_deconv_op.h create mode 100644 user_ops/kernels/flex_pool_kernel.cc create mode 100644 user_ops/kernels/flex_pool_kernel_gpu.cu.cc create mode 100644 user_ops/kernels/flex_pool_op.cc create mode 100644 user_ops/kernels/flex_pool_op.h create mode 100644 user_ops/ops/flex_conv.cc create mode 100644 user_ops/ops/flex_deconv.cc create mode 100644 user_ops/ops/flex_pool.cc create mode 100644 user_ops/profile_flexconv.py create mode 100644 user_ops/test_flex_convolution.py create mode 100644 user_ops/test_flex_convolution_transpose.py create mode 100644 user_ops/test_flex_pooling.py diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..d48cbda --- /dev/null +++ b/.drone.yml @@ -0,0 +1,10 @@ +pipeline: + custom_op: + image: tensorflow:ubuntu16.04-cuda9.2-bazel0.16.1-tensorflow1.10.0 + environment: + - CUB_INC=/extra/cub-1.8.0/ + commands: + - export LD_LIBRARY_PATH=/usr/local/cuda/lib64/stubs:$${LD_LIBRARY_PATH} + - cd user_ops + - cmake . -DPYTHON_EXECUTABLE=python2 + - make diff --git a/.github/flexconv.jpg b/.github/flexconv.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e93931ca2e4a79e98b9f50eb1aea535fbbbc0e19 GIT binary patch literal 344862 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

prV>1WE<3pg2O|;o;V|`!akABQ(=g}2C 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

a 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%0DF{%yK34U`pb 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≥#;yY&bF|NR|6t;gaf$o6BZd_L9j9w2 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 b!N7ko@E;8P2Lu1Xz<)6Ce*y-=?&tn5-wSdO literal 0 HcmV?d00001 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f5c4259 --- /dev/null +++ b/.gitignore @@ -0,0 +1,136 @@ +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +### Python Patch ### +.venv/ + + +### CMake ### +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake + + +### custom ### + +user_ops/.profiling_outputs + +.project +.cproject +tensorflow_config.txt + +.vscode +.cquery + +.settings +.local/ +local/ diff --git a/CPPLINT.cfg b/CPPLINT.cfg new file mode 100644 index 0000000..9b48e1a --- /dev/null +++ b/CPPLINT.cfg @@ -0,0 +1 @@ +filter=-legal/copyright,-readability/casting,-build/include_subdir,-whitespace/tab \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..06e5dd5 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# Flex-Convolution (Million-Scale Pointcloud Learning Beyond Grid-Worlds) +Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +![Build Status TensorFlow v1.10 ](https://ci.patwie.com/api/badges/cgtuebingen/Flex-Convolution/status.svg) + +Abstract +------------------- + +Traditional convolution layers are specifically designed to exploit the natural data representation of images -- a fixed and regular grid. However, unstructured data like 3D point clouds containing irregular neighborhoods constantly breaks the grid-based data assumption. Therefore applying best-practices and design choices from 2D-image learning methods towards processing point clouds are not readily possible. In this work, we introduce a natural generalization flex-convolution of the conventional convolution layer along with an efficient GPU implementation. We demonstrate competitive performance on rather small benchmark sets using fewer parameters and lower memory consumption and obtain significant improvements on a million-scale real-world dataset. Ours is the first which allows to efficiently process 7 million points concurrently. + + +The following figure shows the *raw* network semantic segmentation prediction on a real-world example: + +

+ + +This repository contains contains the source code of our FlexConv Layer from our 2018 ACCV paper "Flex-Convolution (Million-Scale Pointcloud Learning Beyond Grid-Worlds)". + +Example - Usage +------------------- + +We provide GPU-tailored cuda implementation of our novel FlexConv in TensorFlow. + +```console +user@host $ cd user_ops +user@host $ cmake . -DPYTHON_EXECUTABLE=python2 && make -j +user@host $ cd .. +user@host $ python example +``` + + +Experiments +------------------- + +Deep learning on point-clouds is a complex matter and our codebase reflect that complexity. +We are currently working on refactoring our research implementation to ease the usage. Therefore, +`layers.py` contains a Keras/tf.layers compatible implementation. + +More Resources +------------------- + +- [Arxiv Pre-Print](https://arxiv.org/abs/1803.07289) +- [Video](https://www.youtube.com/watch?v=5ftWmuQXU_s) + + +Citation +------------------- +If you use the code in this repository, please cite our paper: +``` +@inproceedings{accv2018/Groh, + author = {Fabian Groh and + Patrick Wieschollek and + Hendrik P. A. Lensch + }, + title = {Flex-Convolution (Million-Scale Pointcloud Learning Beyond Grid-Worlds)}, + booktitle = {Asian Conference on Computer Vision (ACCV)}, + month = {Dezember}, + year = {2018} +} +``` diff --git a/example.py b/example.py new file mode 100644 index 0000000..1d07355 --- /dev/null +++ b/example.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2017 ComputerGraphics Tuebingen. 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. +# ============================================================================== +# Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + + +""" +Demonstration of using FlexConvolution Layer. +""" + +import numpy as np +import tensorflow as tf +from layers import flex_convolution + +B, Din, Dout, Dp, N, K = 1, 2, 4, 3, 10, 5 + +features = np.random.randn(B, Din, N).astype(np.float32) +positions = np.random.randn(B, Dp, N).astype(np.float32) +neighbors = np.random.randint(0, N, [B, K, N]).astype(np.int32) + +features = tf.convert_to_tensor(features) +positions = tf.convert_to_tensor(positions) +neighbors = tf.convert_to_tensor(neighbors) + +features2 = flex_convolution(features, positions, neighbors, Dout) +features3 = flex_convolution(features2, positions, neighbors, Dout, trainable=False) + +with tf.Session() as sess: + sess.run(tf.global_variables_initializer()) + sess.run(features2) + sess.run(features3) + + print(tf.trainable_variables()) diff --git a/layers.py b/layers.py new file mode 100644 index 0000000..ebbb13d --- /dev/null +++ b/layers.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- + +# Copyright 2017 ComputerGraphics Tuebingen. 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. +# ============================================================================== +# Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + + +import tensorflow as tf +from user_ops import flex_convolution as _flex_convolution +from user_ops import flex_pooling as _flex_pooling +from user_ops import flex_convolution_transpose as _flex_convolution_transpose + +from tensorflow.python.keras import activations +from tensorflow.python.keras import initializers +from tensorflow.python.keras.engine.base_layer import Layer +from tensorflow.python.util.tf_export import tf_export +from tensorflow.python.framework import tensor_shape +from tensorflow.python.framework import ops + +flex_pooling = _flex_pooling +flex_convolution_transpose = _flex_convolution_transpose + + +def _remove_dim(x, axis): + shape = x.shape.as_list() + assert shape[axis] == 1 + del shape[axis] + return tf.reshape(x, shape) + + +@tf_export('keras.layers.Dense') +class FlexConvolution(Layer): + """flex convolution layer. + + This layer convolves elements in arbitrary neighborhoods with a kernel to + produce a tensor of outputs. + If `use_feature_bias` is True (and a `features_bias_initializer` is provided), + a bias vector is created and added to the outputs after te convolution. + Finally, if `activation` is not `None`, it is applied to the outputs as well. + + Remarks: + In contrast to traditional convolutions, this operation has two + bias terms: + - bias term when dynamically computing the weight [Din, Dout] + - bias term which is added tot the features [Dout] + + Arguments: + features: A `Tensor` of the format [B, Din, (1), N]. + positions: A `Tensor` of the format [B, Dp, (1), N]. + neighborhoods: A `Tensor` of the format [B, K, (1), N] (tf.int32). + filters: Integer, the dimensionality of the output space (i.e. the number + of filters in the convolution). + activation: Activation function. Set it to None to maintain a + linear activation. + kernel_initializer: An initializer for the convolution kernel. + position_bias_initializer: An initializer for the bias vector within + the convolution. If None, the default initializer will be used. + features_bias_initializer: An initializer for the bias vector after + the convolution. If None, the default initializer will be used. + use_feature_bias: Boolean, whether the layer uses a bias. + data_format: A string, one of `simple` (default) or `expaned`. + If `simple` the shapes are [B, Din, N], when `expanded` the shapes + are assumed to be [B, Din, 1, N] to match `channels_first` in trad + convolutions. + trainable: Boolean, if `True` also add variables to the graph collection + `GraphKeys.TRAINABLE_VARIABLES` (see `tf.Variable`). + name: A string, the name of the layer. + + """ + + def __init__(self, + features, + positions, + neighborhoods, + filters, + activation=None, + kernel_initializer=None, + position_bias_initializer=tf.zeros_initializer(), + features_bias_initializer=tf.zeros_initializer(), + use_feature_bias=True, + data_format='simple', + trainable=True, + name=None): + + super(FlexConvolution, self).__init__(trainable=trainable, + name=name) + self.features = features + self.positions = positions + self.neighborhoods = neighborhoods + + self.filters = int(filters) + self.activation = activations.get(activation) + self.use_feature_bias = use_feature_bias + self.data_format = data_format + self.kernel_initializer = initializers.get(kernel_initializer) + self.position_bias_initializer = initializers.get(position_bias_initializer) + self.features_bias_initializer = initializers.get(features_bias_initializer) + + def compute_output_shape(self, input_shape): + input_shape = tensor_shape.TensorShape(input_shape) + input_shape[1] = self.filters + return input_shape + + def build(self, input_shape): + if self.data_format == 'expanded': + features = _remove_dim(self.features, 2) + positions = _remove_dim(self.positions, 2) + else: + features = self.features + positions = self.positions + + [B, Din, N] = features.shape + Din = int(Din) + N = int(N) + Dp = int(positions.shape[1]) + Dout = self.filters + + self.position_theta = self.add_weight( + 'position_theta', + shape=[1, Dp, Din, Dout], + initializer=self.kernel_initializer, + dtype=self.dtype, + trainable=True) + + self.position_bias = self.add_weight( + 'position_bias', + shape=[Din, Dout], + initializer=self.position_bias_initializer, + dtype=self.dtype, + trainable=True) + + if self.use_feature_bias: + self.feature_bias = self.add_weight( + 'feature_bias', + shape=[Dout, 1], + initializer=self.features_bias_initializer, + dtype=self.dtype, + trainable=True) + else: + self.feature_bias = None + self.built = True + + def call(self, inputs): + + if not isinstance(inputs, list): + raise ValueError('A flexconv layer should be called ' + 'on a list of inputs.') + + features = ops.convert_to_tensor(inputs[0], dtype=self.dtype) + positions = ops.convert_to_tensor(inputs[1], dtype=self.dtype) + neighborhoods = ops.convert_to_tensor(inputs[2], dtype=tf.int32) + + if self.data_format == 'expanded': + features = _remove_dim(inputs[0], 2) + positions = _remove_dim(inputs[1], 2) + neighborhoods = _remove_dim(inputs[2], 2) + else: + features = inputs[0] + positions = inputs[1] + neighborhoods = inputs[2] + + y = _flex_convolution(features, positions, neighborhoods, + self.position_theta, self.position_bias) + + if self.use_feature_bias: + y = tf.add(y, self.feature_bias) + + if self.activation is not None: + y = self.activation(y) + + if self.data_format == 'expanded': + y = tf.expand_dims(y, axis=2) + + return y + + +def flex_convolution(features, + positions, + neighborhoods, + filters, + activation=None, + kernel_initializer=None, + position_bias_initializer=tf.zeros_initializer(), + features_bias_initializer=tf.zeros_initializer(), + use_feature_bias=True, + data_format='simple', + trainable=True, + name=None): + + layer = FlexConvolution(features, + positions, + neighborhoods, + filters, + activation=activation, + kernel_initializer=kernel_initializer, + position_bias_initializer=position_bias_initializer, + features_bias_initializer=features_bias_initializer, + use_feature_bias=use_feature_bias, + data_format=data_format, + trainable=trainable, + name=name) + + return layer.apply([features, positions, neighborhoods]) diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..d882862 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,3 @@ +[flake8] +max-line-length = 120 +ignore = D102,E402,F403,N806,N802,N803,F405,E111,E114 \ No newline at end of file diff --git a/user_ops/CMakeLists.txt b/user_ops/CMakeLists.txt new file mode 100644 index 0000000..7b40ae9 --- /dev/null +++ b/user_ops/CMakeLists.txt @@ -0,0 +1,40 @@ +# University Tuebingen, 2018 +# Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +cmake_minimum_required( VERSION 2.8 ) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +project( FlexConv ) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) + +find_package(CUDA 9 REQUIRED) +find_package(TensorFlow REQUIRED) + + +if (DEFINED ENV{CUB_INC}) + message(STATUS "Use Cuda-CUB from " $ENV{CUB_INC}) + set(CUB_INC $ENV{CUB_INC}) +else() + message(FATAL_ERROR "requires 'export CUB_INC=/path/to/cub") +endif() + +# set necessary flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SSE_FLAGS} -march=native -fopenmp -O3 -D_GLIBCXX_USE_CXX11_ABI=${TensorFlow_ABI}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC --shared -D_GLIBCXX_USE_CXX11_ABI=${TensorFlow_ABI}" ) +set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -std=c++11 -O3 -Xptxas=-v --expt-relaxed-constexpr -D GOOGLE_CUDA=1 --gpu-architecture=sm_52 -D_GLIBCXX_USE_CXX11_ABI=${TensorFlow_ABI}" ) + +# quick fix for drone-ci +include_directories(SYSTEM "/usr/local/") +# fix cgtuebingen +include_directories(SYSTEM "/graphics/opt/opt_Ubuntu18.04/cuda/toolkit_9.2") + +include_directories(SYSTEM ${CUB_INC}) +include_directories(SYSTEM ${TensorFlow_INCLUDE_DIR}) +include_directories(SYSTEM kernels) + +add_tensorflow_gpu_operation("flex_conv") +add_tensorflow_gpu_operation("flex_deconv") +add_tensorflow_gpu_operation("flex_pool") diff --git a/user_ops/FindTensorFlow.cmake b/user_ops/FindTensorFlow.cmake new file mode 100644 index 0000000..d70a4b3 --- /dev/null +++ b/user_ops/FindTensorFlow.cmake @@ -0,0 +1,273 @@ +# Patrick Wieschollek, +# FindTENSORFLOW.cmake +# https://github.com/PatWie/tensorflow-cmake/blob/master/cmake/modules/FindTensorFlow.cmake +# ------------- +# +# Find TensorFlow library and includes +# +# Automatically set variables have prefix "TensorFlow", +# while variables you need to specify have prefix "TENSORFLOW" +# This module will set the following variables in your project: +# +# ``TensorFlow_VERSION`` +# exact TensorFlow version obtained from runtime +# ``TensorFlow_ABI`` +# ABI specification of TensorFlow library obtained from runtime +# ``TensorFlow_INCLUDE_DIR`` +# where to find tensorflow header files obtained from runtime +# ``TensorFlow_LIBRARY`` +# the libraries to link against to use TENSORFLOW obtained from runtime +# ``TensorFlow_FOUND TRUE`` +# If false, do not try to use TENSORFLOW. +# +# for some examples, you will need to specify on of the following paths +# ``TensorFlow_SOURCE_DIR`` +# Path to source of TensorFlow, when env-var 'TENSORFLOW_SOURCE_DIR' is set and path exists +# ``TensorFlow_C_LIBRARY`` +# Path to libtensorflow_cc.so (require env-var 'TENSORFLOW_BUILD_DIR') +# +# +# USAGE +# ------ +# add "list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}../../path/to/this/file)" to your project +# +# "add_tensorflow_gpu_operation" is a macro to compile a custom operation +# +# add_tensorflow_gpu_operation("") expects the following files to exists: +# - kernels/_kernel.cc +# - kernels/_kernel_gpu.cu.cc (kernels/_kernel.cu is supported as well) +# - kernels/_op.cc +# - kernels/_op.h +# - ops/.cc + +if(APPLE) + message(WARNING "This FindTensorflow.cmake is not tested on APPLE\n" + "Please report if this works\n" + "https://github.com/PatWie/tensorflow-cmake") +endif(APPLE) + +if(WIN32) + message(WARNING "This FindTensorflow.cmake is not tested on WIN32\n" + "Please report if this works\n" + "https://github.com/PatWie/tensorflow-cmake") +endif(WIN32) + +set(PYTHON_EXECUTABLE "python3" CACHE STRING "specify the python version TensorFlow is installed on.") + +if(TensorFlow_FOUND) + # reuse cached variables + message(STATUS "Reuse cached information from TensorFlow ${TensorFlow_VERSION} ") +else() + message(STATUS "Detecting TensorFlow using ${PYTHON_EXECUTABLE}" + " (use -DPYTHON_EXECUTABLE=... otherwise)") + execute_process( + COMMAND ${PYTHON_EXECUTABLE} -c "import tensorflow as tf; print(tf.__version__); print(tf.__cxx11_abi_flag__); print(tf.sysconfig.get_include()); print(tf.sysconfig.get_lib() + '/libtensorflow_framework.so')" + OUTPUT_VARIABLE TF_INFORMATION_STRING + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE retcode) + + if(NOT "${retcode}" STREQUAL "0") + message(FATAL_ERROR "Detecting TensorFlow info - failed \n Did you installed TensorFlow?") + else() + message(STATUS "Detecting TensorFlow info - done") + endif() + + string(REPLACE "\n" ";" TF_INFORMATION_LIST ${TF_INFORMATION_STRING}) + list(GET TF_INFORMATION_LIST 0 TF_DETECTED_VERSION) + list(GET TF_INFORMATION_LIST 1 TF_DETECTED_ABI) + list(GET TF_INFORMATION_LIST 2 TF_DETECTED_INCLUDE_DIR) + list(GET TF_INFORMATION_LIST 3 TF_DETECTED_LIBRARY) + + # set(TF_DETECTED_VERSION 1.8) + + set(_packageName "TF") + if (DEFINED TF_DETECTED_VERSION) + string (REGEX MATCHALL "[0-9]+" _versionComponents "${TF_DETECTED_VERSION}") + list (LENGTH _versionComponents _len) + if (${_len} GREATER 0) + list(GET _versionComponents 0 TF_DETECTED_VERSION_MAJOR) + endif() + if (${_len} GREATER 1) + list(GET _versionComponents 1 TF_DETECTED_VERSION_MINOR) + endif() + if (${_len} GREATER 2) + list(GET _versionComponents 2 TF_DETECTED_VERSION_PATCH) + endif() + if (${_len} GREATER 3) + list(GET _versionComponents 3 TF_DETECTED_VERSION_TWEAK) + endif() + set (TF_DETECTED_VERSION_COUNT ${_len}) + else() + set (TF_DETECTED_VERSION_COUNT 0) + endif() + + + # -- prevent pre 1.9 versions + # Note: TensorFlow 1.7 supported custom ops and all header files. + # TensorFlow 1.8 broke that promise and 1.9, 1.10 are fine again. + # This cmake-file is only tested against 1.9+. + if("${TF_DETECTED_VERSION}" VERSION_LESS "1.9") + message(FATAL_ERROR "Your installed TensorFlow version ${TF_DETECTED_VERSION} is too old.") + endif() + + if(TF_FIND_VERSION_EXACT) + # User requested exact match of TensorFlow. + # TensorFlow release cycles are currently just depending on (major, minor) + # But we test against both. + set(_TensorFlow_TEST_VERSIONS + "${TF_FIND_VERSION_MAJOR}.${TF_FIND_VERSION_MINOR}.${TF_FIND_VERSION_PATCH}" + "${TF_FIND_VERSION_MAJOR}.${TF_FIND_VERSION_MINOR}") + else(TF_FIND_VERSION_EXACT) + # User requested not an exact TensorFlow version. + # However, only TensorFlow versions 1.9, 1.10 support all header files + # for custom ops. + set(_TensorFlow_KNOWN_VERSIONS ${TensorFlow_ADDITIONAL_VERSIONS} + "1.9" "1.9.0" "1.10" "1.10.0") + set(_TensorFlow_TEST_VERSIONS) + + if(TF_FIND_VERSION) + set(_TF_FIND_VERSION_SHORT "${TF_FIND_VERSION_MAJOR}.${TF_FIND_VERSION_MINOR}") + # Select acceptable versions. + foreach(version ${_TensorFlow_KNOWN_VERSIONS}) + if(NOT "${version}" VERSION_LESS "${TF_FIND_VERSION}") + # This version is high enough. + list(APPEND _TensorFlow_TEST_VERSIONS "${version}") + endif() + endforeach(version) + else(TF_FIND_VERSION) + # Any version is acceptable. + set(_TensorFlow_TEST_VERSIONS "${_TensorFlow_KNOWN_VERSIONS}") + endif(TF_FIND_VERSION) + endif() + + # test all given versions + set(TensorFlow_FOUND FALSE) + FOREACH(_TensorFlow_VER ${_TensorFlow_TEST_VERSIONS}) + if("${TF_DETECTED_VERSION_MAJOR}.${TF_DETECTED_VERSION_MINOR}" STREQUAL "${_TensorFlow_VER}") + # found appropriate version + set(TensorFlow_VERSION ${TF_DETECTED_VERSION}) + set(TensorFlow_ABI ${TF_DETECTED_ABI}) + set(TensorFlow_INCLUDE_DIR ${TF_DETECTED_INCLUDE_DIR}) + set(TensorFlow_LIBRARY ${TF_DETECTED_LIBRARY}) + set(TensorFlow_FOUND TRUE) + message(STATUS "Found TensorFlow: (found appropriate version \"${TensorFlow_VERSION}\")") + message(STATUS "TensorFlow-ABI is ${TensorFlow_ABI}") + message(STATUS "TensorFlow-INCLUDE_DIR is ${TensorFlow_INCLUDE_DIR}") + message(STATUS "TensorFlow-LIBRARY is ${TensorFlow_LIBRARY}") + + add_definitions("-DTENSORFLOW_ABI=${TensorFlow_ABI}") + add_definitions("-DTENSORFLOW_VERSION=${TensorFlow_VERSION}") + break() + endif() + ENDFOREACH(_TensorFlow_VER) + + if(NOT TensorFlow_FOUND) + message(FATAL_ERROR "Your installed TensorFlow version ${TF_DETECTED_VERSION_MAJOR}.${TF_DETECTED_VERSION_MINOR} is not supported\n" + "We tested against ${_TensorFlow_TEST_VERSIONS}") + endif(NOT TensorFlow_FOUND) + +endif() + +find_library(TensorFlow_C_LIBRARY + NAMES libtensorflow_cc.so + PATHS $ENV{TENSORFLOW_BUILD_DIR} + DOC "TensorFlow CC library." ) + +if(TensorFlow_C_LIBRARY) + message(STATUS "TensorFlow-CC-LIBRARY is ${TensorFlow_C_LIBRARY}") +else() + message(STATUS "No TensorFlow-CC-LIBRARY detected") +endif() + +find_path(TensorFlow_SOURCE_DIR + NAMES + tensorflow/c + tensorflow/cc + tensorflow/core + tensorflow/core/framework + tensorflow/core/platform + tensorflow/python + third_party + PATHS $ENV{TENSORFLOW_SOURCE_DIR}) + +if(TensorFlow_SOURCE_DIR) + message(STATUS "TensorFlow-SOURCE-DIRECTORY is ${TensorFlow_SOURCE_DIR}") +else() + message(STATUS "No TensorFlow source repository detected") +endif() + +macro(TensorFlow_REQUIRE_C_LIBRARY) + if(TensorFlow_C_LIBRARY) + else() + message(FATAL_ERROR "Project requires libtensorflow_cc.so, please specify the path in ENV-VAR 'TENSORFLOW_BUILD_DIR'") + endif() +endmacro() + +macro(TensorFlow_REQUIRE_SOURCE) + if(TensorFlow_SOURCE_DIR) + else() + message(FATAL_ERROR "Project requires TensorFlow source directory, please specify the path in ENV-VAR 'TENSORFLOW_SOURCE_DIR'") + endif() +endmacro() + +macro(add_tensorflow_cpu_operation op_name) + # Compiles a CPU-only operation without invoking NVCC + message(STATUS "will build custom TensorFlow operation \"${op_name}\" (CPU only)") + + add_library(${op_name}_op SHARED kernels/${op_name}_op.cc kernels/${op_name}_kernel.cc ops/${op_name}.cc ) + + set_target_properties(${op_name}_op PROPERTIES PREFIX "") + target_link_libraries(${op_name}_op LINK_PUBLIC ${TensorFlow_LIBRARY}) +endmacro() + + +macro(add_tensorflow_gpu_operation op_name) +# Compiles a CPU + GPU operation with invoking NVCC + message(STATUS "will build custom TensorFlow operation \"${op_name}\" (CPU+GPU)") + + set(kernel_file "") + if(EXISTS "kernels/${op_name}_kernel.cu") + message(WARNING "you should rename your file ${op_name}_kernel.cu to ${op_name}_kernel_gpu.cu.cc") + set(kernel_file kernels/${op_name}_kernel.cu) + else() + set_source_files_properties(kernels/${op_name}_kernel_gpu.cu.cc PROPERTIES CUDA_SOURCE_PROPERTY_FORMAT OBJ) + set(kernel_file kernels/${op_name}_kernel_gpu.cu.cc) + endif() + + cuda_add_library(${op_name}_op_cu SHARED ${kernel_file}) + set_target_properties(${op_name}_op_cu PROPERTIES PREFIX "") + + add_library(${op_name}_op SHARED kernels/${op_name}_op.cc kernels/${op_name}_kernel.cc ops/${op_name}.cc ) + + set_target_properties(${op_name}_op PROPERTIES PREFIX "") + set_target_properties(${op_name}_op PROPERTIES COMPILE_FLAGS "-DGOOGLE_CUDA") + target_link_libraries(${op_name}_op LINK_PUBLIC ${op_name}_op_cu ${TensorFlow_LIBRARY}) +endmacro() + +# simplify TensorFlow dependencies +add_library(TensorFlow_DEP INTERFACE) +TARGET_INCLUDE_DIRECTORIES(TensorFlow_DEP INTERFACE ${TensorFlow_SOURCE_DIR}) +TARGET_INCLUDE_DIRECTORIES(TensorFlow_DEP INTERFACE ${TensorFlow_INCLUDE_DIR}) +TARGET_LINK_LIBRARIES(TensorFlow_DEP INTERFACE -Wl,--allow-multiple-definition -Wl,--whole-archive ${TensorFlow_C_LIBRARY} -Wl,--no-whole-archive) +TARGET_LINK_LIBRARIES(TensorFlow_DEP INTERFACE -Wl,--allow-multiple-definition -Wl,--whole-archive ${TensorFlow_LIBRARY} -Wl,--no-whole-archive) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + TENSORFLOW + FOUND_VAR TENSORFLOW_FOUND + REQUIRED_VARS + TensorFlow_LIBRARY + TensorFlow_INCLUDE_DIR + VERSION_VAR + TensorFlow_VERSION + ) + +mark_as_advanced(TF_INFORMATION_STRING TF_DETECTED_VERSION TF_DETECTED_VERSION_MAJOR TF_DETECTED_VERSION_MINOR TF_DETECTED_VERSION TF_DETECTED_ABI + TF_DETECTED_INCLUDE_DIR TF_DETECTED_LIBRARY + TensorFlow_C_LIBRARY TensorFlow_LIBRARY TensorFlow_SOURCE_DIR TensorFlow_INCLUDE_DIR TensorFlow_ABI) + +SET(TensorFlow_INCLUDE_DIR ${TensorFlow_INCLUDE_DIR} CACHE PATH "path to tensorflow header files") +SET(TensorFlow_VERSION ${TensorFlow_VERSION} CACHE INTERNAL "The Python executable Version") +SET(TensorFlow_ABI ${TensorFlow_ABI} CACHE STRING "The Python executable Version") +SET(TensorFlow_LIBRARY ${TensorFlow_LIBRARY} CACHE PATH "The Python executable Version") +SET(TensorFlow_FOUND ${TensorFlow_FOUND} CACHE BOOL "The Python executable Version") \ No newline at end of file diff --git a/user_ops/PointTestCase.py b/user_ops/PointTestCase.py new file mode 100644 index 0000000..81c634a --- /dev/null +++ b/user_ops/PointTestCase.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2017 ComputerGraphics Tuebingen. 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. +# ============================================================================== +# Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + + +import numpy as np +import tensorflow as tf + +np.random.seed(42) +tf.set_random_seed(42) + + +class FakePointCloud(object): + """docstring for FakePointCloud""" + + def __init__(self, B, N, K, Din, Dout, Dp, N2, scaling=1): + super(FakePointCloud, self).__init__() + assert K < N + self.B = B + self.N = N + self.K = K + self.Din = Din + self.Dout = Dout + self.Dp = Dp + self.N2 = N2 + + def expected_feature_shape(self): + return [self.B, self.Din, self.N] + + def expected_output_shape(self): + return [self.B, self.Dout, self.N] + + +def random_values(shape, human_readable=False): + """Return random values within range [-10, 10] and precision 2 + """ + length = np.prod(shape) + return np.arange(length).astype(np.float32).reshape(shape) / float(length) + + +def summary(numeric_grad, graph_grad, name, eps=0.001, max_outputs=20): + a, b = numeric_grad.flatten(), graph_grad.flatten() + print("summary: %s" % name) + print("\ttheirs\t\tours\t\tabs-diff") + for i in range(np.prod(numeric_grad.shape)): + if np.abs(a[i] - b[i]) > eps and max_outputs > 0: + print('%i\t%f\t%f\t%f' % (i, a[i], b[i], np.abs(a[i] - b[i]))) + max_outputs -= 1 + if max_outputs == 20: + for i in range(max_outputs): + print('%i\t%f\t%f\t%f' % (i, a[i], b[i], np.abs(a[i] - b[i]))) + # print( np.stack([numeric_grad, graph_grad], axis=-1) + print("%s - abs-diff (sum): " % name, np.abs( + graph_grad - numeric_grad).sum()) + print("%s - abs-diff (max): " % name, np.abs( + graph_grad - numeric_grad).max()) + print("%s - abs-diff (mean): " % name, np.abs( + graph_grad - numeric_grad).mean()) + + +# TestPointCloud(B, N, K, Din, Dout, Dp, N2) +# TPC = FakePointCloud(2, 32, 16, 5, 6, 3, 16) +# TPC = FakePointCloud(2, 16, 8, 5, 6, 3, 8) +TPC = FakePointCloud(2, 32, 4, 2, 6, 3, 16) +# TPC = FakePointCloud(2, 64, 8, 1, 6, 3, 64) + + +class PointTestCase(tf.test.TestCase): + + def __init__(self, methodName="runTest", data=None): + + if data is None: + data = TPC + + self.position = random_values([data.B, data.Dp, data.N]) + self.features = random_values([data.B, data.Din, data.N]) + + # make sure, each neighbor hood has no duplicates and first entry is point n + # THIS IS IMPORTANT!! + self.neighborhood = np.zeros((data.B, data.K, data.N), dtype=np.int32) + for b in range(data.B): + for n in range(data.N): + x = np.arange(data.N) + # does not support axis, hence the loop + np.random.shuffle(x) + offset = np.argwhere(x == n)[0][0] + # roll array such that n is first entry + x = np.roll(x, -offset) + self.neighborhood[b, :, n] = x[:data.K].astype(np.int32) + + self.neighborhood_ds = np.zeros((data.B, data.K, data.N2), dtype=np.int32) + for b in range(data.B): + for n in range(data.N2): + x = np.arange(data.N2) + # does not support axis, hence the loop + np.random.shuffle(x) + offset = np.argwhere(x == n)[0][0] + # roll array such that n is first entry + x = np.roll(x, -offset) + self.neighborhood[b, :, n] = x[:data.K].astype(np.int32) + + self.theta = random_values([1, data.Dp, data.Din, data.Dout]) + self.bias = random_values([data.Din, data.Dout]) + + super(PointTestCase, self).__init__(methodName) + + def init_ops(self): + # needs to be called in each method, otherwise graph is empty + # probably tf.reset_graph between calls + self.features_op = tf.convert_to_tensor(self.features) + self.position_op = tf.convert_to_tensor(self.position) + self.neighborhood_op = tf.convert_to_tensor(self.neighborhood) + self.neighborhood_ds_op = tf.convert_to_tensor(self.neighborhood_ds) + self.theta_op = tf.convert_to_tensor(self.theta) + self.bias_op = tf.convert_to_tensor(self.bias) diff --git a/user_ops/__init__.py b/user_ops/__init__.py new file mode 100644 index 0000000..5e1862b --- /dev/null +++ b/user_ops/__init__.py @@ -0,0 +1,176 @@ +# Copyright 2018 ComputerGraphics Tuebingen. 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. +# ============================================================================ +"""Tensorflow op performing flex convolution operation.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf +from tensorflow.python.framework import ops +from tensorflow.contrib.util import loader +from tensorflow.python.platform import resource_loader + +_flex_convolution_op_so = loader.load_op_library( + resource_loader.get_path_to_datafile("flex_conv_op.so")) + +_flex_pooling_op_so = loader.load_op_library( + resource_loader.get_path_to_datafile("flex_pool_op.so")) + +_flex_deconvolution_op_so = loader.load_op_library( + resource_loader.get_path_to_datafile("flex_deconv_op.so")) + + +# undocumented version +flex_conv = _flex_convolution_op_so.flex_conv +flex_conv_grad = _flex_convolution_op_so.flex_conv_grad +flex_pool = _flex_pooling_op_so.flex_pool +flex_pool_grad = _flex_pooling_op_so.flex_pool_grad +flex_deconv = _flex_deconvolution_op_so.flex_deconv +flex_deconv_grad = _flex_deconvolution_op_so.flex_deconv_grad + +# pylint: disable=redefined-builtin + + +def flex_convolution(features, + position, + neighborhood, + theta, + bias, + name=None): + """Flex-Convolution computation. + + Computes a convolution over arbitrary neighborhoods with elements of + arbitrary positions: + + output(c', l) = sum_{c} sum_{l'} w(c, l, l') * f(c, l') + + Args: + features: A `Tensor` of the format [B, Din, N]. + position: A `Tensor` of the format [B, Dp, N]. + neighborhood: A `Tensor` of the format [B, K, N] (tf.int32). + theta: A `Tensor` of the format [1, Dp, Din, Dout]. + bias: A `Tensor` of the format [Din, Dout]. + name: A name for the operation (optional). + + Returns: + A `Tensor` of the format [B, Dout, N]. + """ + + with ops.name_scope(name, "flex_convolution"): + return flex_conv(features, theta, bias, neighborhood, position) + + +@ops.RegisterGradient("FlexConv") +def _FlexConvGrad(op, *grads): # noqa + features = ops.convert_to_tensor(op.inputs[0]) + theta = ops.convert_to_tensor(op.inputs[1]) + bias = ops.convert_to_tensor(op.inputs[2]) + neighborhood = ops.convert_to_tensor(op.inputs[3], dtype=tf.int32) + positions = ops.convert_to_tensor(op.inputs[4]) + topdiff = ops.convert_to_tensor(grads[0]) + + df, dt, db = flex_conv_grad( + features, theta, bias, neighborhood, positions, topdiff) + + df = ops.convert_to_tensor(df, name='gradient_features') + dt = ops.convert_to_tensor(dt, name='gradient_theta') + db = ops.convert_to_tensor(db, name='gradient_bias') + + return [df, dt, db, None, None] + + +# pylint: disable=redefined-builtin +def flex_pooling(features, + neighborhood, + name=None): + """Flex-Pooling computation. + + Computes a pooling over arbitrary neighborhoods: + + output(n) = max_l' f(l') + + Args: + features: A `Tensor` of the format [B, D, N]. + neighborhood: A `Tensor` of the format [B, K, N] (tf.int32). + name: A name for the operation (optional). + + Returns: + A `Tensor` of the format [B, D, N] containing the max values. + A `Tensor` of the format [B, D, N] containing the max indicies. + """ + + with ops.name_scope(name, "flex_pooling"): + return flex_pool(features, neighborhood) + + +@ops.RegisterGradient("FlexPool") +def _FlexPoolGrad(op, *grads): # noqa + features = ops.convert_to_tensor(op.inputs[0]) + neighborhood = ops.convert_to_tensor(op.inputs[1]) + argmax = ops.convert_to_tensor(op.outputs[1]) + topdiff = ops.convert_to_tensor(grads[0]) + + df = flex_pool_grad(features, neighborhood, topdiff, argmax) + df = ops.convert_to_tensor(df, name='gradient_features') + + return [df, None] + + +# pylint: disable=redefined-builtin +def flex_convolution_transpose(features, + position, + neighborhood, + theta, + bias, + name=None): + """Flex-Convolution computation. + + Computes a tranposed convolution over arbitrary neighborhoods with elements of + arbitrary positions. + + Args: + features: A `Tensor` of the format [B, Din, N]. + position: A `Tensor` of the format [B, Dp, N]. + neighborhood: A `Tensor` of the format [B, K, N] (tf.int32). + theta: A `Tensor` of the format [1, Dp, Din, Dout]. + bias: A `Tensor` of the format [Din, Dout]. + name: A name for the operation (optional). + + Returns: + A `Tensor` of the format [B, Dout, N]. + """ + + with ops.name_scope(name, "flex_convolution_transpose"): + return flex_deconv(features, theta, bias, neighborhood, position) + + +@ops.RegisterGradient("FlexDeconv") +def _FlexDeconvGrad(op, *grads): # noqa + features = ops.convert_to_tensor(op.inputs[0]) + theta = ops.convert_to_tensor(op.inputs[1]) + bias = ops.convert_to_tensor(op.inputs[2]) + neighborhood = ops.convert_to_tensor(op.inputs[3], dtype=tf.int32) + positions = ops.convert_to_tensor(op.inputs[4]) + topdiff = ops.convert_to_tensor(grads[0]) + + df, dt, db = flex_deconv_grad( + features, theta, bias, neighborhood, positions, topdiff) + + df = ops.convert_to_tensor(df, name='gradient_features') + dt = ops.convert_to_tensor(dt, name='gradient_theta') + db = ops.convert_to_tensor(db, name='gradient_bias') + + return [df, dt, db, None, None] diff --git a/user_ops/kernels/flex_conv_kernel.cc b/user_ops/kernels/flex_conv_kernel.cc new file mode 100644 index 0000000..5ad7c96 --- /dev/null +++ b/user_ops/kernels/flex_conv_kernel.cc @@ -0,0 +1,173 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "flex_conv_op.h" +#include "tensorflow/core/framework/op.h" + +namespace tensorflow { + +namespace functor { + +template +struct FlexConvFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + Tensor* output_) { + const auto features = features_.tensor(); + const auto theta = theta_.tensor(); + const auto bias = bias_.tensor(); + const auto neighborhood = neighborhood_.tensor(); + const auto positions = positions_.tensor(); + + auto output = output_->tensor(); + + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int Dp = theta_.dim_size(1); + const int Din = theta_.dim_size(2); + const int Dout = theta_.dim_size(3); + + output.setZero(); + + for (int b = 0; b < B; ++b) { + for (int n = 0; n < N; ++n) { + for (int k_ = 0; k_ < K; ++k_) { + int k = neighborhood(b, k_, n); + + for (int dout = 0; dout < Dout; ++dout) { + for (int din = 0; din < Din; ++din) { + const Dtype v = features(b, din, k); + + Dtype W = bias(din, dout); + for (int dp = 0; dp < Dp; ++dp) { + Dtype delta = positions(b, dp, k) - + positions(b, dp, neighborhood(b, 0, n)); + W += theta(0, dp, din, dout) * delta; + } + output(b, dout, n) = output(b, dout, n) + W * v; + } + } + } + } + } + } +}; + +template struct FlexConvFunctor; + +template +struct FlexConvGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + const Tensor& topdiff_, Tensor* grad_features_, + Tensor* grad_theta_, Tensor* grad_bias_) { + const auto features = features_.tensor(); + const auto theta = theta_.tensor(); + const auto bias = bias_.tensor(); + const auto neighborhood = neighborhood_.tensor(); + const auto positions = positions_.tensor(); + const auto topdiff = topdiff_.tensor(); + + auto grad_features = grad_features_->tensor(); + auto grad_theta = grad_theta_->tensor(); + auto grad_bias = grad_bias_->tensor(); + + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int Ddegree = theta_.dim_size(0); + const int Dp = theta_.dim_size(1); + const int Din = theta_.dim_size(2); + const int Dout = theta_.dim_size(3); + + grad_features.setZero(); + grad_theta.setZero(); + grad_bias.setZero(); + + // ========================= bias ============================== + for (int b = 0; b < B; ++b) { + for (int n = 0; n < N; ++n) { + for (int k_ = 0; k_ < K; ++k_) { + int k = neighborhood(b, k_, n); + + for (int j = 0; j < Din; ++j) { + for (int l = 0; l < Dout; ++l) { + grad_bias(j, l) += features(b, j, k) * topdiff(b, l, n); + } + } + } + } + } + + // ========================= theta ============================== + for (int b = 0; b < B; ++b) { + for (int n = 0; n < N; ++n) { + for (int k_ = 0; k_ < K; ++k_) { + int k = neighborhood(b, k_, n); + + for (int j = 0; j < Din; ++j) { + for (int l = 0; l < Dout; ++l) { + for (int i = 0; i < Dp; ++i) { + const Dtype delta = + positions(b, i, k) - positions(b, i, neighborhood(b, 0, n)); + // printf("delta %f\n", delta); + + for (int dd = 0; dd < Ddegree; ++dd) { + grad_theta(dd, i, j, l) += + features(b, j, k) * pow(delta, dd + 1) * topdiff(b, l, n); + } + } + } + } + } + } + } + + // ========================= features ============================== + for (int b = 0; b < B; ++b) { + for (int n = 0; n < N; ++n) { + for (int k_ = 0; k_ < K; ++k_) { + int k = neighborhood(b, k_, n); + + for (int j = 0; j < Din; ++j) { + for (int l = 0; l < Dout; ++l) { + Dtype W = bias(j, l); + for (int i = 0; i < Dp; ++i) { + const Dtype delta = + positions(b, i, k) - positions(b, i, neighborhood(b, 0, n)); + for (int dd = 0; dd < Ddegree; ++dd) + W += theta(dd, i, j, l) * pow(delta, dd + 1); + } + grad_features(b, j, k) += W * topdiff(b, l, n); + } + } + } + } + } + } +}; + +// template struct FlexConvGrad; +template struct FlexConvGrad; +// template struct FlexConvGrad; + +} // namespace functor +} // namespace tensorflow diff --git a/user_ops/kernels/flex_conv_kernel_gpu.cu.cc b/user_ops/kernels/flex_conv_kernel_gpu.cu.cc new file mode 100644 index 0000000..3925bbf --- /dev/null +++ b/user_ops/kernels/flex_conv_kernel_gpu.cu.cc @@ -0,0 +1,532 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#if GOOGLE_CUDA + +#define EIGEN_USE_GPU + +#include + +#include "flex_conv_op.h" +#include "tensorflow/core/util/cuda_kernel_helper.h" + +namespace FlexConvCuda { + +using CudaLaunchConfig = ::tensorflow::CudaLaunchConfig; + +constexpr __host__ __device__ int pmin(int x, int y) { return x <= y ? x : y; } + +template +struct ForwardKernel; + +template +__global__ void runForwardKernel( + const ForwardKernel kernel) { + kernel(); +} + +template +struct ForwardKernel { + enum { + PMIN = 3 // only for unrolling + }; + + void launch(int B) { + dim3 block(C_N); + dim3 grid((N - 1) / C_N + 1, (Dout - 1) / C_Dout + 1, B); + + size_t shm_size = (Dp + 1) * C_Din * C_Dout * sizeof(Dtype); + + runForwardKernel<<>>((*this)); + } + + __device__ __forceinline__ void operator()() const { + extern __shared__ Dtype s_shm[]; + + Dtype* s_theta = (float*)&s_shm[0]; + Dtype* s_bias = (float*)&s_shm[Dp * C_Din * C_Dout]; + + // glob ids + int b = blockIdx.z; + int n = blockIdx.x * C_N + threadIdx.x; + + Dtype result[C_Dout]; + for (int dout = 0; dout < C_Dout; ++dout) { + result[dout] = 0.0; + } + + Dtype p0[Dp]; +#pragma unroll pmin(Dp, PMIN) + for (int dp = 0; dp < Dp && n < N; ++dp) { + p0[dp] = d_positions[b * Dp * N + dp * N + n]; + } + + for (int o_din = 0; o_din < Din; o_din += C_Din) { + // load shm + __syncthreads(); + for (int tid = threadIdx.x; tid < Dp * C_Din * C_Dout; tid += C_N) { + int dp = tid / (C_Din * C_Dout); + int din = (tid % (C_Din * C_Dout)) / C_Dout; + int dout = tid % C_Dout; + + int g_dout = (dout + blockIdx.y * C_Dout); + int g_din = o_din + din; + + if (g_dout < Dout && g_din < Din) { + s_theta[dp * C_Din * C_Dout + din * C_Dout + dout] = + d_theta[dp * Din * Dout + g_din * Dout + g_dout]; + + if (!dp) s_bias[din * C_Dout + dout] = d_bias[g_din * Dout + g_dout]; + } + } + __syncthreads(); + + if (n < N) { + // Loop over K + for (int k = 0; k < K && n < N; ++k) { + NBtype nk = d_neighborhood[b * K * N + k * N + n]; + + Dtype q[Dp]; +#pragma unroll pmin(Dp, PMIN) + for (int dp = 0; dp < Dp; ++dp) { + q[dp] = d_positions[b * Dp * N + dp * N + nk] - p0[dp]; + } + + // Loop over Din + for (int din = 0; din < C_Din && (o_din + din) < Din; ++din) { + Dtype fk = d_features[b * Din * N + (o_din + din) * N + nk]; + + // Loop over partial Dout + for (int dout = 0; + dout < C_Dout && (dout + blockIdx.y * C_Dout) < Dout; ++dout) { + Dtype w = 0.0; + + for (int dp = 0; dp < Dp; ++dp) + w += q[dp] * s_theta[dp * C_Din * C_Dout + din * C_Dout + dout]; + w += s_bias[din * C_Dout + dout]; + result[dout] += w * fk; + } + } + } + } + } + + for (int dout = 0; + dout < C_Dout && (dout + blockIdx.y * C_Dout) < Dout && n < N; + ++dout) { + d_output[b * Dout * N + (dout + blockIdx.y * C_Dout) * N + n] = + result[dout]; + } + } + + // features: incoming features [B, Din, N]. + // position: each datapoint in nd space [B, Dp, N]. + // neighborhood: all K nearest neighbors [B, K, N]. + const Dtype* d_features; + const Dtype* d_positions; + const NBtype* d_neighborhood; + + // theta: parameters for kernel function [Dp, + // Din, Dout]. bias: parameters for kernel function [Din, Dout]. + const Dtype* d_theta; + const Dtype* d_bias; + + // output: each feature description for each point [B, Dout, N]. + Dtype* d_output; + + int N; + int K; + int Din; + int Dout; +}; + +template +struct BackwardThetaKernel; + +template +__global__ void runBackwardKernel(const BackwardThetaKernel kernel) { + kernel(); +} + +template +struct BackwardThetaKernel { + enum { C_N = 256, DP_MAX = 3, DEGREE_MAX = 2 }; + + void launch() { + dim3 block(C_N); + dim3 grid(Dout, Din); + + runBackwardKernel<<>>((*this)); + } + + __device__ __forceinline__ void operator()() const { + typedef cub::BlockReduce BlockReduce; + __shared__ typename BlockReduce::TempStorage temp_storage; + + Dtype theta_diff[DP_MAX]; + for (int dp = 0; dp < Dp; ++dp) theta_diff[dp] = 0; + + Dtype bias_diff = 0; + + int dout = blockIdx.x; + int din = blockIdx.y; + + for (int b = 0; b < B; ++b) { + for (int n = threadIdx.x; n < N; n += C_N) { + Dtype topdiff = d_topdiff[b * Dout * N + dout * N + n]; + + for (int k = 0; k < K; ++k) { + int nk0 = d_neigh[b * N * K + 0 * N + n]; + int nk = d_neigh[b * N * K + k * N + n]; + + Dtype feature = d_features[b * Din * N + din * N + nk]; + for (int dp = 0; dp < Dp; ++dp) { + Dtype diffpos = d_pos[b * Dp * N + dp * N + nk] - + d_pos[b * Dp * N + dp * N + nk0]; + theta_diff[dp] += feature * diffpos * topdiff; + } + bias_diff += feature * topdiff; + } + } + } + + for (int dp = 0; dp < Dp; ++dp) { + // for (int dd = 0; dd < Ddegree; ++dd) { + Dtype thread_data = theta_diff[dp]; + Dtype aggregate = BlockReduce(temp_storage).Sum(thread_data, N); + + if (!threadIdx.x) { + d_theta_out[dp * Din * Dout + din * Dout + dout] = aggregate; + } + // } + __syncthreads(); + } + + Dtype thread_data = bias_diff; + + Dtype aggregate = BlockReduce(temp_storage).Sum(thread_data, N); + + if (!threadIdx.x) d_bias_out[din * Dout + dout] = aggregate; + } + + const Dtype* d_topdiff; + + const Dtype* d_pos; + const Dtype* d_features; + const int* d_neigh; + + const Dtype* d_theta; + const Dtype* d_bias; + + Dtype* d_theta_out; + Dtype* d_bias_out; + + int B; + int N; + int K; + int Ddegree; + int Dp; + int Din; + int Dout; +}; + +template +struct BackwardFeatureKernel; + +template +__global__ void runBackwardKernel(const BackwardFeatureKernel kernel) { + kernel(); +} + +template +struct BackwardFeatureKernel { + enum { + C_N = 32, + C_Dout = 32, // multiple of Warpsize is better + + C_Din = 8 // reduce first + }; + + void launch(int B) { + dim3 fblock(C_N, C_Din); + dim3 fgrid((N - 1) / C_N + 1, (Din - 1) / C_Din + 1, B); + + const int theta_size = Dp * C_Din * C_Dout; + const int bias_size = C_Din * C_Dout; + const int topdiff_size = C_N * C_Dout; + const int pos_size = C_N * K * Dp; + const int nk_size = C_N * K; + + int shm = + (theta_size + bias_size + topdiff_size + pos_size) * sizeof(Dtype) + + (nk_size) * sizeof(int); + + runBackwardKernel<<>>((*this)); + } + + __device__ __forceinline__ void operator()() const { + extern __shared__ float s_shm[]; + + int i_n = threadIdx.x; + int i_din = threadIdx.y; + + int b = blockIdx.z; + int n = blockIdx.x * C_N + i_n; + int din = blockIdx.y * C_Din + i_din; + + Dtype* s_theta = (Dtype*)&s_shm[0]; + Dtype* s_bias = (Dtype*)&s_theta[Dp * C_Din * C_Dout]; + Dtype* s_topdiff = (Dtype*)&s_bias[C_Din * C_Dout]; + Dtype* s_pos = (Dtype*)&s_topdiff[C_N * C_Dout]; + int* s_nk = (int*)&s_pos[C_N * K * Dp]; + + for (int k = threadIdx.y; k < K && n < N; k += blockDim.y) { + int nk = d_neigh[b * K * N + k * N + n]; + s_nk[k * C_N + i_n] = nk; + + for (int i_dp = 0; i_dp < Dp; ++i_dp) { + s_pos[k * C_N * Dp + i_dp * C_N + i_n] = + d_pos[b * Dp * N + i_dp * N + nk]; + } + } + + __syncthreads(); + + for (int i_dp = 0; i_dp < Dp; ++i_dp) { + Dtype val0 = s_pos[0 * C_N * Dp + i_dp * C_N + i_n]; + __syncthreads(); + for (int k = threadIdx.y; k < K && n < N; k += blockDim.y) { + s_pos[k * C_N * Dp + i_dp * C_N + i_n] -= val0; + } + } + + for (int dout_outer = 0; dout_outer < (Dout - 1) / C_Dout + 1; + ++dout_outer) { + __syncthreads(); + + // fill s_theta + int dout = dout_outer * C_Dout + i_n; + if (din < Din && dout < Dout) { + for (int i_dp = 0; i_dp < Dp; ++i_dp) + s_theta[i_dp * C_Din * C_Dout + i_din * C_Dout + i_n] = + d_theta[i_dp * Din * Dout + din * Dout + dout]; + + s_bias[i_din * C_Dout + i_n] = d_bias[din * Dout + dout]; + } + + if (n < N) { + for (int i_dout = threadIdx.y; + i_dout < C_Dout && (dout_outer * C_Dout + i_dout) < Dout; + i_dout += blockDim.y) + s_topdiff[i_dout * C_N + i_n] = + d_topdiff[b * Dout * N + (dout_outer * C_Dout + i_dout) * N + n]; + } + + for (int dout_inner = 0; + dout_inner < C_Dout && (dout_outer * C_Dout + dout_inner) < Dout; + ++dout_inner) { + for (int k = 0; k < K; k++) { + __syncthreads(); + + if (n < N && din < Din) { + Dtype W = 0; + for (int dp = 0; dp < Dp; ++dp) { + const Dtype diffpos = s_pos[k * C_N * Dp + dp * C_N + i_n]; + W += s_theta[dp * C_Din * C_Dout + i_din * C_Dout + dout_inner] * + diffpos; + } + W += s_bias[i_din * C_Dout + dout_inner]; + Dtype value = W * s_topdiff[dout_inner * C_N + i_n]; + + atomicAdd( + &d_features_out[b * Din * N + din * N + s_nk[k * C_N + i_n]], + value); + } + } + } + } + } + + const Dtype* d_topdiff; + const Dtype* d_pos; + const Dtype* d_features; + const int* d_neigh; + const Dtype* d_theta; + const Dtype* d_bias; + + Dtype* d_features_out; + + int N; + int K; + int Dp; + int Din; + int Dout; +}; + +} // namespace FlexConvCuda + +namespace tensorflow { +namespace functor { + +template +struct FlexConvFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features, + const Tensor& theta, const Tensor& bias, + const Tensor& neighborhood, const Tensor& positions, + Tensor* output) { + typedef int NBtype; + + const int B = neighborhood.dim_size(0); + const int K = neighborhood.dim_size(1); + const int N = neighborhood.dim_size(2); + const int Dp = theta.dim_size(1); + const int Din = theta.dim_size(2); + const int Dout = theta.dim_size(3); + + FlexConvCuda::ForwardKernel fwk; + fwk.N = N; + fwk.K = K; + fwk.Din = Din; + fwk.Dout = Dout; + + fwk.d_features = features.flat().data(); + fwk.d_positions = positions.flat().data(); + fwk.d_neighborhood = neighborhood.flat().data(); + fwk.d_theta = theta.flat().data(); + fwk.d_bias = bias.flat().data(); + fwk.d_output = output->flat().data(); + + fwk.launch(B); + + if (!ctx->eigen_gpu_device().ok()) { + ctx->SetStatus(tensorflow::errors::Internal( + "FlexConvInvFunctor::forward::ForwardKernel execution failed")); + } + } +}; + +template struct FlexConvFunctor; + +template +struct FlexConvGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + const Tensor& topdiff_, Tensor* grad_features_, + Tensor* grad_theta_, Tensor* grad_bias_) { + const auto features = features_.tensor(); + const auto theta = theta_.tensor(); + const auto bias = bias_.tensor(); + const auto neighborhood = neighborhood_.tensor(); + const auto positions = positions_.tensor(); + const auto topdiff = topdiff_.tensor(); + + auto grad_features = grad_features_->tensor(); + auto grad_theta = grad_theta_->tensor(); + auto grad_bias = grad_bias_->tensor(); + + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int Dp = theta_.dim_size(1); + const int Din = theta_.dim_size(2); + const int Dout = theta_.dim_size(3); + + const int* neighborhood_ptr = + reinterpret_cast(neighborhood.data()); + const Dtype* positions_ptr = + reinterpret_cast(positions.data()); + const Dtype* features_ptr = reinterpret_cast(features.data()); + const Dtype* theta_ptr = reinterpret_cast(theta.data()); + const Dtype* bias_ptr = reinterpret_cast(bias.data()); + + const Dtype* topdiff_ptr = reinterpret_cast(topdiff.data()); + + Dtype* grad_features_ptr = reinterpret_cast(grad_features.data()); + Dtype* grad_theta_ptr = reinterpret_cast(grad_theta.data()); + Dtype* grad_bias_ptr = reinterpret_cast(grad_bias.data()); + + cudaMemset(grad_features_ptr, 0, B * Din * N * sizeof(Dtype)); + + ::tensorflow::CudaLaunchConfig cfg = + ::tensorflow::GetCudaLaunchConfig(N, ctx->eigen_device()); + + typedef FlexConvCuda::BackwardFeatureKernel BFK; + + BFK bfk; + bfk.N = N; + bfk.K = K; + bfk.Dp = Dp; + bfk.Din = Din; + bfk.Dout = Dout; + + bfk.d_pos = positions_ptr; + bfk.d_neigh = neighborhood_ptr; + bfk.d_features = features_ptr; + bfk.d_theta = theta_ptr; + bfk.d_bias = bias_ptr; + + bfk.d_topdiff = topdiff_ptr; + + bfk.d_features_out = grad_features_ptr; + + bfk.launch(B); + + if (!ctx->eigen_gpu_device().ok()) { + ctx->SetStatus( + tensorflow::errors::Internal("CUDA: BackwardFeatureKernel Error!\n")); + } + + typedef FlexConvCuda::BackwardThetaKernel BTK; + + BTK btk; + btk.B = B; + btk.N = N; + btk.K = K; + btk.Dp = Dp; + btk.Din = Din; + btk.Dout = Dout; + + btk.d_pos = positions_ptr; + btk.d_neigh = neighborhood_ptr; + btk.d_features = features_ptr; + btk.d_theta = theta_ptr; + btk.d_bias = bias_ptr; + + btk.d_topdiff = topdiff_ptr; + + btk.d_theta_out = grad_theta_ptr; + btk.d_bias_out = grad_bias_ptr; + + btk.launch(); + + if (!ctx->eigen_gpu_device().ok()) { + ctx->SetStatus( + tensorflow::errors::Internal("CUDA: BackwardThetaKernel Error!\n")); + } + } +}; + +template struct FlexConvGrad; + +} // namespace functor +} // namespace tensorflow + +#endif // GOOGLE_CUDA diff --git a/user_ops/kernels/flex_conv_op.cc b/user_ops/kernels/flex_conv_op.cc new file mode 100644 index 0000000..2b47b0b --- /dev/null +++ b/user_ops/kernels/flex_conv_op.cc @@ -0,0 +1,122 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "flex_conv_op.h" + +#include +#include + +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/op_kernel.h" +#include "tensorflow/core/framework/register_types.h" + +namespace tensorflow { + +// Forward-Pass (CPU, GPU) +// -------------------------------------------------- +template +class FlexConvOp : public OpKernel { + public: + explicit FlexConvOp(OpKernelConstruction* ctx) : OpKernel(ctx) {} + + void Compute(OpKernelContext* ctx) override { + // printf("--> Compute CPU Version <--\n"); + const Tensor& features_ = ctx->input(0); + const Tensor& theta_ = ctx->input(1); + const Tensor& bias_ = ctx->input(2); + const Tensor& neighborhood_ = ctx->input(3); + const Tensor& positions_ = ctx->input(4); + + const int B = neighborhood_.shape().dim_size(0); + const int N = neighborhood_.shape().dim_size(2); + const int Dout = theta_.shape().dim_size(3); + + Tensor* output_ = nullptr; + OP_REQUIRES_OK( + ctx, ctx->allocate_output(0, TensorShape({B, Dout, N}), &output_)); + + ::tensorflow::functor::FlexConvFunctor()( + ctx, features_, theta_, bias_, neighborhood_, positions_, output_); + } + + private: + TF_DISALLOW_COPY_AND_ASSIGN(FlexConvOp); +}; + +// Backward-Pass (CPU, GPU) +// -------------------------------------------------- +template +class FlexConvGradOp : public OpKernel { + public: + explicit FlexConvGradOp(OpKernelConstruction* ctx) : OpKernel(ctx) {} + + void Compute(OpKernelContext* ctx) override { + // printf("--> Compute CPU Version <--\n"); + const Tensor& features_ = ctx->input(0); + const Tensor& theta_ = ctx->input(1); + const Tensor& bias_ = ctx->input(2); + const Tensor& neighborhood_ = ctx->input(3); + const Tensor& positions_ = ctx->input(4); + + const Tensor& topdiff_ = ctx->input(5); + + // specify output shape + Tensor* grad_features_ = nullptr; + Tensor* grad_theta_ = nullptr; + Tensor* grad_bias_ = nullptr; + + const int Degree = theta_.shape().dim_size(0); + + OP_REQUIRES_OK(ctx, + ctx->allocate_output(0, features_.shape(), &grad_features_)); + OP_REQUIRES_OK(ctx, ctx->allocate_output(1, theta_.shape(), &grad_theta_)); + OP_REQUIRES_OK(ctx, ctx->allocate_output(2, bias_.shape(), &grad_bias_)); + + ::tensorflow::functor::FlexConvGrad()( + ctx, features_, theta_, bias_, neighborhood_, positions_, topdiff_, + grad_features_, grad_theta_, grad_bias_); + } +}; + +// Register the CPU kernels. +#define REGISTER_FLEXCONV_OP_CPU(T) \ + REGISTER_KERNEL_BUILDER( \ + Name("FlexConv").Device(DEVICE_CPU).TypeConstraint("T"), \ + FlexConvOp) \ + REGISTER_KERNEL_BUILDER( \ + Name("FlexConvGrad").Device(DEVICE_CPU).TypeConstraint("T"), \ + FlexConvGradOp) + +TF_CALL_float(REGISTER_FLEXCONV_OP_CPU); +#undef REGISTER_FLEXCONV_OP_CPU + +// Register the GPU kernels. +// #ifdef GOOGLE_CUDA + +#define REGISTER_FLEXCONV_OP_GPU(T) \ + REGISTER_KERNEL_BUILDER( \ + Name("FlexConv").Device(DEVICE_GPU).TypeConstraint("T"), \ + FlexConvOp) \ + REGISTER_KERNEL_BUILDER( \ + Name("FlexConvGrad").Device(DEVICE_GPU).TypeConstraint("T"), \ + FlexConvGradOp) + +TF_CALL_float(REGISTER_FLEXCONV_OP_GPU); +#undef REGISTER_FLEXCONV_OP_GPU + +// #endif // GOOGLE_CUDA + +} // namespace tensorflow diff --git a/user_ops/kernels/flex_conv_op.h b/user_ops/kernels/flex_conv_op.h new file mode 100644 index 0000000..d5bfd3f --- /dev/null +++ b/user_ops/kernels/flex_conv_op.h @@ -0,0 +1,53 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#ifndef USER_OPS_KERNELS_FLEX_CONV_OP_H_ +#define USER_OPS_KERNELS_FLEX_CONV_OP_H_ + +#include "tensorflow/core/framework/op_kernel.h" + +namespace tensorflow { +class OpKernelContext; +class Tensor; + +using CPUDevice = Eigen::ThreadPoolDevice; +using GPUDevice = Eigen::GpuDevice; +} // namespace tensorflow + +namespace tensorflow { +namespace functor { + +template +struct FlexConvFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + Tensor* output_); +}; + +template +struct FlexConvGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + const Tensor& topdiff_, Tensor* grad_features_, + Tensor* grad_theta_, Tensor* grad_bias_); +}; + +} // namespace functor +} // namespace tensorflow + +#endif // USER_OPS_KERNELS_FLEX_CONV_OP_H_ diff --git a/user_ops/kernels/flex_deconv_kernel.cc b/user_ops/kernels/flex_deconv_kernel.cc new file mode 100644 index 0000000..d4c618c --- /dev/null +++ b/user_ops/kernels/flex_deconv_kernel.cc @@ -0,0 +1,173 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "flex_deconv_op.h" +#include "tensorflow/core/framework/op.h" + +namespace tensorflow { + +namespace functor { + +template +struct FlexDeconvFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + Tensor* output_) { + const auto features = features_.tensor(); + const auto theta = theta_.tensor(); + const auto bias = bias_.tensor(); + const auto neighborhood = neighborhood_.tensor(); + const auto positions = positions_.tensor(); + + auto output = output_->tensor(); + + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int Dp = theta_.dim_size(1); + const int Din = theta_.dim_size(2); + const int Dout = theta_.dim_size(3); + + output.setZero(); + + for (int b = 0; b < B; ++b) { + for (int n = 0; n < N; ++n) { + const int self_k = neighborhood(b, 0, n); + for (int k_ = 0; k_ < K; ++k_) { + const int other_k = neighborhood(b, k_, n); + + for (int dout = 0; dout < Dout; ++dout) { + for (int din = 0; din < Din; ++din) { + const Dtype v = features(b, din, self_k); + + Dtype W = bias(din, dout); + for (int dp = 0; dp < Dp; ++dp) { + Dtype delta = + positions(b, dp, other_k) - positions(b, dp, self_k); + W += theta(0, dp, din, dout) * delta; + } + output(b, dout, other_k) = output(b, dout, other_k) + W * v; + } + } + } + } + } + } +}; + +template struct FlexDeconvFunctor; + +template +struct FlexDeconvGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + const Tensor& topdiff_, Tensor* grad_features_, + Tensor* grad_theta_, Tensor* grad_bias_) { + const auto features = features_.tensor(); + const auto theta = theta_.tensor(); + const auto bias = bias_.tensor(); + const auto neighborhood = neighborhood_.tensor(); + const auto positions = positions_.tensor(); + const auto topdiff = topdiff_.tensor(); + + auto grad_features = grad_features_->tensor(); + auto grad_theta = grad_theta_->tensor(); + auto grad_bias = grad_bias_->tensor(); + + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int Dp = theta_.dim_size(1); + const int Din = theta_.dim_size(2); + const int Dout = theta_.dim_size(3); + + grad_features.setZero(); + grad_theta.setZero(); + grad_bias.setZero(); + + // ========================= bias ============================== + for (int b = 0; b < B; ++b) { + for (int n = 0; n < N; ++n) { + const int self_k = neighborhood(b, 0, n); + for (int k_ = 0; k_ < K; ++k_) { + const int other_k = neighborhood(b, k_, n); + + for (int din = 0; din < Din; ++din) { + for (int dout = 0; dout < Dout; ++dout) { + grad_bias(din, dout) += + features(b, din, self_k) * topdiff(b, dout, other_k); + } + } + } + } + } + + // ========================= theta ============================== + for (int b = 0; b < B; ++b) { + for (int n = 0; n < N; ++n) { + const int self_k = neighborhood(b, 0, n); + for (int k_ = 0; k_ < K; ++k_) { + const int other_k = neighborhood(b, k_, n); + + for (int din = 0; din < Din; ++din) { + for (int dout = 0; dout < Dout; ++dout) { + for (int dp = 0; dp < Dp; ++dp) { + const Dtype delta = + positions(b, dp, other_k) - positions(b, dp, self_k); + grad_theta(0, dp, din, dout) += features(b, din, self_k) * + delta * + topdiff(b, dout, other_k); + } + } + } + } + } + } + + // ========================= features ============================== + for (int b = 0; b < B; ++b) { + for (int n = 0; n < N; ++n) { + const int self_k = neighborhood(b, 0, n); + for (int k_ = 0; k_ < K; ++k_) { + const int other_k = neighborhood(b, k_, n); + + for (int din = 0; din < Din; ++din) { + for (int dout = 0; dout < Dout; ++dout) { + Dtype W = bias(din, dout); + for (int dp = 0; dp < Dp; ++dp) { + const Dtype delta = + positions(b, dp, other_k) - positions(b, dp, self_k); + W += theta(0, dp, din, dout) * delta; + } + grad_features(b, din, self_k) += W * topdiff(b, dout, other_k); + } + } + } + } + } + } +}; + +// template struct FlexDeconvGrad; +template struct FlexDeconvGrad; +// template struct FlexDeconvGrad; + +} // namespace functor +} // namespace tensorflow diff --git a/user_ops/kernels/flex_deconv_kernel_gpu.cu.cc b/user_ops/kernels/flex_deconv_kernel_gpu.cu.cc new file mode 100644 index 0000000..05518a7 --- /dev/null +++ b/user_ops/kernels/flex_deconv_kernel_gpu.cu.cc @@ -0,0 +1,227 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#if GOOGLE_CUDA + +#define EIGEN_USE_GPU + +#include + +#include "flex_deconv_op.h" +#include "tensorflow/core/util/cuda_kernel_helper.h" + +namespace { +inline int up2(int len, int th) { return (len - 1) / th + 1; } + +template +__global__ void forward(const int B, const int N, const int K, const int Dp, + const int Din, const int Dout, const Dtype* positions, + const Dtype* features, const int* neighborhood, + const Dtype* theta, const Dtype* bias, Dtype* output) { + /* + positions B, Dp, N + features B, Din, N + neighborhood B, K, N + theta Dp, Din, Dout + bias Din, Dout + output B, Dout, N + */ + + const int b = blockIdx.z; + + for (int n = blockIdx.y * blockDim.y + threadIdx.y; n < N; + n += blockDim.y * gridDim.y) { + const int self_k = neighborhood[b * K * N + 0 * N + n]; + + for (int k_ = 0; k_ < K; ++k_) { + const int other_k = neighborhood[b * K * N + k_ * N + n]; + + for (int dout = blockIdx.x * blockDim.x + threadIdx.x; dout < Dout; + dout += blockDim.x * gridDim.x) { + for (int din = 0; din < Din; ++din) { + const Dtype v = features[b * Din * N + din * N + self_k]; + Dtype W = bias[din * Dout + dout]; + + for (int dp = 0; dp < Dp; ++dp) { + Dtype delta = positions[b * Dp * N + dp * N + other_k] - + positions[b * Dp * N + dp * N + self_k]; + W += theta[dp * Din * Dout + din * Dout + dout] * delta; + } + + Dtype Wv = W * v; + tensorflow::CudaAtomicAdd(&output[b * Dout * N + dout * N + other_k], + Wv); + } + } + } + } +} + +template +__global__ void backward(const int B, const int N, const int K, const int Dp, + const int Din, const int Dout, + + const Dtype* positions, const Dtype* features, + const int* neighborhood, + + const Dtype* theta, const Dtype* bias, + + const Dtype* top_diff, + + Dtype* grad_features, Dtype* grad_theta, + Dtype* grad_bias) { + /* + B, Dp, N positions, grad_positions + B, Din, N features, grad_features + B, K, N neighborhood + Dp, Din, Dout theta, grad_theta + Din, Dout bias, grad_bias + B, Dout, N output, top_diff + */ + + const int b = blockIdx.z; + + // Compute + // --------------------------------------------------------------- + + for (int n = blockIdx.y * blockDim.y + threadIdx.y; n < N; + n += blockDim.y * gridDim.y) { + const int self_k = neighborhood[b * K * N + 0 * N + n]; + + for (int k_ = 0; k_ < K; ++k_) { + const int other_k = neighborhood[b * K * N + k_ * N + n]; + + for (int dout = blockIdx.x * blockDim.x + threadIdx.x; dout < Dout; + dout += blockDim.x * gridDim.x) { + for (int din = 0; din < Din; ++din) { + const Dtype current_top_diff = + top_diff[b * Dout * N + dout * N + other_k]; + const Dtype v = features[b * Din * N + din * N + self_k]; + + // update bias + Dtype bias_update = v * current_top_diff; + tensorflow::CudaAtomicAdd(&grad_bias[din * Dout + dout], bias_update); + + Dtype W = bias[din * Dout + dout]; + + // update theta + for (int dp = 0; dp < Dp; ++dp) { + Dtype delta = positions[b * Dp * N + dp * N + other_k] - + positions[b * Dp * N + dp * N + self_k]; + Dtype theta_update = v * delta * current_top_diff; + tensorflow::CudaAtomicAdd( + &grad_theta[dp * Din * Dout + din * Dout + dout], theta_update); + + W += theta[dp * Din * Dout + din * Dout + dout] * delta; + } + + // update features + Dtype feature_update = W * current_top_diff; + tensorflow::CudaAtomicAdd( + &grad_features[b * Din * N + din * N + self_k], feature_update); + // tensorflow::CudaAtomicAdd(&grad_features[b * Din * N + din * N + + // self_k], 1); + } + } + } + } +} + +} // namespace + +namespace tensorflow { +namespace functor { + +template +struct FlexDeconvFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + Tensor* output_) { + // printf("GPU::FlexDeconvFunctor:operator()\n"); + + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int Dp = theta_.dim_size(1); + const int Din = theta_.dim_size(2); + const int Dout = theta_.dim_size(3); + + const int threads = 32; + dim3 block(threads, threads, 1); + dim3 grid(up2(Dout, threads), up2(N, threads), B); + + cudaMemset(output_->flat().data(), 0, + output_->NumElements() * sizeof(Dtype)); + + forward<<>>( + B, N, K, Dp, Din, Dout, positions_.flat().data(), + features_.flat().data(), neighborhood_.flat().data(), + theta_.flat().data(), bias_.flat().data(), + output_->flat().data()); + } +}; + +template struct FlexDeconvFunctor; + +template +struct FlexDeconvGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + const Tensor& topdiff_, Tensor* grad_features_, + Tensor* grad_theta_, Tensor* grad_bias_) { + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int Dp = theta_.dim_size(1); + const int Din = theta_.dim_size(2); + const int Dout = theta_.dim_size(3); + + const int threads = 32; + dim3 block(threads, threads, 1); + dim3 grid(up2(Dout, threads), up2(N, threads), B); + + cudaMemset(grad_features_->flat().data(), 0, + grad_features_->NumElements() * sizeof(Dtype)); + cudaMemset(grad_theta_->flat().data(), 0, + grad_theta_->NumElements() * sizeof(Dtype)); + cudaMemset(grad_bias_->flat().data(), 0, + grad_bias_->NumElements() * sizeof(Dtype)); + + backward<<>>( + B, N, K, Dp, Din, Dout, + + positions_.flat().data(), features_.flat().data(), + neighborhood_.flat().data(), + + theta_.flat().data(), bias_.flat().data(), + + topdiff_.flat().data(), + + grad_features_->flat().data(), grad_theta_->flat().data(), + grad_bias_->flat().data()); + } +}; + +template struct FlexDeconvGrad; + +} // namespace functor +} // namespace tensorflow + +#endif // GOOGLE_CUDA diff --git a/user_ops/kernels/flex_deconv_op.cc b/user_ops/kernels/flex_deconv_op.cc new file mode 100644 index 0000000..05e5d64 --- /dev/null +++ b/user_ops/kernels/flex_deconv_op.cc @@ -0,0 +1,103 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "flex_deconv_op.h" + +#include +#include + +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/op_kernel.h" + +namespace tensorflow { + +// Forward-Pass (CPU, GPU) +// -------------------------------------------------- +template +class FlexDeconvOp : public OpKernel { + public: + explicit FlexDeconvOp(OpKernelConstruction* ctx) : OpKernel(ctx) {} + + void Compute(OpKernelContext* ctx) override { + // printf("--> Compute CPU Version <--\n"); + const Tensor& features_ = ctx->input(0); + const Tensor& theta_ = ctx->input(1); + const Tensor& bias_ = ctx->input(2); + const Tensor& neighborhood_ = ctx->input(3); + const Tensor& positions_ = ctx->input(4); + + const int B = neighborhood_.shape().dim_size(0); + const int N = neighborhood_.shape().dim_size(2); + const int Dout = theta_.shape().dim_size(3); + + Tensor* output_ = nullptr; + OP_REQUIRES_OK( + ctx, ctx->allocate_output(0, TensorShape({B, Dout, N}), &output_)); + + ::tensorflow::functor::FlexDeconvFunctor()( + ctx, features_, theta_, bias_, neighborhood_, positions_, output_); + } + + private: + TF_DISALLOW_COPY_AND_ASSIGN(FlexDeconvOp); +}; + +// Backward-Pass (CPU, GPU) +// -------------------------------------------------- +template +class FlexDeconvGradOp : public OpKernel { + public: + explicit FlexDeconvGradOp(OpKernelConstruction* ctx) : OpKernel(ctx) {} + + void Compute(OpKernelContext* ctx) override { + // printf("--> Compute CPU Version <--\n"); + const Tensor& features_ = ctx->input(0); + const Tensor& theta_ = ctx->input(1); + const Tensor& bias_ = ctx->input(2); + const Tensor& neighborhood_ = ctx->input(3); + const Tensor& positions_ = ctx->input(4); + + const Tensor& topdiff_ = ctx->input(5); + + // specify output shape + Tensor* grad_features_ = nullptr; + Tensor* grad_theta_ = nullptr; + Tensor* grad_bias_ = nullptr; + + OP_REQUIRES_OK(ctx, + ctx->allocate_output(0, features_.shape(), &grad_features_)); + OP_REQUIRES_OK(ctx, ctx->allocate_output(1, theta_.shape(), &grad_theta_)); + OP_REQUIRES_OK(ctx, ctx->allocate_output(2, bias_.shape(), &grad_bias_)); + + ::tensorflow::functor::FlexDeconvGrad()( + ctx, features_, theta_, bias_, neighborhood_, positions_, topdiff_, + grad_features_, grad_theta_, grad_bias_); + } +}; + +#define OPNAME(NAME) NAME##Op +#define REGISTER(NAME, Dtype) \ + REGISTER_KERNEL_BUILDER( \ + Name(#NAME).Device(DEVICE_CPU).TypeConstraint("T"), \ + OPNAME(NAME) < CPUDevice, Dtype >); \ + REGISTER_KERNEL_BUILDER( \ + Name(#NAME).Device(DEVICE_GPU).TypeConstraint("T"), \ + OPNAME(NAME) < GPUDevice, Dtype >); + +REGISTER(FlexDeconv, float); +REGISTER(FlexDeconvGrad, float); + +} // namespace tensorflow diff --git a/user_ops/kernels/flex_deconv_op.h b/user_ops/kernels/flex_deconv_op.h new file mode 100644 index 0000000..49ed8a9 --- /dev/null +++ b/user_ops/kernels/flex_deconv_op.h @@ -0,0 +1,53 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#ifndef USER_OPS_KERNELS_FLEX_DECONV_OP_H_ +#define USER_OPS_KERNELS_FLEX_DECONV_OP_H_ + +#include "tensorflow/core/framework/op_kernel.h" + +namespace tensorflow { +class OpKernelContext; +class Tensor; + +using CPUDevice = Eigen::ThreadPoolDevice; +using GPUDevice = Eigen::GpuDevice; +} // namespace tensorflow + +namespace tensorflow { +namespace functor { + +template +struct FlexDeconvFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + Tensor* output_); +}; + +template +struct FlexDeconvGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& theta_, const Tensor& bias_, + const Tensor& neighborhood_, const Tensor& positions_, + const Tensor& topdiff_, Tensor* grad_features_, + Tensor* grad_theta_, Tensor* grad_bias_); +}; + +} // namespace functor +} // namespace tensorflow + +#endif // USER_OPS_KERNELS_FLEX_DECONV_OP_H_ diff --git a/user_ops/kernels/flex_pool_kernel.cc b/user_ops/kernels/flex_pool_kernel.cc new file mode 100644 index 0000000..4158286 --- /dev/null +++ b/user_ops/kernels/flex_pool_kernel.cc @@ -0,0 +1,102 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "flex_pool_op.h" +#include "tensorflow/core/framework/op.h" + +namespace tensorflow { + +namespace functor { + +template +struct FlexPoolFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& neighborhood_, Tensor* output_, + Tensor* argmax_) { + const auto features = features_.tensor(); + const auto neighborhood = neighborhood_.tensor(); + + auto output = output_->tensor(); + auto argmax = argmax_->tensor(); + + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int D = features_.dim_size(1); + + output.setConstant(Eigen::NumTraits::lowest()); + argmax.setZero(); // stores global id + + for (int b = 0; b < B; ++b) { + for (int d = 0; d < D; ++d) { + for (int n = 0; n < N; ++n) { + // max in neighborhood + for (int k_ = 0; k_ < K; ++k_) { + const int other_global_id = neighborhood(b, k_, n); + if (output(b, d, n) < features(b, d, other_global_id)) { + argmax(b, d, n) = other_global_id; + output(b, d, n) = features(b, d, other_global_id); + } + } + } + } + } + } +}; + +template struct FlexPoolFunctor; + +template +struct FlexPoolGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& neighborhood_, const Tensor& topdiff_, + const Tensor& argmax_, Tensor* grad_features_) { + // as only argmax contributes to the output + // only argmax receives the topdiff + + const auto features = features_.tensor(); + const auto neighborhood = neighborhood_.tensor(); + const auto topdiff = topdiff_.tensor(); + const auto argmax = argmax_.tensor(); + + auto grad_features = grad_features_->tensor(); + + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int D = features_.dim_size(1); + // printf("B %i K %i N %i D %i\n", B, K ,N, D); + + grad_features.setZero(); + + for (int b = 0; b < B; ++b) { + for (int d = 0; d < D; ++d) { + for (int n = 0; n < N; ++n) { + grad_features(b, d, argmax(b, d, n)) += topdiff(b, d, n); + } + } + } + } +}; + +// template struct FlexPoolGrad; +template struct FlexPoolGrad; +// template struct FlexPoolGrad; + +} // namespace functor +} // namespace tensorflow diff --git a/user_ops/kernels/flex_pool_kernel_gpu.cu.cc b/user_ops/kernels/flex_pool_kernel_gpu.cu.cc new file mode 100644 index 0000000..ecb39d2 --- /dev/null +++ b/user_ops/kernels/flex_pool_kernel_gpu.cu.cc @@ -0,0 +1,171 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#if GOOGLE_CUDA + +#define EIGEN_USE_GPU + +#include +#include + +#include "flex_pool_op.h" +#include "tensorflow/core/util/cuda_kernel_helper.h" + +namespace { +inline int up2(int len, int th) { return (len - 1) / th + 1; } + +template +__global__ void forward(const int B, const int N, const int K, const int D, + const Dtype* features, const int* neighborhood, + Dtype* output, int* argmax, float float_min_value) { + // features: each feature description for each point [B, D, N]. + // neighborhood: all K nearest neighbors [B, K, N]. + // output: each feature description for each point [B, D, N]. + // argmax: global id in neighborhood who was winning the pooling [B, D, N]. + const int b = blockIdx.z; + + for (int d = blockIdx.y * blockDim.y + threadIdx.y; d < D; + d += blockDim.y * gridDim.y) { + for (int n = blockIdx.x * blockDim.x + threadIdx.x; n < N; + n += blockDim.x * gridDim.x) { + float best_value = float_min_value; + int best_id = 0; + + const int current_flat = b * D * N + d * N + n; + + for (int k_ = 0; k_ < K; ++k_) { + const int other_global_id = neighborhood[b * K * N + k_ * N + n]; + const float v = features[b * D * N + d * N + other_global_id]; + + if (best_value < v) { + best_id = other_global_id; + best_value = v; + } + } + + output[current_flat] = best_value; + argmax[current_flat] = best_id; + } + } +} + +template +__global__ void backward(const int B, const int N, const int K, const int D, + + const Dtype* features, const int* neighborhood, + const Dtype* topdiff, const int* argmax, + + Dtype* grad_features) { + // features: each feature description for each point [B, D, N]. + // neighborhood: all K nearest neighbors [B, K, N]. + // gradients: topdiff[B, D, N]. + // argmax: argmax[B, D, N]. + // grad_features: gradient to each feature description for each point [B, D, + // N]. + const int b = blockIdx.z; + + for (int d = blockIdx.y * blockDim.y + threadIdx.y; d < D; + d += blockDim.y * gridDim.y) { + for (int n = blockIdx.x * blockDim.x + threadIdx.x; n < N; + n += blockDim.x * gridDim.x) { + const int top_id_flat = b * D * N + d * N + n; + const int argmax_id = argmax[top_id_flat]; + const int bottom_id_flat = b * D * N + d * N + argmax_id; + + // TODO(patwie): scattered write, yeah :-( + tensorflow::CudaAtomicAdd(&grad_features[bottom_id_flat], + topdiff[top_id_flat]); + } + } +} + +} // namespace + +namespace tensorflow { +namespace functor { + +template +struct FlexPoolFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& neighborhood_, Tensor* output_, + Tensor* argmax_) { + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int D = features_.dim_size(1); + + const int threads = 32; + dim3 block(threads, threads, 1); + dim3 grid(up2(N, threads), up2(D, threads), B); + + forward<<>>( + B, N, K, D, + + features_.flat().data(), neighborhood_.flat().data(), + + output_->flat().data(), argmax_->flat().data(), + + std::numeric_limits::lowest()); + + if (!ctx->eigen_gpu_device().ok()) { + ctx->SetStatus( + tensorflow::errors::Internal("CUDA: FlexPoolFunctor Error!")); + } + } +}; + +template struct FlexPoolFunctor; + +template +struct FlexPoolGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& neighborhood_, const Tensor& topdiff_, + const Tensor& argmax_, Tensor* grad_features_) { + // get dimensions + const int B = neighborhood_.dim_size(0); + const int K = neighborhood_.dim_size(1); + const int N = neighborhood_.dim_size(2); + const int D = features_.dim_size(1); + + const int threads = 32; + dim3 block(threads, threads, 1); + dim3 grid(up2(N, threads), up2(D, threads), B); + + cudaMemset(grad_features_->flat().data(), 0, + grad_features_->NumElements() * sizeof(Dtype)); + + backward<<>>( + B, N, K, D, + + features_.flat().data(), neighborhood_.flat().data(), + + topdiff_.flat().data(), argmax_.flat().data(), + + grad_features_->flat().data()); + + if (!ctx->eigen_gpu_device().ok()) { + ctx->SetStatus(tensorflow::errors::Internal("CUDA: FlexPoolGrad Error!")); + } + } +}; + +template struct FlexPoolGrad; + +} // namespace functor +} // namespace tensorflow + +#endif // GOOGLE_CUDA diff --git a/user_ops/kernels/flex_pool_op.cc b/user_ops/kernels/flex_pool_op.cc new file mode 100644 index 0000000..508a8dd --- /dev/null +++ b/user_ops/kernels/flex_pool_op.cc @@ -0,0 +1,113 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "flex_pool_op.h" + +#include +#include + +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/op_kernel.h" +#include "tensorflow/core/framework/register_types.h" + +namespace tensorflow { + +// Forward-Pass (CPU, GPU) +// -------------------------------------------------- +template +class FlexPoolOp : public OpKernel { + public: + explicit FlexPoolOp(OpKernelConstruction* ctx) : OpKernel(ctx) {} + + void Compute(OpKernelContext* ctx) override { + // printf("--> Compute CPU Version <--\n"); + const Tensor& features_ = ctx->input(0); + const Tensor& neighborhood_ = ctx->input(1); + + const int B = features_.dim_size(0); + const int D = features_.dim_size(1); + const int N = features_.dim_size(2); + + Tensor* output_ = nullptr; + OP_REQUIRES_OK(ctx, + ctx->allocate_output(0, TensorShape({B, D, N}), &output_)); + + Tensor* argmax_ = nullptr; + OP_REQUIRES_OK(ctx, + ctx->allocate_output(1, TensorShape({B, D, N}), &argmax_)); + + ::tensorflow::functor::FlexPoolFunctor()( + ctx, features_, neighborhood_, output_, argmax_); + } + + private: + TF_DISALLOW_COPY_AND_ASSIGN(FlexPoolOp); +}; + +// Backward-Pass (CPU, GPU) +// -------------------------------------------------- +template +class FlexPoolGradOp : public OpKernel { + public: + explicit FlexPoolGradOp(OpKernelConstruction* ctx) : OpKernel(ctx) {} + + void Compute(OpKernelContext* ctx) override { + // printf("--> Compute CPU Version <--\n"); + const Tensor& features_ = ctx->input(0); + const Tensor& neighborhood_ = ctx->input(1); + const Tensor& topdiff_ = ctx->input(2); + const Tensor& argmax_ = ctx->input(3); + + // specify output shape + Tensor* grad_features_ = nullptr; + + OP_REQUIRES_OK(ctx, + ctx->allocate_output(0, features_.shape(), &grad_features_)); + + ::tensorflow::functor::FlexPoolGrad()( + ctx, features_, neighborhood_, topdiff_, argmax_, grad_features_); + } +}; + +// Register the CPU kernels. +#define REGISTER_FLEXPOOL_OP_CPU(T) \ + REGISTER_KERNEL_BUILDER( \ + Name("FlexPool").Device(DEVICE_CPU).TypeConstraint("T"), \ + FlexPoolOp) \ + REGISTER_KERNEL_BUILDER( \ + Name("FlexPoolGrad").Device(DEVICE_CPU).TypeConstraint("T"), \ + FlexPoolGradOp) + +TF_CALL_float(REGISTER_FLEXPOOL_OP_CPU); +#undef REGISTER_FLEXPOOL_OP_CPU + +// Register the GPU kernels. +#ifdef GOOGLE_CUDA + +#define REGISTER_FLEXPOOL_OP_GPU(T) \ + REGISTER_KERNEL_BUILDER( \ + Name("FlexPool").Device(DEVICE_GPU).TypeConstraint("T"), \ + FlexPoolOp) \ + REGISTER_KERNEL_BUILDER( \ + Name("FlexPoolGrad").Device(DEVICE_GPU).TypeConstraint("T"), \ + FlexPoolGradOp) + +TF_CALL_float(REGISTER_FLEXPOOL_OP_GPU); +#undef REGISTER_FLEXPOOL_OP_GPU + +#endif // GOOGLE_CUDA + +} // namespace tensorflow diff --git a/user_ops/kernels/flex_pool_op.h b/user_ops/kernels/flex_pool_op.h new file mode 100644 index 0000000..bc43b35 --- /dev/null +++ b/user_ops/kernels/flex_pool_op.h @@ -0,0 +1,50 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#ifndef USER_OPS_KERNELS_FLEX_POOL_OP_H_ +#define USER_OPS_KERNELS_FLEX_POOL_OP_H_ + +#include "tensorflow/core/framework/op_kernel.h" + +namespace tensorflow { +class OpKernelContext; +class Tensor; + +using CPUDevice = Eigen::ThreadPoolDevice; +using GPUDevice = Eigen::GpuDevice; +} // namespace tensorflow + +namespace tensorflow { +namespace functor { + +template +struct FlexPoolFunctor { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& neighborhood_, Tensor* output_, + Tensor* argmax_); +}; + +template +struct FlexPoolGrad { + void operator()(::tensorflow::OpKernelContext* ctx, const Tensor& features_, + const Tensor& neighborhood_, const Tensor& topdiff_, + const Tensor& argmax_, Tensor* grad_features_); +}; + +} // namespace functor +} // namespace tensorflow + +#endif // USER_OPS_KERNELS_FLEX_POOL_OP_H_ diff --git a/user_ops/ops/flex_conv.cc b/user_ops/ops/flex_conv.cc new file mode 100644 index 0000000..19e696d --- /dev/null +++ b/user_ops/ops/flex_conv.cc @@ -0,0 +1,133 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/shape_inference.h" + +namespace tensorflow { + +using ::tensorflow::shape_inference::InferenceContext; +using ::tensorflow::shape_inference::ShapeHandle; + +REGISTER_OP("FlexConv") + .Input("features: T") + .Input("theta: T") + .Input("bias: T") + .Input("neighborhood: int32") + .Input("position: T") + .Output("output: T") + .Attr("T: realnumbertype") + .SetShapeFn([](::tensorflow::shape_inference::InferenceContext* c) { + const auto features = c->input(0); + const auto theta = c->input(1); + const auto bias = c->input(2); + const auto neighborhood = c->input(3); + const auto position = c->input(4); + + // we require the input to have 4 axes + ::tensorflow::shape_inference::ShapeHandle shape_hnd; + TF_RETURN_IF_ERROR(c->WithRank(features, 3, &shape_hnd)); // B x Din x Ng + TF_RETURN_IF_ERROR( + c->WithRank(theta, 4, &shape_hnd)); // 1 x Dp x Din x Dout + TF_RETURN_IF_ERROR(c->WithRank(bias, 2, &shape_hnd)); // Din x Dout + TF_RETURN_IF_ERROR( + c->WithRank(neighborhood, 3, &shape_hnd)); // B x K x N + TF_RETURN_IF_ERROR(c->WithRank(position, 3, &shape_hnd)); // B x Dp x Ng + + shape_inference::DimensionHandle merged; + + // assert B equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 0), c->Dim(neighborhood, 0), &merged)); + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 0), c->Dim(position, 0), &merged)); + + // assert Ng equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 2), c->Dim(neighborhood, 2), + &merged)); // TODO(fabi?) fix global access and remove + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 2), c->Dim(position, 2), &merged)); + + // assert Dp equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(theta, 1), c->Dim(position, 1), &merged)); + + // assert Dout equal + TF_RETURN_IF_ERROR(c->Merge(c->Dim(theta, 3), c->Dim(bias, 1), &merged)); + + // assert Din equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 1), c->Dim(theta, 2), &merged)); + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 1), c->Dim(bias, 0), &merged)); + + // specify output-shape + auto B = c->Dim(features, 0); + auto Dout = c->Dim(bias, 1); + auto N = c->Dim(neighborhood, 2); + c->set_output(0, c->MakeShape({B, Dout, N})); + + return Status::OK(); + }) + .Doc(R"doc( +Apply Sparse Convolution to inputs. + +This applies a convolution to a neighborhood of inputs. The formula for computing the output is as follows: + + `output_j = \sum_i w(x_i, x0) * x_i` + `w(x_i, x0) = ??` + +features: each feature description for each point [B, Din, N]. +theta: parameters for kernel function [1, Dp, Din, Dout]. +bias: bias for kernel function [Din, Dout]. +neighborhood: all K nearest neighbors [B, K, N]. +position: each datapoint in 3d space [B, Dp, N]. +output: each feature description for each point [B, Dout, N]. +)doc"); + +REGISTER_OP("FlexConvGrad") + .Input("features: T") + .Input("theta: T") + .Input("bias: T") + .Input("neighborhood: int32") + .Input("position: T") + .Input("gradients: T") + .Output("grad_features: T") + .Output("grad_theta: T") + .Output("grad_bias: T") + .Attr("T: realnumbertype") + .SetShapeFn([](InferenceContext* c) { + c->set_output(0, c->input(0)); // features + c->set_output(1, c->input(1)); // theta + c->set_output(2, c->input(2)); // bias + return ::tensorflow::Status::OK(); + }) + .Doc(R"doc( +Returns gradients of Sparse Convolution to inputs. + +gradients: topdiff[B, N, Dout]. +neighborhood: all K nearest neighbors [B, K, N]. +position: each datapoint in 3d space [B, Dp, N]. +features: each feature description for each point [B, Din, N]. +theta: parameters for kernel function [1, Dp, Din, Dout]. +bias: bias for kernel function [Din, Dout]. +grad_features: gradient to each feature description for each point [B, N, Din]. +grad_theta: gradient to parameters for kernel function [1, Dp, Din, Dout]. +grad_bias: gradient to bias for kernel function [Din, Dout]. +)doc"); + +} // namespace tensorflow diff --git a/user_ops/ops/flex_deconv.cc b/user_ops/ops/flex_deconv.cc new file mode 100644 index 0000000..90028db --- /dev/null +++ b/user_ops/ops/flex_deconv.cc @@ -0,0 +1,129 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/shape_inference.h" + +namespace tensorflow { + +using ::tensorflow::shape_inference::InferenceContext; +using ::tensorflow::shape_inference::ShapeHandle; + +REGISTER_OP("FlexDeconv") + .Input("features: T") + .Input("theta: T") + .Input("bias: T") + .Input("neighborhood: int32") + .Input("position: T") + .Output("output: T") + .Attr("T: realnumbertype") + .SetShapeFn([](::tensorflow::shape_inference::InferenceContext* c) { + const auto features = c->input(0); + const auto theta = c->input(1); + const auto bias = c->input(2); + const auto neighborhood = c->input(3); + const auto position = c->input(4); + + // we require the input to have 4 axes + ::tensorflow::shape_inference::ShapeHandle shape_hnd; + TF_RETURN_IF_ERROR(c->WithRank(features, 3, &shape_hnd)); // B x Din x N + TF_RETURN_IF_ERROR( + c->WithRank(theta, 4, &shape_hnd)); // 1 x Dp x Din x Dout + TF_RETURN_IF_ERROR(c->WithRank(bias, 2, &shape_hnd)); // Din x Dout + TF_RETURN_IF_ERROR( + c->WithRank(neighborhood, 3, &shape_hnd)); // B x K x N + TF_RETURN_IF_ERROR(c->WithRank(position, 3, &shape_hnd)); // B x Dp x N + + shape_inference::DimensionHandle merged; + + // assert B equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 0), c->Dim(neighborhood, 0), &merged)); + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 0), c->Dim(position, 0), &merged)); + + // assert N equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 2), c->Dim(neighborhood, 2), &merged)); + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 2), c->Dim(position, 2), &merged)); + + // assert Dp equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(theta, 1), c->Dim(position, 1), &merged)); + + // assert Dout equal + TF_RETURN_IF_ERROR(c->Merge(c->Dim(theta, 3), c->Dim(bias, 1), &merged)); + + // assert Din equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 1), c->Dim(theta, 2), &merged)); + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 1), c->Dim(bias, 0), &merged)); + + // specify output-shape + auto B = c->Dim(features, 0); + auto Dout = c->Dim(bias, 1); + auto N = c->Dim(neighborhood, 2); + c->set_output(0, c->MakeShape({B, Dout, N})); + + return Status::OK(); + }) + .Doc(R"doc( +Apply Sparse Convolution to inputs. + +This applies a deconvolution to a neighborhood of inputs. F_i spread its value to all neighbors. + +features: each feature description for each point [B, Din, N]. +theta: parameters for kernel function [1, Dp, Din, Dout]. +bias: bias for kernel function [Din, Dout]. +neighborhood: all K nearest neighbors [B, K, N]. +position: each datapoint in 3d space [B, Dp, N]. +output: each feature description for each point [B, Dout, N]. +)doc"); + +REGISTER_OP("FlexDeconvGrad") + .Input("features: T") + .Input("theta: T") + .Input("bias: T") + .Input("neighborhood: int32") + .Input("position: T") + .Input("gradients: T") + .Output("grad_features: T") + .Output("grad_theta: T") + .Output("grad_bias: T") + .Attr("T: realnumbertype") + .SetShapeFn([](InferenceContext* c) { + c->set_output(0, c->input(0)); // features + c->set_output(1, c->input(1)); // theta + c->set_output(2, c->input(2)); // bias + return ::tensorflow::Status::OK(); + }) + .Doc(R"doc( +Returns gradients of Sparse Deconvolution to inputs. + +gradients: topdiff[B, N, Dout]. +neighborhood: all K nearest neighbors [B, K, N]. +position: each datapoint in 3d space [B, Dp, N]. +features: each feature description for each point [B, Din, N]. +theta: parameters for kernel function [1, Dp, Din, Dout]. +bias: bias for kernel function [Din, Dout]. +grad_features: gradient to each feature description for each point [B, N, Din]. +grad_theta: gradient to parameters for kernel function [1, Dp, Din, Dout]. +grad_bias: gradient to bias for kernel function [Din, Dout]. +)doc"); + +} // namespace tensorflow diff --git a/user_ops/ops/flex_pool.cc b/user_ops/ops/flex_pool.cc new file mode 100644 index 0000000..26ecf1e --- /dev/null +++ b/user_ops/ops/flex_pool.cc @@ -0,0 +1,93 @@ +/* Copyright 2017 ComputerGraphics Tuebingen. 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. +==============================================================================*/ +//Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/shape_inference.h" + +namespace tensorflow { + +using ::tensorflow::shape_inference::InferenceContext; +using ::tensorflow::shape_inference::ShapeHandle; + +REGISTER_OP("FlexPool") + .Input("features: T") + .Input("neighborhood: int32") + .Output("output: T") + .Output("argmax: int32") + .Attr("T: realnumbertype") + .SetShapeFn([](::tensorflow::shape_inference::InferenceContext* c) { + const auto features = c->input(0); + const auto neighborhood = c->input(1); + + // we require the input to have 3 axes + ::tensorflow::shape_inference::ShapeHandle shape_hnd; + TF_RETURN_IF_ERROR(c->WithRank(features, 3, &shape_hnd)); // B x D x N + TF_RETURN_IF_ERROR( + c->WithRank(neighborhood, 3, &shape_hnd)); // B x K x N + + shape_inference::DimensionHandle merged; + + // assert B equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 0), c->Dim(neighborhood, 0), &merged)); + + // assert N equal + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(features, 2), c->Dim(neighborhood, 2), &merged)); + + // specify output-shape + auto B = c->Dim(features, 0); + auto D = c->Dim(features, 1); + auto N = c->Dim(features, 2); + c->set_output(0, c->MakeShape({B, D, N})); + c->set_output(1, c->MakeShape({B, D, N})); + + return Status::OK(); + }) + .Doc(R"doc( +Apply Sparse Pooling to inputs. + +This applies a max-pooling to a neighborhood of inputs. T + +features: each feature description for each point [B, D, N]. +neighborhood: all K nearest neighbors [B, K, N]. +output: each feature description for each point [B, D, N]. +argmax: global id in neighborhood who was winning the pooling [B, D, N]. This is needed for gradients. +)doc"); + +REGISTER_OP("FlexPoolGrad") + .Input("features: T") + .Input("neighborhood: int32") + .Input("gradients: T") + .Input("argmax: int32") + .Output("grad_features: T") + .Attr("T: realnumbertype") + .SetShapeFn([](InferenceContext* c) { + c->set_output(0, c->input(0)); // features + return ::tensorflow::Status::OK(); + }) + .Doc(R"doc( +Returns gradients of MaxPool to inputs. + +features: each feature description for each point [B, D, N]. +neighborhood: all K nearest neighbors [B, K, N]. +gradients: topdiff[B, D, N]. +argmax: argmax[B, D, N]. +grad_features: gradient to each feature description for each point [B, D, N]. + +)doc"); + +} // namespace tensorflow diff --git a/user_ops/profile_flexconv.py b/user_ops/profile_flexconv.py new file mode 100644 index 0000000..3cc38e7 --- /dev/null +++ b/user_ops/profile_flexconv.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2017 ComputerGraphics Tuebingen. 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. +# ============================================================================== +# Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + + +import numpy as np +import tensorflow as tf + +from PointTestCase import FakePointCloud, random_values +from __init__ import flex_conv + +""" +export LD_LIBRARY_PATH=/graphics/opt/opt_Ubuntu16.04/cuda/toolkit_9.0/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH +""" + + +np.random.seed(42) +tf.set_random_seed(42) + +N = 8 +TPC = FakePointCloud(8, 4096, N, 64, 64, 2, 1, N) + + +class PointTestCase(object): + + def __init__(self, data): + self.position = random_values([data.B, data.Dp, data.N]) + self.features = random_values([data.B, data.Din, data.N]) + + # make sure, each neighbor hood has no duplicates and first entry is point n + # THIS IS IMPORTANT!! + self.neighborhood = np.zeros((data.B, data.K, data.N), dtype=np.int32) + for b in range(data.B): + for n in range(data.N): + x = np.arange(data.N) + # does not support axis, hence the loop + np.random.shuffle(x) + offset = np.argwhere(x == n)[0][0] + # roll array such that n is first entry + x = np.roll(x, -offset) + self.neighborhood[b, :, n] = x[:data.K].astype(np.int32) + + self.neighborhood_ds = np.zeros((data.B, data.K, data.N2), dtype=np.int32) + for b in range(data.B): + for n in range(data.N2): + x = np.arange(data.N2) + # does not support axis, hence the loop + np.random.shuffle(x) + offset = np.argwhere(x == n)[0][0] + # roll array such that n is first entry + x = np.roll(x, -offset) + self.neighborhood[b, :, n] = x[:data.K].astype(np.int32) + + self.theta = random_values([data.Degree, data.Dp, data.Din, data.Dout]) + self.bias = random_values([data.Din, data.Dout]) + + def init_ops(self): + self.features_op = tf.Variable(self.features, name='f') + self.position_op = tf.Variable(self.position, name='p') + self.neighborhood_op = tf.Variable(self.neighborhood, name='n') + self.neighborhood_ds_op = tf.Variable(self.neighborhood_ds, name='m') + self.theta_op = tf.Variable(self.theta, name='t') + self.bias_op = tf.Variable(self.bias, name='b') + + +TestCase = PointTestCase(data=TPC) +TestCase.init_ops() + + +forward_op = flex_conv(TestCase.features_op, + TestCase.theta_op, TestCase.bias_op, TestCase.neighborhood_op, + TestCase.position_op, degree=1) + +builder = tf.profiler.ProfileOptionBuilder +opts = builder(builder.time_and_memory()).order_by('micros').build() + +with tf.contrib.tfprof.ProfileContext('./.profiling_outputs/flex_conv') as pctx: + + with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess: + sess.run(tf.global_variables_initializer()) + + back_prop = tf.gradients(forward_op, [TestCase.theta_op, TestCase.bias_op, TestCase.features_op]) + back_prop2 = tf.gradients(forward_op, [TestCase.theta_op, TestCase.bias_op, + TestCase.features_op, TestCase.position_op]) + + # warmup + for i in range(2): + actual = sess.run([forward_op, back_prop]) + + # benchmark + for i in range(10): + pctx.trace_next_step() + pctx.dump_next_step() + _ = sess.run([forward_op]) + pctx.profiler.profile_operations(options=opts) + + for i in range(10): + pctx.trace_next_step() + pctx.dump_next_step() + _ = sess.run([back_prop]) + pctx.profiler.profile_operations(options=opts) diff --git a/user_ops/test_flex_convolution.py b/user_ops/test_flex_convolution.py new file mode 100644 index 0000000..4465474 --- /dev/null +++ b/user_ops/test_flex_convolution.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2017 ComputerGraphics Tuebingen. 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. +# ============================================================================== +# Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + + +from PointTestCase import TPC, PointTestCase, summary +import tensorflow as tf + +from __init__ import flex_convolution + + +class FlexConvTest(PointTestCase): + def __init__(self, methodName="runTest"): + super(FlexConvTest, self).__init__(methodName) + + def _forward(self, use_gpu=False, force_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu) as sess: + actual_op = flex_convolution(self.features_op, + self.position_op, self.neighborhood_op, + self.theta_op, self.bias_op) + actual = sess.run(actual_op) + return actual + + def test_forward(self): + cpu = self._forward(use_gpu=False) + gpu = self._forward(use_gpu=True) + self.assertAllClose(cpu, gpu, 1e-5, 1e-5) + + def _backward_features(self, use_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu): + actual_op = flex_convolution(self.features_op, + self.position_op, self.neighborhood_op, + self.theta_op, self.bias_op) + graph_features_grad, num_features_grad = tf.test.compute_gradient( + [self.features_op], [self.features.shape], actual_op, + TPC.expected_output_shape())[0] + summary(num_features_grad, graph_features_grad, 'self.features') + + err = tf.test.compute_gradient_error([self.features_op], + [self.features.shape], + actual_op, TPC.expected_output_shape()) + self.assertLess(err, 1e-2) + + def _backward_bias(self, use_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu): + actual_op = flex_convolution(self.features_op, + self.position_op, self.neighborhood_op, + self.theta_op, self.bias_op) + + graph_bias_grad, num_bias_grad = tf.test.compute_gradient( + [self.bias_op], [self.bias.shape], actual_op, + TPC.expected_output_shape())[0] + summary(num_bias_grad, graph_bias_grad, 'self.bias') + + err = tf.test.compute_gradient_error([self.bias_op], + [self.bias.shape], actual_op, + TPC.expected_output_shape()) + self.assertLess(err, 1e-2) + + def _backward_theta(self, use_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu): + actual_op = flex_convolution(self.features_op, + self.position_op, self.neighborhood_op, + self.theta_op, self.bias_op) + + graph_theta_grad, num_theta_grad = tf.test.compute_gradient( + [self.theta_op], [self.theta.shape], actual_op, + TPC.expected_output_shape())[0] + summary(num_theta_grad, graph_theta_grad, 'self.theta') + + err = tf.test.compute_gradient_error([self.theta_op], + [self.theta.shape], actual_op, + TPC.expected_output_shape()) + self.assertLess(err, 1e-2) + + def test_backward_features(self): + self._backward_features(use_gpu=False) + self._backward_features(use_gpu=True) + + def test_backward_bias(self): + self._backward_bias(use_gpu=False) + self._backward_bias(use_gpu=True) + + def test_backward_theta(self): + self._backward_theta(use_gpu=False) + self._backward_theta(use_gpu=True) + + +if __name__ == '__main__': + tf.test.main() diff --git a/user_ops/test_flex_convolution_transpose.py b/user_ops/test_flex_convolution_transpose.py new file mode 100644 index 0000000..d627793 --- /dev/null +++ b/user_ops/test_flex_convolution_transpose.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2017 ComputerGraphics Tuebingen. 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. +# ============================================================================== +# Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + + +from PointTestCase import TPC, PointTestCase, summary +import tensorflow as tf +from __init__ import flex_convolution_transpose + + +class FlexDeconvTest(PointTestCase): + def __init__(self, methodName="runTest"): + super(FlexDeconvTest, self).__init__(methodName) + + def _forward(self, use_gpu=False, force_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu) as sess: + actual = flex_convolution_transpose(self.features_op, + self.position_op, self.neighborhood_op, + self.theta_op, self.bias_op) + + actual = sess.run(actual) + + return actual + + def test_forward(self): + cpu = self._forward(use_gpu=False) + gpu = self._forward(use_gpu=True) + summary(cpu, gpu, 'self.features') + self.assertAllClose(cpu, gpu, rtol=1e-05) + + def _backward_features(self, use_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu): + actual_op = flex_convolution_transpose(self.features_op, + self.position_op, + self.neighborhood_op, + self.theta_op, self.bias_op) + + graph_features_grad, num_features_grad = tf.test.compute_gradient( + [self.features_op], [self.features.shape], actual_op, + TPC.expected_output_shape())[0] + summary(num_features_grad, graph_features_grad, + 'self.features', max_outputs=1200000) + + err = tf.test.compute_gradient_error([self.features_op], + [self.features.shape], + actual_op, TPC.expected_output_shape()) + self.assertLess(err, 1e-2) + + def _backward_bias(self, use_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu): + actual_op = flex_convolution_transpose(self.features_op, + self.position_op, + self.neighborhood_op, + self.theta_op, self.bias_op) + + graph_bias_grad, num_bias_grad = tf.test.compute_gradient( + [self.bias_op], [self.bias.shape], actual_op, + TPC.expected_output_shape())[0] + summary(num_bias_grad, graph_bias_grad, 'self.bias') + + err = tf.test.compute_gradient_error([self.bias_op], + [self.bias.shape], actual_op, + TPC.expected_output_shape()) + self.assertLess(err, 1e-2) + + def _backward_theta(self, use_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu): + actual_op = flex_convolution_transpose(self.features_op, + self.position_op, + self.neighborhood_op, + self.theta_op, self.bias_op) + + graph_theta_grad, num_theta_grad = tf.test.compute_gradient( + [self.theta_op], [self.theta.shape], actual_op, + TPC.expected_output_shape())[0] + summary(num_theta_grad, graph_theta_grad, 'self.theta') + + err = tf.test.compute_gradient_error([self.theta_op], + [self.theta.shape], actual_op, + TPC.expected_output_shape()) + self.assertLess(err, 1e-2) + + def test_backward_features(self): + self._backward_features(use_gpu=False) + self._backward_features(use_gpu=True) + + def test_backward_bias(self): + self._backward_bias(use_gpu=False) + self._backward_bias(use_gpu=True) + + def test_backward_theta(self): + self._backward_theta(use_gpu=False) + self._backward_theta(use_gpu=True) + + +if __name__ == '__main__': + tf.test.main() diff --git a/user_ops/test_flex_pooling.py b/user_ops/test_flex_pooling.py new file mode 100644 index 0000000..c97a9bd --- /dev/null +++ b/user_ops/test_flex_pooling.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Copyright 2017 ComputerGraphics Tuebingen. 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. +# ============================================================================== +# Authors: Fabian Groh, Patrick Wieschollek, Hendrik P.A. Lensch + + +from PointTestCase import PointTestCase +import tensorflow as tf +import numpy as np + +from __init__ import flex_pooling + + +class FlexPoolTest(PointTestCase): + def __init__(self, methodName="runTest"): + super(FlexPoolTest, self).__init__(methodName) + + def _forward(self, use_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu) as sess: + actual_op, winner_op = flex_pooling(self.features_op, self.neighborhood_op) + actual = sess.run(actual_op) + return actual + + def test_forward(self): + cpu = self._forward(use_gpu=False) + gpu = self._forward(use_gpu=True) + self.assertAllClose(cpu, gpu) + + def test_backward(self): + cpu, winner_cpu = self._backward(use_gpu=False) + gpu, winner_gpu = self._backward(use_gpu=True) + self.assertAllClose(cpu, gpu) + self.assertAllClose(cpu[winner_cpu == 0].sum(), 0) + self.assertAllClose(gpu[winner_gpu == 0].sum(), 0) + + def _backward(self, use_gpu=False): + self.init_ops() + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu) as sess: + actual_op, winner_op = flex_pooling( + self.features_op, + self.neighborhood_op) + + graph_features_grad = tf.gradients(actual_op, [self.features_op])[0] + + dx, winner = sess.run([graph_features_grad, winner_op]) + return dx, winner + + def _simple_backward(self, use_gpu=False): + # BN + x = np.array([[[1], [2], [5], [3]]]).transpose(0, 2, 1) + n = np.array([[[0, 1, 2, 3], [1, 2, 3, 0], [2, 3, 0, 1], [3, 0, 1, 2, ]]]).transpose(0, 2, 1) + + x = tf.convert_to_tensor(x.astype(np.float32)) + n = tf.convert_to_tensor(n.astype(np.int32)) + + with self.test_session(use_gpu=use_gpu, force_gpu=use_gpu) as sess: + actual_op, winner_op = flex_pooling(x, n) + graph_features_grad = tf.gradients(actual_op, [x])[0] + return sess.run(graph_features_grad) + + def test_backward_simple(self): + cpu = self._simple_backward(use_gpu=False) + cpu[0, 0, 2] -= 4 + self.assertEqual(cpu.sum(), 0) + + gpu = self._simple_backward(use_gpu=True) + gpu[0, 0, 2] -= 4 + self.assertEqual(gpu.sum(), 0) + + +if __name__ == '__main__': + tf.test.main()