1#ifndef TMVA_SOFIE_ROPERATOR_LAYERNORMALIZATION
2#define TMVA_SOFIE_ROPERATOR_LAYERNORMALIZATION
11namespace Experimental {
55 const std::string &nameScale,
const std::string &nameB,
const std::string &nameY,
56 const std::string &nameMean,
const std::string &nameInvStdDev)
58 fNScale(UTILITY::Clean_name(nameScale)),
fNB(UTILITY::Clean_name(nameB)),
59 fNY(UTILITY::Clean_name(nameY)),
fNMean(UTILITY::Clean_name(nameMean)),
fNInvStdDev(UTILITY::Clean_name(nameInvStdDev))
70 throw std::runtime_error(
"TMVA::SOFIE - Tensor " +
fNX +
" not found.");
123 std::stringstream out;
125 out <<
SP <<
"// Broadcasting the bias of LayerNormlization op\n";
127 out <<
SP <<
SP <<
"float* data = TMVA::Experimental::SOFIE::UTILITY::UnidirectionalBroadcast<float>(tensor_";
130 out <<
SP <<
"delete[] data;\n";
138 OpName =
"op_" + OpName;
140 throw std::runtime_error(
"TMVA::SOFIE LayerNormalization operator " + OpName +
141 " called to generate without beging initialized first.");
144 throw std::runtime_error(
"TMVA::SOFIE LayerNormalization operator not "
145 "implemented for input tensor of size > 5.");
148 std::stringstream out;
150 out <<
SP <<
"// Operator " << OpName <<
"\n";
153 out <<
SP <<
"std::vector<size_t> " << OpName <<
"_InputShape ({";
154 for (
size_t i = 0; i <
fSize; i++) {
161 std::string inputShape = OpName +
"_InputShape";
164 std::string InputIndex =
"axis_0 * " + std::to_string(strides[0]);
165 for (
size_t i = 1; i <
fSize; i++) {
166 InputIndex +=
" + axis_" + std::to_string(i) +
" * " + std::to_string(strides[i]);
170 std::string axesIndex =
"axis_" + std::to_string(0) +
" * " + std::to_string(axesStrides[0]);
171 for (
size_t i = 1; i <
fAxis; i++) {
172 axesIndex +=
" + axis_" + std::to_string(i) +
" * " + std::to_string(axesStrides[i]);
176 std::string normalizedIndex =
"axis_" + std::to_string(
fAxis) +
" * " + std::to_string(normalizedStrides[0]);
178 normalizedIndex +=
" + axis_" + std::to_string(i) +
" * " + std::to_string(normalizedStrides[i -
fAxis]);
183 out <<
SP <<
"for (size_t i = 0; i < " <<
fLength <<
"; i++) {\n";
184 out <<
SP <<
SP <<
"tensor_" <<
fNCastedX <<
"[i] = " <<
"static_cast<float>(tensor_" <<
fNX;
189 out <<
SP <<
"// Compute the mean\n";
191 for (
size_t i = 0; i <
fAxis; i++) {
192 std::string iIdx =
"axis_" + std::to_string(i);
193 out <<
SP <<
"for (size_t " << iIdx <<
" = 0; " << iIdx <<
" < " << inputShape;
194 out <<
"[" << i <<
"]; " << iIdx <<
"++) {\n";
196 out <<
SP <<
SP <<
fType <<
" sum = 0.;\n";
199 std::string jIdx =
"axis_" + std::to_string(j);
200 out <<
SP <<
SP <<
"for (size_t " << jIdx <<
" = 0; " << jIdx <<
" < " << inputShape;
201 out <<
"[" << j <<
"]; " << jIdx <<
"++) {\n";
203 out <<
SP <<
SP <<
SP <<
"sum += tensor_" <<
fNX <<
"[" << InputIndex <<
"];\n";
205 out <<
SP <<
SP <<
"}\n";
207 out <<
SP <<
SP <<
"tensor_" <<
fNMean <<
"[" << axesIndex <<
"] = sum / " <<
fType <<
"(";
213 out <<
SP <<
"// Compute the inverse Standard Deviation\n";
215 for (
size_t i = 0; i <
fAxis; i++) {
216 std::string iIdx =
"axis_" + std::to_string(i);
217 out <<
SP <<
"for (size_t " << iIdx <<
" = 0; " << iIdx <<
" < " << inputShape;
218 out <<
"[" << i <<
"]; " << iIdx <<
"++){\n";
221 out <<
SP <<
SP <<
fType <<
" sum = 0.;\n";
224 std::string jIdx =
"axis_" + std::to_string(j);
225 out <<
SP <<
SP <<
"for (size_t " << jIdx <<
" = 0; " << jIdx <<
" < " << inputShape;
226 out <<
"[" << j <<
"]; " << jIdx <<
"++){\n";
228 out <<
SP <<
SP <<
SP <<
"sum += std::pow(tensor_" <<
fNX <<
"[" << InputIndex <<
"] - tensor_";
229 out <<
fNMean <<
"[" << axesIndex <<
"], 2);\n";
231 out <<
SP <<
SP <<
"}\n";
233 out <<
SP <<
SP <<
"tensor_" <<
fNInvStdDev <<
"[" << axesIndex <<
"] = 1 / std::sqrt(";
235 for (
size_t i = 0; i <
fAxis; i++) {
240 out <<
"// NormalizedX = InvStdDev * (CastedX - Mean)\n";
241 for (
size_t i = 0; i <
fAxis; i++) {
242 std::string iIdx =
"axis_" + std::to_string(i);
243 out <<
SP <<
"for (size_t " << iIdx <<
" = 0; " << iIdx <<
" < " << inputShape;
244 out <<
"[" << i <<
"]; " << iIdx <<
"++){\n";
247 std::string jIdx =
"axis_" + std::to_string(j);
248 out <<
SP <<
SP <<
"for (size_t " << jIdx <<
" = 0; " << jIdx <<
" < " << inputShape;
249 out <<
"[" << j <<
"]; " << jIdx <<
"++){\n";
253 out <<
"] - tensor_" <<
fNMean <<
"[" << axesIndex <<
"])\n";
255 out <<
SP <<
SP <<
"}\n";
260 out <<
"// Y = Scale o NormalizedX";
261 for (
size_t i = 0; i <
fAxis; i++) {
262 std::string iIdx =
"axis_" + std::to_string(i);
263 out <<
SP <<
"for (size_t " << iIdx <<
" = 0; " << iIdx <<
" < " << inputShape;
264 out <<
"[" << i <<
"]; " << iIdx <<
"++){\n";
267 std::string jIdx =
"axis_" + std::to_string(j);
268 out <<
SP <<
SP <<
"for (size_t " << jIdx <<
" = 0; " << jIdx <<
" < " << inputShape;
269 out <<
"[" << j <<
"]; " << jIdx <<
"++){\n";
271 out <<
SP <<
SP <<
SP <<
"tensor_" <<
fNY <<
"[" << InputIndex <<
"] = tensor_" <<
fNScale;
272 out <<
"[" << axesIndex <<
"] * static_cast<" <<
fType <<
">(tensor_" <<
fNCastedX <<
"[" << InputIndex;
275 out <<
SP <<
SP <<
"}\n";
281 out <<
SP <<
"// Y = Scale o InvStdDev (X - Mean)\n";
282 for (
size_t i = 0; i <
fAxis; i++) {
283 std::string iIdx =
"axis_" + std::to_string(i);
284 out <<
SP <<
"for (size_t " << iIdx <<
" = 0; " << iIdx <<
" < " << inputShape;
285 out <<
"[" << i <<
"]; " << iIdx <<
"++){\n";
288 std::string jIdx =
"axis_" + std::to_string(j);
289 out <<
SP <<
SP <<
"for (size_t " << jIdx <<
" = 0; " << jIdx <<
" < " << inputShape;
290 out <<
"[" << j <<
"]; " << jIdx <<
"++){\n";
292 out <<
SP <<
SP <<
SP <<
"tensor_" <<
fNY <<
"[" << InputIndex <<
"] = tensor_" <<
fNScale;
293 out <<
"[" << normalizedIndex <<
"] * tensor_" <<
fNInvStdDev <<
"[" << axesIndex;
294 out <<
"] * (tensor_" <<
fNX <<
"[" << InputIndex <<
"] - tensor_" <<
fNMean <<
"[";
295 out << axesIndex <<
"]);\n";
297 out <<
SP <<
SP <<
"}\n";
306 out <<
SP <<
"// Add the bias to Y\n";
307 out <<
SP <<
"int " << OpName <<
"_n = " <<
fLength <<
";\n";
308 out <<
SP <<
"float " << OpName <<
"_alpha = 1.;\n";
309 out <<
SP <<
"int " << OpName <<
"_inc = 1;\n";
310 out <<
SP <<
"BLAS::saxpy_(&" << OpName <<
"_n, &" << OpName <<
"_alpha, " << Bias <<
", &";
311 out << OpName <<
"_inc, " <<
"tensor_" <<
fNY <<
", &" << OpName <<
"_inc);\n";
317 std::vector<std::string>
GetBlasRoutines()
override {
return { std::string(
"Axpy") }; }
319 std::vector<std::string>
GetStdLibs()
override {
return { std::string(
"cmath") }; }
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
const ETensorType & GetTensorType(std::string name)
void AddIntermediateTensor(std::string tensor_name, ETensorType type, std::vector< std::size_t > shape)
bool CheckIfTensorAlreadyExist(std::string tensor_name)
const std::vector< size_t > & GetTensorShape(std::string name)
std::vector< std::string > GetBlasRoutines() override
ROperator_LayerNormalization()
std::vector< size_t > fShapeX
std::vector< size_t > fShapeScale
std::vector< size_t > fShapeMean
ROperator_LayerNormalization(int axis, float epsilon, size_t stashType, const std::string &nameX, const std::string &nameScale, const std::string &nameB, const std::string &nameY, const std::string &nameMean, const std::string &nameInvStdDev)
std::vector< size_t > fShapeInvStdDev
std::vector< std::string > GetStdLibs() override
std::string GenerateInitCode() override
std::vector< size_t > fNormalizedShape
void Initialize(RModel &model) override
std::vector< size_t > fShapeB
std::string Generate(std::string OpName) override
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input) override
std::string fNBroadcastedB
std::vector< size_t > fAxesShape
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
std::string fNNormalizedX
std::vector< size_t > fShapeY
const std::string SP
space used to correctly indent the generated C++ code
std::vector< size_t > ComputeStrideFromShape(const std::vector< size_t > &shape)
compute stride of a tensor given its shape (assume layout is row-major)
std::string ConvertShapeToString(std::vector< size_t > shape)
std::string ConvertTypeToString(ETensorType type)
ETensorType ConvertStringToType(std::string type)
std::size_t ConvertShapeToLength(std::vector< size_t > shape)
create variable transformations