// File: /workspace/github_c_makefile_star2_O3/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 $0x48, %rsp
movslq 0x701f(%rip), %rdi      # 0xb268
shlq $0x3, %rdi
callq 0x2300
movq %rax, %rbx
leaq 0x2ef9(%rip), %rdi      # 0x7155
leaq 0x705d(%rip), %rsi      # 0xb2c0
xorl %eax, %eax
callq 0x2050
movd 0x7016(%rip), %xmm0     # 0xb288
movd %xmm0, 0x723e(%rip)     # 0xb4b8
cmpb $0x0, 0x718f(%rip)      # 0xb410
je 0x428a
callq 0x3321
jmp 0x428f
callq 0x30c2
cmpb $0x0, 0x710a(%rip)      # 0xb3a0
je 0x429d
callq 0x32a9
cmpb $0x0, 0x708c(%rip)      # 0xb330
je 0x4762
callq 0x347a
cmpl $0x0, 0x6fda(%rip)      # 0xb290
jle 0x42bd
callq 0x268c
callq 0x2170
movq %rax, 0x7217(%rip)      # 0xb4e0
cmpl $0x0, 0x6f98(%rip)      # 0xb268
jle 0x4323
xorl %r14d, %r14d
leaq -0xc88(%rip), %r15      # 0x3654
movq %rbx, %r12
movq %r12, %rdi
xorl %esi, %esi
movq %r15, %rdx
movq %r14, %rcx
callq 0x2430
incq %r14
movslq 0x6f6f(%rip), %rax      # 0xb268
addq $0x8, %r12
cmpq %rax, %r14
jl 0x42df
testl %eax, %eax
jle 0x4323
xorl %r14d, %r14d
movq (%rbx,%r14,8), %rdi
xorl %esi, %esi
callq 0x21e0
incq %r14
movslq 0x6f4a(%rip), %rax      # 0xb268
cmpq %rax, %r14
jl 0x4309
leaq 0x7006(%rip), %rdi      # 0xb330
leaq 0x2dd8(%rip), %rsi      # 0x7109
callq 0x22a0
movq %rax, %r14
movq 0x7170(%rip), %r15      # 0xb4b0
testq %r15, %r15
je 0x47dc
movq %r14, 0x10(%rsp)
leaq (,%r15,4), %rdi
callq 0x2300
movq %rax, %r14
movq 0x712b(%rip), %r13      # 0xb490
movl $0x4, %esi
movq %r13, %rdi
callq 0x2160
movq %rax, 0x8(%rsp)
movq 0x6efa(%rip), %rbx      # 0xb278
movq %rbx, %rdi
imulq %r15, %rdi
movl $0x4, %esi
callq 0x2160
movq %rax, %r12
movq %r15, %rax
shlq $0x20, %rax
movq %rax, 0x18(%rsp)
movslq %r15d, %rbp
movq 0x8(%rsp), %rdi
testq %r13, %r13
jle 0x4449
leaq 0x1(%r13), %rsi
andq $-0x2, %rsi
leaq -0x1(%r13), %rax
movq %rax, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
movdqa 0x2c63(%rip), %xmm1     # 0x7030
xorl %ecx, %ecx
movdqa 0x2c69(%rip), %xmm2     # 0x7040
pxor %xmm2, %xmm0
pcmpeqd %xmm3, %xmm3
movdqa 0x2c79(%rip), %xmm4     # 0x7060
movdqa %xmm1, %xmm5
pxor %xmm2, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
movd %xmm5, %eax
notl %eax
testb $0x1, %al
je 0x4422
movq %rcx, %rax
cqto
idivq %rbp
movl %edx, (%rdi,%rcx,4)
pxor %xmm3, %xmm5
pextrw $0x4, %xmm5, %eax
testb $0x1, %al
je 0x443c
leaq 0x1(%rcx), %rax
cqto
idivq %rbp
movl %edx, 0x4(%rdi,%rcx,4)
addq $0x2, %rcx
paddq %xmm4, %xmm1
cmpq %rcx, %rsi
jne 0x43e7
sarq $0x1e, 0x18(%rsp)
leaq 0x3(%rbp), %rax
movabsq $0x7ffffffffffffffc, %r15 # imm = 0x7FFFFFFFFFFFFFFC
andq %rax, %r15
leaq -0x1(%rbp), %rax
movq %rax, %xmm0
pshufd $0x44, %xmm0, %xmm5     # xmm5 = xmm0[0,1,0,1]
xorl %eax, %eax
movdqa 0x2bc8(%rip), %xmm6     # 0x7040
pxor %xmm6, %xmm5
pcmpeqd %xmm7, %xmm7
movdqa %xmm5, 0x30(%rsp)
movq %r15, 0x28(%rsp)
movq %rax, 0x20(%rsp)
movq %rbx, %rax
imulq %rbp, %rax
testq %rax, %rax
jle 0x44c1
movq 0x18(%rsp), %rdx
imulq %rbx, %rdx
movq %r12, %rdi
xorl %esi, %esi
callq 0x2150
pcmpeqd %xmm7, %xmm7
movdqa 0x2b85(%rip), %xmm6     # 0x7040
movdqa 0x30(%rsp), %xmm5
testq %rbp, %rbp
movq 0x8(%rsp), %r10
jle 0x459e
xorl %eax, %eax
movdqa 0x2b57(%rip), %xmm0     # 0x7030
movdqa 0x2b8f(%rip), %xmm1     # 0x7070
movdqa %xmm0, %xmm2
pxor %xmm6, %xmm2
movdqa %xmm2, %xmm3
pcmpgtd %xmm5, %xmm3
pcmpeqd %xmm5, %xmm2
pshufd $0xf5, %xmm2, %xmm4     # xmm4 = xmm2[1,1,3,3]
pand %xmm3, %xmm4
pshufd $0xf5, %xmm3, %xmm2     # xmm2 = xmm3[1,1,3,3]
por %xmm4, %xmm2
movd %xmm2, %ecx
notl %ecx
testb $0x1, %cl
je 0x451a
movl $0x1, (%r14,%rax,4)
pxor %xmm7, %xmm2
pextrw $0x4, %xmm2, %ecx
testb $0x1, %cl
je 0x4531
movl $0x1, 0x4(%r14,%rax,4)
movdqa %xmm1, %xmm2
pxor %xmm6, %xmm2
movdqa %xmm2, %xmm3
pcmpgtd %xmm5, %xmm3
pcmpeqd %xmm5, %xmm2
pshufd $0xf5, %xmm2, %xmm4     # xmm4 = xmm2[1,1,3,3]
pand %xmm3, %xmm4
pshufd $0xf5, %xmm3, %xmm2     # xmm2 = xmm3[1,1,3,3]
por %xmm4, %xmm2
pxor %xmm7, %xmm2
pextrw $0x0, %xmm2, %ecx
testb $0x1, %cl
je 0x456e
movl $0x1, 0x8(%r14,%rax,4)
pextrw $0x4, %xmm2, %ecx
testb $0x1, %cl
je 0x4581
movl $0x1, 0xc(%r14,%rax,4)
addq $0x4, %rax
movdqa 0x2af3(%rip), %xmm2     # 0x7080
paddq %xmm2, %xmm0
paddq %xmm2, %xmm1
cmpq %rax, %r15
jne 0x44e1
testq %r13, %r13
jle 0x45fa
movq 0x6f16(%rip), %rax      # 0xb4c0
leaq (,%rbx,4), %rcx
xorl %edx, %edx
testq %rbx, %rbx
jle 0x45e7
movslq (%r10,%rdx,4), %rsi
movq %rbx, %rdi
imulq %rsi, %rdi
leaq (%r12,%rdi,4), %rdi
xorl %r8d, %r8d
movss (%rax,%r8,4), %xmm0
addss (%rdi,%r8,4), %xmm0
movss %xmm0, (%rdi,%r8,4)
incq %r8
cmpq %r8, %rbx
jne 0x45cb
jmp 0x45eb
movslq (%r10,%rdx,4), %rsi
incl (%r14,%rsi,4)
incq %rdx
addq %rcx, %rax
cmpq %r13, %rdx
jne 0x45b4
testq %rbp, %rbp
jle 0x46c0
xorl %r13d, %r13d
xorl %r15d, %r15d
testq %rbx, %rbx
jle 0x4647
xorps %xmm1, %xmm1
cvtsi2ssl (%r14,%r15,4), %xmm1
movq %rbx, %rax
imulq %r13, %rax
addq %r12, %rax
pxor %xmm0, %xmm0
xorl %ecx, %ecx
movss (%rax,%rcx,4), %xmm2
divss %xmm1, %xmm2
movss %xmm2, (%rax,%rcx,4)
mulss %xmm2, %xmm2
addss %xmm2, %xmm0
incq %rcx
cmpq %rcx, %rbx
jne 0x4627
jmp 0x464b
pxor %xmm0, %xmm0
ucomiss 0x2a72(%rip), %xmm0     # 0x70c4
jb 0x465a
sqrtss %xmm0, %xmm0
jmp 0x4671
callq 0x2420
pcmpeqd %xmm7, %xmm7
movdqa 0x29d5(%rip), %xmm6     # 0x7040
movdqa 0x30(%rsp), %xmm5
movq 0x6c00(%rip), %rbx      # 0xb278
testq %rbx, %rbx
jle 0x469f
movq %rbx, %rax
imulq %r13, %rax
addq %r12, %rax
xorl %ecx, %ecx
movss (%rax,%rcx,4), %xmm1
divss %xmm0, %xmm1
movss %xmm1, (%rax,%rcx,4)
incq %rcx
cmpq %rcx, %rbx
jne 0x4689
incq %r15
addq $0x4, %r13
cmpq %rbp, %r15
jne 0x4609
movq 0x6dda(%rip), %r13      # 0xb490
movq 0x8(%rsp), %r10
movq 0x28(%rsp), %r15
testq %r13, %r13
jle 0x474e
movq 0x6df0(%rip), %rax      # 0xb4c0
leaq (,%rbx,4), %rcx
xorl %edx, %edx
xorl %esi, %esi
testq %rbp, %rbp
jle 0x472b
movq %r12, %rdi
movss 0x29d4(%rip), %xmm0     # 0x70c0
xorl %r8d, %r8d
xorps %xmm1, %xmm1
testq %rbx, %rbx
jle 0x4712
xorl %r9d, %r9d
movss (%rdi,%r9,4), %xmm2
mulss (%rax,%r9,4), %xmm2
addss %xmm2, %xmm1
incq %r9
cmpq %r9, %rbx
jne 0x46fa
ucomiss %xmm0, %xmm1
cmoval %r8d, %esi
maxss %xmm0, %xmm1
incq %r8
addq %rcx, %rdi
movaps %xmm1, %xmm0
cmpq %rbp, %r8
jne 0x46ef
movl %esi, (%r10,%rdx,4)
incq %rdx
addq %rcx, %rax
cmpq %r13, %rdx
jne 0x46da
movq 0x20(%rsp), %rax
incq %rax
cmpq $0xa, %rax
jne 0x448b
jmp 0x4771
movq 0x20(%rsp), %rax
incq %rax
cmpq $0xa, %rax
jne 0x448b
jmp 0x47b8
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testq %r13, %r13
jle 0x47b8
movl $0x4, %ebx
leaq 0x2a08(%rip), %r13      # 0x718a
xorl %r15d, %r15d
movq 0x6cec(%rip), %rax      # 0xb478
movq (%rax,%rbx,4), %rdx
movq 0x8(%rsp), %rax
movl (%rax,%r15,4), %ecx
movq 0x10(%rsp), %rdi
movq %r13, %rsi
xorl %eax, %eax
callq 0x2330
incq %r15
addq $0xa, %rbx
cmpq 0x6cda(%rip), %r15      # 0xb490
jl 0x4785
movq %r14, %rdi
callq 0x22b0
movq %r12, %rdi
callq 0x22b0
movq 0x8(%rsp), %rdi
callq 0x22b0
movq 0x10(%rsp), %r14
jmp 0x48e7
movq 0x6cad(%rip), %rdx      # 0xb490
movq 0x6a8e(%rip), %rcx      # 0xb278
leaq 0x2985(%rip), %rsi      # 0x7176
movq %r14, %rdi
xorl %eax, %eax
callq 0x2330
cmpq $0x0, 0x6c8d(%rip)      # 0xb490
jle 0x48e7
leaq 0x2975(%rip), %r15      # 0x7185
xorl %ebx, %ebx
xorl %r12d, %r12d
movq 0x6c5c(%rip), %rax      # 0xb478
leaq (%r12,%r12,4), %rcx
movq 0x10(%rax,%rcx,8), %rdx
movq %r14, %r13
movq %r14, %rdi
leaq 0x294f(%rip), %rsi      # 0x7181
xorl %eax, %eax
callq 0x2330
cmpl $0x0, 0x6c40(%rip)      # 0xb480
movq 0x6a31(%rip), %rdi      # 0xb278
je 0x488b
testq %rdi, %rdi
movq %r13, %r14
jle 0x48c6
xorl %r13d, %r13d
xorl %ebp, %ebp
imulq %rbx, %rdi
addq 0x6c5f(%rip), %rdi      # 0xb4c0
addq %r13, %rdi
movl $0x4, %esi
movl $0x1, %edx
movq %r14, %rcx
callq 0x2480
incq %rbp
movq 0x69f8(%rip), %rdi      # 0xb278
addq $0x4, %r13
cmpq %rdi, %rbp
jl 0x4856
jmp 0x48c6
testq %rdi, %rdi
movq %r13, %r14
jle 0x48c6
xorl %r13d, %r13d
imulq %rbx, %rdi
addq 0x6c1f(%rip), %rdi      # 0xb4c0
xorps %xmm0, %xmm0
cvtss2sd (%rdi,%r13,4), %xmm0
movq %r14, %rdi
movq %r15, %rsi
movb $0x1, %al
callq 0x2330
incq %r13
movq 0x69b7(%rip), %rdi      # 0xb278
cmpq %rdi, %r13
jl 0x4896
movl $0xa, %edi
movq %r14, %rsi
callq 0x22e0
incq %r12
addq $0x4, %rbx
cmpq 0x6baf(%rip), %r12      # 0xb490
jl 0x4815
movq %r14, %rdi
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2220