// File: /workspace/github_cpp_makefile_star2_O1/yuang-chen[P]paraGCN/src/module.cpp
// Function: CrossEntropyLoss::forward(bool)
void CrossEntropyLoss::forward(bool training) {
    float total_loss = 0;
    int count = 0;
    if(training) {
        logits->zero_grad();
    }

    for(int i = 0; i < logits->data.size() / num_classes; i++) {
        if(truth[i] < 0) {
            continue;
        }
        count++;
        float *logit = &logits->data[i * num_classes];
        float max_logit = -1e30, sum_exp = 0;

        for(int j = 0; j < num_classes; j++) {
            max_logit = fmax(max_logit, logit[j]);
        }
        for(int j = 0; j < num_classes; j++) {
            logit[j] -= max_logit;
            sum_exp += expf(logit[j]);
        }
        total_loss += logf(sum_exp) - logit[truth[i]];

        if(training) {
            for(int j = 0; j < num_classes; j++) {
                float prob = expf(logit[j]) / sum_exp;
                logits->grad[i * num_classes + j] = prob;
            }
            logits->grad[i * num_classes + truth[i]] -= 1.0;
        }
    }
    *loss = total_loss / count;
    if(training) {
        for(int i = 0; i < logits->grad.size(); i++) {
            logits->grad[i] /= count;
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %r14
movl %esi, 0xc(%rsp)
testl %esi, %esi
je 0x6802
movq 0x8(%r14), %rdi
callq 0x6e10
movq 0x8(%r14), %rcx
movq (%rcx), %r12
movq 0x8(%rcx), %rax
subq %r12, %rax
sarq $0x2, %rax
movslq 0x20(%r14), %r13
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
cmpq %r13, %rax
jb 0x69e8
xorl %r15d, %r15d
movl $0x0, 0x8(%rsp)
movq 0x10(%r14), %rax
cmpl $0x0, (%rax,%r15,4)
js 0x69b8
movss %xmm1, 0x4(%rsp)
movss 0x1995(%rip), %xmm3     # 0x81e4
testl %r13d, %r13d
jle 0x6897
movl %r13d, %eax
movl %r13d, %ecx
imull %r15d, %ecx
movslq %ecx, %rcx
leaq (%r12,%rcx,4), %rcx
xorl %edx, %edx
movss 0x1975(%rip), %xmm0     # 0x81e4
movaps %xmm0, %xmm3
movss (%rcx,%rdx,4), %xmm1
cmpunordss %xmm3, %xmm3
movaps %xmm3, %xmm2
andps %xmm1, %xmm2
maxss %xmm0, %xmm1
andnps %xmm1, %xmm3
orps %xmm2, %xmm3
incq %rdx
movaps %xmm3, %xmm0
cmpq %rdx, %rax
jne 0x6872
cmpl $0x0, 0x20(%r14)
jle 0x68f3
movl %r13d, %eax
imull %r15d, %eax
cltq
leaq (%r12,%rax,4), %rbx
xorps %xmm0, %xmm0
xorl %ebp, %ebp
movaps %xmm3, 0x10(%rsp)
movss %xmm0, (%rsp)
movss (%rbx,%rbp,4), %xmm0
subss %xmm3, %xmm0
movss %xmm0, (%rbx,%rbp,4)
callq 0x3330
movaps 0x10(%rsp), %xmm3
movss (%rsp), %xmm1
addss %xmm0, %xmm1
movss %xmm1, (%rsp)
movss (%rsp), %xmm0
incq %rbp
movslq 0x20(%r14), %rax
cmpq %rax, %rbp
jl 0x68b5
jmp 0x68f6
xorps %xmm0, %xmm0
incl 0x8(%rsp)
movl %r13d, %eax
imull %r15d, %eax
cltq
leaq (%r12,%rax,4), %rbp
movss %xmm0, (%rsp)
callq 0x33a0
movq 0x10(%r14), %rbx
movslq (%rbx,%r15,4), %rax
subss (%rbp,%rax,4), %xmm0
movss 0x4(%rsp), %xmm1
addss %xmm0, %xmm1
cmpb $0x0, 0xc(%rsp)
je 0x69b8
movl 0x20(%r14), %eax
testl %eax, %eax
jle 0x698e
movss %xmm1, 0x4(%rsp)
movq 0x8(%r14), %rax
movq 0x18(%rax), %rbp
imull %r15d, %r13d
movslq %r13d, %rax
leaq (%r12,%rax,4), %r12
xorl %r13d, %r13d
movss (%r12,%r13,4), %xmm0
callq 0x3330
divss (%rsp), %xmm0
movslq 0x20(%r14), %rax
movslq %r15d, %rcx
imulq %rax, %rcx
addq %r13, %rcx
movss %xmm0, (%rbp,%rcx,4)
incq %r13
movslq 0x20(%r14), %rax
cmpq %rax, %r13
jl 0x6958
movss 0x4(%rsp), %xmm1
movq 0x8(%r14), %rcx
movl %r15d, %edx
imull %eax, %edx
movslq (%rbx,%r15,4), %rax
movslq %edx, %rdx
addq %rax, %rdx
movq 0x18(%rcx), %rax
movss (%rax,%rdx,4), %xmm0
addss 0x1835(%rip), %xmm0     # 0x81e8
movss %xmm0, (%rax,%rdx,4)
incq %r15
movq 0x8(%r14), %rcx
movq (%rcx), %r12
movq 0x8(%rcx), %rax
subq %r12, %rax
sarq $0x2, %rax
movslq 0x20(%r14), %r13
xorl %edx, %edx
divq %r13
cmpq %r15, %rax
ja 0x6832
xorps %xmm0, %xmm0
cvtsi2ssl 0x8(%rsp), %xmm0
divss %xmm0, %xmm1
movq 0x18(%r14), %rax
movss %xmm1, (%rax)
cmpb $0x0, 0xc(%rsp)
je 0x6a2c
movq 0x18(%rcx), %rax
movq 0x20(%rcx), %rcx
subq %rax, %rcx
je 0x6a2c
sarq $0x2, %rcx
cmpq $0x1, %rcx
adcq $0x0, %rcx
xorl %edx, %edx
movss (%rax,%rdx,4), %xmm1
divss %xmm0, %xmm1
movss %xmm1, (%rax,%rdx,4)
incq %rdx
cmpq %rdx, %rcx
jne 0x6a16
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop