// File: /workspace/github_cpp_makefile_star2_O2/ddu1[P]polarizedtext/src/fasttext.cc
// Function: fasttext::FastText::train(std::shared_ptr<fasttext::Args>)
void FastText::train(std::shared_ptr<Args> args) {
  args_ = args;
  dict_ = std::make_shared<Dictionary>(args_);
  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();

// set dim to number of labels (ddu)
  if( args_->model == model_name::pwv) { 
    args_->dim = dict_->nlabels();
  }

  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);
  }

  //input_->uniform(1.0 / args_->dim);
  //output_->zero();

  // initialized vectors with labels (ddu)
  auto words = dict_->getWords();
  output_->zero();

    if (args_->pretrainedVectors.size() != 0) {
        loadVectors(args_->pretrainedVectors);
    } else {

        input_ = std::make_shared<Matrix>(dict_->nwords()+args_->bucket, args_->dim);
        if(args_->model == model_name::pwv ) {
          input_->zero();
          for( int32_t i = 0; i < dict_->nwords(); ++i) { // for words
            int32_t non_zero_size = words[i].nlabels;
            Vector vec = Vector(args_->dim, dict_->getLabels(i));
            input_->addRow(vec, i, non_zero_size? (1.0/non_zero_size): 0);
          }
          for( int32_t i = 0; i < args_->bucket; ++i) { // for buckets (subwords)
            Vector ones = Vector(args_->dim);
            ones.ones();
            input_->addRow(ones, dict_->nwords()+i, 1.0 / args_->dim);
          }
        }
        else {
          input_->uniform(1.0 / args_->dim);
        }  
    }

  start = clock();
  tokenCount = 0;
  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();
  }
  model_ = std::make_shared<Model>(input_, output_, args_, 0);

  saveModel();
  if (args_->model != model_name::sup) {
    saveVectors();
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x298, %rsp            # imm = 0x298
movq %rdi, %r14
callq 0x617e
leaq 0x90(%rsp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0xca48
leaq 0x10(%r14), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0xd00a
leaq 0x98(%rsp), %rdi
callq 0x625c
movq (%r14), %rdi
leaq 0x3a4c(%rip), %rsi      # 0xff1c
callq 0x44b1
testb %al, %al
jne 0xc8ea
movq (%r14), %rsi
leaq 0x90(%rsp), %rdi
pushq $0x8
popq %rdx
callq 0x33c0
leaq 0x108(%rsp), %rdi
callq 0x3060
testb %al, %al
je 0xc90d
movq (%r15), %rdi
leaq 0x90(%rsp), %rsi
callq 0x4eae
leaq 0x90(%rsp), %rdi
callq 0x3050
movq (%r14), %rax
movl 0x8c(%rax), %eax
cmpl $0x4, %eax
jne 0xc544
movq (%r15), %rdi
callq 0x4838
movq (%r14), %rcx
movl %eax, 0x6c(%rcx)
movl 0x8c(%rcx), %eax
cmpl $0x3, %eax
jne 0xc56b
movq (%r15), %rdi
callq 0x4838
leaq 0x20(%rsp), %rsi
movl %eax, (%rsi)
movq (%r14), %rdx
addq $0x6c, %rdx
leaq 0x48(%rsp), %rdi
callq 0xcb1a
jmp 0xc58b
movq (%r15), %rdi
callq 0x4834
leaq 0x20(%rsp), %rsi
movl %eax, (%rsi)
movq (%r14), %rdx
addq $0x6c, %rdx
leaq 0x48(%rsp), %rdi
callq 0xcb1a
leaq 0x30(%r14), %rdi
leaq 0x48(%rsp), %rsi
callq 0xd19c
leaq 0x50(%rsp), %rdi
callq 0x625c
movq (%r15), %rdi
callq 0x4842
leaq 0x48(%rsp), %rdi
movq %rax, %rsi
callq 0xcb3c
movq 0x30(%r14), %rdi
callq 0x7a0c
movq (%r14), %rsi
cmpq $0x0, 0xd8(%rsi)
je 0xc5fb
addq $0xd0, %rsi
leaq 0x70(%rsp), %rdi
callq 0x3340
leaq 0x70(%rsp), %rsi
movq %r14, %rdi
callq 0xc19e
leaq 0x70(%rsp), %rdi
callq 0x34e8
jmp 0xc738
movq (%r15), %rdi
callq 0x4834
movq (%r14), %rdx
addl 0x90(%rdx), %eax
leaq 0x10(%rsp), %rsi
movl %eax, (%rsi)
addq $0x6c, %rdx
leaq 0x20(%rsp), %rdi
callq 0xcb1a
leaq 0x20(%r14), %rdi
leaq 0x20(%rsp), %rsi
movq %rdi, 0x68(%rsp)
callq 0xd19c
leaq 0x28(%rsp), %rdi
callq 0x625c
movq (%r14), %rax
movq 0x20(%r14), %rdi
cmpl $0x4, 0x8c(%rax)
jne 0xc71e
callq 0x7a0c
movq %r15, 0x60(%rsp)
pushq $0x48
popq %rbx
movq $0x0, 0x8(%rsp)
leaq 0x10(%rsp), %r15
movq 0x60(%rsp), %rax
movq (%rax), %rdi
callq 0x4834
cltq
movq 0x8(%rsp), %rdx
cmpq %rax, %rdx
jge 0xc877
movq 0x48(%rsp), %rax
movq %r14, %rcx
movq %rbx, %r12
movb (%rax,%rbx), %bl
movq (%r14), %rax
movslq 0x6c(%rax), %r14
movq %rcx, %r13
movq 0x10(%rcx), %rsi
leaq 0x20(%rsp), %rbp
movq %rbp, %rdi
callq 0x4848
movq %r15, %rdi
movq %r14, %rsi
movq %rbp, %rdx
callq 0x7cb6
movq %rbp, %rdi
callq 0x626a
xorps %xmm0, %xmm0
testb %bl, %bl
je 0xc6e7
movsbl %bl, %eax
cvtsi2sd %eax, %xmm0
movsd 0x2f09(%rip), %xmm1     # 0xf5e8
divsd %xmm0, %xmm1
cvtsd2ss %xmm1, %xmm0
movq 0x68(%rsp), %rax
movq (%rax), %rdi
movq %r15, %rsi
movq 0x8(%rsp), %rbx
movq %rbx, %rdx
callq 0x7a98
movq %r15, %rdi
callq 0x7d50
incq %rbx
movq %rbx, 0x8(%rsp)
movq %r12, %rbx
addq $0x68, %rbx
movq %r13, %r14
jmp 0xc66d
cvtsi2sdl 0x6c(%rax), %xmm0
movsd 0x2ebd(%rip), %xmm1     # 0xf5e8
divsd %xmm0, %xmm1
cvtsd2ss %xmm1, %xmm0
callq 0x7a2a
leaq 0x30(%r14), %rax
movq %rax, 0x8(%rsp)
callq 0x3170
movq %rax, 0x58(%r14)
xorl %eax, %eax
movq %r14, %rbx
xchgq %rax, 0x50(%r14)
xorl %r14d, %r14d
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %r15
movaps %xmm0, (%r15)
andq $0x0, 0x10(%r15)
leaq 0xb5fa(%rip), %r12      # 0x17d68
leaq 0x40(%rsp), %r13
leaq 0x10(%rsp), %rbp
movq (%rbx), %rax
cmpl 0x9c(%rax), %r14d
jge 0xc7d7
andq $0x0, 0x40(%rsp)
pushq $0x18
popq %rdi
callq 0x3250
movq %r12, (%rax)
movq %rbx, 0x8(%rax)
movl %r14d, 0x10(%rax)
movq %rax, 0x10(%rsp)
movq %r13, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x3220
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0xc7bf
movq (%rdi), %rax
callq *0x8(%rax)
movq %r15, %rdi
movq %r13, %rsi
callq 0xdcec
movq %r13, %rdi
callq 0xcb96
incl %r14d
jmp 0xc778
movq 0x20(%rsp), %r15
cmpq 0x28(%rsp), %r15
je 0xc7f1
movq %r15, %rdi
callq 0x3410
addq $0x8, %r15
jmp 0xc7dc
leaq 0x20(%rbx), %rsi
leaq 0x40(%rsp), %r8
andl $0x0, (%r8)
leaq 0x10(%rsp), %rdi
movq 0x8(%rsp), %rdx
movq %rbx, %rcx
callq 0xca81
leaq 0x40(%rbx), %rdi
leaq 0x10(%rsp), %rsi
callq 0xd424
leaq 0x18(%rsp), %rdi
callq 0x625c
movq %rbx, %rdi
callq 0xad60
movq (%rbx), %rax
cmpl $0x3, 0x8c(%rax)
je 0xc844
movq %rbx, %rdi
callq 0xaba6
leaq 0x20(%rsp), %rdi
callq 0xcba4
leaq 0x48(%rsp), %rdi
callq 0x5ea4
leaq 0x90(%rsp), %rdi
callq 0x3070
addq $0x298, %rsp            # imm = 0x298
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ebp, %ebp
leaq 0x20(%rsp), %r12
movq 0x60(%rsp), %rbx
movq (%r14), %rax
cmpl 0x90(%rax), %ebp
jge 0xc738
movslq 0x6c(%rax), %rsi
movq %r12, %rdi
callq 0x7c8c
movq %r12, %rdi
callq 0x7d62
movq 0x68(%rsp), %rax
movq (%rax), %r13
movq (%rbx), %rdi
callq 0x4834
addl %ebp, %eax
movslq %eax, %rdx
movq (%r14), %rax
cvtsi2sdl 0x6c(%rax), %xmm0
movsd 0x2d1d(%rip), %xmm1     # 0xf5e8
divsd %xmm0, %xmm1
cvtsd2ss %xmm1, %xmm0
movq %r13, %rdi
movq %r12, %rsi
callq 0x7a98
movq %r12, %rdi
callq 0x7d50
incl %ebp
jmp 0xc883
movq 0xb6ff(%rip), %rdi      # 0x17ff0
leaq 0x3626(%rip), %rsi      # 0xff1e
callq 0x3240
movq %rax, %rdi
callq 0x3100
pushq $0x1
popq %rdi
callq 0x32a0
movq 0xb6dc(%rip), %rdi      # 0x17ff0
leaq 0x3622(%rip), %rsi      # 0xff3d
callq 0x3240
movq %rax, %rdi
callq 0x3100
jmp 0xc905
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x34e8
jmp 0xc9b0
jmp 0xc969
jmp 0xc9a3
jmp 0xc947
jmp 0xc947
jmp 0xc9a3
jmp 0xc969
jmp 0xc947
movq %rax, %rbx
jmp 0xc9ba
jmp 0xc969
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
jmp 0xc976
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x626a
jmp 0xc9b0
jmp 0xc969
movq %rax, %rbx
jmp 0xc9b0
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x7d50
jmp 0xc9b0
jmp 0xc9a3
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0xcb96
jmp 0xc9a6
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0xc9a6
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0xc9a6
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0xcba4
leaq 0x48(%rsp), %rdi
callq 0x5ea4
leaq 0x90(%rsp), %rdi
callq 0x3070
movq %rbx, %rdi
callq 0x3440
nop