1#ifndef TMVA_SOFIE_ROPERATOR_LAYERNORMALIZATION
2#define TMVA_SOFIE_ROPERATOR_LAYERNORMALIZATION
12namespace Experimental {
58 const std::string &nameScale,
const std::string &nameB,
const std::string &nameY,
59 const std::string &nameMean,
const std::string &nameInvStdDev)
61 fNScale(UTILITY::Clean_name(nameScale)),
fNB(UTILITY::Clean_name(nameB)),
62 fNY(UTILITY::Clean_name(nameY)),
fNMean(UTILITY::Clean_name(nameMean)),
fNInvStdDev(UTILITY::Clean_name(nameInvStdDev))
79 if (!model.CheckIfTensorAlreadyExist(
fNX)) {
80 throw std::runtime_error(
"TMVA::SOFIE - LayerNormalization - Tensor " +
fNX +
" not found.");
82 bool isDynamic = model.IsDynamicTensor(
fNX);
129 if (dimScale <
fSize) {
130 for (
size_t i = 0; i <
fSize-dimScale; i++)
134 for (
size_t i = 0; i <
fSize; i++) {
143 for (
size_t i = 0; i <
fSize-dimB; i++)
146 for (
size_t i = 0; i <
fSize; i++) {
152 model.AddIntermediateTensor(
fNY, model.GetTensorType(
fNX),
fShapeY);
153 if (model.Verbose()){
159 model.AddNeededStdLib(
"cmath");
163 model.AddNeededHelperFunction(
"UnidirectionalBroadcast");
168 std::stringstream out;
170 out <<
SP <<
"// Broadcasting the bias of LayerNormalization op\n";
172 out <<
SP <<
SP <<
"float* data = UTILITY::UnidirectionalBroadcast(tensor_";
175 out <<
SP <<
"delete[] data;\n";
183 opName =
"op_" + opName;
185 throw std::runtime_error(
"TMVA::SOFIE LayerNormalization operator " + opName +
186 " called to generate without being initialized first.");
189 std::stringstream out;
191 out <<
"//---- Layer Normalization operator " << opName <<
"\n";
194 std::vector<std::string> inputShape(
fSize);
196 for (
size_t i = 0; i <
fSize; i++) {
197 inputShape[i] =
fShapeX[i].GetVal();
201 std::string inputIndex =
"axis_0 * " + strides[0].GetVal();
202 for (
size_t i = 1; i <
fSize; i++) {
203 inputIndex +=
" + axis_" + std::to_string(i);
204 if (i <
fSize-1) inputIndex +=
" * " + strides[i].GetVal();
207 std::string scaleIndex;
208 for (
size_t i = 0; i <
fSize; i++) {
210 if (!scaleIndex.empty()) scaleIndex +=
" + ";
211 scaleIndex +=
"axis_" + std::to_string(i);
212 if ( scaleStrides[i].dim != 1) scaleIndex +=
" * " + scaleStrides[i].GetVal();
215 if (scaleIndex.empty()) scaleIndex =
"0";
218 std::string biasIndex;
219 for (
size_t i = 0; i <
fSize; i++) {
221 if (!biasIndex.empty()) biasIndex +=
" + ";
222 biasIndex +=
"axis_" + std::to_string(i);
223 if ( biasStrides[i].dim != 1) biasIndex +=
" * " + biasStrides[i].GetVal();
226 if (biasIndex.empty()) biasIndex =
"0";
229 std::string axesIndex =
"axis_" + std::to_string(0) +
" * " + axesStrides[0].GetVal();
230 for (
size_t i = 1; i <
fAxis; i++) {
231 axesIndex +=
" + axis_" + std::to_string(i) +
" * " + axesStrides[i].GetVal();
237 out <<
SP <<
"// Compute the mean\n";
240 for (
size_t i = 0; i <
fAxis; i++) {
241 std::string iIdx =
"axis_" + std::to_string(i);
242 out <<
SP <<
"for (size_t " << iIdx <<
" = 0; " << iIdx <<
" < " << inputShape[i]
243 <<
"; " << iIdx <<
"++) {\n";
245 out <<
SP <<
SP <<
fType <<
" mean = 0.;\n";
248 std::string jIdx =
"axis_" + std::to_string(j);
249 out <<
SP <<
SP <<
"for (size_t " << jIdx <<
" = 0; " << jIdx <<
" < " << inputShape[j]
250 <<
"; " << jIdx <<
"++) {\n";
252 out <<
SP <<
SP <<
SP <<
"mean += tensor_" <<
fNX <<
"[" << inputIndex <<
"];\n";
254 out <<
SP <<
SP <<
"}\n";
259 out <<
SP <<
"// Compute the inverse Standard Deviation\n";
262 out <<
SP <<
SP <<
fType <<
" sum = 0.;\n";
265 std::string jIdx =
"axis_" + std::to_string(j);
266 out <<
SP <<
SP <<
"for (size_t " << jIdx <<
" = 0; " << jIdx <<
" < " << inputShape[j]
267 <<
"; " << jIdx <<
"++){\n";
269 out <<
SP <<
SP <<
SP <<
"float tmp = tensor_" <<
fNX <<
"[" << inputIndex <<
"] - mean;\n";
270 out <<
SP <<
SP <<
SP <<
"sum += tmp*tmp;\n";
272 out <<
SP <<
SP <<
"}\n";
274 out <<
SP <<
SP <<
fType <<
" invStdDev = 1 / std::sqrt(";
280 out <<
SP <<
SP <<
"tensor_" <<
fNMean <<
"[" << axesIndex <<
"] = mean;\n";
282 out <<
SP <<
SP <<
"tensor_" <<
fNInvStdDev <<
"[" << axesIndex <<
"] = invStdDev;\n";
286 out <<
SP <<
"// Y = Scale o InvStdDev (X - Mean)\n";
289 std::string jIdx =
"axis_" + std::to_string(j);
290 out <<
SP <<
SP <<
"for (size_t " << jIdx <<
" = 0; " << jIdx <<
" < " << inputShape[j] <<
"; " << jIdx
293 out <<
SP <<
SP <<
SP <<
"tensor_" <<
fNY <<
"[" << inputIndex <<
"] = tensor_" <<
fNScale;
294 out <<
"[" << scaleIndex <<
"] * invStdDev * (tensor_" <<
fNX <<
"[" << inputIndex <<
"] - mean)";
299 out <<
" + tensor_" <<
fNB <<
"[" << biasIndex <<
"]";
304 out <<
SP <<
SP <<
"}\n";
307 for (
size_t i = 0; i <
fAxis; i++) {
314 std::vector<std::string>
GetBlasRoutines()
override {
return { std::string(
"Axpy") }; }
316 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 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
std::vector< std::string > GetBlasRoutines() override
std::vector< Dim > fShapeX
ROperator_LayerNormalization()
std::vector< Dim > fShapeInvStdDev
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< Dim > fShapeB
std::string fNormalizedLength
std::string Generate(std::string opName) override
std::vector< std::string > GetStdLibs() override
std::string GenerateInitCode() override
std::vector< Dim > fNormalizedShape
std::vector< Dim > fShapeScale
void Initialize(RModel &model) override
std::vector< Dim > fShapeY
std::string fNBroadcastedB
std::vector< Dim > fShapeMean
std::string fNNormalizedX
std::vector< Dim > fAxesShape
std::vector< std::string_view > fInputTensorNames
const std::string SP
space used to correctly indent the generated C++ code
std::vector< std::string_view > fOutputTensorNames
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 ConvertDimShapeToString(const std::vector< Dim > &shape)
std::string ConvertTypeToString(ETensorType type)
std::string ConvertDimShapeToLength(const std::vector< Dim > &shape)
create variable transformations