1#ifndef TMVA_SOFIE_ROPERATOR_RNN
2#define TMVA_SOFIE_ROPERATOR_RNN
89 if (std::is_same<T, float>::value) {
92 throw std::runtime_error(
93 "TMVA SOFIE Encountered unsupported type parsing a RNN operator");
126 std::vector<std::vector<size_t>>
146 std::vector<std::string>
GetBlasRoutines()
override {
return { std::string(
"Gemm"), std::string(
"Axpy") }; }
161 if (fAttrLayout == 0) {
164 std::vector<std::vector<size_t>>
ret(
170 std::vector<std::vector<size_t>>
ret(
179 fUseSession = model.UseSession();
181 if (!model.CheckIfTensorAlreadyExist(fNX)) {
182 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNX +
" is not found in model.");
184 fShapeX = model.GetTensorShape(fNX);
185 if (fShapeX.size() != 3) {
186 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNX +
" is not of 3 dimensions.");
188 if (!model.CheckIfTensorAlreadyExist(fNW)) {
189 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNW +
" is not found in model.");
191 fShapeW = model.GetTensorShape(fNW);
192 if (fShapeW.size() != 3) {
193 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNW +
" is not of 3 dimensions.");
195 if (!model.CheckIfTensorAlreadyExist(fNR)) {
196 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNR +
" is not found in model.");
198 fShapeR = model.GetTensorShape(fNR);
199 if (fShapeR.size() != 3) {
200 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNR +
" is not of 3 dimensions.");
203 if (!model.CheckIfTensorAlreadyExist(fNB)) {
204 throw std::runtime_error(
"TMVA SOFIE RNN op input tensor " + fNB +
" is not found in model.");
206 fShapeB = model.GetTensorShape(fNB);
207 if (fShapeB.size() != 2 && fShapeB.size() != 4) {
208 throw std::runtime_error(
"TMVA SOFIE RNN op input tensor " + fNB +
" is not of 2 or 4 dimensions.");
210 if (fShapeB.size() == 2) {
214 size_t seq_length = (fAttrLayout == 0) ? fShapeX[0] : fShapeX[1];
215 size_t batch_size = (fAttrLayout == 0) ? fShapeX[1] : fShapeX[0];
216 if (fType ==
"float") {
219 std::vector<float>
sum(fAttrHiddenSize);
221 for (
size_t h = 0;
h < fAttrHiddenSize;
h++) {
236 fShapeB = model.GetTensorShape(fNB);
240 if (!fNSequence_lens.empty()) {
241 if (!model.CheckIfTensorAlreadyExist(fNSequence_lens)) {
242 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNSequence_lens +
"is not found in model.");
244 fShapeSequence_lens = model.GetTensorShape(fNSequence_lens);
245 if (fShapeSequence_lens.size() != 1) {
246 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNSequence_lens +
" is not of 1 dimension.");
249 if (!fNInitial_h.empty()) {
250 if (!model.CheckIfTensorAlreadyExist(fNInitial_h)) {
251 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNInitial_h +
" is not found in model.");
253 fShapeInitial_h = model.GetTensorShape(fNInitial_h);
254 if (fShapeInitial_h.size() != 3) {
255 throw std::runtime_error(
"TMVA SOFIE RNN Op input tensor " + fNInitial_h +
" is not of 3 dimensions.");
259 fShapeY = ShapeInference({fShapeX, fShapeW})[0];
260 if (!model.CheckIfTensorAlreadyExist(fNY)) {
261 model.AddIntermediateTensor(fNY, model.GetTensorType(fNX), fShapeY);
264 if (!fNY_h.empty()) {
265 fShapeY_h = ShapeInference({fShapeX, fShapeW})[1];
266 if (!model.CheckIfTensorAlreadyExist(fNY_h)) {
267 model.AddIntermediateTensor(fNY_h, model.GetTensorType(fNX), fShapeY_h);
275 throw std::runtime_error(
"TMVA SOFIE - Activation function " +
activation +
" not implemented");
278 if (fAttrDirection !=
"forward" && fAttrDirection !=
"backward" && fAttrDirection !=
"bidirectional") {
279 throw std::runtime_error(
"TMVA SOFIE - Invalid RNN direction fAttrDirection = " + fAttrDirection);
281 if (fAttrHiddenSize != fShapeW[1]) {
282 throw std::runtime_error(
"TMVA SOFIE - fAttrHiddenSize must be equal to " + std::to_string(fShapeW[1]));
284 if (fAttrLayout > 1) {
285 throw std::runtime_error(
"TMVA SOFIE - Layout fAttrLayout = " + std::to_string(fAttrLayout) +
286 " must be 0 (timewise) or 1 (batchwise)");
288 if (fAttrActivations.empty()) {
289 if (fAttrDirection ==
"bidirectional") {
290 fAttrActivations = {
"Tanh",
"Tanh"};
292 fAttrActivations = {
"Tanh"};
296 model.AddNeededStdLib(
"cmath");
304 std::stringstream out;
307 size_t seq_length = (fAttrLayout == 0) ? fShapeX[0] : fShapeX[1];
308 size_t batch_size = (fAttrLayout == 0) ? fShapeX[1] : fShapeX[0];
311 if (fAttrLayout != 0) {
312 out <<
"std::vector<" << fType <<
"> fVec_" <<
opName <<
"_input = std::vector<" << fType <<
">("
314 out <<
"std::vector<" << fType <<
"> fVec_" <<
opName <<
"_initial_hidden_state = std::vector<" << fType <<
">("
317 out <<
"std::vector<" << fType <<
"> fVec_" <<
opName <<
"_feedforward = std::vector<" << fType <<
">("
320 if (fAttrLayout != 0 || fNY.empty()) {
321 out <<
"std::vector<" << fType <<
"> fVec_" <<
opName <<
"_hidden_state = std::vector<" << fType <<
">("
335 std::stringstream out;
337 size_t seq_length = (fAttrLayout == 0) ? fShapeX[0] : fShapeX[1];
338 size_t batch_size = (fAttrLayout == 0) ? fShapeX[1] : fShapeX[0];
343 if (fAttrLayout == 0) {
344 if (fType ==
"float") {
345 out << SP <<
"float const*" <<
OpName <<
"_input = tensor_" << fNX <<
";\n";
349 out << SP << fType <<
" * " <<
OpName <<
"_input = this->fVec_" <<
OpName <<
"_input.data();\n";
352 out << SP <<
"for(size_t seq = 0; seq < " <<
seq_length <<
"; seq++) {\n";
353 out << SP << SP <<
"for(size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
354 out << SP << SP << SP <<
"for(size_t i = 0; i < " <<
input_size <<
"; i++) {\n";
358 out << SP << SP << SP <<
"}\n";
359 out << SP << SP <<
"}\n";
364 if (!fNInitial_h.empty()) {
365 if (fAttrLayout == 0) {
366 out << SP << fType <<
" *" <<
OpName <<
"_initial_hidden_state = " <<
" tensor_" << fNInitial_h <<
";\n";
369 out << SP << fType <<
" * " <<
OpName <<
"_initial_hidden_state = this->fVec_" <<
OpName
370 <<
"_initial_hidden_state.data();\n";
376 out << SP <<
"for(size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
377 out << SP << SP <<
"for(size_t h = 0; h < " << fAttrHiddenSize <<
"; h++) {\n";
379 <<
" + batch * " << fAttrHiddenSize <<
" + h] = tensor_" << fNInitial_h <<
"[batch * "
381 out << SP << SP <<
"}\n";
388 out << SP << fType <<
" * " <<
OpName <<
"_feedforward = this->fVec_" <<
OpName <<
"_feedforward.data();\n";
394 if (fAttrLayout == 0 && !fNY.empty()) {
395 out << SP << fType <<
" *" <<
OpName <<
"_hidden_state = tensor_" << fNY <<
";\n";
398 out << SP << fType <<
" * " <<
OpName <<
"_hidden_state = this->fVec_" <<
OpName <<
"_hidden_state.data();\n";
400 out << SP << fType <<
" " <<
OpName <<
"_hidden_state["
404 out << SP <<
"char " <<
OpName <<
"_transA = 'N';\n";
405 out << SP <<
"char " <<
OpName <<
"_transB = 'T';\n";
407 out << SP <<
"int " <<
OpName <<
"_n = " << fAttrHiddenSize <<
";\n";
409 if (fType ==
"float") {
410 out << SP <<
"float " <<
OpName <<
"_alpha = 1.;\n";
411 out << SP <<
"float " <<
OpName <<
"_beta = .0;\n";
415 out << SP <<
"int " <<
OpName <<
"_incx = 1;\n";
416 out << SP <<
"int " <<
OpName <<
"_incy = 1;\n";
421 if (fType ==
"float") {
423 out << SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transB, &" <<
OpName <<
"_transA, &" <<
OpName <<
"_n, &"
426 <<
"_feedforward, &" <<
OpName <<
"_n);\n";
428 out << SP <<
"size_t " <<
OpName <<
"_w_offset = " << fAttrHiddenSize *
input_size <<
";\n";
429 out << SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transB, &" <<
OpName <<
"_transA, &" <<
OpName <<
"_n, &"
432 <<
"_beta, " <<
OpName <<
"_feedforward, &" <<
OpName <<
"_n);\n";
437 if (fType ==
"float") {
439 out << SP <<
"BLAS::saxpy_(&" <<
OpName <<
"_bias_size, &" <<
OpName <<
"_alpha, tensor_" << fNB <<
", &"
444 out << SP <<
"BLAS::saxpy_(&" <<
OpName <<
"_bias_size, &" <<
OpName <<
"_alpha, tensor_" << fNB <<
" + "
452 out << SP <<
"for (size_t seq = 0; seq < " <<
seq_length <<
"; seq++) {\n";
453 out << SP << SP <<
"size_t offset = seq * " <<
batch_size * fAttrHiddenSize <<
";\n";
454 out << SP << SP <<
"size_t size = " <<
batch_size * fAttrHiddenSize <<
";\n";
457 out << SP << SP <<
"std::copy(" <<
OpName <<
"_feedforward + offset, " <<
OpName
458 <<
"_feedforward + offset + size, " <<
OpName <<
"_hidden_state + h_offset);\n";
461 out << SP <<
"for (size_t seq = 0; seq < " <<
seq_length <<
"; seq++) {\n";
462 if (fAttrDirection ==
"backward" ||
direction == 1) {
463 out << SP << SP <<
"size_t index = " <<
seq_length - 1 <<
" - seq;\n";
465 out << SP << SP <<
"size_t index = seq;\n";
468 out << SP << SP <<
"int m2 = " <<
batch_size <<
";\n";
471 out << SP << SP <<
"size_t size = " <<
batch_size * fAttrHiddenSize <<
";\n";
472 out << SP << SP <<
"if (seq == 0) {\n";
473 if (!fNInitial_h.empty()) {
475 out << SP << SP << SP <<
"size_t r_offset = " <<
direction * fAttrHiddenSize * fAttrHiddenSize <<
";\n";
476 out << SP << SP << SP <<
"size_t initial_hidden_state_offset = " <<
direction *
batch_size * fAttrHiddenSize
478 if (fType ==
"float") {
479 out << SP << SP << SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transB, &" <<
OpName <<
"_transA, &" <<
OpName
480 <<
"_n, &m2, &" <<
OpName <<
"_n, &" <<
OpName <<
"_alpha, tensor_" << fNR <<
" + r_offset, &" <<
OpName
481 <<
"_n, " <<
OpName <<
"_initial_hidden_state + initial_hidden_state_offset, &" <<
OpName <<
"_n, &"
482 <<
OpName <<
"_alpha, " <<
OpName <<
"_hidden_state + offset, &" <<
OpName <<
"_n);\n";
485 out << SP << SP <<
"} else {\n";
487 out << SP << SP << SP <<
"size_t r_offset = " <<
direction * fAttrHiddenSize * fAttrHiddenSize <<
";\n";
488 if (fAttrDirection ==
"backward" ||
direction == 1) {
489 out << SP << SP << SP <<
"size_t previous_offset = (index + 1) * "
493 out << SP << SP << SP <<
"size_t previous_offset = (seq - 1) * "
497 if (fType ==
"float") {
498 out << SP << SP << SP <<
"BLAS::sgemm_(&" <<
OpName <<
"_transB, &" <<
OpName <<
"_transA, &" <<
OpName
499 <<
"_n, &m2, &" <<
OpName <<
"_n, &" <<
OpName <<
"_alpha, tensor_" << fNR <<
" + r_offset, &" <<
OpName
500 <<
"_n, " <<
OpName <<
"_hidden_state + previous_offset, &" <<
OpName <<
"_n, &" <<
OpName <<
"_alpha, "
501 <<
OpName <<
"_hidden_state + offset, &" <<
OpName <<
"_n);\n";
503 out << SP << SP <<
"}\n";
506 if (fAttrClip > .0) {
507 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
508 if (fType ==
"float") {
509 out << SP << SP << SP <<
"float x = (" <<
OpName <<
"_hidden_state[i] > " << -fAttrClip <<
") ? " <<
OpName
510 <<
"_hidden_state[i] : " << -fAttrClip <<
";\n";
512 out << SP << SP << SP <<
OpName <<
"_hidden_state[i] = (x < " << fAttrClip <<
") ? x : " << fAttrClip <<
";\n";
513 out << SP << SP <<
"}\n";
517 if (fAttrActivations[
direction] ==
"Relu") {
518 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
519 out << SP << SP << SP <<
"if (" <<
OpName <<
"_hidden_state[i] < 0.)\n";
520 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = 0.;\n";
521 out << SP << SP <<
"}\n";
522 }
else if (fAttrActivations[
direction] ==
"Tanh") {
523 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
524 if (fType ==
"float") {
525 out << SP << SP << SP <<
"float ex = std::exp(-2 * " <<
OpName <<
"_hidden_state[i]);\n";
527 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = (1. - ex) / (1. + ex);\n";
528 out << SP << SP <<
"}\n";
529 }
else if (fAttrActivations[
direction] ==
"Sigmoid") {
530 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
531 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = 1. / (1. + std::exp(-" <<
OpName
532 <<
"_hidden_state[i]));\n";
533 out << SP << SP <<
"}\n";
534 }
else if (fAttrActivations[
direction] ==
"Affine") {
535 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
536 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = " << fAttrActivationAlpha[
direction] <<
" * "
537 <<
OpName <<
"_hidden_state[i] + " << fAttrActivationBeta[
direction] <<
";\n";
538 out << SP << SP <<
"}\n";
539 }
else if (fAttrActivations[
direction] ==
"ScaledTanh") {
540 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
541 if (fType ==
"float") {
542 out << SP << SP << SP <<
"float ex = std::exp(-2 * " << fAttrActivationBeta[
direction] <<
" * " <<
OpName
543 <<
"_hidden_state[i]);\n";
545 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = " << fAttrActivationAlpha[
direction]
546 <<
" * (1. - ex) / (1. + ex);\n";
547 out << SP << SP <<
"}\n";
548 }
else if (fAttrActivations[
direction] ==
"HardSigmoid") {
549 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
550 if (fType ==
"float") {
551 out << SP << SP << SP <<
"float a = " << fAttrActivationAlpha[
direction] <<
" * " <<
OpName
552 <<
"_hidden_state[i] + " << fAttrActivationBeta[
direction] <<
";\n";
553 out << SP << SP << SP <<
"float b = (a > 0.) ? a : 0.;\n";
555 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = (b < 1.) ? b : 1.;\n";
556 out << SP << SP <<
"}\n";
557 }
else if (fAttrActivations[
direction] ==
"LeakyRelu") {
558 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
559 out << SP << SP << SP <<
"if (" <<
OpName <<
"_hidden_state[i] < 0.)\n";
560 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = " << fAttrActivationAlpha[
direction] <<
" * "
561 <<
OpName <<
"_hidden_state[i];\n";
562 out << SP << SP <<
"}\n";
563 }
else if (fAttrActivations[
direction] ==
"ThresholdRelu") {
564 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
565 out << SP << SP << SP <<
"if (" <<
OpName <<
"_hidden_state[i] < " << fAttrActivationAlpha[
direction] <<
")\n";
566 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = 0.;\n";
567 out << SP << SP <<
"}";
568 }
else if (fAttrActivations[
direction] ==
"Elu") {
569 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
570 out << SP << SP << SP <<
"if (" <<
OpName <<
"_hidden_state[i] < 0.)\n";
571 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = " << fAttrActivationAlpha[
direction]
572 <<
" * std::exp(" <<
OpName <<
"_hidden_state[i] - 1.);\n";
573 out << SP << SP <<
"}\n";
574 }
else if (fAttrActivations[
direction] ==
"Softsign") {
575 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
576 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = " <<
OpName <<
"_hidden_state[i] / (1. + abs("
577 <<
OpName <<
"_hidden_state[i]));\n";
578 out << SP << SP <<
"}\n";
580 out << SP << SP <<
"for (size_t i = offset; i < offset + size; i++) {\n";
581 out << SP << SP << SP << SP <<
OpName <<
"_hidden_state[i] = log(1. + std::exp(" <<
OpName
582 <<
"_hidden_state[i]));\n";
583 out << SP << SP <<
"}\n";
590 if (!fNSequence_lens.empty()) {
591 out << SP <<
"for (size_t seq = 0; seq < " <<
seq_length <<
"; seq++) {\n";
592 out << SP << SP <<
"for (size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
593 out << SP << SP << SP <<
"if (seq >= tensor_" << fNSequence_lens <<
"[batch]) {\n";
594 out << SP << SP << SP << SP <<
"for (size_t h = 0; h < " << fAttrHiddenSize <<
"; h++) {\n";
596 out << SP << SP << SP << SP << SP <<
OpName <<
"_hidden_state[seq * "
599 out << SP << SP << SP << SP << SP <<
OpName <<
"_hidden_state[seq * "
601 out << SP << SP << SP << SP << SP <<
OpName <<
"_hidden_state[seq * "
603 << fAttrHiddenSize <<
" + h] = 0.;\n";
605 out << SP << SP << SP << SP <<
"}\n";
606 out << SP << SP << SP <<
"}\n";
607 out << SP << SP <<
"}\n";
612 if (fAttrLayout == 0) {
613 if (!fNY_h.empty()) {
614 if (fNSequence_lens.empty()) {
616 if (fAttrDirection ==
"backward") {
617 out << SP <<
"std::copy(" <<
OpName <<
"_hidden_state, " <<
OpName <<
"_hidden_state + " <<
yh_size
618 <<
", tensor_" << fNY_h <<
");\n";
622 <<
"_hidden_state + " <<
offset <<
" + " <<
yh_size <<
", tensor_" << fNY_h <<
");\n";
626 <<
"_hidden_state + " << 2 *
yh_size <<
", tensor_" << fNY_h <<
" + " <<
yh_size <<
");\n";
629 if (fAttrDirection ==
"backward") {
630 out << SP <<
"for (size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
631 out << SP << SP <<
"size_t offset = batch * " << fAttrHiddenSize <<
";\n";
632 out << SP << SP <<
"std::copy(" <<
OpName <<
"_hidden_state + offset, " <<
OpName
633 <<
"_hidden_state + offset + " << fAttrHiddenSize <<
", tensor_" << fNY_h <<
" + offset);\n";
636 out << SP <<
"for (size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
637 out << SP << SP <<
"size_t seq = " <<
"tensor_" << fNSequence_lens <<
"[batch] - 1;\n";
639 <<
" + batch * " << fAttrHiddenSize <<
";\n";
640 out << SP << SP <<
"size_t yh_offset = batch * " << fAttrHiddenSize <<
";\n";
641 out << SP << SP <<
"std::copy(" <<
OpName <<
"_hidden_state + offset, " <<
OpName
642 <<
"_hidden_state + offset + " << fAttrHiddenSize <<
", tensor_" << fNY_h <<
" + yh_offset);\n";
646 out << SP <<
"for (size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
647 out << SP << SP <<
"size_t offset = " <<
batch_size * fAttrHiddenSize <<
" + batch * " << fAttrHiddenSize
649 out << SP << SP <<
"size_t yh_offset = " <<
batch_size * fAttrHiddenSize <<
" + batch * "
650 << fAttrHiddenSize <<
";\n";
651 out << SP << SP <<
"std::copy(" <<
OpName <<
"_hidden_state + offset, " <<
OpName
652 <<
"_hidden_state + offset + " << fAttrHiddenSize <<
", tensor_" << fNY_h <<
" + yh_offset);\n";
660 out << SP <<
"for (size_t seq = 0; seq < " <<
seq_length <<
"; seq++) {\n";
661 out << SP << SP <<
"for (size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
666 out << SP << SP << SP <<
"std::copy(" <<
OpName <<
"_hidden_state + offset, " <<
OpName
667 <<
"_hidden_state + offset + " << fAttrHiddenSize <<
", tensor_" << fNY <<
" + y_offset);\n";
668 out << SP << SP <<
"}\n";
672 if (!fNY_h.empty()) {
673 if (fAttrDirection ==
"backward") {
674 out << SP <<
"for (size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
675 out << SP << SP <<
"size_t offset = batch * " << fAttrHiddenSize <<
";\n";
676 out << SP << SP <<
"size_t yh_offset = batch * " <<
num_directions * fAttrHiddenSize <<
";\n";
677 out << SP << SP <<
"std::copy(" <<
OpName <<
"_hidden_state + offset, " <<
OpName
678 <<
"_hidden_state + offset + " << fAttrHiddenSize <<
", tensor_" << fNY_h <<
" + yh_offset);\n";
681 out << SP <<
"for (size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
682 if (fNSequence_lens.empty()) {
683 out << SP << SP <<
"size_t seq = " <<
seq_length - 1 <<
";\n";
685 out << SP << SP <<
"size_t seq = " <<
"tensor_" << fNSequence_lens <<
"[batch] - 1;\n";
688 <<
" + batch * " << fAttrHiddenSize <<
";\n";
689 out << SP << SP <<
"size_t yh_offset = batch * " <<
num_directions * fAttrHiddenSize <<
";\n";
690 out << SP << SP <<
"std::copy(" <<
OpName <<
"_hidden_state + offset, " <<
OpName
691 <<
"_hidden_state + offset + " << fAttrHiddenSize <<
", tensor_" << fNY_h <<
" + yh_offset);\n";
695 out << SP <<
"for (size_t batch = 0; batch < " <<
batch_size <<
"; batch++) {\n";
696 out << SP << SP <<
"size_t offset = " <<
batch_size * fAttrHiddenSize <<
" + batch * " << fAttrHiddenSize
698 out << SP << SP <<
"size_t yh_offset = batch * " <<
num_directions * fAttrHiddenSize <<
" + "
699 << fAttrHiddenSize <<
";\n";
700 out << SP << SP <<
"std::copy(" <<
OpName <<
"_hidden_state + offset, " <<
OpName
701 <<
"_hidden_state + offset + " << fAttrHiddenSize <<
", tensor_" << fNY_h <<
" + yh_offset);\n";
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 offset
const_iterator begin() const
const_iterator end() const
Recurrent Neural Network operator.
std::vector< size_t > fShapeB
Shape of the bias.
std::vector< float > fAttrActivationBeta
Scaling values used by some activation functions.
size_t fAttrHiddenSize
Number of the hidden layers.
std::string fNInitial_h
Name of the initial value of the hidden states.
ROperator_RNN(std::vector< float > activation_alpha, std::vector< float > activation_beta, std::vector< std::string > activations, float clip, std::string direction, size_t hidden_size, size_t layout, std::string nameX, std::string nameW, std::string nameR, std::string nameB, std::string nameSequence_lens, std::string nameInitial_h, std::string nameY, std::string nameY_h)
Constructor of ROperator_RNN from the attributes.
void Initialize(RModel &) override
Initialize the model.
std::vector< size_t > fShapeR
Shape of the recurrence.
std::string fNW
Name of the weights.
std::string fNB
Name of the bias.
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
Infers the type of the output tensors.
std::vector< size_t > fShapeY
Shape of the output.
float fAttrClip
Clip threshold.
std::string fType
Type of the tensors.
size_t fAttrLayout
Data layout.
std::string fNY
Name of the output.
std::string fNSequence_lens
Name of the length of the sequences.
std::vector< size_t > fShapeSequence_lens
Shape of the length of the sequences.
std::vector< std::string > GetBlasRoutines() override
Returns the blas routines needed to compile the generated code.
std::string fNR
Name of the recurrence.
std::string GenerateSessionMembersCode(std::string opName) override
std::vector< float > fAttrActivationAlpha
Scaling values used by some activation functions.
ROperator_RNN()
Default constructor of ROperator_RNN.
std::vector< size_t > fShapeX
Shape of the input.
std::string fAttrDirection
Direction of processing.
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input) override
Infers the shape of the output tensors.
std::string fNX
Name of the input.
std::string Generate(std::string OpName) override
Generates the inference code.
std::string fNY_h
Name of the last sequence of the output.
std::vector< size_t > fShapeInitial_h
Shape of the initial value of the hidden states.
std::vector< size_t > fShapeW
Shape of the weights.
std::vector< std::string > fAttrActivations
Activation functions.
std::vector< size_t > fShapeY_h
Shape of the last sequence of the output.
std::vector< std::string_view > fInputTensorNames
std::vector< std::string_view > fOutputTensorNames
static uint64_t sum(uint64_t i)