// File: ddu1[P]polarizedtext/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);

  Model model(input_, output_, args_, threadId);
  if (args_->model == model_name::sup) {
    model.setTargetCounts(dict_->getCounts(entry_type::label));
  } else {
    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::sup) {
      dict_->addNgrams(line, args_->wordNgrams);
      supervised(model, lr, line, labels);
    } else if (args_->model == model_name::cbow) {
      cbow(model, lr, line);
    } else if (args_->model == model_name::sg) {
      skipgram(model, lr, line);
    } else if (args_->model == model_name::pwv) { // updated
      pwv(model, lr, line);
    }     
    if (localTokenCount > args_->lrUpdateRate) {
      tokenCount += localTokenCount;
      localTokenCount = 0;
      if (threadId == 0 && args_->verbose > 1) {
        printInfo(progress, model.getLoss());
      }
    }
  }
  if (threadId == 0 && args_->verbose > 0) {
    printInfo(1.0, model.getLoss());
    std::cout << std::endl;
  }
  ifs.close();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x460, %rsp            # imm = 0x460
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x400(%rbp)
callq 0xa170
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
movq %rdi, -0x3f8(%rbp)
movl $0x8, %edx
callq 0x4510
movq -0x3f8(%rbp), %rdi
movslq -0xc(%rbp), %rax
movq %rax, -0x3f0(%rbp)
callq 0x1c420
movq %rax, -0x3e8(%rbp)
jmp 0x1e58d
movq -0x400(%rbp), %rdi
movq -0x3e8(%rbp), %rcx
movq -0x3f0(%rbp), %rax
imulq %rcx, %rax
movq %rax, -0x408(%rbp)
callq 0xa170
movq %rax, %rcx
movq -0x408(%rbp), %rax
movslq 0x9c(%rcx), %rcx
cqto
idivq %rcx
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
callq 0x1c460
jmp 0x1e5d9
movq -0x400(%rbp), %rsi
addq $0x20, %rsi
leaq -0x348(%rbp), %rdi
movq %rdi, -0x420(%rbp)
callq 0x20980
movq -0x400(%rbp), %rsi
addq $0x30, %rsi
leaq -0x358(%rbp), %rdi
movq %rdi, -0x418(%rbp)
callq 0x20980
movq -0x400(%rbp), %rsi
leaq -0x368(%rbp), %rdi
movq %rdi, -0x410(%rbp)
callq 0x209b0
movq -0x420(%rbp), %rsi
movq -0x418(%rbp), %rdx
movq -0x410(%rbp), %rcx
movl -0xc(%rbp), %r8d
leaq -0x338(%rbp), %rdi
callq 0x138e0
jmp 0x1e656
leaq -0x368(%rbp), %rdi
callq 0xa0a0
leaq -0x358(%rbp), %rdi
callq 0x159f0
leaq -0x348(%rbp), %rdi
callq 0x159f0
movq -0x400(%rbp), %rdi
callq 0xa170
cmpl $0x3, 0x8c(%rax)
jne 0x1e76b
movq -0x400(%rbp), %rdi
addq $0x10, %rdi
callq 0x1ff50
movq %rax, %rsi
leaq -0x380(%rbp), %rdi
movl $0x1, %edx
callq 0x7e80
jmp 0x1e6b9
leaq -0x338(%rbp), %rdi
leaq -0x380(%rbp), %rsi
callq 0x15040
jmp 0x1e6ce
leaq -0x380(%rbp), %rdi
callq 0xacf0
jmp 0x1e7d4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x1ec25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x368(%rbp), %rdi
callq 0xa0a0
leaq -0x358(%rbp), %rdi
callq 0x159f0
leaq -0x348(%rbp), %rdi
callq 0x159f0
jmp 0x1ec25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x1ec19
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x380(%rbp), %rdi
callq 0xacf0
jmp 0x1ec19
movq -0x400(%rbp), %rdi
addq $0x10, %rdi
callq 0x1ff50
movq %rax, %rsi
leaq -0x398(%rbp), %rdi
xorl %edx, %edx
callq 0x7e80
jmp 0x1e78e
leaq -0x338(%rbp), %rdi
leaq -0x398(%rbp), %rsi
callq 0x15040
jmp 0x1e7a3
leaq -0x398(%rbp), %rdi
callq 0xacf0
jmp 0x1e7d4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x398(%rbp), %rdi
callq 0xacf0
jmp 0x1ec19
movq -0x400(%rbp), %rdi
addq $0x10, %rdi
callq 0x1ff50
movq %rax, %rdi
callq 0x6bb0
movq %rax, -0x428(%rbp)
jmp 0x1e7f5
movq -0x428(%rbp), %rax
movq %rax, -0x3a0(%rbp)
movq $0x0, -0x3a8(%rbp)
leaq -0x3c0(%rbp), %rdi
callq 0x9e40
leaq -0x3d8(%rbp), %rdi
callq 0x9e40
movq -0x400(%rbp), %rdi
addq $0x50, %rdi
callq 0x202f0
movq -0x400(%rbp), %rdi
movq %rax, -0x430(%rbp)
callq 0xa170
movq %rax, %rcx
movq -0x430(%rbp), %rax
movslq 0x74(%rcx), %rcx
imulq -0x3a0(%rbp), %rcx
cmpq %rcx, %rax
jge 0x1eb6c
movq -0x400(%rbp), %rdi
addq $0x50, %rdi
callq 0x202f0
movq -0x400(%rbp), %rdi
cvtsi2ss %rax, %xmm0
movss %xmm0, -0x438(%rbp)
callq 0xa170
movss -0x438(%rbp), %xmm0
movq -0x400(%rbp), %rdi
movslq 0x74(%rax), %rax
movq -0x3a0(%rbp), %rcx
imulq %rcx, %rax
cvtsi2ss %rax, %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x3dc(%rbp)
callq 0xa170
movq -0x400(%rbp), %rdi
movsd 0x60(%rax), %xmm0
movss -0x3dc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm2
movsd 0xace3(%rip), %xmm1     # 0x295c8
subsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x3e0(%rbp)
addq $0x10, %rdi
callq 0x1ff50
movq %rax, %rdi
leaq -0x230(%rbp), %r8
leaq -0x218(%rbp), %rsi
leaq -0x3c0(%rbp), %rdx
leaq -0x3d8(%rbp), %rcx
callq 0x8090
movl %eax, -0x434(%rbp)
jmp 0x1e92e
movq -0x400(%rbp), %rdi
movl -0x434(%rbp), %eax
cltq
addq -0x3a8(%rbp), %rax
movq %rax, -0x3a8(%rbp)
callq 0xa170
cmpl $0x3, 0x8c(%rax)
jne 0x1e9fa
movq -0x400(%rbp), %rdi
addq $0x10, %rdi
callq 0x1ff50
movq -0x400(%rbp), %rdi
movq %rax, -0x440(%rbp)
callq 0xa170
movq -0x440(%rbp), %rdi
movl 0x84(%rax), %edx
leaq -0x3c0(%rbp), %rsi
callq 0x7f70
jmp 0x1e99b
movq -0x400(%rbp), %rdi
movss -0x3e0(%rbp), %xmm0
leaq -0x338(%rbp), %rsi
leaq -0x3c0(%rbp), %rdx
leaq -0x3d8(%rbp), %rcx
callq 0x1d150
jmp 0x1e9c6
jmp 0x1eab1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x3d8(%rbp), %rdi
callq 0xa040
leaq -0x3c0(%rbp), %rdi
callq 0xa040
jmp 0x1ec19
movq -0x400(%rbp), %rdi
callq 0xa170
cmpl $0x1, 0x8c(%rax)
jne 0x1ea35
movq -0x400(%rbp), %rdi
movss -0x3e0(%rbp), %xmm0
leaq -0x338(%rbp), %rsi
leaq -0x3c0(%rbp), %rdx
callq 0x1d200
jmp 0x1ea33
jmp 0x1eaaf
movq -0x400(%rbp), %rdi
callq 0xa170
cmpl $0x2, 0x8c(%rax)
jne 0x1ea70
movq -0x400(%rbp), %rdi
movss -0x3e0(%rbp), %xmm0
leaq -0x338(%rbp), %rsi
leaq -0x3c0(%rbp), %rdx
callq 0x1d660
jmp 0x1ea6e
jmp 0x1eaad
movq -0x400(%rbp), %rdi
callq 0xa170
cmpl $0x4, 0x8c(%rax)
jne 0x1eaab
movq -0x400(%rbp), %rdi
movss -0x3e0(%rbp), %xmm0
leaq -0x338(%rbp), %rsi
leaq -0x3c0(%rbp), %rdx
callq 0x1d440
jmp 0x1eaa9
jmp 0x1eaab
jmp 0x1eaad
jmp 0x1eaaf
jmp 0x1eab1
movq -0x400(%rbp), %rdi
movq -0x3a8(%rbp), %rax
movq %rax, -0x448(%rbp)
callq 0xa170
movq %rax, %rcx
movq -0x448(%rbp), %rax
movslq 0x68(%rcx), %rcx
cmpq %rcx, %rax
jle 0x1eb67
movq -0x400(%rbp), %rdi
movq -0x3a8(%rbp), %rsi
addq $0x50, %rdi
callq 0x209e0
movq $0x0, -0x3a8(%rbp)
cmpl $0x0, -0xc(%rbp)
jne 0x1eb65
movq -0x400(%rbp), %rdi
callq 0xa170
cmpl $0x1, 0xc8(%rax)
jle 0x1eb65
movss -0x3dc(%rbp), %xmm0
movss %xmm0, -0x450(%rbp)
leaq -0x338(%rbp), %rdi
callq 0x157d0
movss %xmm0, -0x44c(%rbp)
jmp 0x1eb45
movss -0x44c(%rbp), %xmm1
movss -0x450(%rbp), %xmm0
movq -0x400(%rbp), %rdi
callq 0x1cee0
jmp 0x1eb63
jmp 0x1eb65
jmp 0x1eb67
jmp 0x1e826
cmpl $0x0, -0xc(%rbp)
jne 0x1ebd2
movq -0x400(%rbp), %rdi
callq 0xa170
cmpl $0x0, 0xc8(%rax)
jle 0x1ebd2
leaq -0x338(%rbp), %rdi
callq 0x157d0
movss %xmm0, -0x454(%rbp)
jmp 0x1eb9d
movss -0x454(%rbp), %xmm1
movq -0x400(%rbp), %rdi
movss 0xada4(%rip), %xmm0     # 0x29958
callq 0x1cee0
jmp 0x1ebbb
movq 0x1d3fe(%rip), %rdi     # 0x3bfc0
movq 0x1d3cf(%rip), %rsi     # 0x3bf98
callq 0x4310
jmp 0x1ebd0
jmp 0x1ebd2
leaq -0x218(%rbp), %rdi
callq 0x4080
jmp 0x1ebe0
leaq -0x3d8(%rbp), %rdi
callq 0xa040
leaq -0x3c0(%rbp), %rdi
callq 0xa040
leaq -0x338(%rbp), %rdi
callq 0x13d10
leaq -0x218(%rbp), %rdi
callq 0x4090
addq $0x460, %rsp            # imm = 0x460
popq %rbp
retq
leaq -0x338(%rbp), %rdi
callq 0x13d10
leaq -0x218(%rbp), %rdi
callq 0x4090
movq -0x220(%rbp), %rdi
callq 0x45b0
nopl (%rax)