// File: /workspace/github_c_makefile_star2_O2/Leeheng86[P]word2vec/word2vec.c
// Function: TrainModel()
void TrainModel() {
  long a, b, c, d;
  FILE *fo;
  pthread_t *pt = (pthread_t *)malloc(num_threads * sizeof(pthread_t));
  printf("Starting training using file %s\n", train_file);
  starting_alpha = alpha;
  if (read_vocab_file[0] != 0) ReadVocab(); else LearnVocabFromTrainFile();
  if (save_vocab_file[0] != 0) SaveVocab();
  if (output_file[0] == 0) return;
  InitNet();
  if (negative > 0) InitUnigramTable();
  start = clock();
  for (a = 0; a < num_threads; a++) pthread_create(&pt[a], NULL, TrainModelThread, (void *)a);
  for (a = 0; a < num_threads; a++) pthread_join(pt[a], NULL);
  fo = fopen(output_file, "wb");
  if (classes == 0) {
    // Save the word vectors
    fprintf(fo, "%lld %lld\n", vocab_size, layer1_size);
    for (a = 0; a < vocab_size; a++) {
      fprintf(fo, "%s ", vocab[a].word);
      if (binary) for (b = 0; b < layer1_size; b++) fwrite(&syn0[a * layer1_size + b], sizeof(real), 1, fo);
      else for (b = 0; b < layer1_size; b++) fprintf(fo, "%lf ", syn0[a * layer1_size + b]);
      fprintf(fo, "\n");
    }
  } else {
    // Run K-means on the word vectors
    int clcn = classes, iter = 10, closeid;
    int *centcn = (int *)malloc(classes * sizeof(int));
    int *cl = (int *)calloc(vocab_size, sizeof(int));
    real closev, x;
    real *cent = (real *)calloc(classes * layer1_size, sizeof(real));
    for (a = 0; a < vocab_size; a++) cl[a] = a % clcn;
    for (a = 0; a < iter; a++) {
      for (b = 0; b < clcn * layer1_size; b++) cent[b] = 0;
      for (b = 0; b < clcn; b++) centcn[b] = 1;
      for (c = 0; c < vocab_size; c++) {
        for (d = 0; d < layer1_size; d++) cent[layer1_size * cl[c] + d] += syn0[c * layer1_size + d];
        centcn[cl[c]]++;
      }
      for (b = 0; b < clcn; b++) {
        closev = 0;
        for (c = 0; c < layer1_size; c++) {
          cent[layer1_size * b + c] /= centcn[b];
          closev += cent[layer1_size * b + c] * cent[layer1_size * b + c];
        }
        closev = sqrt(closev);
        for (c = 0; c < layer1_size; c++) cent[layer1_size * b + c] /= closev;
      }
      for (c = 0; c < vocab_size; c++) {
        closev = -10;
        closeid = 0;
        for (d = 0; d < clcn; d++) {
          x = 0;
          for (b = 0; b < layer1_size; b++) x += cent[layer1_size * d + b] * syn0[c * layer1_size + b];
          if (x > closev) {
            closev = x;
            closeid = d;
          }
        }
        cl[c] = closeid;
      }
    }
    // Save the K-means classes
    for (a = 0; a < vocab_size; a++) fprintf(fo, "%s %d\n", vocab[a].word, cl[a]);
    free(centcn);
    free(cent);
    free(cl);
  }
  fclose(fo);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movslq 0x7455(%rip), %rdi      # 0xb270
shlq $0x3, %rdi
callq 0x22f0
movq %rax, %rbx
leaq 0x32cb(%rip), %rdi      # 0x70f9
leaq 0x748b(%rip), %rsi      # 0xb2c0
xorl %eax, %eax
callq 0x2050
movss 0x744c(%rip), %xmm0     # 0xb290
movss %xmm0, 0x766c(%rip)     # 0xb4b8
cmpb $0x0, 0x75bd(%rip)      # 0xb410
je 0x3e5c
callq 0x2fff
jmp 0x3e61
callq 0x2de9
cmpb $0x0, 0x7538(%rip)      # 0xb3a0
je 0x3e6f
callq 0x2f91
cmpb $0x0, 0x74ba(%rip)      # 0xb330
je 0x4211
callq 0x313b
cmpl $0x0, 0x7410(%rip)      # 0xb298
jle 0x3e8f
callq 0x267c
callq 0x2170
movq %rax, 0x7645(%rip)      # 0xb4e0
xorl %r14d, %r14d
leaq -0xb7c(%rip), %r15      # 0x3329
movq %rbx, %r12
movslq 0x73c1(%rip), %rax      # 0xb270
cmpq %rax, %r14
jge 0x3ecd
movq %r12, %rdi
xorl %esi, %esi
movq %r15, %rdx
movq %r14, %rcx
callq 0x2430
incq %r14
addq $0x8, %r12
jmp 0x3ea8
xorl %r14d, %r14d
cltq
cmpq %rax, %r14
jge 0x3eed
movq (%rbx,%r14,8), %rdi
xorl %esi, %esi
callq 0x21d0
incq %r14
movl 0x7385(%rip), %eax      # 0xb270
jmp 0x3ed0
leaq 0x743c(%rip), %rdi      # 0xb330
leaq 0x31b2(%rip), %rsi      # 0x70ad
callq 0x2280
movq %rax, %r14
movq 0x75a6(%rip), %rbx      # 0xb4b0
testq %rbx, %rbx
je 0x4220
movq %r14, 0x10(%rsp)
leaq (,%rbx,4), %rdi
callq 0x22f0
movq %rax, %r14
movq 0x7561(%rip), %rbp      # 0xb490
pushq $0x4
popq %r13
movq %rbp, %rdi
movq %r13, %rsi
callq 0x2160
movq %rax, %r15
movq 0x7338(%rip), %r12      # 0xb280
movq %r12, %rdi
imulq %rbx, %rdi
movq %r13, 0x18(%rsp)
movq %r13, %rsi
callq 0x2160
movq %rax, %r13
movslq %ebx, %rax
movq %rax, 0x8(%rsp)
xorl %ecx, %ecx
testq %rbp, %rbp
movl $0x0, %esi
cmovgq %rbp, %rsi
cmpq %rcx, %rsi
je 0x3f8d
movq %rcx, %rax
cqto
idivq 0x8(%rsp)
movl %edx, (%r15,%rcx,4)
incq %rcx
jmp 0x3f75
xorl %edx, %edx
movq 0x8(%rsp), %rax
testq %rax, %rax
movl $0x0, %ebx
cmovgq %rax, %rbx
movss 0x30a0(%rip), %xmm3     # 0x7048
xorps %xmm4, %xmm4
xorl %eax, %eax
cmpq $0xa, %rax
je 0x419b
movq %rax, 0x20(%rsp)
movq %r12, %rax
imulq 0x8(%rsp), %rax
testq %rax, %rax
cmovleq %rdx, %rax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x3fde
andl $0x0, (%r13,%rcx,4)
incq %rcx
jmp 0x3fce
xorl %eax, %eax
cmpq %rax, %rbx
je 0x3ff2
movl $0x1, (%r14,%rax,4)
incq %rax
jmp 0x3fe0
movq 0x74c7(%rip), %rax      # 0xb4c0
testq %r12, %r12
movl $0x0, %ecx
cmovgq %r12, %rcx
testq %rbp, %rbp
cmovleq %rdx, %rbp
leaq (,%r12,4), %rdx
xorl %esi, %esi
cmpq %rbp, %rsi
je 0x4053
xorl %edi, %edi
cmpq %rdi, %rcx
je 0x4043
movss (%rax,%rdi,4), %xmm0
movslq (%r15,%rsi,4), %r8
imulq %rdx, %r8
addq %r13, %r8
addss (%r8,%rdi,4), %xmm0
movss %xmm0, (%r8,%rdi,4)
incq %rdi
jmp 0x401d
movslq (%r15,%rsi,4), %rdi
incl (%r14,%rdi,4)
incq %rsi
addq %rdx, %rax
jmp 0x4016
xorl %esi, %esi
xorl %ebp, %ebp
cmpq %rbx, %rbp
je 0x4104
testq %r12, %r12
movl $0x0, %eax
cmovgq %r12, %rax
imulq %rsi, %r12
addq %r13, %r12
xorps %xmm0, %xmm0
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x40a0
cvtsi2ssl (%r14,%rbp,4), %xmm1
movss (%r12,%rcx,4), %xmm2
divss %xmm1, %xmm2
movss %xmm2, (%r12,%rcx,4)
mulss %xmm2, %xmm2
addss %xmm2, %xmm0
incq %rcx
jmp 0x4078
ucomiss %xmm4, %xmm0
jb 0x40ab
sqrtss %xmm0, %xmm0
jmp 0x40c1
movq %rsi, %r12
callq 0x2420
movq %r12, %rsi
xorps %xmm4, %xmm4
movss 0x2f87(%rip), %xmm3     # 0x7048
movq 0x71b8(%rip), %r12      # 0xb280
testq %r12, %r12
movl $0x0, %eax
cmovgq %r12, %rax
movq %r12, %rcx
imulq %rsi, %rcx
addq %r13, %rcx
xorl %edx, %edx
cmpq %rdx, %rax
je 0x40f8
movss (%rcx,%rdx,4), %xmm1
divss %xmm0, %xmm1
movss %xmm1, (%rcx,%rdx,4)
incq %rdx
jmp 0x40e0
incq %rbp
addq $0x4, %rsi
jmp 0x4057
movq 0x7385(%rip), %rbp      # 0xb490
movq 0x73ae(%rip), %rax      # 0xb4c0
testq %r12, %r12
movl $0x0, %ecx
cmovgq %r12, %rcx
testq %rbp, %rbp
movl $0x0, %edx
cmovgq %rbp, %rdx
leaq (,%r12,4), %rsi
xorl %edi, %edi
cmpq %rdx, %rdi
je 0x418c
xorl %r8d, %r8d
movq %r13, %r9
xorl %r10d, %r10d
movaps %xmm3, %xmm0
cmpq %rbx, %r8
je 0x4180
xorps %xmm1, %xmm1
xorl %r11d, %r11d
cmpq %r11, %rcx
je 0x416a
movss (%r9,%r11,4), %xmm2
mulss (%rax,%r11,4), %xmm2
addss %xmm2, %xmm1
incq %r11
jmp 0x4150
ucomiss %xmm0, %xmm1
cmoval %r8d, %r10d
maxss %xmm0, %xmm1
incq %r8
addq %rsi, %r9
movaps %xmm1, %xmm0
jmp 0x4145
movl %r10d, (%r15,%rdi,4)
incq %rdi
addq %rsi, %rax
jmp 0x4134
movq 0x20(%rsp), %rax
incq %rax
xorl %edx, %edx
jmp 0x3fad
xorl %ebx, %ebx
cmpq %rbp, %rbx
jge 0x41de
movq 0x72cf(%rip), %rax      # 0xb478
movq 0x18(%rsp), %r12
movq (%rax,%r12,4), %rdx
movl (%r15,%rbx,4), %ecx
movq 0x10(%rsp), %rdi
leaq 0x2f6c(%rip), %rsi      # 0x712e
xorl %eax, %eax
callq 0x2330
incq %rbx
movq 0x72bd(%rip), %rbp      # 0xb490
addq $0xa, %r12
movq %r12, 0x18(%rsp)
jmp 0x419d
movq %r14, %rdi
callq 0x2290
movq %r13, %rdi
callq 0x2290
movq %r15, %rdi
callq 0x2290
movq 0x10(%rsp), %r14
movq %r14, %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2210
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x7269(%rip), %rdx      # 0xb490
movq 0x7052(%rip), %rcx      # 0xb280
leaq 0x2ee5(%rip), %rsi      # 0x711a
movq %r14, %rdi
xorl %eax, %eax
callq 0x2330
pushq $0x4
popq %r12
pushq $0x1
popq %r13
xorl %ebx, %ebx
xorl %ecx, %ecx
cmpq 0x723e(%rip), %rcx      # 0xb490
jge 0x41fb
movq 0x721d(%rip), %rax      # 0xb478
movq %rcx, 0x8(%rsp)
imulq $0x28, %rcx, %rcx
movq 0x10(%rax,%rcx), %rdx
movq %r14, %r15
movq %r14, %rdi
leaq 0x2eaf(%rip), %rsi      # 0x7125
xorl %eax, %eax
callq 0x2330
cmpl $0x0, 0x71fc(%rip)      # 0xb480
je 0x42bc
xorl %ebp, %ebp
xorl %r14d, %r14d
movq 0x6fee(%rip), %rdi      # 0xb280
cmpq %rdi, %r14
jge 0x42f2
imulq %rbx, %rdi
addq 0x721e(%rip), %rdi      # 0xb4c0
addq %rbp, %rdi
movq %r12, %rsi
movq %r13, %rdx
movq %r15, %rcx
callq 0x2480
incq %r14
addq $0x4, %rbp
jmp 0x428b
xorl %r14d, %r14d
movq 0x6fba(%rip), %rax      # 0xb280
cmpq %rax, %r14
jge 0x42f2
imulq %rbx, %rax
addq 0x71ea(%rip), %rax      # 0xb4c0
cvtss2sd (%rax,%r14,4), %xmm0
movq %r15, %rdi
leaq 0x2e43(%rip), %rsi      # 0x7129
movb $0x1, %al
callq 0x2330
incq %r14
jmp 0x42bf
pushq $0xa
popq %rdi
movq %r15, %r14
movq %r15, %rsi
callq 0x22c0
movq 0x8(%rsp), %rcx
incq %rcx
addq $0x4, %rbx
jmp 0x424b