// File: btbujiangjun[P]abcdl/src/rnn/RNN.cpp
// Function: abcdl::rnn::RNN::total_loss(abcdl::algebra::MatrixSet<float> const&, abcdl::algebra::MatrixSet<float> const&)
real RNN::total_loss(const abcdl::algebra::MatSet& train_seq_data,
                     const abcdl::algebra::MatSet& train_seq_label){

	real loss_value = 0;
    abcdl::algebra::Mat state;
    abcdl::algebra::Mat activation;
	
    size_t num_train_data = train_seq_data.size();
	for(size_t j = 0; j != num_train_data; j++){
		_layer->farward(train_seq_data[j], _U, _W, _V, state, activation);

		auto mat_label = train_seq_label[j].argmax(abcdl::algebra::Axis_type::ROW);
        size_t rows = mat_label.rows();
        for(size_t row = 0; row != rows; row++){
            loss_value -= std::log(activation.get_data(row, mat_label.get_data(row, 0)));
        }
	}

	return loss_value;
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x160(%rsp)
movq %rsi, 0x158(%rsp)
movq %rdx, 0x150(%rsp)
movq 0x160(%rsp), %rax
movq %rax, 0x48(%rsp)
movl $0x0, 0x14c(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x5b7d0
leaq 0xf8(%rsp), %rdi
callq 0x5b7d0
jmp 0x552a3
movq 0x158(%rsp), %rdi
callq 0x193c0
movq %rax, 0x40(%rsp)
jmp 0x552b7
movq 0x40(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq $0x0, 0xd8(%rsp)
movq 0xd8(%rsp), %rax
cmpq 0xe0(%rsp), %rax
je 0x55529
movq 0x48(%rsp), %rax
movq 0x118(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x158(%rsp), %rsi
movq 0xd8(%rsp), %rdx
leaq 0xb0(%rsp), %rdi
callq 0x55ba0
jmp 0x55316
movq 0x38(%rsp), %rdi
movq 0x48(%rsp), %r8
movq %r8, %rdx
addq $0x70, %rdx
movq %r8, %rcx
addq $0xa8, %rcx
addq $0xe0, %r8
movq %rsp, %rax
leaq 0xf8(%rsp), %rsi
movq %rsi, (%rax)
leaq 0xb0(%rsp), %rsi
leaq 0x120(%rsp), %r9
callq 0x53210
jmp 0x5535d
leaq 0xb0(%rsp), %rdi
callq 0x5bc10
movq 0x150(%rsp), %rsi
movq 0xd8(%rsp), %rdx
leaq 0x60(%rsp), %rdi
callq 0x55ba0
jmp 0x55386
leaq 0x88(%rsp), %rdi
leaq 0x60(%rsp), %rsi
xorl %edx, %edx
callq 0x84d40
jmp 0x5539c
leaq 0x60(%rsp), %rdi
callq 0x5bc10
leaq 0x88(%rsp), %rdi
callq 0x55d50
movq %rax, 0x30(%rsp)
jmp 0x553ba
movq 0x30(%rsp), %rax
movq %rax, 0x58(%rsp)
movq $0x0, 0x50(%rsp)
movq 0x50(%rsp), %rax
cmpq 0x58(%rsp), %rax
je 0x55503
movq 0x50(%rsp), %rsi
movq %rsi, 0x20(%rsp)
xorl %eax, %eax
movl %eax, %edx
leaq 0x88(%rsp), %rdi
callq 0x55e80
movq %rax, 0x28(%rsp)
jmp 0x553ff
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rax
movq (%rax), %rdx
leaq 0xf8(%rsp), %rdi
callq 0x55d80
movq %rax, 0x18(%rsp)
jmp 0x55420
movq 0x18(%rsp), %rax
movss (%rax), %xmm0
callq 0x55d60
movss %xmm0, 0x14(%rsp)
jmp 0x55436
movss 0x14(%rsp), %xmm1
movss 0x14c(%rsp), %xmm0
subss %xmm1, %xmm0
movss %xmm0, 0x14c(%rsp)
movq 0x50(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x50(%rsp)
jmp 0x553cd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
jmp 0x5556d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
jmp 0x55560
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x5bc10
jmp 0x55560
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x5bc10
jmp 0x55560
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x5ffd0
jmp 0x55560
leaq 0x88(%rsp), %rdi
callq 0x5ffd0
movq 0xd8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xd8(%rsp)
jmp 0x552d0
movss 0x14c(%rsp), %xmm0
movss %xmm0, 0x10(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0x5bc10
leaq 0x120(%rsp), %rdi
callq 0x5bc10
movss 0x10(%rsp), %xmm0
addq $0x168, %rsp            # imm = 0x168
retq
leaq 0xf8(%rsp), %rdi
callq 0x5bc10
leaq 0x120(%rsp), %rdi
callq 0x5bc10
movq 0xf0(%rsp), %rdi
callq 0xb980
nopw (%rax,%rax)