// File: epfml[P]sent2vec/src/fasttext.cc
// Function: fasttext::FastText::savedDictTrain(std::shared_ptr<fasttext::Args>)
void FastText::savedDictTrain(std::shared_ptr<Args> args) {
  loadDict(args_->dict);
  if (args_->input == "-") {
    // manage expectations
    std::cerr << "Cannot use stdin for training!" << std::endl;
    exit(EXIT_FAILURE);
  }
  std::ifstream ifs(args_->input);
  if (!ifs.is_open()) {
    std::cerr << "Input file cannot be opened!" << std::endl;
    exit(EXIT_FAILURE);
  }
  dict_->readFromFile(ifs);
  ifs.close();

  if (args_->pretrainedVectors.size() != 0) {
    loadVectors(args_->pretrainedVectors);
  } else {
    input_ = std::make_shared<Matrix>(dict_->nwords()+args_->bucket, args_->dim);
    input_->uniform(1.0 / args_->dim);
  }

  if (args_->model == model_name::sup) {
    output_ = std::make_shared<Matrix>(dict_->nlabels(), args_->dim);
  } else {
    output_ = std::make_shared<Matrix>(dict_->nwords(), args_->dim);
  }
  output_->zero();

  start = clock();
  tokenCount = 0;
  if (args_->thread > 1) {
    std::vector<std::thread> threads;
    for (int32_t i = 0; i < args_->thread; i++) {
      threads.push_back(std::thread([=]() { trainThread(i); }));
    }
    for (auto it = threads.begin(); it != threads.end(); ++it) {
      it->join();
    }
  } else {
    trainThread(0);
  }
  model_ = std::make_shared<Model>(input_, output_, args_, 0);

  saveModel();
  if (args_->model != model_name::sup && args_->model != model_name::sent2vec && args_->model != model_name::cbowCWNgrams) {
    saveVectors();
    if (args_->saveOutput > 0) {
      saveOutput();
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x350, %rsp            # imm = 0x350
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x2f8(%rbp)
callq 0xea70
movq -0x2f8(%rbp), %rdi
movq %rax, %rsi
addq $0x60, %rsi
callq 0x28ca0
movq -0x2f8(%rbp), %rdi
callq 0xea70
movq %rax, %rdi
leaq 0x12ddd(%rip), %rsi     # 0x439b9
callq 0x7ec0
testb $0x1, %al
jne 0x30be7
jmp 0x30c13
movq 0x2e402(%rip), %rdi     # 0x5eff0
leaq 0x12dc6(%rip), %rsi     # 0x439bb
callq 0x5420
movq %rax, %rdi
movq 0x2e38c(%rip), %rsi     # 0x5ef90
callq 0x5460
movl $0x1, %edi
callq 0x54f0
movq -0x2f8(%rbp), %rdi
callq 0xea70
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
movq %rdi, -0x308(%rbp)
movl $0x8, %edx
callq 0x56d0
movq -0x308(%rbp), %rdi
callq 0x56c0
movb %al, -0x2f9(%rbp)
jmp 0x30c4e
movb -0x2f9(%rbp), %al
testb $0x1, %al
jne 0x30cac
jmp 0x30c5a
movq 0x2e38f(%rip), %rdi     # 0x5eff0
leaq 0x12d72(%rip), %rsi     # 0x439da
callq 0x5420
movq %rax, -0x310(%rbp)
jmp 0x30c76
movq -0x310(%rbp), %rdi
movq 0x2e30c(%rip), %rsi     # 0x5ef90
callq 0x5460
jmp 0x30c8b
movl $0x1, %edi
callq 0x54f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x31213
movq -0x2f8(%rbp), %rdi
addq $0x10, %rdi
callq 0x33af0
movq %rax, %rdi
leaq -0x218(%rbp), %rsi
callq 0x9590
jmp 0x30ccd
leaq -0x218(%rbp), %rdi
callq 0x50f0
jmp 0x30cdb
movq -0x2f8(%rbp), %rdi
callq 0xea70
movq %rax, %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x5300
cmpq $0x0, %rax
je 0x30d69
movq -0x2f8(%rbp), %rdi
callq 0xea70
movq %rax, %rsi
addq $0x108, %rsi            # imm = 0x108
leaq -0x248(%rbp), %rdi
callq 0x51d0
jmp 0x30d20
movq -0x2f8(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x305e0
jmp 0x30d35
leaq -0x248(%rbp), %rdi
callq 0x58d8
jmp 0x30e4f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x248(%rbp), %rdi
callq 0x58d8
jmp 0x31213
movq -0x2f8(%rbp), %rdi
addq $0x10, %rdi
callq 0x33af0
movq %rax, %rdi
callq 0x8540
movl %eax, -0x314(%rbp)
jmp 0x30d89
movq -0x2f8(%rbp), %rdi
callq 0xea70
movq -0x2f8(%rbp), %rdi
movq %rax, %rcx
movl -0x314(%rbp), %eax
movl 0xc4(%rcx), %ecx
addl %ecx, %eax
movl %eax, -0x25c(%rbp)
callq 0xea70
movq %rax, %rdx
addq $0x94, %rdx
leaq -0x258(%rbp), %rdi
leaq -0x25c(%rbp), %rsi
callq 0x352a0
jmp 0x30dd7
movq -0x2f8(%rbp), %rdi
addq $0x20, %rdi
movq %rdi, -0x328(%rbp)
leaq -0x258(%rbp), %rsi
movq %rsi, -0x330(%rbp)
callq 0x33f20
movq -0x330(%rbp), %rdi
callq 0x23bb0
movq -0x328(%rbp), %rdi
callq 0x23990
movq -0x2f8(%rbp), %rdi
movq %rax, -0x320(%rbp)
callq 0xea70
movq -0x320(%rbp), %rdi
cvtsi2sdl 0x94(%rax), %xmm1
movsd 0x11af2(%rip), %xmm0    # 0x42930
divsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
callq 0x1e3b0
jmp 0x30e4d
jmp 0x30e4f
movq -0x2f8(%rbp), %rdi
callq 0xea70
cmpl $0x3, 0xc0(%rax)
jne 0x30ee0
movq -0x2f8(%rbp), %rdi
addq $0x10, %rdi
callq 0x33af0
movq %rax, %rdi
callq 0x8560
movl %eax, -0x334(%rbp)
jmp 0x30e84
movq -0x2f8(%rbp), %rdi
movl -0x334(%rbp), %eax
movl %eax, -0x274(%rbp)
callq 0xea70
movq %rax, %rdx
addq $0x94, %rdx
leaq -0x270(%rbp), %rdi
leaq -0x274(%rbp), %rsi
callq 0x352a0
jmp 0x30ebb
movq -0x2f8(%rbp), %rdi
addq $0x30, %rdi
leaq -0x270(%rbp), %rsi
callq 0x33f20
leaq -0x270(%rbp), %rdi
callq 0x23bb0
jmp 0x30f5a
movq -0x2f8(%rbp), %rdi
addq $0x10, %rdi
callq 0x33af0
movq %rax, %rdi
callq 0x8540
movl %eax, -0x338(%rbp)
jmp 0x30f00
movq -0x2f8(%rbp), %rdi
movl -0x338(%rbp), %eax
movl %eax, -0x28c(%rbp)
callq 0xea70
movq %rax, %rdx
addq $0x94, %rdx
leaq -0x288(%rbp), %rdi
leaq -0x28c(%rbp), %rsi
callq 0x352a0
jmp 0x30f37
movq -0x2f8(%rbp), %rdi
addq $0x30, %rdi
leaq -0x288(%rbp), %rsi
callq 0x33f20
leaq -0x288(%rbp), %rdi
callq 0x23bb0
movq -0x2f8(%rbp), %rdi
addq $0x30, %rdi
callq 0x23990
movq %rax, %rdi
callq 0x1e350
jmp 0x30f74
callq 0x52e0
movq -0x2f8(%rbp), %rdi
movq %rax, 0x78(%rdi)
addq $0x70, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x34390
movq -0x2f8(%rbp), %rdi
callq 0xea70
cmpl $0x1, 0xd4(%rax)
jle 0x3110c
leaq -0x2a8(%rbp), %rdi
callq 0x34420
movl $0x0, -0x2ac(%rbp)
movq -0x2f8(%rbp), %rdi
movl -0x2ac(%rbp), %eax
movl %eax, -0x33c(%rbp)
callq 0xea70
movq %rax, %rcx
movl -0x33c(%rbp), %eax
cmpl 0xd4(%rcx), %eax
jge 0x31088
movq -0x2f8(%rbp), %rax
movq %rax, -0x2c8(%rbp)
movl -0x2ac(%rbp), %eax
movl %eax, -0x2c0(%rbp)
leaq -0x2b8(%rbp), %rdi
leaq -0x2c8(%rbp), %rsi
callq 0x31230
jmp 0x3101c
leaq -0x2a8(%rbp), %rdi
leaq -0x2b8(%rbp), %rsi
callq 0x34440
jmp 0x31031
leaq -0x2b8(%rbp), %rdi
callq 0x34470
movl -0x2ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2ac(%rbp)
jmp 0x30fc0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x310fb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0x34470
jmp 0x310fb
leaq -0x2a8(%rbp), %rdi
callq 0x344a0
movq %rax, -0x2d0(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x34510
movq %rax, -0x2d8(%rbp)
leaq -0x2d0(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0x344d0
testb $0x1, %al
jne 0x310c7
jmp 0x310ed
leaq -0x2d0(%rbp), %rdi
callq 0x34540
movq %rax, %rdi
callq 0x5750
jmp 0x310dd
jmp 0x310df
leaq -0x2d0(%rbp), %rdi
callq 0x34560
jmp 0x3109b
leaq -0x2a8(%rbp), %rdi
callq 0x34580
jmp 0x3111e
leaq -0x2a8(%rbp), %rdi
callq 0x34580
jmp 0x31213
movq -0x2f8(%rbp), %rdi
xorl %esi, %esi
callq 0x2fd30
jmp 0x3111c
jmp 0x3111e
movq -0x2f8(%rbp), %rcx
movq %rcx, %rsi
addq $0x20, %rsi
movq %rcx, %rdx
addq $0x30, %rdx
movl $0x0, -0x2ec(%rbp)
leaq -0x2e8(%rbp), %rdi
leaq -0x2ec(%rbp), %r8
callq 0x33ff0
jmp 0x31152
movq -0x2f8(%rbp), %rdi
addq $0x60, %rdi
leaq -0x2e8(%rbp), %rsi
movq %rsi, -0x348(%rbp)
callq 0x34080
movq -0x348(%rbp), %rdi
callq 0x340b0
movq -0x2f8(%rbp), %rdi
callq 0x28ea0
jmp 0x3118a
movq -0x2f8(%rbp), %rdi
callq 0xea70
cmpl $0x3, 0xc0(%rax)
je 0x311fe
movq -0x2f8(%rbp), %rdi
callq 0xea70
cmpl $0x4, 0xc0(%rax)
je 0x311fe
movq -0x2f8(%rbp), %rdi
callq 0xea70
cmpl $0x5, 0xc0(%rax)
je 0x311fe
movq -0x2f8(%rbp), %rdi
callq 0x283c0
jmp 0x311d7
movq -0x2f8(%rbp), %rdi
callq 0xea70
cmpl $0x0, 0x128(%rax)
jle 0x311fc
movq -0x2f8(%rbp), %rdi
callq 0x28710
jmp 0x311fa
jmp 0x311fc
jmp 0x311fe
leaq -0x218(%rbp), %rdi
callq 0x5130
addq $0x350, %rsp            # imm = 0x350
popq %rbp
retq
leaq -0x218(%rbp), %rdi
callq 0x5130
movq -0x220(%rbp), %rdi
callq 0x57a0
nopl (%rax,%rax)