// File: epfml[P]Bi-Sent2Vec/src/fasttext.cc
// Function: fasttext::FastText::trainThread(int)
void FastText::trainThread(int32_t threadId) {
  std::ifstream ifs(args_->input);
  utils::seek(ifs, threadId * utils::size(ifs) / args_->thread);
  int32_t currCheckPoint = 0;
  Model model(input_, output_, args_, threadId);
  model.setTargetCounts(dict_->getCounts(entry_type::word));

  const int64_t ntokens = dict_->ntokens();
  int64_t localTokenCount = 0;
  std::vector<int32_t> line, labels;
  while (tokenCount < args_->epoch * ntokens) {
    real progress = real(tokenCount) / (args_->epoch * ntokens);
    real lr = args_->lr * (1.0 - progress);
    localTokenCount += dict_->getLine(ifs, line, labels, model.rng);
    if (args_->model == model_name::bisent2vec) {
      bisent2vec(model, lr, line);
    } else if (args_->model == model_name::cbow) {
      cbow(model, lr, line);
    } else if (args_->model == model_name::transgram) {
      transgram(model, lr, line);
    }
    if (localTokenCount > args_->lrUpdateRate) {
      tokenCount += localTokenCount;
      localTokenCount = 0;
      if (threadId == 0 && args_->verbose > 1) {
        printInfo(progress, model.getLoss());
      }
    }
    if (threadId == 0 && currCheckPoint != (int)(progress*args_->numCheckPoints)) {
      currCheckPoint++;
      printInfo(progress, model.getLoss());
      std::cerr << std::endl;
      std::cerr<<"Saving Model ----- Checkpoint "<< currCheckPoint<< std::endl;
      model_ = std::make_shared<Model>(input_, output_, args_, 0);
      saveModel(currCheckPoint);
      saveVectors(currCheckPoint);
    }
  }
  if (threadId == 0 && args_->verbose > 0) {
    printInfo(1.0, model.getLoss());
    std::cerr << std::endl;
  }
  ifs.close();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x490, %rsp            # imm = 0x490
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x410(%rbp)
callq 0xe6e0
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
movq %rdi, -0x408(%rbp)
movl $0x8, %edx
callq 0x56d0
movq -0x408(%rbp), %rdi
movslq -0xc(%rbp), %rax
movq %rax, -0x400(%rbp)
callq 0x27d10
movq %rax, -0x3f8(%rbp)
jmp 0x2fe4d
movq -0x410(%rbp), %rdi
movq -0x3f8(%rbp), %rcx
movq -0x400(%rbp), %rax
imulq %rcx, %rax
movq %rax, -0x418(%rbp)
callq 0xe6e0
movq %rax, %rcx
movq -0x418(%rbp), %rax
movslq 0xd4(%rcx), %rcx
cqto
idivq %rcx
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
callq 0x27d50
jmp 0x2fe99
movq -0x410(%rbp), %rsi
movl $0x0, -0x228(%rbp)
addq $0x20, %rsi
leaq -0x358(%rbp), %rdi
movq %rdi, -0x430(%rbp)
callq 0x352c0
movq -0x410(%rbp), %rsi
addq $0x30, %rsi
leaq -0x368(%rbp), %rdi
movq %rdi, -0x428(%rbp)
callq 0x352c0
movq -0x410(%rbp), %rsi
leaq -0x378(%rbp), %rdi
movq %rdi, -0x420(%rbp)
callq 0xe060
movq -0x430(%rbp), %rsi
movq -0x428(%rbp), %rdx
movq -0x420(%rbp), %rcx
movl -0xc(%rbp), %r8d
leaq -0x348(%rbp), %rdi
callq 0x21510
jmp 0x2ff20
leaq -0x378(%rbp), %rdi
callq 0xe1b0
leaq -0x368(%rbp), %rdi
callq 0x23810
leaq -0x358(%rbp), %rdi
callq 0x23810
movq -0x410(%rbp), %rdi
addq $0x10, %rdi
callq 0x34050
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
xorl %edx, %edx
callq 0x9e50
jmp 0x2ff67
leaq -0x348(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0x22e20
jmp 0x2ff7c
leaq -0x390(%rbp), %rdi
callq 0xecf0
movq -0x410(%rbp), %rdi
addq $0x10, %rdi
callq 0x34050
movq %rax, %rdi
callq 0x8380
movq %rax, -0x438(%rbp)
jmp 0x2ffa9
movq -0x438(%rbp), %rax
movq %rax, -0x398(%rbp)
movq $0x0, -0x3a0(%rbp)
leaq -0x3b8(%rbp), %rdi
callq 0xe440
leaq -0x3d0(%rbp), %rdi
callq 0xe440
movq -0x410(%rbp), %rdi
addq $0x70, %rdi
callq 0x34720
movq -0x410(%rbp), %rdi
movq %rax, -0x440(%rbp)
callq 0xe6e0
movq %rax, %rcx
movq -0x440(%rbp), %rax
movslq 0xa0(%rcx), %rcx
imulq -0x398(%rbp), %rcx
cmpq %rcx, %rax
jge 0x304cc
movq -0x410(%rbp), %rdi
addq $0x70, %rdi
callq 0x34720
movq -0x410(%rbp), %rdi
cvtsi2ss %rax, %xmm0
movss %xmm0, -0x448(%rbp)
callq 0xe6e0
movss -0x448(%rbp), %xmm0
movq -0x410(%rbp), %rdi
movslq 0xa0(%rax), %rax
movq -0x398(%rbp), %rcx
imulq %rcx, %rax
cvtsi2ss %rax, %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x3d4(%rbp)
callq 0xe6e0
movq -0x410(%rbp), %rdi
movsd 0x80(%rax), %xmm0
movss -0x3d4(%rbp), %xmm1
cvtss2sd %xmm1, %xmm2
movsd 0x12816(%rip), %xmm1    # 0x428b8
subsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x3d8(%rbp)
addq $0x10, %rdi
callq 0x34050
movq %rax, %rdi
leaq -0x238(%rbp), %r8
leaq -0x218(%rbp), %rsi
leaq -0x3b8(%rbp), %rdx
leaq -0x3d0(%rbp), %rcx
callq 0xac80
movl %eax, -0x444(%rbp)
jmp 0x300eb
movq -0x410(%rbp), %rdi
movl -0x444(%rbp), %eax
cltq
addq -0x3a0(%rbp), %rax
movq %rax, -0x3a0(%rbp)
callq 0xe6e0
cmpl $0x4, 0xc0(%rax)
jne 0x301fe
movq -0x410(%rbp), %rdi
movss -0x3d8(%rbp), %xmm0
leaq -0x348(%rbp), %rsi
leaq -0x3b8(%rbp), %rdx
callq 0x2b690
jmp 0x3013e
jmp 0x30278
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x30585
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x378(%rbp), %rdi
callq 0xe1b0
leaq -0x368(%rbp), %rdi
callq 0x23810
leaq -0x358(%rbp), %rdi
callq 0x23810
jmp 0x30585
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x30579
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x390(%rbp), %rdi
callq 0xecf0
jmp 0x30579
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x3d0(%rbp), %rdi
callq 0xe530
leaq -0x3b8(%rbp), %rdi
callq 0xe530
jmp 0x30579
movq -0x410(%rbp), %rdi
callq 0xe6e0
cmpl $0x1, 0xc0(%rax)
jne 0x30239
movq -0x410(%rbp), %rdi
movss -0x3d8(%rbp), %xmm0
leaq -0x348(%rbp), %rsi
leaq -0x3b8(%rbp), %rdx
callq 0x2b440
jmp 0x30237
jmp 0x30276
movq -0x410(%rbp), %rdi
callq 0xe6e0
cmpl $0x2, 0xc0(%rax)
jne 0x30274
movq -0x410(%rbp), %rdi
movss -0x3d8(%rbp), %xmm0
leaq -0x348(%rbp), %rsi
leaq -0x3b8(%rbp), %rdx
callq 0x2adf0
jmp 0x30272
jmp 0x30274
jmp 0x30276
jmp 0x30278
movq -0x410(%rbp), %rdi
movq -0x3a0(%rbp), %rax
movq %rax, -0x450(%rbp)
callq 0xe6e0
movq %rax, %rcx
movq -0x450(%rbp), %rax
movslq 0x90(%rcx), %rcx
cmpq %rcx, %rax
jle 0x30331
movq -0x410(%rbp), %rdi
movq -0x3a0(%rbp), %rsi
addq $0x70, %rdi
callq 0x35600
movq $0x0, -0x3a0(%rbp)
cmpl $0x0, -0xc(%rbp)
jne 0x3032f
movq -0x410(%rbp), %rdi
callq 0xe6e0
cmpl $0x1, 0x100(%rax)
jle 0x3032f
movss -0x3d4(%rbp), %xmm0
movss %xmm0, -0x458(%rbp)
leaq -0x348(%rbp), %rdi
callq 0x23560
movss %xmm0, -0x454(%rbp)
jmp 0x3030f
movss -0x454(%rbp), %xmm1
movss -0x458(%rbp), %xmm0
movq -0x410(%rbp), %rdi
callq 0x29fe0
jmp 0x3032d
jmp 0x3032f
jmp 0x30331
cmpl $0x0, -0xc(%rbp)
jne 0x304c7
movq -0x410(%rbp), %rdi
movl -0x228(%rbp), %eax
movl %eax, -0x45c(%rbp)
movss -0x3d4(%rbp), %xmm0
movss %xmm0, -0x460(%rbp)
callq 0xe6e0
movss -0x460(%rbp), %xmm0
movq %rax, %rcx
movl -0x45c(%rbp), %eax
cvtsi2ssl 0xb8(%rcx), %xmm1
mulss %xmm1, %xmm0
cvttss2si %xmm0, %ecx
cmpl %ecx, %eax
je 0x304c7
movl -0x228(%rbp), %eax
incl %eax
movl %eax, -0x228(%rbp)
movss -0x3d4(%rbp), %xmm0
movss %xmm0, -0x468(%rbp)
leaq -0x348(%rbp), %rdi
callq 0x23560
movss %xmm0, -0x464(%rbp)
jmp 0x303c0
movss -0x464(%rbp), %xmm1
movss -0x468(%rbp), %xmm0
movq -0x410(%rbp), %rdi
callq 0x29fe0
jmp 0x303de
movq 0x2ec0b(%rip), %rdi     # 0x5eff0
movq 0x2eba4(%rip), %rsi     # 0x5ef90
callq 0x5460
jmp 0x303f3
movq 0x2ebf6(%rip), %rdi     # 0x5eff0
leaq 0x134d3(%rip), %rsi     # 0x438d4
callq 0x5420
movq %rax, -0x470(%rbp)
jmp 0x3040f
movq -0x470(%rbp), %rdi
movl -0x228(%rbp), %esi
callq 0x5770
movq %rax, -0x478(%rbp)
jmp 0x3042a
movq -0x478(%rbp), %rdi
movq 0x2eb58(%rip), %rsi     # 0x5ef90
callq 0x5460
jmp 0x3043f
movq -0x410(%rbp), %rcx
movq %rcx, %rsi
addq $0x20, %rsi
movq %rcx, %rdx
addq $0x30, %rdx
movl $0x0, -0x3ec(%rbp)
leaq -0x3e8(%rbp), %rdi
leaq -0x3ec(%rbp), %r8
callq 0x34550
jmp 0x30473
movq -0x410(%rbp), %rdi
addq $0x60, %rdi
leaq -0x3e8(%rbp), %rsi
movq %rsi, -0x480(%rbp)
callq 0x345e0
movq -0x480(%rbp), %rdi
callq 0x34610
movq -0x410(%rbp), %rdi
movl -0x228(%rbp), %esi
callq 0x29230
jmp 0x304b1
movq -0x410(%rbp), %rdi
movl -0x228(%rbp), %esi
callq 0x283e0
jmp 0x304c5
jmp 0x304c7
jmp 0x2ffda
cmpl $0x0, -0xc(%rbp)
jne 0x30532
movq -0x410(%rbp), %rdi
callq 0xe6e0
cmpl $0x0, 0x100(%rax)
jle 0x30532
leaq -0x348(%rbp), %rdi
callq 0x23560
movss %xmm0, -0x484(%rbp)
jmp 0x304fd
movss -0x484(%rbp), %xmm1
movq -0x410(%rbp), %rdi
movss 0x123b4(%rip), %xmm0    # 0x428c8
callq 0x29fe0
jmp 0x3051b
movq 0x2eace(%rip), %rdi     # 0x5eff0
movq 0x2ea67(%rip), %rsi     # 0x5ef90
callq 0x5460
jmp 0x30530
jmp 0x30532
leaq -0x218(%rbp), %rdi
callq 0x50f0
jmp 0x30540
leaq -0x3d0(%rbp), %rdi
callq 0xe530
leaq -0x3b8(%rbp), %rdi
callq 0xe530
leaq -0x348(%rbp), %rdi
callq 0x21960
leaq -0x218(%rbp), %rdi
callq 0x5130
addq $0x490, %rsp            # imm = 0x490
popq %rbp
retq
leaq -0x348(%rbp), %rdi
callq 0x21960
leaq -0x218(%rbp), %rdi
callq 0x5130
movq -0x220(%rbp), %rdi
callq 0x57a0
nopl (%rax)