// File: btbujiangjun[P]abcdl/src/fnn/FNN.cpp
// Function: abcdl::fnn::FNN::load_model(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
bool FNN::load_model(const std::string& path){
    _path = path;
    LOG(INFO) << "loading model from:" << path;
    std::vector<abcdl::algebra::Mat*> params;
    if(!_model_loader.read<real>(path, &params, "FNNMODEL") || params.size() % 2 != 0){
        if(params.size() == 0){
            LOG(INFO) << "Train with new model";
            return false;
        }
        for(auto& param : params){
            delete param;
        }
        params.clear();
        LOG(FATAL) << "Load model error:" << params.size() << " must be:" << _layers.size();
        return false;
    }
    
    size_t size = params.size() / 2;
    if(_layers.size() - 1 != size){
        LOG(FATAL) << "Model size is error:" << size << " must be:" << _layers.size() - 1;
        return false;
    }

    for(size_t i = 1; i < _layers.size(); i++){
        if(!_layers[i]->set_weight(*params[2 * (i-1)])){
            LOG(FATAL) << "Set Layer weight error, layer: " << i;
            return false;
        }
        if(!_layers[i]->set_bias(*params[2 * (i - 1) + 1])){
            LOG(FATAL) << "Set Layer bias error, layer: " << i;
            return false;
        }
    }

    for(auto& param : params){
        delete param;
    }
    params.clear();
    LOG(INFO) << "Load model success:" << path;
    
    return true;
}

// Assembly:
subq $0xc48, %rsp            # imm = 0xC48
movq %rdi, 0xc38(%rsp)
movq %rsi, 0xc30(%rsp)
movq 0xc38(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
movq 0xc30(%rsp), %rsi
addq $0x10, %rdi
callq 0x9040
leaq 0x66451(%rip), %rsi     # 0x8ffb0
leaq 0xaa8(%rsp), %rdi
movq %rdi, 0xa8(%rsp)
movl $0x98, %edx
xorl %ecx, %ecx
callq 0x89860
movq 0xa8(%rsp), %rdi
leaq 0x666fa(%rip), %rsi     # 0x90284
callq 0x2c260
movq %rax, 0xb0(%rsp)
jmp 0x29b99
movq 0xb0(%rsp), %rdi
movq 0xc30(%rsp), %rsi
callq 0x2c230
jmp 0x29bb0
leaq 0xaa8(%rsp), %rdi
callq 0x89c20
leaq 0xa80(%rsp), %rdi
callq 0x2c290
movq 0xa0(%rsp), %rax
addq $0x50, %rax
movq %rax, 0x88(%rsp)
movq 0xc30(%rsp), %rax
movq %rax, 0x90(%rsp)
leaq 0xa5f(%rsp), %rdi
movq %rdi, 0x98(%rsp)
callq 0x9710
movq 0x98(%rsp), %rdx
leaq 0x66686(%rip), %rsi     # 0x90298
leaq 0xa60(%rsp), %rdi
callq 0x9580
jmp 0x29c21
movq 0x90(%rsp), %rsi
movq 0x88(%rsp), %rdi
leaq 0xa80(%rsp), %rdx
leaq 0xa60(%rsp), %rcx
callq 0x2c2a0
movb %al, 0x87(%rsp)
jmp 0x29c4f
movb 0x87(%rsp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0x86(%rsp)
jne 0x29c66
jmp 0x29c85
leaq 0xa80(%rsp), %rdi
callq 0x2c820
andq $0x1, %rax
cmpq $0x0, %rax
setne %al
movb %al, 0x86(%rsp)
movb 0x86(%rsp), %al
movb %al, 0x85(%rsp)
leaq 0xa60(%rsp), %rdi
callq 0x9260
leaq 0xa5f(%rsp), %rdi
callq 0x9470
movb 0x85(%rsp), %al
testb $0x1, %al
jne 0x29cbd
jmp 0x29f85
leaq 0xa80(%rsp), %rdi
callq 0x2c820
cmpq $0x0, %rax
jne 0x29dda
leaq 0x662d5(%rip), %rsi     # 0x8ffb0
leaq 0x8d0(%rsp), %rdi
movl $0x9c, %edx
xorl %ecx, %ecx
callq 0x89860
jmp 0x29cf1
leaq 0x665a9(%rip), %rsi     # 0x902a1
leaq 0x8d0(%rsp), %rdi
callq 0x2c840
jmp 0x29d07
leaq 0x8d0(%rsp), %rdi
callq 0x89c20
movb $0x0, 0xc47(%rsp)
movl $0x1, 0x8cc(%rsp)
jmp 0x2a42a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
leaq 0xaa8(%rsp), %rdi
callq 0x89c20
jmp 0x2a455
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
jmp 0x29d89
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
leaq 0xa60(%rsp), %rdi
callq 0x9260
leaq 0xa5f(%rsp), %rdi
callq 0x9470
jmp 0x2a448
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
jmp 0x2a448
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
leaq 0x8d0(%rsp), %rdi
callq 0x89c20
jmp 0x2a448
leaq 0xa80(%rsp), %rax
movq %rax, 0x8c0(%rsp)
movq 0x8c0(%rsp), %rdi
callq 0x2c870
movq %rax, 0x8b8(%rsp)
movq 0x8c0(%rsp), %rdi
callq 0x2c8a0
movq %rax, 0x8b0(%rsp)
leaq 0x8b8(%rsp), %rdi
leaq 0x8b0(%rsp), %rsi
callq 0x2c8d0
testb $0x1, %al
jne 0x29e2f
jmp 0x29e7f
leaq 0x8b8(%rsp), %rdi
callq 0x2c910
movq %rax, 0x8a8(%rsp)
movq 0x8a8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x78(%rsp)
cmpq $0x0, %rax
je 0x29e6e
movq 0x78(%rsp), %rdi
callq 0x33e80
movq 0x78(%rsp), %rdi
callq 0x9410
jmp 0x29e70
leaq 0x8b8(%rsp), %rdi
callq 0x2c920
jmp 0x29e14
leaq 0xa80(%rsp), %rdi
callq 0x2c940
leaq 0x6611d(%rip), %rsi     # 0x8ffb0
leaq 0x720(%rsp), %rdi
movl $0xa3, %edx
movl $0x3, %ecx
callq 0x89860
jmp 0x29eac
leaq 0x66403(%rip), %rsi     # 0x902b6
leaq 0x720(%rsp), %rdi
callq 0x2c990
movq %rax, 0x70(%rsp)
jmp 0x29ec7
leaq 0xa80(%rsp), %rdi
callq 0x2c820
movq 0x70(%rsp), %rdi
movq %rax, 0x718(%rsp)
leaq 0x718(%rsp), %rsi
callq 0x2c100
movq %rax, 0x68(%rsp)
jmp 0x29ef5
movq 0x68(%rsp), %rdi
leaq 0x663c7(%rip), %rsi     # 0x902c8
callq 0x2c960
movq %rax, 0x60(%rsp)
jmp 0x29f0d
movq 0xa0(%rsp), %rdi
addq $0x30, %rdi
callq 0x17250
movq 0x60(%rsp), %rdi
movq %rax, 0x710(%rsp)
leaq 0x710(%rsp), %rsi
callq 0x2c100
jmp 0x29f3a
leaq 0x720(%rsp), %rdi
callq 0x89c20
movb $0x0, 0xc47(%rsp)
movl $0x1, 0x8cc(%rsp)
jmp 0x2a42a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
leaq 0x720(%rsp), %rdi
callq 0x89c20
jmp 0x2a448
leaq 0xa80(%rsp), %rdi
callq 0x2c820
movq 0xa0(%rsp), %rdi
shrq %rax
movq %rax, 0x708(%rsp)
addq $0x30, %rdi
callq 0x17250
subq $0x1, %rax
cmpq 0x708(%rsp), %rax
je 0x2a0a7
leaq 0x65fe9(%rip), %rsi     # 0x8ffb0
leaq 0x580(%rsp), %rdi
movl $0xa9, %edx
movl $0x3, %ecx
callq 0x89860
jmp 0x29fe0
leaq 0x662eb(%rip), %rsi     # 0x902d2
leaq 0x580(%rsp), %rdi
callq 0x2c840
movq %rax, 0x58(%rsp)
jmp 0x29ffb
movq 0x58(%rsp), %rdi
leaq 0x708(%rsp), %rsi
callq 0x2c100
movq %rax, 0x50(%rsp)
jmp 0x2a014
movq 0x50(%rsp), %rdi
leaq 0x662a8(%rip), %rsi     # 0x902c8
callq 0x2c960
movq %rax, 0x48(%rsp)
jmp 0x2a02c
movq 0xa0(%rsp), %rdi
addq $0x30, %rdi
callq 0x17250
movq 0x48(%rsp), %rdi
decq %rax
movq %rax, 0x578(%rsp)
leaq 0x578(%rsp), %rsi
callq 0x2c100
jmp 0x2a05c
leaq 0x580(%rsp), %rdi
callq 0x89c20
movb $0x0, 0xc47(%rsp)
movl $0x1, 0x8cc(%rsp)
jmp 0x2a42a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
leaq 0x580(%rsp), %rdi
callq 0x89c20
jmp 0x2a448
movq $0x1, 0x570(%rsp)
movq 0xa0(%rsp), %rdi
movq 0x570(%rsp), %rax
movq %rax, 0x40(%rsp)
addq $0x30, %rdi
callq 0x17250
movq %rax, %rcx
movq 0x40(%rsp), %rax
cmpq %rcx, %rax
jae 0x2a2e9
movq 0xa0(%rsp), %rdi
addq $0x30, %rdi
movq 0x570(%rsp), %rsi
callq 0x17270
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x570(%rsp), %rax
leaq -0x2(%rax,%rax), %rsi
leaq 0xa80(%rsp), %rdi
callq 0x2cc90
movq 0x30(%rsp), %rdi
movq (%rax), %rsi
callq 0x2c9c0
movb %al, 0x3f(%rsp)
jmp 0x2a130
movb 0x3f(%rsp), %al
testb $0x1, %al
jne 0x2a1d8
jmp 0x2a13e
leaq 0x65e6b(%rip), %rsi     # 0x8ffb0
leaq 0x3e8(%rsp), %rdi
movl $0xaf, %edx
movl $0x3, %ecx
callq 0x89860
jmp 0x2a15e
leaq 0x66182(%rip), %rsi     # 0x902e7
leaq 0x3e8(%rsp), %rdi
callq 0x2ccb0
movq %rax, 0x28(%rsp)
jmp 0x2a179
movq 0x28(%rsp), %rdi
leaq 0x570(%rsp), %rsi
callq 0x2c100
jmp 0x2a18d
leaq 0x3e8(%rsp), %rdi
callq 0x89c20
movb $0x0, 0xc47(%rsp)
movl $0x1, 0x8cc(%rsp)
jmp 0x2a42a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
leaq 0x3e8(%rsp), %rdi
callq 0x89c20
jmp 0x2a448
movq 0xa0(%rsp), %rdi
addq $0x30, %rdi
movq 0x570(%rsp), %rsi
callq 0x17270
movq (%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x570(%rsp), %rax
leaq -0x1(%rax,%rax), %rsi
leaq 0xa80(%rsp), %rdi
callq 0x2cc90
movq 0x18(%rsp), %rdi
movq (%rax), %rsi
callq 0x2cce0
movb %al, 0x27(%rsp)
jmp 0x2a226
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0x2a2ce
jmp 0x2a234
leaq 0x65d75(%rip), %rsi     # 0x8ffb0
leaq 0x260(%rsp), %rdi
movl $0xb3, %edx
movl $0x3, %ecx
callq 0x89860
jmp 0x2a254
leaq 0x660ac(%rip), %rsi     # 0x90307
leaq 0x260(%rsp), %rdi
callq 0x2cfb0
movq %rax, 0x10(%rsp)
jmp 0x2a26f
movq 0x10(%rsp), %rdi
leaq 0x570(%rsp), %rsi
callq 0x2c100
jmp 0x2a283
leaq 0x260(%rsp), %rdi
callq 0x89c20
movb $0x0, 0xc47(%rsp)
movl $0x1, 0x8cc(%rsp)
jmp 0x2a42a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
leaq 0x260(%rsp), %rdi
callq 0x89c20
jmp 0x2a448
jmp 0x2a2d0
movq 0x570(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x570(%rsp)
jmp 0x2a0b3
leaq 0xa80(%rsp), %rax
movq %rax, 0x258(%rsp)
movq 0x258(%rsp), %rdi
callq 0x2c870
movq %rax, 0x250(%rsp)
movq 0x258(%rsp), %rdi
callq 0x2c8a0
movq %rax, 0x248(%rsp)
leaq 0x250(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x2c8d0
testb $0x1, %al
jne 0x2a33e
jmp 0x2a38e
leaq 0x250(%rsp), %rdi
callq 0x2c910
movq %rax, 0x240(%rsp)
movq 0x240(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x2a37d
movq 0x8(%rsp), %rdi
callq 0x33e80
movq 0x8(%rsp), %rdi
callq 0x9410
jmp 0x2a37f
leaq 0x250(%rsp), %rdi
callq 0x2c920
jmp 0x2a323
leaq 0xa80(%rsp), %rdi
callq 0x2c940
leaq 0x65c0e(%rip), %rsi     # 0x8ffb0
leaq 0xb8(%rsp), %rdi
movl $0xbc, %edx
xorl %ecx, %ecx
callq 0x89860
jmp 0x2a3b8
leaq 0x65f66(%rip), %rsi     # 0x90325
leaq 0xb8(%rsp), %rdi
callq 0x2c260
movq %rax, (%rsp)
jmp 0x2a3d2
movq (%rsp), %rdi
movq 0xc30(%rsp), %rsi
callq 0x2c230
jmp 0x2a3e5
leaq 0xb8(%rsp), %rdi
callq 0x89c20
movb $0x1, 0xc47(%rsp)
movl $0x1, 0x8cc(%rsp)
jmp 0x2a42a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xaa0(%rsp)
movl %eax, 0xa9c(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x89c20
jmp 0x2a448
leaq 0xa80(%rsp), %rdi
callq 0x2cfe0
movb 0xc47(%rsp), %al
andb $0x1, %al
addq $0xc48, %rsp            # imm = 0xC48
retq
leaq 0xa80(%rsp), %rdi
callq 0x2cfe0
movq 0xaa0(%rsp), %rdi
callq 0x9700
nopw %cs:(%rax,%rax)