models_animerun / UnFlow /ops /downsample_op.cc
doanh25032004's picture
Upload folder using huggingface_hub
872b0a0 verified
Raw
History Blame Contribute Delete
2.82 kB
#define EIGEN_USE_THREADS
#include <memory>
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/framework/common_shape_fns.h"
using namespace tensorflow;
using CPUDevice = Eigen::ThreadPoolDevice;
using GPUDevice = Eigen::GpuDevice;
void Downsample(const GPUDevice& d,
typename TTypes<float, 4>::ConstTensor images,
typename TTypes<float, 4>::Tensor output);
class DownsampleOp : public OpKernel {
public:
explicit DownsampleOp(OpKernelConstruction* c) : OpKernel(c) {
OP_REQUIRES_OK(c, c->GetAttr("scale", &scale));
}
void Compute(OpKernelContext* context) override {
const Tensor& input = context->input(0);
typename TTypes<float, 4>::ConstTensor input_data = input.tensor<float, 4>();
OP_REQUIRES(context,
input_data.dimension(1) % scale == 0 &&
input_data.dimension(2) % scale == 0,
errors::InvalidArgument("Input height and width must be divisible by scale"));
const int batch = input_data.dimension(0);
const int height = input_data.dimension(1) / scale;
const int width = input_data.dimension(2) / scale;
const int channels = input_data.dimension(3);
auto output_shape = TensorShape({batch, height, width, channels});
Tensor* output = NULL;
OP_REQUIRES_OK(context, context->allocate_output(0, output_shape, &output));
typename TTypes<float, 4>::Tensor output_data = output->tensor<float, 4>();
Downsample(context->eigen_device<GPUDevice>(), input_data, output_data);
}
private:
int scale;
};
using shape_inference::DimensionHandle;
using shape_inference::ShapeHandle;
REGISTER_OP("Downsample")
.Input("images: float")
.Attr("scale: int = 2")
.Output("out_images: float")
.SetShapeFn([](shape_inference::InferenceContext* c) {
ShapeHandle in = c->input(0);
int scale;
DimensionHandle batch = c->Dim(in, 0);
DimensionHandle channels = c->Dim(in, 3);
DimensionHandle height;
DimensionHandle width;
c->GetAttr("scale", &scale);
c->Divide(c->Dim(in, 1), scale, true, &height);
c->Divide(c->Dim(in, 2), scale, true, &width);
c->set_output(0, c->MakeShape({batch, height, width, channels}));
return Status::OK();
});
#if GOOGLE_CUDA
REGISTER_KERNEL_BUILDER(Name("Downsample").Device(DEVICE_GPU), DownsampleOp);
#endif // GOOGLE_CUDA