Add files using upload-large-folder tool
Browse files- models/protenix/__pycache__/loss.cpython-310.pyc +0 -0
- models/protenix/__pycache__/loss.cpython-311.pyc +0 -0
- models/protenix/__pycache__/protenix.cpython-310.pyc +0 -0
- models/protenix/config/__pycache__/__init__.cpython-310.pyc +0 -0
- models/protenix/config/__pycache__/__init__.cpython-311.pyc +0 -0
- models/protenix/config/__pycache__/config.cpython-310.pyc +0 -0
- models/protenix/config/__pycache__/config.cpython-311.pyc +0 -0
- models/protenix/config/__pycache__/extend_types.cpython-311.pyc +0 -0
- models/protenix/layer_norm/__init__.py +1 -0
- models/protenix/layer_norm/__pycache__/__init__.cpython-310.pyc +0 -0
- models/protenix/layer_norm/__pycache__/layer_norm.cpython-310.pyc +0 -0
- models/protenix/layer_norm/kernel/compat.h +9 -0
- models/protenix/layer_norm/kernel/layer_norm_cuda.cpp +179 -0
- models/protenix/layer_norm/kernel/layer_norm_cuda_kernel.cu +599 -0
- models/protenix/layer_norm/kernel/type_shim.h +231 -0
- models/protenix/layer_norm/layer_norm.py +198 -0
- models/protenix/layer_norm/torch_ext_compile.py +41 -0
- weight/model_v0.5.0.pt +3 -0
models/protenix/__pycache__/loss.cpython-310.pyc
ADDED
|
Binary file (47.3 kB). View file
|
|
|
models/protenix/__pycache__/loss.cpython-311.pyc
ADDED
|
Binary file (76.9 kB). View file
|
|
|
models/protenix/__pycache__/protenix.cpython-310.pyc
ADDED
|
Binary file (16.3 kB). View file
|
|
|
models/protenix/config/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (240 Bytes). View file
|
|
|
models/protenix/config/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (329 Bytes). View file
|
|
|
models/protenix/config/__pycache__/config.cpython-310.pyc
ADDED
|
Binary file (9.03 kB). View file
|
|
|
models/protenix/config/__pycache__/config.cpython-311.pyc
ADDED
|
Binary file (13.6 kB). View file
|
|
|
models/protenix/config/__pycache__/extend_types.cpython-311.pyc
ADDED
|
Binary file (2.69 kB). View file
|
|
|
models/protenix/layer_norm/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
from .layer_norm import FusedLayerNorm
|
models/protenix/layer_norm/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (180 Bytes). View file
|
|
|
models/protenix/layer_norm/__pycache__/layer_norm.cpython-310.pyc
ADDED
|
Binary file (4.43 kB). View file
|
|
|
models/protenix/layer_norm/kernel/compat.h
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#ifndef TORCH_CHECK
|
| 2 |
+
#define TORCH_CHECK AT_CHECK
|
| 3 |
+
#endif
|
| 4 |
+
|
| 5 |
+
#ifdef VERSION_GE_1_3
|
| 6 |
+
#define DATA_PTR data_ptr
|
| 7 |
+
#else
|
| 8 |
+
#define DATA_PTR data
|
| 9 |
+
#endif
|
models/protenix/layer_norm/kernel/layer_norm_cuda.cpp
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Copyright 2021- HPC-AI Technology Inc.
|
| 2 |
+
//
|
| 3 |
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
// you may not use this file except in compliance with the License.
|
| 5 |
+
// You may obtain a copy of the License at
|
| 6 |
+
//
|
| 7 |
+
// http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
//
|
| 9 |
+
// Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
// See the License for the specific language governing permissions and
|
| 13 |
+
|
| 14 |
+
#include <torch/extension.h>
|
| 15 |
+
#include <c10/cuda/CUDAGuard.h>
|
| 16 |
+
|
| 17 |
+
#include <cassert>
|
| 18 |
+
#include <vector>
|
| 19 |
+
#include <functional>
|
| 20 |
+
|
| 21 |
+
#include "compat.h"
|
| 22 |
+
|
| 23 |
+
void compute_n1_n2(at::Tensor input, at::IntArrayRef normalized_shape, int& n1, int& n2) {
|
| 24 |
+
int idiff = input.ndimension() - normalized_shape.size();
|
| 25 |
+
n2 = 1;
|
| 26 |
+
for (int i = 0; i < (int)normalized_shape.size(); ++i) {
|
| 27 |
+
assert(input.sizes()[i + idiff] == normalized_shape[i]);
|
| 28 |
+
n2 *= normalized_shape[i];
|
| 29 |
+
}
|
| 30 |
+
n1 = 1;
|
| 31 |
+
for (int i = 0; i < idiff; ++i) {
|
| 32 |
+
n1 *= input.sizes()[i];
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
void check_args(at::Tensor input, at::IntArrayRef normalized_shape, int& n1, int& n2) {
|
| 37 |
+
int64_t normalized_ndim = normalized_shape.size();
|
| 38 |
+
|
| 39 |
+
if (normalized_ndim < 1) {
|
| 40 |
+
std::stringstream ss;
|
| 41 |
+
ss << "Expected normalized_shape to be at least 1-dimensional, i.e., "
|
| 42 |
+
<< "containing at least one element, but got normalized_shape=" << normalized_shape;
|
| 43 |
+
throw std::runtime_error(ss.str());
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
auto input_shape = input.sizes();
|
| 47 |
+
auto input_ndim = input.dim();
|
| 48 |
+
|
| 49 |
+
if (input_ndim < normalized_ndim ||
|
| 50 |
+
!input_shape.slice(input_ndim - normalized_ndim).equals(normalized_shape)) {
|
| 51 |
+
std::stringstream ss;
|
| 52 |
+
ss << "Given normalized_shape=" << normalized_shape << ", expected input with shape [*";
|
| 53 |
+
for (auto size : normalized_shape) {
|
| 54 |
+
ss << ", " << size;
|
| 55 |
+
}
|
| 56 |
+
ss << "], but got input of size" << input_shape;
|
| 57 |
+
throw std::runtime_error(ss.str());
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
compute_n1_n2(input, normalized_shape, n1, n2);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
void cuda_layer_norm(at::Tensor* output, at::Tensor* mean, at::Tensor* invvar, at::Tensor* input,
|
| 64 |
+
int n1, int n2, at::IntArrayRef normalized_shape, at::Tensor* gamma,
|
| 65 |
+
at::Tensor* beta, double epsilon);
|
| 66 |
+
|
| 67 |
+
#define CHECK_CUDA(x) TORCH_CHECK(x.is_cuda(), #x " must be a CUDA tensor")
|
| 68 |
+
#define CHECK_CONTIGUOUS(x) TORCH_CHECK(x.is_contiguous(), #x " must be contiguous")
|
| 69 |
+
#define CHECK_INPUT(x) \
|
| 70 |
+
CHECK_CUDA(x); \
|
| 71 |
+
CHECK_CONTIGUOUS(x)
|
| 72 |
+
|
| 73 |
+
std::vector<at::Tensor> layer_norm_affine(at::Tensor input, at::IntArrayRef normalized_shape,
|
| 74 |
+
at::Tensor *gamma, at::Tensor *beta, double epsilon) {
|
| 75 |
+
CHECK_INPUT(input);
|
| 76 |
+
// CHECK_INPUT((*gamma));
|
| 77 |
+
// CHECK_INPUT((*beta));
|
| 78 |
+
int n1, n2;
|
| 79 |
+
check_args(input, normalized_shape, n1, n2);
|
| 80 |
+
|
| 81 |
+
const at::cuda::OptionalCUDAGuard device_guard(device_of(input));
|
| 82 |
+
|
| 83 |
+
at::Tensor output = at::empty_like(input, input.options().dtype(input.scalar_type()));
|
| 84 |
+
at::Tensor mean = at::empty({n1}, input.options().dtype(at::ScalarType::Float));
|
| 85 |
+
at::Tensor invvar = at::empty_like(mean);
|
| 86 |
+
|
| 87 |
+
cuda_layer_norm(&output, &mean, &invvar, &input, n1, n2, normalized_shape, gamma, beta, epsilon);
|
| 88 |
+
|
| 89 |
+
return {output, mean, invvar};
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
void cuda_layer_norm_gradient(at::Tensor* dout, at::Tensor* mean, at::Tensor* invvar,
|
| 93 |
+
at::Tensor* input, int n1, int n2, at::IntArrayRef normalized_shape,
|
| 94 |
+
at::Tensor* gamma, at::Tensor* beta, double epsilon,
|
| 95 |
+
at::Tensor* grad_input, at::Tensor* grad_gamma,
|
| 96 |
+
at::Tensor* grad_beta);
|
| 97 |
+
|
| 98 |
+
std::vector<at::Tensor> layer_norm_gradient_affine(at::Tensor dout, at::Tensor mean,
|
| 99 |
+
at::Tensor invvar, at::Tensor input,
|
| 100 |
+
at::IntArrayRef normalized_shape,
|
| 101 |
+
at::Tensor* gamma, at::Tensor* beta,
|
| 102 |
+
double epsilon) {
|
| 103 |
+
CHECK_INPUT(dout);
|
| 104 |
+
CHECK_INPUT(mean);
|
| 105 |
+
CHECK_INPUT(invvar);
|
| 106 |
+
CHECK_INPUT(input);
|
| 107 |
+
int n1, n2;
|
| 108 |
+
check_args(input, normalized_shape, n1, n2);
|
| 109 |
+
|
| 110 |
+
const at::cuda::OptionalCUDAGuard device_guard(device_of(input));
|
| 111 |
+
|
| 112 |
+
at::Tensor grad_input = at::empty_like(input);
|
| 113 |
+
|
| 114 |
+
at::Tensor grad_gamma;
|
| 115 |
+
at::Tensor grad_beta;
|
| 116 |
+
if (gamma != NULL)
|
| 117 |
+
grad_gamma = at::empty_like(*gamma);
|
| 118 |
+
if (beta != NULL)
|
| 119 |
+
grad_beta = at::empty_like(*beta);
|
| 120 |
+
|
| 121 |
+
if (gamma != NULL) {
|
| 122 |
+
if(beta != NULL) {
|
| 123 |
+
cuda_layer_norm_gradient(&dout, &mean, &invvar, &input, n1, n2, normalized_shape, gamma, beta,
|
| 124 |
+
epsilon, &grad_input, &grad_gamma, &grad_beta);
|
| 125 |
+
} else {
|
| 126 |
+
cuda_layer_norm_gradient(&dout, &mean, &invvar, &input, n1, n2, normalized_shape, gamma, beta,
|
| 127 |
+
epsilon, &grad_input, &grad_gamma, NULL);
|
| 128 |
+
}
|
| 129 |
+
} else {
|
| 130 |
+
if(beta != NULL) {
|
| 131 |
+
cuda_layer_norm_gradient(&dout, &mean, &invvar, &input, n1, n2, normalized_shape, gamma, beta,
|
| 132 |
+
epsilon, &grad_input, NULL, &grad_beta);
|
| 133 |
+
} else {
|
| 134 |
+
cuda_layer_norm_gradient(&dout, &mean, &invvar, &input, n1, n2, normalized_shape, gamma, beta,
|
| 135 |
+
epsilon, &grad_input, NULL, NULL);
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
return {grad_input, grad_gamma, grad_beta};
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
|
| 143 |
+
m.def("forward_none_affine", [](at::Tensor input, at::IntArrayRef normalized_shape, double epsilon) {
|
| 144 |
+
return layer_norm_affine(input, normalized_shape, NULL, NULL, epsilon);
|
| 145 |
+
}, "LayerNorm forward (CUDA)");
|
| 146 |
+
|
| 147 |
+
m.def("forward_with_bias_affine", [](at::Tensor input, at::IntArrayRef normalized_shape, at::Tensor *beta, double epsilon) {
|
| 148 |
+
return layer_norm_affine(input, normalized_shape, NULL, beta, epsilon);
|
| 149 |
+
}, "LayerNorm forward (CUDA)");
|
| 150 |
+
|
| 151 |
+
m.def("forward_with_weight_affine", [](at::Tensor input, at::IntArrayRef normalized_shape, at::Tensor *gamma, double epsilon) {
|
| 152 |
+
return layer_norm_affine(input, normalized_shape, gamma, NULL, epsilon);
|
| 153 |
+
}, "LayerNorm forward (CUDA)");
|
| 154 |
+
|
| 155 |
+
m.def("forward_with_both_affine", [](at::Tensor input, at::IntArrayRef normalized_shape, at::Tensor *gamma, at::Tensor *beta, double epsilon) {
|
| 156 |
+
return layer_norm_affine(input, normalized_shape, gamma, beta, epsilon);
|
| 157 |
+
}, "LayerNorm forward (CUDA)");
|
| 158 |
+
|
| 159 |
+
m.def("backward_none_affine", [](at::Tensor dout, at::Tensor mean, at::Tensor invvar, at::Tensor input,
|
| 160 |
+
at::IntArrayRef normalized_shape, double epsilon) {
|
| 161 |
+
return layer_norm_gradient_affine(dout, mean, invvar, input, normalized_shape, NULL, NULL, epsilon);
|
| 162 |
+
|
| 163 |
+
}, "LayerNorm backward (CUDA)");
|
| 164 |
+
|
| 165 |
+
m.def("backward_with_bias_affine", [](at::Tensor dout, at::Tensor mean, at::Tensor invvar, at::Tensor input,
|
| 166 |
+
at::IntArrayRef normalized_shape, at::Tensor *beta, double epsilon) {
|
| 167 |
+
return layer_norm_gradient_affine(dout, mean, invvar, input, normalized_shape, NULL, beta, epsilon);
|
| 168 |
+
}, "LayerNorm backward (CUDA)");
|
| 169 |
+
|
| 170 |
+
m.def("backward_with_weight_affine", [](at::Tensor dout, at::Tensor mean, at::Tensor invvar, at::Tensor input,
|
| 171 |
+
at::IntArrayRef normalized_shape, at::Tensor *gamma, double epsilon) {
|
| 172 |
+
return layer_norm_gradient_affine(dout, mean, invvar, input, normalized_shape, gamma, NULL, epsilon);
|
| 173 |
+
}, "LayerNorm backward (CUDA)");
|
| 174 |
+
|
| 175 |
+
m.def("backward_with_both_affine", [](at::Tensor dout, at::Tensor mean, at::Tensor invvar, at::Tensor input,
|
| 176 |
+
at::IntArrayRef normalized_shape, at::Tensor *gamma, at::Tensor *beta, double epsilon) {
|
| 177 |
+
return layer_norm_gradient_affine(dout, mean, invvar, input, normalized_shape, gamma, beta, epsilon);
|
| 178 |
+
}, "LayerNorm backward (CUDA)");
|
| 179 |
+
}
|
models/protenix/layer_norm/kernel/layer_norm_cuda_kernel.cu
ADDED
|
@@ -0,0 +1,599 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <cooperative_groups.h>
|
| 2 |
+
#include <cuda.h>
|
| 3 |
+
#include <cuda_runtime.h>
|
| 4 |
+
#include <torch/extension.h>
|
| 5 |
+
#include <iostream>
|
| 6 |
+
|
| 7 |
+
#include <THC/THCDeviceUtils.cuh>
|
| 8 |
+
|
| 9 |
+
#include "ATen/ATen.h"
|
| 10 |
+
#include "ATen/AccumulateType.h"
|
| 11 |
+
#include "ATen/cuda/CUDAContext.h"
|
| 12 |
+
#include "compat.h"
|
| 13 |
+
#include "type_shim.h"
|
| 14 |
+
|
| 15 |
+
#define CHECK_CUDA(x) TORCH_CHECK(x.is_cuda(), #x " must be a CUDA tensor")
|
| 16 |
+
#define CHECK_CONTIGUOUS(x) TORCH_CHECK(x.is_contiguous(), #x " must be contiguous")
|
| 17 |
+
#define CHECK_INPUT(x) \
|
| 18 |
+
CHECK_CUDA(x); \
|
| 19 |
+
CHECK_CONTIGUOUS(x)
|
| 20 |
+
|
| 21 |
+
#define WarpNum 8
|
| 22 |
+
#define WarpSize 32
|
| 23 |
+
#define BlockSzie WarpNum*WarpSize
|
| 24 |
+
|
| 25 |
+
inline __device__ void WelfordOnline(float val, float* mean, float* m2, float* count) {
|
| 26 |
+
*count += 1;
|
| 27 |
+
float delta1 = val - *mean;
|
| 28 |
+
*mean += delta1 / (*count);
|
| 29 |
+
float delta2 = val - *mean;
|
| 30 |
+
*m2 += delta1 * delta2;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
inline __device__ void WelfordOnline(float b_mean, float b_m2, float b_count, float* mean,
|
| 34 |
+
float* m2, float* count) {
|
| 35 |
+
if (b_count == 0) {
|
| 36 |
+
return;
|
| 37 |
+
}
|
| 38 |
+
float new_count = *count + b_count;
|
| 39 |
+
float nb_n = b_count / new_count;
|
| 40 |
+
float delta = b_mean - *mean;
|
| 41 |
+
*mean += delta * nb_n;
|
| 42 |
+
*m2 += b_m2 + delta * delta * (*count) * nb_n;
|
| 43 |
+
*count = new_count;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
__inline__ __device__ void WelfordWarpAllReduce(float thread_mean, float thread_m2,
|
| 47 |
+
float thread_count, float* mean, float* m2,
|
| 48 |
+
float* count) {
|
| 49 |
+
*mean = thread_mean;
|
| 50 |
+
*m2 = thread_m2;
|
| 51 |
+
*count = thread_count;
|
| 52 |
+
for (int mask = 1; mask < 32; mask *= 2) {
|
| 53 |
+
float b_mean = __shfl_down_sync(0xffffffff, *mean, mask);
|
| 54 |
+
float b_m2 = __shfl_down_sync(0xffffffff, *m2, mask);
|
| 55 |
+
float b_count = __shfl_down_sync(0xffffffff, *count, mask);
|
| 56 |
+
WelfordOnline(b_mean, b_m2, b_count, mean, m2, count);
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
*mean = __shfl_sync(0xffffffff, *mean, 0, 32);
|
| 60 |
+
*m2 = __shfl_sync(0xffffffff, *m2, 0, 32);
|
| 61 |
+
*count = __shfl_sync(0xffffffff, *count, 0, 32);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
extern __shared__ float shared_data[];
|
| 65 |
+
template <typename T>
|
| 66 |
+
__global__ void LayerNormForward(T* input, T* output, T* gamma, T* beta, float* mean,
|
| 67 |
+
float* invvar, int rows, int cols, double epsilon) {
|
| 68 |
+
int warp_id = threadIdx.x / WarpSize;
|
| 69 |
+
int lane_id = threadIdx.x % WarpSize;
|
| 70 |
+
int row_offset = blockIdx.x * WarpNum + warp_id;
|
| 71 |
+
|
| 72 |
+
T* shared_data_warp = (T*)shared_data + warp_id*cols;
|
| 73 |
+
|
| 74 |
+
if (row_offset < rows) {
|
| 75 |
+
T* row_input = input + (long long)(row_offset) * (long long)(cols); // Starting point for input data
|
| 76 |
+
T* row_output = output + (long long)(row_offset) * (long long)(cols); // Starting point for output data
|
| 77 |
+
|
| 78 |
+
float thread_mean = 0.f;
|
| 79 |
+
float thread_m2 = 0.f;
|
| 80 |
+
float thread_count = 0.f;
|
| 81 |
+
|
| 82 |
+
float warp_mean;
|
| 83 |
+
float warp_m2;
|
| 84 |
+
float warp_count;
|
| 85 |
+
// load data to shared memory
|
| 86 |
+
#pragma unroll
|
| 87 |
+
for(int idx = lane_id; idx < cols; idx += WarpSize) {
|
| 88 |
+
shared_data_warp[idx] = row_input[idx];
|
| 89 |
+
WelfordOnline(static_cast<float>(shared_data_warp[idx]), &thread_mean, &thread_m2, &thread_count);
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
WelfordWarpAllReduce(thread_mean, thread_m2, thread_count, &warp_mean, &warp_m2,
|
| 93 |
+
&warp_count);
|
| 94 |
+
|
| 95 |
+
float row_mean = warp_mean;
|
| 96 |
+
float row_variance = max(warp_m2 / warp_count, 0.f);
|
| 97 |
+
float row_inv_var = rsqrt(row_variance + epsilon);
|
| 98 |
+
if (lane_id == 0) {
|
| 99 |
+
mean[row_offset] = row_mean;
|
| 100 |
+
invvar[row_offset] = row_inv_var;
|
| 101 |
+
}
|
| 102 |
+
int process_type = (gamma != NULL)*2 + (beta != NULL);
|
| 103 |
+
if (process_type == 0) {
|
| 104 |
+
#pragma unroll
|
| 105 |
+
for(int idx = lane_id; idx < cols; idx += WarpSize)
|
| 106 |
+
row_output[idx] = static_cast<T>((static_cast<float>(shared_data_warp[idx]) - row_mean) * row_inv_var);
|
| 107 |
+
} else if (process_type == 1) {
|
| 108 |
+
#pragma unroll
|
| 109 |
+
for(int idx = lane_id; idx < cols; idx += WarpSize)
|
| 110 |
+
row_output[idx] = static_cast<T>((static_cast<float>(shared_data_warp[idx]) - row_mean) * row_inv_var + beta[idx]);
|
| 111 |
+
} else if(process_type == 2) {
|
| 112 |
+
#pragma unroll
|
| 113 |
+
for(int idx = lane_id; idx < cols; idx += WarpSize)
|
| 114 |
+
row_output[idx] = static_cast<T>((static_cast<float>(shared_data_warp[idx]) - row_mean) * row_inv_var * gamma[idx]);
|
| 115 |
+
} else {
|
| 116 |
+
#pragma unroll
|
| 117 |
+
for(int idx = lane_id; idx < cols; idx += WarpSize)
|
| 118 |
+
row_output[idx] = static_cast<T>((static_cast<float>(shared_data_warp[idx]) - row_mean) * row_inv_var * gamma[idx] + beta[idx]);
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
void cuda_layer_norm(at::Tensor* output, at::Tensor* mean, at::Tensor* invvar, at::Tensor* input,
|
| 124 |
+
int rows, int cols, at::IntArrayRef normalized_shape, at::Tensor* gamma,
|
| 125 |
+
at::Tensor* beta, double epsilon) {
|
| 126 |
+
int grid = (rows + WarpNum - 1) / WarpNum; // each warp process one line
|
| 127 |
+
dim3 block(BlockSzie);
|
| 128 |
+
// add shared memory size
|
| 129 |
+
if (output->dtype() == torch::kFloat32) {
|
| 130 |
+
int shared_meory_size = WarpNum*sizeof(float)*cols;
|
| 131 |
+
LayerNormForward<float><<<grid, block, shared_meory_size>>>(
|
| 132 |
+
(float*)input->data_ptr(), (float*)output->data_ptr(),
|
| 133 |
+
gamma != NULL ? (float*)gamma->data_ptr() : NULL, beta != NULL ? (float*)beta->data_ptr() : NULL,
|
| 134 |
+
(float*)mean->data_ptr(), (float*)invvar->data_ptr(), rows, cols, epsilon);
|
| 135 |
+
} else if (output->dtype() == torch::kFloat16) {
|
| 136 |
+
int shared_meory_size = WarpNum*sizeof(at::Half)*cols;
|
| 137 |
+
LayerNormForward<at::Half><<<grid, block, shared_meory_size>>>(
|
| 138 |
+
(at::Half*)input->data_ptr(), (at::Half*)output->data_ptr(),
|
| 139 |
+
gamma != NULL ? (at::Half*)gamma->data_ptr() : NULL, beta != NULL ? (at::Half*)beta->data_ptr() : NULL,
|
| 140 |
+
(float*)mean->data_ptr(), (float*)invvar->data_ptr(), rows, cols, epsilon);
|
| 141 |
+
} else if (output->dtype() == torch::kBFloat16) {
|
| 142 |
+
int shared_meory_size = WarpNum*sizeof(at::BFloat16)*cols;
|
| 143 |
+
LayerNormForward<at::BFloat16><<<grid, block, shared_meory_size>>>(
|
| 144 |
+
(at::BFloat16*)input->data_ptr(), (at::BFloat16*)output->data_ptr(),
|
| 145 |
+
gamma != NULL ? (at::BFloat16*)gamma->data_ptr() : NULL, beta != NULL ? (at::BFloat16*)beta->data_ptr() : NULL,
|
| 146 |
+
(float*)mean->data_ptr(), (float*)invvar->data_ptr(), rows, cols, epsilon);
|
| 147 |
+
}
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
template <typename T>
|
| 151 |
+
struct SharedMemory;
|
| 152 |
+
|
| 153 |
+
template <>
|
| 154 |
+
struct SharedMemory<float> {
|
| 155 |
+
__device__ float* getPointer() {
|
| 156 |
+
extern __shared__ float s_float[];
|
| 157 |
+
return s_float;
|
| 158 |
+
}
|
| 159 |
+
};
|
| 160 |
+
|
| 161 |
+
template<typename T>
|
| 162 |
+
__inline__ __device__ T WarpReduce(T val) {
|
| 163 |
+
for (int mask = 16; mask > 0; mask /= 2) { val += __shfl_xor_sync(0xffffffff, val, mask); }
|
| 164 |
+
return val;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
constexpr int tile_size = 32;
|
| 168 |
+
constexpr int num_per_block = 4;
|
| 169 |
+
constexpr int block_dim_x = 32;
|
| 170 |
+
constexpr int block_dim_y = 32 / num_per_block;
|
| 171 |
+
|
| 172 |
+
template <typename T, typename V>
|
| 173 |
+
__global__ void LayerNormParamGradStep1(int rows, int cols, const V* __restrict__ dy,
|
| 174 |
+
const T* __restrict__ x, const float* __restrict__ mean,
|
| 175 |
+
const float* __restrict__ inv_var,
|
| 176 |
+
float* __restrict__ tmp_gamma_diff, float* __restrict__ tmp_beta_diff) {
|
| 177 |
+
__shared__ float dgamma[32][33];
|
| 178 |
+
__shared__ float dbeta[32][33];
|
| 179 |
+
float dgamma_sum[num_per_block];
|
| 180 |
+
float dbeta_sum[num_per_block];
|
| 181 |
+
#pragma unroll
|
| 182 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 183 |
+
dgamma_sum[index] = 0;
|
| 184 |
+
dbeta_sum[index] = 0;
|
| 185 |
+
}
|
| 186 |
+
const int col_id = blockIdx.x * blockDim.x + threadIdx.x;
|
| 187 |
+
if (col_id < cols) {
|
| 188 |
+
for (int i = blockIdx.y * tile_size + threadIdx.y; i < rows; i += tile_size * gridDim.y) {
|
| 189 |
+
#pragma unroll
|
| 190 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 191 |
+
int row_id = i + index * blockDim.y;
|
| 192 |
+
if (row_id < rows) {
|
| 193 |
+
int offset = row_id * cols + col_id;
|
| 194 |
+
const float dy_val = static_cast<float>(dy[offset]);
|
| 195 |
+
const float x_val = static_cast<float>(x[offset]);
|
| 196 |
+
const float mean_val = mean[row_id];
|
| 197 |
+
const float inv_var_val = inv_var[row_id];
|
| 198 |
+
dgamma_sum[index] += dy_val * (x_val - mean_val) * inv_var_val;
|
| 199 |
+
dbeta_sum[index] += dy_val;
|
| 200 |
+
}
|
| 201 |
+
}
|
| 202 |
+
}
|
| 203 |
+
}
|
| 204 |
+
#pragma unroll
|
| 205 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 206 |
+
dgamma[index * blockDim.y + threadIdx.y][threadIdx.x] = dgamma_sum[index];
|
| 207 |
+
dbeta[index * blockDim.y + threadIdx.y][threadIdx.x] = dbeta_sum[index];
|
| 208 |
+
}
|
| 209 |
+
__syncthreads();
|
| 210 |
+
#pragma unroll
|
| 211 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 212 |
+
const int col_id = blockIdx.x * blockDim.x + threadIdx.y + index * blockDim.y;
|
| 213 |
+
if (col_id < cols) {
|
| 214 |
+
float gamma_sum = dgamma[threadIdx.x][threadIdx.y + index * blockDim.y];
|
| 215 |
+
float beta_sum = dbeta[threadIdx.x][threadIdx.y + index * blockDim.y];
|
| 216 |
+
float global_dgamma = WarpReduce<float>(gamma_sum);
|
| 217 |
+
float global_dbeta = WarpReduce<float>(beta_sum);
|
| 218 |
+
if (threadIdx.x == 0) {
|
| 219 |
+
const int offset = blockIdx.y * cols + col_id;
|
| 220 |
+
tmp_gamma_diff[offset] = global_dgamma;
|
| 221 |
+
tmp_beta_diff[offset] = global_dbeta;
|
| 222 |
+
}
|
| 223 |
+
}
|
| 224 |
+
}
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
template <typename T, typename V>
|
| 228 |
+
__global__ void LayerNormGammaGradStep1(int rows, int cols, const V* __restrict__ dy,
|
| 229 |
+
const T* __restrict__ x, const float* __restrict__ mean,
|
| 230 |
+
const float* __restrict__ inv_var, float* __restrict__ tmp_gamma_diff) {
|
| 231 |
+
__shared__ float dgamma[32][33];
|
| 232 |
+
float dgamma_sum[num_per_block];
|
| 233 |
+
#pragma unroll
|
| 234 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 235 |
+
dgamma_sum[index] = 0;
|
| 236 |
+
}
|
| 237 |
+
const int col_id = blockIdx.x * blockDim.x + threadIdx.x;
|
| 238 |
+
if (col_id < cols) {
|
| 239 |
+
for (int i = blockIdx.y * tile_size + threadIdx.y; i < rows; i += tile_size * gridDim.y) {
|
| 240 |
+
#pragma unroll
|
| 241 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 242 |
+
int row_id = i + index * blockDim.y;
|
| 243 |
+
if (row_id < rows) {
|
| 244 |
+
int offset = row_id * cols + col_id;
|
| 245 |
+
const float dy_val = static_cast<float>(dy[offset]);
|
| 246 |
+
const float x_val = static_cast<float>(x[offset]);
|
| 247 |
+
const float mean_val = mean[row_id];
|
| 248 |
+
const float inv_var_val = inv_var[row_id];
|
| 249 |
+
dgamma_sum[index] += dy_val * (x_val - mean_val) * inv_var_val;
|
| 250 |
+
}
|
| 251 |
+
}
|
| 252 |
+
}
|
| 253 |
+
}
|
| 254 |
+
#pragma unroll
|
| 255 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 256 |
+
dgamma[index * blockDim.y + threadIdx.y][threadIdx.x] = dgamma_sum[index];
|
| 257 |
+
}
|
| 258 |
+
__syncthreads();
|
| 259 |
+
#pragma unroll
|
| 260 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 261 |
+
const int col_id = blockIdx.x * blockDim.x + threadIdx.y + index * blockDim.y;
|
| 262 |
+
if (col_id < cols) {
|
| 263 |
+
float gamma_sum = dgamma[threadIdx.x][threadIdx.y + index * blockDim.y];
|
| 264 |
+
float global_dgamma = WarpReduce<float>(gamma_sum);
|
| 265 |
+
if (threadIdx.x == 0) {
|
| 266 |
+
const int offset = blockIdx.y * cols + col_id;
|
| 267 |
+
tmp_gamma_diff[offset] = global_dgamma;
|
| 268 |
+
}
|
| 269 |
+
}
|
| 270 |
+
}
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
template <typename T, typename V>
|
| 274 |
+
__global__ void LayerNormBetaGradStep1(int rows, int cols, const V* __restrict__ dy,
|
| 275 |
+
const T* __restrict__ x, const float* __restrict__ mean,
|
| 276 |
+
const float* __restrict__ inv_var, float* __restrict__ tmp_beta_diff) {
|
| 277 |
+
__shared__ float dbeta[32][33];
|
| 278 |
+
float dbeta_sum[num_per_block];
|
| 279 |
+
#pragma unroll
|
| 280 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 281 |
+
dbeta_sum[index] = 0;
|
| 282 |
+
}
|
| 283 |
+
const int col_id = blockIdx.x * blockDim.x + threadIdx.x;
|
| 284 |
+
if (col_id < cols) {
|
| 285 |
+
for (int i = blockIdx.y * tile_size + threadIdx.y; i < rows; i += tile_size * gridDim.y) {
|
| 286 |
+
#pragma unroll
|
| 287 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 288 |
+
int row_id = i + index * blockDim.y;
|
| 289 |
+
if (row_id < rows) {
|
| 290 |
+
int offset = row_id * cols + col_id;
|
| 291 |
+
const float dy_val = static_cast<float>(dy[offset]);
|
| 292 |
+
dbeta_sum[index] += dy_val;
|
| 293 |
+
}
|
| 294 |
+
}
|
| 295 |
+
}
|
| 296 |
+
}
|
| 297 |
+
#pragma unroll
|
| 298 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 299 |
+
dbeta[index * blockDim.y + threadIdx.y][threadIdx.x] = dbeta_sum[index];
|
| 300 |
+
}
|
| 301 |
+
__syncthreads();
|
| 302 |
+
#pragma unroll
|
| 303 |
+
for (int index = 0; index < num_per_block; ++index) {
|
| 304 |
+
const int col_id = blockIdx.x * blockDim.x + threadIdx.y + index * blockDim.y;
|
| 305 |
+
if (col_id < cols) {
|
| 306 |
+
float beta_sum = dbeta[threadIdx.x][threadIdx.y + index * blockDim.y];
|
| 307 |
+
float global_dbeta = WarpReduce<float>(beta_sum);
|
| 308 |
+
if (threadIdx.x == 0) {
|
| 309 |
+
const int offset = blockIdx.y * cols + col_id;
|
| 310 |
+
tmp_beta_diff[offset] = global_dbeta;
|
| 311 |
+
}
|
| 312 |
+
}
|
| 313 |
+
}
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
template <typename V>
|
| 317 |
+
__global__ void LayerNormParamGradStep2(const float* part_grad_gamma, const float* part_grad_beta,
|
| 318 |
+
const int part_size, const int n1, const int n2,
|
| 319 |
+
V* grad_gamma, V* grad_beta) {
|
| 320 |
+
// sum partial gradients for gamma and beta
|
| 321 |
+
SharedMemory<float> shared;
|
| 322 |
+
float* buf = shared.getPointer();
|
| 323 |
+
int i2 = blockIdx.x * blockDim.x + threadIdx.x;
|
| 324 |
+
if (i2 < n2) {
|
| 325 |
+
// each warp does sequential reductions until reduced part_size is num_warps
|
| 326 |
+
// int num_warp_reductions = part_size / blockDim.y;
|
| 327 |
+
float sum_gamma = float(0);
|
| 328 |
+
float sum_beta = float(0);
|
| 329 |
+
const float* part_grad_gamma_ptr = part_grad_gamma + i2;
|
| 330 |
+
const float* part_grad_beta_ptr = part_grad_beta + i2;
|
| 331 |
+
for (int row_idx = threadIdx.y; row_idx < part_size; row_idx += blockDim.y) {
|
| 332 |
+
sum_gamma += part_grad_gamma_ptr[row_idx * n2];
|
| 333 |
+
sum_beta += part_grad_beta_ptr[row_idx * n2];
|
| 334 |
+
}
|
| 335 |
+
// inter-warp reductions
|
| 336 |
+
const int nbsize3 = blockDim.x * blockDim.y / 2;
|
| 337 |
+
for (int offset = blockDim.y / 2; offset >= 1; offset /= 2) {
|
| 338 |
+
// top half write to shared memory
|
| 339 |
+
if (threadIdx.y >= offset && threadIdx.y < 2 * offset) {
|
| 340 |
+
const int write_idx = (threadIdx.y - offset) * blockDim.x + threadIdx.x;
|
| 341 |
+
buf[write_idx] = sum_gamma;
|
| 342 |
+
buf[write_idx + nbsize3] = sum_beta;
|
| 343 |
+
}
|
| 344 |
+
__syncthreads();
|
| 345 |
+
// bottom half sums
|
| 346 |
+
if (threadIdx.y < offset) {
|
| 347 |
+
const int read_idx = threadIdx.y * blockDim.x + threadIdx.x;
|
| 348 |
+
sum_gamma += buf[read_idx];
|
| 349 |
+
sum_beta += buf[read_idx + nbsize3];
|
| 350 |
+
}
|
| 351 |
+
__syncthreads();
|
| 352 |
+
}
|
| 353 |
+
// write out fully summed gradients
|
| 354 |
+
if (threadIdx.y == 0) {
|
| 355 |
+
grad_gamma[i2] = sum_gamma;
|
| 356 |
+
grad_beta[i2] = sum_beta;
|
| 357 |
+
}
|
| 358 |
+
}
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
template <typename V>
|
| 362 |
+
__global__ void LayerNormGammaGradStep2(const float* part_grad_gamma, const int part_size, const int n1, const int n2, V* grad_gamma) {
|
| 363 |
+
// sum partial gradients for gamma and beta
|
| 364 |
+
SharedMemory<float> shared;
|
| 365 |
+
float* buf = shared.getPointer();
|
| 366 |
+
int i2 = blockIdx.x * blockDim.x + threadIdx.x;
|
| 367 |
+
if (i2 < n2) {
|
| 368 |
+
// each warp does sequential reductions until reduced part_size is num_warps
|
| 369 |
+
// int num_warp_reductions = part_size / blockDim.y;
|
| 370 |
+
float sum_gamma = float(0);
|
| 371 |
+
const float* part_grad_gamma_ptr = part_grad_gamma + i2;
|
| 372 |
+
for (int row_idx = threadIdx.y; row_idx < part_size; row_idx += blockDim.y) {
|
| 373 |
+
sum_gamma += part_grad_gamma_ptr[row_idx * n2];
|
| 374 |
+
}
|
| 375 |
+
// inter-warp reductions
|
| 376 |
+
for (int offset = blockDim.y / 2; offset >= 1; offset /= 2) {
|
| 377 |
+
// top half write to shared memory
|
| 378 |
+
if (threadIdx.y >= offset && threadIdx.y < 2 * offset) {
|
| 379 |
+
const int write_idx = (threadIdx.y - offset) * blockDim.x + threadIdx.x;
|
| 380 |
+
buf[write_idx] = sum_gamma;
|
| 381 |
+
}
|
| 382 |
+
__syncthreads();
|
| 383 |
+
// bottom half sums
|
| 384 |
+
if (threadIdx.y < offset) {
|
| 385 |
+
const int read_idx = threadIdx.y * blockDim.x + threadIdx.x;
|
| 386 |
+
sum_gamma += buf[read_idx];
|
| 387 |
+
}
|
| 388 |
+
__syncthreads();
|
| 389 |
+
}
|
| 390 |
+
// write out fully summed gradients
|
| 391 |
+
if (threadIdx.y == 0) {
|
| 392 |
+
grad_gamma[i2] = sum_gamma;
|
| 393 |
+
}
|
| 394 |
+
}
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
template <typename V>
|
| 398 |
+
__global__ void LayerNormBetaGradStep2(const float* part_grad_beta, const int part_size, const int n1, const int n2, V* grad_beta) {
|
| 399 |
+
// sum partial gradients for gamma and beta
|
| 400 |
+
SharedMemory<float> shared;
|
| 401 |
+
float* buf = shared.getPointer();
|
| 402 |
+
int i2 = blockIdx.x * blockDim.x + threadIdx.x;
|
| 403 |
+
if (i2 < n2) {
|
| 404 |
+
// each warp does sequential reductions until reduced part_size is num_warps
|
| 405 |
+
// int num_warp_reductions = part_size / blockDim.y;
|
| 406 |
+
float sum_beta = float(0);
|
| 407 |
+
const float* part_grad_beta_ptr = part_grad_beta + i2;
|
| 408 |
+
for (int row_idx = threadIdx.y; row_idx < part_size; row_idx += blockDim.y) {
|
| 409 |
+
sum_beta += part_grad_beta_ptr[row_idx * n2];
|
| 410 |
+
}
|
| 411 |
+
// inter-warp reductions
|
| 412 |
+
for (int offset = blockDim.y / 2; offset >= 1; offset /= 2) {
|
| 413 |
+
// top half write to shared memory
|
| 414 |
+
if (threadIdx.y >= offset && threadIdx.y < 2 * offset) {
|
| 415 |
+
const int write_idx = (threadIdx.y - offset) * blockDim.x + threadIdx.x;
|
| 416 |
+
buf[write_idx] = sum_beta;
|
| 417 |
+
}
|
| 418 |
+
__syncthreads();
|
| 419 |
+
// bottom half sums
|
| 420 |
+
if (threadIdx.y < offset) {
|
| 421 |
+
const int read_idx = threadIdx.y * blockDim.x + threadIdx.x;
|
| 422 |
+
sum_beta += buf[read_idx];
|
| 423 |
+
}
|
| 424 |
+
__syncthreads();
|
| 425 |
+
}
|
| 426 |
+
// write out fully summed gradients
|
| 427 |
+
if (threadIdx.y == 0) {
|
| 428 |
+
grad_beta[i2] = sum_beta;
|
| 429 |
+
}
|
| 430 |
+
}
|
| 431 |
+
}
|
| 432 |
+
|
| 433 |
+
template <typename T, typename V>
|
| 434 |
+
__global__ void LayerNormInputGrad(const V* __restrict__ dout, const T* __restrict__ input,
|
| 435 |
+
const int rows, const int cols, const float* __restrict__ mean,
|
| 436 |
+
const float* __restrict__ invvar, float epsilon, const V* gamma,
|
| 437 |
+
T* grad_input) {
|
| 438 |
+
int WarpPerBlock = blockDim.x / WarpSize;
|
| 439 |
+
int thread_idx = threadIdx.x;
|
| 440 |
+
int warp_idx = thread_idx / WarpSize;
|
| 441 |
+
int lane_idx = thread_idx % WarpSize;
|
| 442 |
+
|
| 443 |
+
float* shared_dout = shared_data + warp_idx*cols;
|
| 444 |
+
float* shared_input = shared_data + WarpPerBlock*cols + warp_idx*cols;
|
| 445 |
+
float* shared_gamma = shared_data + 2*WarpPerBlock*cols;
|
| 446 |
+
int row_stride = gridDim.x*WarpPerBlock;
|
| 447 |
+
for(int row = blockIdx.x*WarpPerBlock+warp_idx; row < rows; row += row_stride) {
|
| 448 |
+
float mean_r = mean[row];
|
| 449 |
+
float invvar_r = invvar[row];
|
| 450 |
+
// load dout, input and gamma
|
| 451 |
+
long long data_offset = (long long)(row) * cols;
|
| 452 |
+
const V* dout_r = dout + data_offset;
|
| 453 |
+
const T* input_r = input + data_offset;
|
| 454 |
+
T* grad_input_r = grad_input + data_offset;
|
| 455 |
+
#pragma unroll
|
| 456 |
+
for(int col = lane_idx; col < cols; col += WarpSize) {
|
| 457 |
+
shared_dout[col] = float(dout_r[col]);
|
| 458 |
+
shared_input[col] = float(input_r[col]);
|
| 459 |
+
}
|
| 460 |
+
if(warp_idx == 0) {
|
| 461 |
+
#pragma unroll
|
| 462 |
+
for(int col = lane_idx; col < cols; col += WarpSize) {
|
| 463 |
+
shared_gamma[col] = gamma != NULL ? float(gamma[col]) : 1.0f;
|
| 464 |
+
}
|
| 465 |
+
}
|
| 466 |
+
__syncthreads();
|
| 467 |
+
|
| 468 |
+
float gamma_dout = 0.0;
|
| 469 |
+
float gamma_dout_input_mean = 0.0;
|
| 470 |
+
// reduction, gamma*dout and gamma*dout*(input-mean)
|
| 471 |
+
#pragma unroll
|
| 472 |
+
for(int col = lane_idx; col < cols; col += WarpSize) {
|
| 473 |
+
float temp = shared_gamma[col] * shared_dout[col];
|
| 474 |
+
gamma_dout += temp;
|
| 475 |
+
gamma_dout_input_mean += temp * (shared_input[col] - mean_r);
|
| 476 |
+
}
|
| 477 |
+
float global_gamma_dout = WarpReduce<float>(gamma_dout);
|
| 478 |
+
float global_gamma_dout_input_mean = WarpReduce<float>(gamma_dout_input_mean);
|
| 479 |
+
|
| 480 |
+
float part3_temp_value = global_gamma_dout_input_mean * invvar_r * invvar_r * invvar_r / cols;
|
| 481 |
+
float part2 = global_gamma_dout * invvar_r / cols;
|
| 482 |
+
#pragma unroll
|
| 483 |
+
for(int col = lane_idx; col < cols; col += WarpSize) {
|
| 484 |
+
float part1 = shared_gamma[col] * shared_dout[col] * invvar_r;
|
| 485 |
+
float part3 = (shared_input[col] - mean_r) * part3_temp_value;
|
| 486 |
+
grad_input_r[col] = part1 - part2 - part3;
|
| 487 |
+
}
|
| 488 |
+
}
|
| 489 |
+
}
|
| 490 |
+
|
| 491 |
+
template <typename T, typename V>
|
| 492 |
+
int GetGirdDimY(const int64_t num_instances, const int64_t norm_size) {
|
| 493 |
+
const int grid_dim_x = (norm_size + tile_size - 1) / tile_size;
|
| 494 |
+
const int max_grid_dim_y = (num_instances + tile_size - 1) / tile_size;
|
| 495 |
+
const int block_size = block_dim_x * block_dim_y;
|
| 496 |
+
int max_active_blocks = 0;
|
| 497 |
+
cudaOccupancyMaxActiveBlocksPerMultiprocessor(
|
| 498 |
+
&max_active_blocks, LayerNormParamGradStep1<T, V>, block_size, 0);
|
| 499 |
+
int waves = 1;
|
| 500 |
+
int dev;
|
| 501 |
+
cudaGetDevice(&dev);
|
| 502 |
+
int sm_count;
|
| 503 |
+
cudaDeviceGetAttribute(&sm_count, cudaDevAttrMultiProcessorCount, dev);
|
| 504 |
+
int num_blocks = max_active_blocks * sm_count * waves;
|
| 505 |
+
int grid_dim_y = std::min(max_grid_dim_y, static_cast<int>(num_blocks / grid_dim_x));
|
| 506 |
+
return std::max(grid_dim_y, 1);
|
| 507 |
+
}
|
| 508 |
+
|
| 509 |
+
template <typename T, typename V>
|
| 510 |
+
void HostLayerNormGradient(const V* dout, const float* mean, const float* invvar, at::Tensor* input, int n1,
|
| 511 |
+
int n2, const V* gamma, const V* beta, double epsilon, T* grad_input,
|
| 512 |
+
V* grad_gamma, V* grad_beta) {
|
| 513 |
+
auto stream = at::cuda::getCurrentCUDAStream().stream();
|
| 514 |
+
|
| 515 |
+
if (gamma != NULL && beta != NULL) {
|
| 516 |
+
// compute grad_gamma(j) and grad_beta(j)
|
| 517 |
+
const int part_size = GetGirdDimY<T, V>(n1, n2);
|
| 518 |
+
const int grid_dim_x = (n2 + tile_size - 1) / tile_size;
|
| 519 |
+
const int grid_dim_y = part_size;
|
| 520 |
+
|
| 521 |
+
at::Tensor part_grad_gamma = at::empty({part_size, n2}, input->options().dtype(at::ScalarType::Float));
|
| 522 |
+
at::Tensor part_grad_beta = at::empty_like(part_grad_gamma);
|
| 523 |
+
LayerNormParamGradStep1<T, V><<<dim3(grid_dim_x, grid_dim_y), dim3(32, 32 / num_per_block)>>>(
|
| 524 |
+
n1, n2, dout, input->DATA_PTR<T>(), mean, invvar, part_grad_gamma.DATA_PTR<float>(), part_grad_beta.DATA_PTR<float>()
|
| 525 |
+
);
|
| 526 |
+
|
| 527 |
+
const dim3 threads3(32, 8, 1);
|
| 528 |
+
const dim3 blocks3((n2 + 32 - 1) / 32, 1, 1);
|
| 529 |
+
const int nshared3 = threads3.x * threads3.y * sizeof(float);
|
| 530 |
+
LayerNormParamGradStep2<<<blocks3, threads3, nshared3, stream>>>(
|
| 531 |
+
part_grad_gamma.DATA_PTR<float>(), part_grad_beta.DATA_PTR<float>(), part_size, n1, n2,
|
| 532 |
+
grad_gamma, grad_beta);
|
| 533 |
+
} else if (gamma != NULL && beta == NULL) {
|
| 534 |
+
// compute grad_gamma(j) and grad_beta(j)
|
| 535 |
+
const int part_size = GetGirdDimY<T, V>(n1, n2);
|
| 536 |
+
const int grid_dim_x = (n2 + tile_size - 1) / tile_size;
|
| 537 |
+
const int grid_dim_y = part_size;
|
| 538 |
+
|
| 539 |
+
at::Tensor part_grad_gamma = at::empty({part_size, n2}, input->options().dtype(at::ScalarType::Float));
|
| 540 |
+
LayerNormGammaGradStep1<T, V><<<dim3(grid_dim_x, grid_dim_y), dim3(32, 32 / num_per_block)>>>(
|
| 541 |
+
n1, n2, dout, input->DATA_PTR<T>(), mean, invvar, part_grad_gamma.DATA_PTR<float>());
|
| 542 |
+
|
| 543 |
+
const dim3 threads3(32, 8, 1);
|
| 544 |
+
const dim3 blocks3((n2 + 32 - 1) / 32, 1, 1);
|
| 545 |
+
const int nshared3 = threads3.x * threads3.y * sizeof(float);
|
| 546 |
+
LayerNormGammaGradStep2<<<blocks3, threads3, nshared3, stream>>>(
|
| 547 |
+
part_grad_gamma.DATA_PTR<float>(), part_size, n1, n2, grad_gamma);
|
| 548 |
+
} else if (gamma == NULL && beta!= NULL) {
|
| 549 |
+
// compute grad_gamma(j) and grad_beta(j)
|
| 550 |
+
const int part_size = GetGirdDimY<T, V>(n1, n2);
|
| 551 |
+
const int grid_dim_x = (n2 + tile_size - 1) / tile_size;
|
| 552 |
+
const int grid_dim_y = part_size;
|
| 553 |
+
|
| 554 |
+
at::Tensor part_grad_beta = at::empty({part_size, n2}, input->options().dtype(at::ScalarType::Float));
|
| 555 |
+
LayerNormBetaGradStep1<T, V><<<dim3(grid_dim_x, grid_dim_y), dim3(32, 32 / num_per_block)>>>(
|
| 556 |
+
n1, n2, dout, input->DATA_PTR<T>(), mean, invvar, part_grad_beta.DATA_PTR<float>()
|
| 557 |
+
);
|
| 558 |
+
|
| 559 |
+
const dim3 threads3(32, 8, 1);
|
| 560 |
+
const dim3 blocks3((n2 + 32 - 1) / 32, 1, 1);
|
| 561 |
+
const int nshared3 = threads3.x * threads3.y * sizeof(float);
|
| 562 |
+
LayerNormBetaGradStep2<<<blocks3, threads3, nshared3, stream>>>(
|
| 563 |
+
part_grad_beta.DATA_PTR<float>(), part_size, n1, n2, grad_beta);
|
| 564 |
+
}
|
| 565 |
+
|
| 566 |
+
const uint64_t maxGridY = at::cuda::getCurrentDeviceProperties()->maxGridSize[1];
|
| 567 |
+
#define BlockDim 128
|
| 568 |
+
int WarpNumPerBlock = BlockDim / WarpSize;
|
| 569 |
+
const dim3 threads1(BlockDim);
|
| 570 |
+
int nshared = sizeof(float)*n2*(WarpNumPerBlock*2 + 1);
|
| 571 |
+
|
| 572 |
+
int max_active_blocks = 0;
|
| 573 |
+
cudaOccupancyMaxActiveBlocksPerMultiprocessor(
|
| 574 |
+
&max_active_blocks, LayerNormInputGrad<T, V>, BlockDim, nshared);
|
| 575 |
+
int dev;
|
| 576 |
+
cudaGetDevice(&dev);
|
| 577 |
+
int sm_count;
|
| 578 |
+
cudaDeviceGetAttribute(&sm_count, cudaDevAttrMultiProcessorCount, dev);
|
| 579 |
+
|
| 580 |
+
const dim3 blocks1(std::min((uint64_t)((n1 + WarpNumPerBlock - 1)/WarpNumPerBlock), (uint64_t)(max_active_blocks * sm_count)));
|
| 581 |
+
LayerNormInputGrad<<<blocks1, threads1, nshared>>>(dout, input->DATA_PTR<T>(), n1, n2, mean, invvar, float(epsilon), gamma, grad_input);
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
void cuda_layer_norm_gradient(at::Tensor* dout, at::Tensor* mean, at::Tensor* invvar,
|
| 585 |
+
at::Tensor* input, int n1, int n2, at::IntArrayRef normalized_shape,
|
| 586 |
+
at::Tensor* gamma, at::Tensor* beta, double epsilon,
|
| 587 |
+
at::Tensor* grad_input, at::Tensor* grad_gamma,
|
| 588 |
+
at::Tensor* grad_beta) {
|
| 589 |
+
using namespace at;
|
| 590 |
+
DISPATCH_FLOAT_HALF_AND_BFLOAT_INOUT_TYPES(
|
| 591 |
+
input->scalar_type(), dout->scalar_type(), "cuda_layer_norm_gradient_kernel",
|
| 592 |
+
HostLayerNormGradient(dout->DATA_PTR<scalar_t_out>(), mean->DATA_PTR<float>(),
|
| 593 |
+
invvar->DATA_PTR<float>(), input, n1, n2,
|
| 594 |
+
gamma != NULL ? gamma->DATA_PTR<scalar_t_out>() : NULL,
|
| 595 |
+
beta != NULL ? beta->DATA_PTR<scalar_t_out>() : NULL, epsilon,
|
| 596 |
+
grad_input->DATA_PTR<scalar_t_in>(),
|
| 597 |
+
gamma != NULL ? grad_gamma->DATA_PTR<scalar_t_out>() : NULL,
|
| 598 |
+
beta != NULL ? grad_beta->DATA_PTR<scalar_t_out>() : NULL);)
|
| 599 |
+
}
|
models/protenix/layer_norm/kernel/type_shim.h
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <ATen/ATen.h>
|
| 2 |
+
|
| 3 |
+
#include "compat.h"
|
| 4 |
+
|
| 5 |
+
#define DISPATCH_HALF_AND_BFLOAT(TYPE, NAME, ...) \
|
| 6 |
+
switch (TYPE) { \
|
| 7 |
+
case at::ScalarType::Half: { \
|
| 8 |
+
using scalar_t = at::Half; \
|
| 9 |
+
__VA_ARGS__; \
|
| 10 |
+
break; \
|
| 11 |
+
} \
|
| 12 |
+
case at::ScalarType::BFloat16: { \
|
| 13 |
+
using scalar_t = at::BFloat16; \
|
| 14 |
+
__VA_ARGS__; \
|
| 15 |
+
break; \
|
| 16 |
+
} \
|
| 17 |
+
default: \
|
| 18 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPE), "'"); \
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
#define DISPATCH_FLOAT_HALF_AND_BFLOAT_INOUT_TYPES(TYPEIN, TYPEOUT, NAME, ...) \
|
| 22 |
+
switch (TYPEIN) { \
|
| 23 |
+
case at::ScalarType::Float: { \
|
| 24 |
+
using scalar_t_in = float; \
|
| 25 |
+
switch (TYPEOUT) { \
|
| 26 |
+
case at::ScalarType::Float: { \
|
| 27 |
+
using scalar_t_out = float; \
|
| 28 |
+
__VA_ARGS__; \
|
| 29 |
+
break; \
|
| 30 |
+
} \
|
| 31 |
+
case at::ScalarType::Half: { \
|
| 32 |
+
using scalar_t_out = at::Half; \
|
| 33 |
+
__VA_ARGS__; \
|
| 34 |
+
break; \
|
| 35 |
+
} \
|
| 36 |
+
case at::ScalarType::BFloat16: { \
|
| 37 |
+
using scalar_t_out = at::BFloat16; \
|
| 38 |
+
__VA_ARGS__; \
|
| 39 |
+
break; \
|
| 40 |
+
} \
|
| 41 |
+
default: \
|
| 42 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPEOUT), "'"); \
|
| 43 |
+
} \
|
| 44 |
+
break; \
|
| 45 |
+
} \
|
| 46 |
+
case at::ScalarType::Half: { \
|
| 47 |
+
using scalar_t_in = at::Half; \
|
| 48 |
+
using scalar_t_out = at::Half; \
|
| 49 |
+
__VA_ARGS__; \
|
| 50 |
+
break; \
|
| 51 |
+
} \
|
| 52 |
+
case at::ScalarType::BFloat16: { \
|
| 53 |
+
using scalar_t_in = at::BFloat16; \
|
| 54 |
+
using scalar_t_out = at::BFloat16; \
|
| 55 |
+
__VA_ARGS__; \
|
| 56 |
+
break; \
|
| 57 |
+
} \
|
| 58 |
+
default: \
|
| 59 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPEIN), "'"); \
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
// Forward/backward compatiblity hack around
|
| 63 |
+
// https://github.com/pytorch/pytorch/commit/3aeb78079bcd68282fe9117088e138b77318e288
|
| 64 |
+
// pending more future-proof guidance from upstream.
|
| 65 |
+
// struct TypeShim
|
| 66 |
+
// {
|
| 67 |
+
// const at::Type& payload;
|
| 68 |
+
// TypeShim(const at::Type& type) : payload(type) {}
|
| 69 |
+
// // Enable trivial conversion to a const at::Type& for pre-3aeb78
|
| 70 |
+
// operator const at::Type&(){ return payload; };
|
| 71 |
+
// // Enable dispatch switch statements to take *this directly for post-3aeb78
|
| 72 |
+
// //operator at::ScalarType(){ return payload.; };
|
| 73 |
+
// };
|
| 74 |
+
|
| 75 |
+
#define DISPATCH_FLOAT_AND_HALF(TYPE, LEVEL, NAME, ...) \
|
| 76 |
+
switch (TYPE) { \
|
| 77 |
+
case at::ScalarType::Float: { \
|
| 78 |
+
using scalar_t_##LEVEL = float; \
|
| 79 |
+
__VA_ARGS__; \
|
| 80 |
+
break; \
|
| 81 |
+
} \
|
| 82 |
+
case at::ScalarType::Half: { \
|
| 83 |
+
using scalar_t_##LEVEL = at::Half; \
|
| 84 |
+
__VA_ARGS__; \
|
| 85 |
+
break; \
|
| 86 |
+
} \
|
| 87 |
+
default: \
|
| 88 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPE), "'"); \
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
#define DISPATCH_FLOAT_HALF_AND_BYTE(TYPE, LEVEL, NAME, ...) \
|
| 92 |
+
switch (TYPE) { \
|
| 93 |
+
case at::ScalarType::Float: { \
|
| 94 |
+
using scalar_t_##LEVEL = float; \
|
| 95 |
+
__VA_ARGS__; \
|
| 96 |
+
break; \
|
| 97 |
+
} \
|
| 98 |
+
case at::ScalarType::Half: { \
|
| 99 |
+
using scalar_t_##LEVEL = at::Half; \
|
| 100 |
+
__VA_ARGS__; \
|
| 101 |
+
break; \
|
| 102 |
+
} \
|
| 103 |
+
case at::ScalarType::Byte: { \
|
| 104 |
+
using scalar_t_##LEVEL = uint8_t; \
|
| 105 |
+
__VA_ARGS__; \
|
| 106 |
+
break; \
|
| 107 |
+
} \
|
| 108 |
+
default: \
|
| 109 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPE), "'"); \
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
#define DISPATCH_DOUBLE_FLOAT_AND_HALF(TYPE, LEVEL, NAME, ...) \
|
| 113 |
+
switch (TYPE) { \
|
| 114 |
+
case at::ScalarType::Double: { \
|
| 115 |
+
using scalar_t_##LEVEL = double; \
|
| 116 |
+
__VA_ARGS__; \
|
| 117 |
+
break; \
|
| 118 |
+
} \
|
| 119 |
+
case at::ScalarType::Float: { \
|
| 120 |
+
using scalar_t_##LEVEL = float; \
|
| 121 |
+
__VA_ARGS__; \
|
| 122 |
+
break; \
|
| 123 |
+
} \
|
| 124 |
+
case at::ScalarType::Half: { \
|
| 125 |
+
using scalar_t_##LEVEL = at::Half; \
|
| 126 |
+
__VA_ARGS__; \
|
| 127 |
+
break; \
|
| 128 |
+
} \
|
| 129 |
+
default: \
|
| 130 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPE), "'"); \
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
#define DISPATCH_DOUBLE_AND_FLOAT(TYPE, LEVEL, NAME, ...) \
|
| 134 |
+
switch (TYPE) { \
|
| 135 |
+
case at::ScalarType::Double: { \
|
| 136 |
+
using scalar_t_##LEVEL = double; \
|
| 137 |
+
__VA_ARGS__; \
|
| 138 |
+
break; \
|
| 139 |
+
} \
|
| 140 |
+
case at::ScalarType::Float: { \
|
| 141 |
+
using scalar_t_##LEVEL = float; \
|
| 142 |
+
__VA_ARGS__; \
|
| 143 |
+
break; \
|
| 144 |
+
} \
|
| 145 |
+
default: \
|
| 146 |
+
AT_ERROR(#NAME, " not implemented for '", toString(TYPE), "'"); \
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
template <typename T>
|
| 150 |
+
__device__ __forceinline__ T
|
| 151 |
+
reduce_block_into_lanes(T *x, T val, int lanes = 1,
|
| 152 |
+
bool share_result = false) // lanes is intended to be <= 32.
|
| 153 |
+
{
|
| 154 |
+
int tid = threadIdx.x + threadIdx.y * blockDim.x;
|
| 155 |
+
int blockSize = blockDim.x * blockDim.y; // blockSize is intended to be a multiple of 32.
|
| 156 |
+
|
| 157 |
+
if (blockSize >= 64) {
|
| 158 |
+
x[tid] = val;
|
| 159 |
+
__syncthreads();
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
#pragma unroll
|
| 163 |
+
for (int i = (blockSize >> 1); i >= 64; i >>= 1) {
|
| 164 |
+
if (tid < i) x[tid] = x[tid] + x[tid + i];
|
| 165 |
+
__syncthreads();
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
T final;
|
| 169 |
+
|
| 170 |
+
if (tid < 32) {
|
| 171 |
+
if (blockSize >= 64)
|
| 172 |
+
final = x[tid] + x[tid + 32];
|
| 173 |
+
else
|
| 174 |
+
final = val;
|
| 175 |
+
// __SYNCWARP();
|
| 176 |
+
|
| 177 |
+
#pragma unroll
|
| 178 |
+
for (int i = 16; i >= lanes; i >>= 1)
|
| 179 |
+
final = final + __shfl_down_sync(0xffffffff, final, i);
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
if (share_result) {
|
| 183 |
+
if (tid < lanes) x[tid] = final; // EpilogueOp
|
| 184 |
+
// Make sure the smem result is visible to all warps.
|
| 185 |
+
__syncthreads();
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
return final;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
template <typename T>
|
| 192 |
+
__device__ __forceinline__ T
|
| 193 |
+
reduce_block_into_lanes_max_op(T *x, T val, int lanes = 1,
|
| 194 |
+
bool share_result = false) // lanes is intended to be <= 32.
|
| 195 |
+
{
|
| 196 |
+
int tid = threadIdx.x + threadIdx.y * blockDim.x;
|
| 197 |
+
int blockSize = blockDim.x * blockDim.y; // blockSize is intended to be a multiple of 32.
|
| 198 |
+
|
| 199 |
+
if (blockSize >= 64) {
|
| 200 |
+
x[tid] = val;
|
| 201 |
+
__syncthreads();
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
#pragma unroll
|
| 205 |
+
for (int i = (blockSize >> 1); i >= 64; i >>= 1) {
|
| 206 |
+
if (tid < i) x[tid] = fmaxf(fabsf(x[tid]), fabsf(x[tid + i]));
|
| 207 |
+
__syncthreads();
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
T final;
|
| 211 |
+
|
| 212 |
+
if (tid < 32) {
|
| 213 |
+
if (blockSize >= 64)
|
| 214 |
+
final = fmaxf(fabsf(x[tid]), fabsf(x[tid + 32]));
|
| 215 |
+
else
|
| 216 |
+
final = val;
|
| 217 |
+
// __SYNCWARP();
|
| 218 |
+
|
| 219 |
+
#pragma unroll
|
| 220 |
+
for (int i = 16; i >= lanes; i >>= 1)
|
| 221 |
+
final = fmaxf(fabsf(final), fabsf(__shfl_down_sync(0xffffffff, final, i)));
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
if (share_result) {
|
| 225 |
+
if (tid < lanes) x[tid] = final; // EpilogueOp
|
| 226 |
+
// Make sure the smem result is visible to all warps.
|
| 227 |
+
__syncthreads();
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
return final;
|
| 231 |
+
}
|
models/protenix/layer_norm/layer_norm.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import importlib
|
| 2 |
+
import numbers
|
| 3 |
+
import os
|
| 4 |
+
import sys
|
| 5 |
+
import time
|
| 6 |
+
|
| 7 |
+
import torch
|
| 8 |
+
from torch.nn.parameter import Parameter
|
| 9 |
+
|
| 10 |
+
sys.path.append(os.path.dirname(__file__))
|
| 11 |
+
|
| 12 |
+
try:
|
| 13 |
+
fastfold_layer_norm_cuda = importlib.import_module("fastfold_layer_norm_cuda")
|
| 14 |
+
except ImportError:
|
| 15 |
+
from models.protenix.layer_norm.torch_ext_compile import compile
|
| 16 |
+
|
| 17 |
+
current_dir = os.path.dirname(__file__)
|
| 18 |
+
fastfold_layer_norm_cuda = compile(
|
| 19 |
+
name="fastfold_layer_norm_cuda",
|
| 20 |
+
sources=[
|
| 21 |
+
os.path.join(f"{current_dir}/kernel", file)
|
| 22 |
+
for file in ["layer_norm_cuda.cpp", "layer_norm_cuda_kernel.cu"]
|
| 23 |
+
],
|
| 24 |
+
extra_include_paths=[f"{current_dir}/kernel"],
|
| 25 |
+
build_directory=current_dir,
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class FusedLayerNormAffineFunction(torch.autograd.Function):
|
| 30 |
+
|
| 31 |
+
@staticmethod
|
| 32 |
+
def forward(ctx, input, weight, bias, normalized_shape, eps):
|
| 33 |
+
d = input.dtype
|
| 34 |
+
|
| 35 |
+
ctx.normalized_shape = normalized_shape
|
| 36 |
+
ctx.eps = eps
|
| 37 |
+
input_ = input.contiguous()
|
| 38 |
+
|
| 39 |
+
if weight is None:
|
| 40 |
+
if bias is None:
|
| 41 |
+
output, mean, invvar = fastfold_layer_norm_cuda.forward_none_affine(
|
| 42 |
+
input_, ctx.normalized_shape, ctx.eps
|
| 43 |
+
)
|
| 44 |
+
else:
|
| 45 |
+
output, mean, invvar = (
|
| 46 |
+
fastfold_layer_norm_cuda.forward_with_bias_affine(
|
| 47 |
+
input_, ctx.normalized_shape, bias.to(d), ctx.eps
|
| 48 |
+
)
|
| 49 |
+
)
|
| 50 |
+
else:
|
| 51 |
+
if bias is None:
|
| 52 |
+
output, mean, invvar = (
|
| 53 |
+
fastfold_layer_norm_cuda.forward_with_weight_affine(
|
| 54 |
+
input_, ctx.normalized_shape, weight.to(d), ctx.eps
|
| 55 |
+
)
|
| 56 |
+
)
|
| 57 |
+
else:
|
| 58 |
+
output, mean, invvar = (
|
| 59 |
+
fastfold_layer_norm_cuda.forward_with_both_affine(
|
| 60 |
+
input_, ctx.normalized_shape, weight.to(d), bias.to(d), ctx.eps
|
| 61 |
+
)
|
| 62 |
+
)
|
| 63 |
+
ctx.save_for_backward(input_, weight, bias, mean, invvar)
|
| 64 |
+
return output
|
| 65 |
+
|
| 66 |
+
@staticmethod
|
| 67 |
+
def backward(ctx, grad_output):
|
| 68 |
+
d = grad_output.dtype
|
| 69 |
+
input_, weight_, bias_, mean, invvar = ctx.saved_tensors
|
| 70 |
+
grad_input = grad_weight = grad_bias = None
|
| 71 |
+
|
| 72 |
+
if weight_ is None:
|
| 73 |
+
if bias_ is None:
|
| 74 |
+
grad_input, grad_weight, grad_bias = (
|
| 75 |
+
fastfold_layer_norm_cuda.backward_none_affine(
|
| 76 |
+
grad_output.contiguous(),
|
| 77 |
+
mean,
|
| 78 |
+
invvar,
|
| 79 |
+
input_,
|
| 80 |
+
ctx.normalized_shape,
|
| 81 |
+
ctx.eps,
|
| 82 |
+
)
|
| 83 |
+
)
|
| 84 |
+
else:
|
| 85 |
+
grad_input, grad_weight, grad_bias = (
|
| 86 |
+
fastfold_layer_norm_cuda.backward_with_bias_affine(
|
| 87 |
+
grad_output.contiguous(),
|
| 88 |
+
mean,
|
| 89 |
+
invvar,
|
| 90 |
+
input_,
|
| 91 |
+
ctx.normalized_shape,
|
| 92 |
+
bias_.to(dtype=d),
|
| 93 |
+
ctx.eps,
|
| 94 |
+
)
|
| 95 |
+
)
|
| 96 |
+
else:
|
| 97 |
+
if bias_ is None:
|
| 98 |
+
grad_input, grad_weight, grad_bias = (
|
| 99 |
+
fastfold_layer_norm_cuda.backward_with_weight_affine(
|
| 100 |
+
grad_output.contiguous(),
|
| 101 |
+
mean,
|
| 102 |
+
invvar,
|
| 103 |
+
input_,
|
| 104 |
+
ctx.normalized_shape,
|
| 105 |
+
weight_.to(dtype=d),
|
| 106 |
+
ctx.eps,
|
| 107 |
+
)
|
| 108 |
+
)
|
| 109 |
+
else:
|
| 110 |
+
grad_input, grad_weight, grad_bias = (
|
| 111 |
+
fastfold_layer_norm_cuda.backward_with_both_affine(
|
| 112 |
+
grad_output.contiguous(),
|
| 113 |
+
mean,
|
| 114 |
+
invvar,
|
| 115 |
+
input_,
|
| 116 |
+
ctx.normalized_shape,
|
| 117 |
+
weight_.to(dtype=d),
|
| 118 |
+
bias_.to(dtype=d),
|
| 119 |
+
ctx.eps,
|
| 120 |
+
)
|
| 121 |
+
)
|
| 122 |
+
return (
|
| 123 |
+
grad_input,
|
| 124 |
+
None if weight_ is None else grad_weight,
|
| 125 |
+
None if bias_ is None else grad_bias,
|
| 126 |
+
None,
|
| 127 |
+
None,
|
| 128 |
+
)
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
class FusedLayerNorm(torch.nn.Module):
|
| 132 |
+
|
| 133 |
+
def __init__(
|
| 134 |
+
self,
|
| 135 |
+
normalized_shape,
|
| 136 |
+
create_scale=True,
|
| 137 |
+
create_offset=True,
|
| 138 |
+
eps=1e-5,
|
| 139 |
+
):
|
| 140 |
+
"""
|
| 141 |
+
Args:
|
| 142 |
+
normalized_shape (int or list or torch.Size) input shape from an expected input of size
|
| 143 |
+
create_scale (bool) If set to False, the layer will not learn an additive weight, Default: True
|
| 144 |
+
create_offset (bool) If set to False, the layer will not learn an additive bias, Default: True
|
| 145 |
+
eps (float) a value added to the denominator for numerical stability. Default: 1e-5
|
| 146 |
+
"""
|
| 147 |
+
super(FusedLayerNorm, self).__init__()
|
| 148 |
+
|
| 149 |
+
if isinstance(normalized_shape, numbers.Integral):
|
| 150 |
+
normalized_shape = (normalized_shape,)
|
| 151 |
+
self.normalized_shape = torch.Size(normalized_shape)
|
| 152 |
+
self.eps = eps
|
| 153 |
+
if create_scale:
|
| 154 |
+
self.weight = Parameter(torch.ones(*normalized_shape))
|
| 155 |
+
else:
|
| 156 |
+
self.weight = None
|
| 157 |
+
|
| 158 |
+
if create_offset:
|
| 159 |
+
self.bias = Parameter(torch.zeros(*normalized_shape))
|
| 160 |
+
else:
|
| 161 |
+
self.bias = None
|
| 162 |
+
|
| 163 |
+
self.reset_parameters()
|
| 164 |
+
|
| 165 |
+
def reset_parameters(self):
|
| 166 |
+
if self.weight is not None:
|
| 167 |
+
torch.nn.init.ones_(self.weight)
|
| 168 |
+
if self.bias is not None:
|
| 169 |
+
torch.nn.init.zeros_(self.bias)
|
| 170 |
+
|
| 171 |
+
def forward(self, input):
|
| 172 |
+
return FusedLayerNormAffineFunction.apply(
|
| 173 |
+
input, self.weight, self.bias, self.normalized_shape, self.eps
|
| 174 |
+
)
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
if __name__ == "__main__":
|
| 178 |
+
dtype = torch.float32
|
| 179 |
+
data = torch.rand(10, 10).cuda().to(dtype=dtype)
|
| 180 |
+
data1 = data * 1
|
| 181 |
+
data.requires_grad = True
|
| 182 |
+
data1.requires_grad = True
|
| 183 |
+
layer_norm = (
|
| 184 |
+
FusedLayerNorm(10, create_scale=True, create_offset=True).cuda().to(dtype=dtype)
|
| 185 |
+
)
|
| 186 |
+
layer_norm_torch = torch.nn.LayerNorm(10).cuda().to(dtype=dtype)
|
| 187 |
+
out = layer_norm(data)
|
| 188 |
+
out1 = layer_norm_torch(data1)
|
| 189 |
+
# print(out - out1)
|
| 190 |
+
loss = out.sum()
|
| 191 |
+
loss.backward()
|
| 192 |
+
loss1 = out1.sum()
|
| 193 |
+
loss1.backward()
|
| 194 |
+
print(data.grad - data1.grad)
|
| 195 |
+
print(layer_norm.weight.grad - layer_norm_torch.weight.grad)
|
| 196 |
+
print(layer_norm.bias.grad - layer_norm_torch.bias.grad)
|
| 197 |
+
print(layer_norm.weight.grad, layer_norm.bias.grad)
|
| 198 |
+
|
models/protenix/layer_norm/torch_ext_compile.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
|
| 3 |
+
from torch.utils.cpp_extension import load
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def compile(name, sources, extra_include_paths, build_directory):
|
| 7 |
+
os.environ["TORCH_CUDA_ARCH_LIST"] = "7.0;8.0"
|
| 8 |
+
return load(
|
| 9 |
+
name=name,
|
| 10 |
+
sources=sources,
|
| 11 |
+
extra_include_paths=extra_include_paths,
|
| 12 |
+
extra_cflags=[
|
| 13 |
+
"-O3",
|
| 14 |
+
"-DVERSION_GE_1_1",
|
| 15 |
+
"-DVERSION_GE_1_3",
|
| 16 |
+
"-DVERSION_GE_1_5",
|
| 17 |
+
],
|
| 18 |
+
extra_cuda_cflags=[
|
| 19 |
+
"-O3",
|
| 20 |
+
"--use_fast_math",
|
| 21 |
+
"-DVERSION_GE_1_1",
|
| 22 |
+
"-DVERSION_GE_1_3",
|
| 23 |
+
"-DVERSION_GE_1_5",
|
| 24 |
+
"-std=c++17",
|
| 25 |
+
"-maxrregcount=50",
|
| 26 |
+
"-U__CUDA_NO_HALF_OPERATORS__",
|
| 27 |
+
"-U__CUDA_NO_HALF_CONVERSIONS__",
|
| 28 |
+
"--expt-relaxed-constexpr",
|
| 29 |
+
"--expt-extended-lambda",
|
| 30 |
+
"-gencode",
|
| 31 |
+
"arch=compute_70,code=sm_70",
|
| 32 |
+
"-gencode",
|
| 33 |
+
"arch=compute_80,code=sm_80",
|
| 34 |
+
"-gencode",
|
| 35 |
+
"arch=compute_86,code=sm_86",
|
| 36 |
+
"-gencode",
|
| 37 |
+
"arch=compute_90,code=sm_90",
|
| 38 |
+
],
|
| 39 |
+
verbose=True,
|
| 40 |
+
build_directory=build_directory,
|
| 41 |
+
)
|
weight/model_v0.5.0.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9ea20b0aba42f2256711da1d0cd081510a4b291e64375bff6b70ced70b87a5f1
|
| 3 |
+
size 1474265486
|