Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
POSTECH-CVLab
GitHub Repository: POSTECH-CVLab/PyTorch-StudioGAN
Path: blob/master/src/utils/style_ops/bias_act.cpp
809 views
1
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
//
3
// NVIDIA CORPORATION and its licensors retain all intellectual property
4
// and proprietary rights in and to this software, related documentation
5
// and any modifications thereto. Any use, reproduction, disclosure or
6
// distribution of this software and related documentation without an express
7
// license agreement from NVIDIA CORPORATION is strictly prohibited.
8
9
#include <torch/extension.h>
10
#include <ATen/cuda/CUDAContext.h>
11
#include <c10/cuda/CUDAGuard.h>
12
#include "bias_act.h"
13
14
//------------------------------------------------------------------------
15
16
static bool has_same_layout(torch::Tensor x, torch::Tensor y)
17
{
18
if (x.dim() != y.dim())
19
return false;
20
for (int64_t i = 0; i < x.dim(); i++)
21
{
22
if (x.size(i) != y.size(i))
23
return false;
24
if (x.size(i) >= 2 && x.stride(i) != y.stride(i))
25
return false;
26
}
27
return true;
28
}
29
30
//------------------------------------------------------------------------
31
32
static torch::Tensor bias_act(torch::Tensor x, torch::Tensor b, torch::Tensor xref, torch::Tensor yref, torch::Tensor dy, int grad, int dim, int act, float alpha, float gain, float clamp)
33
{
34
// Validate arguments.
35
TORCH_CHECK(x.is_cuda(), "x must reside on CUDA device");
36
TORCH_CHECK(b.numel() == 0 || (b.dtype() == x.dtype() && b.device() == x.device()), "b must have the same dtype and device as x");
37
TORCH_CHECK(xref.numel() == 0 || (xref.sizes() == x.sizes() && xref.dtype() == x.dtype() && xref.device() == x.device()), "xref must have the same shape, dtype, and device as x");
38
TORCH_CHECK(yref.numel() == 0 || (yref.sizes() == x.sizes() && yref.dtype() == x.dtype() && yref.device() == x.device()), "yref must have the same shape, dtype, and device as x");
39
TORCH_CHECK(dy.numel() == 0 || (dy.sizes() == x.sizes() && dy.dtype() == x.dtype() && dy.device() == x.device()), "dy must have the same dtype and device as x");
40
TORCH_CHECK(x.numel() <= INT_MAX, "x is too large");
41
TORCH_CHECK(b.dim() == 1, "b must have rank 1");
42
TORCH_CHECK(b.numel() == 0 || (dim >= 0 && dim < x.dim()), "dim is out of bounds");
43
TORCH_CHECK(b.numel() == 0 || b.numel() == x.size(dim), "b has wrong number of elements");
44
TORCH_CHECK(grad >= 0, "grad must be non-negative");
45
46
// Validate layout.
47
TORCH_CHECK(x.is_non_overlapping_and_dense(), "x must be non-overlapping and dense");
48
TORCH_CHECK(b.is_contiguous(), "b must be contiguous");
49
TORCH_CHECK(xref.numel() == 0 || has_same_layout(xref, x), "xref must have the same layout as x");
50
TORCH_CHECK(yref.numel() == 0 || has_same_layout(yref, x), "yref must have the same layout as x");
51
TORCH_CHECK(dy.numel() == 0 || has_same_layout(dy, x), "dy must have the same layout as x");
52
53
// Create output tensor.
54
const at::cuda::OptionalCUDAGuard device_guard(device_of(x));
55
torch::Tensor y = torch::empty_like(x);
56
TORCH_CHECK(has_same_layout(y, x), "y must have the same layout as x");
57
58
// Initialize CUDA kernel parameters.
59
bias_act_kernel_params p;
60
p.x = x.data_ptr();
61
p.b = (b.numel()) ? b.data_ptr() : NULL;
62
p.xref = (xref.numel()) ? xref.data_ptr() : NULL;
63
p.yref = (yref.numel()) ? yref.data_ptr() : NULL;
64
p.dy = (dy.numel()) ? dy.data_ptr() : NULL;
65
p.y = y.data_ptr();
66
p.grad = grad;
67
p.act = act;
68
p.alpha = alpha;
69
p.gain = gain;
70
p.clamp = clamp;
71
p.sizeX = (int)x.numel();
72
p.sizeB = (int)b.numel();
73
p.stepB = (b.numel()) ? (int)x.stride(dim) : 1;
74
75
// Choose CUDA kernel.
76
void* kernel;
77
AT_DISPATCH_FLOATING_TYPES_AND_HALF(x.scalar_type(), "upfirdn2d_cuda", [&]
78
{
79
kernel = choose_bias_act_kernel<scalar_t>(p);
80
});
81
TORCH_CHECK(kernel, "no CUDA kernel found for the specified activation func");
82
83
// Launch CUDA kernel.
84
p.loopX = 4;
85
int blockSize = 4 * 32;
86
int gridSize = (p.sizeX - 1) / (p.loopX * blockSize) + 1;
87
void* args[] = {&p};
88
AT_CUDA_CHECK(cudaLaunchKernel(kernel, gridSize, blockSize, args, 0, at::cuda::getCurrentCUDAStream()));
89
return y;
90
}
91
92
//------------------------------------------------------------------------
93
94
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m)
95
{
96
m.def("bias_act", &bias_act);
97
}
98
99
//------------------------------------------------------------------------
100
101