// File: /workspace/github_cpp_makefile_star2_O2/myudelson[P]hmm-scalable/InputUtilSt.cpp
// Function: InputUtilSt::readBin(char const*, task*)
bool InputUtilSt::readBin(const char *fn, struct task *task) {
    char c, v/*version*/;
    NDAT i;
    NDAT nread;
    FILE *fid = fopen(fn,"rb");
    
    // version
    nread = (NDAT)fread (&v, sizeof(char), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading version data from %s\n",fn);
        return false;
    }
    if( v > bin_input_file_verstion) { // we will handle earlier versions
        fprintf(stderr,"Wrong version of the data file. Expected %d, actual %d\n",(int)bin_input_file_verstion, (int)v);
        return false;
    }
    
    // N
    nread = (NDAT)fread (&i, sizeof(NDAT), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading number of rows from %s\n",fn);
        return false;
    }
    task->N = (NDAT)i;
    
    // Nst
    nread = (NDAT)fread (&i, sizeof(NDAT), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading number of rows (stacked) from %s\n",fn);
        return false;
    }
    task->Nst = (NDAT)i;
    
    // N_null
    nread = (NDAT)fread (&i, sizeof(NDAT), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading number of rows with null skills from %s\n",fn);
        return false;
    }
    task->N_null = (NDAT)i;
    
    // nO
    nread = (NDAT)fread (&i, sizeof(NDAT), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading number of observations from %s\n",fn);
        return false;
    }
    task->nO = (NPAR)i;
    
    // nG
    nread = (NDAT)fread (&i, sizeof(NDAT), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading number of groups (students) from %s\n",fn);
        return false;
    }
    task->nG = (NCAT)i;
    
    // nI
    nread = (NDAT)fread (&i, sizeof(NDAT), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading number of items from %s\n",fn);
        return false;
    }
    task->nI = (NCAT)i;
    
    // nK
    nread = (NDAT)fread (&i, sizeof(NDAT), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading number of skills from %s\n",fn);
        return false;
    }
    task->nK = (NCAT)i;
    
    // nZ
    nread = (NDAT)fread (&i, sizeof(NDAT), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading number of slices from %s\n",fn);
        return false;
    }
    task->nZ = (NPAR)i;
    if(task->nZ<1) {
        fprintf(stderr,"Number of slices should be at least 1\n");
        return true;
    }
    
    // multiskill
    nread = (NDAT)fread (&c, sizeof(char), (size_t)1, fid);
    if(nread != 1) {
        fprintf(stderr,"Error reading multiskill flag from %s\n",fn);
        return false;
    }
    task->multiskill = (NPAR)c;
    
    
    // dat_obs
//    StripedArray<NPAR> *striped_dat_obs = new StripedArray<NPAR>(fid, task->N);
//    task->dat_obs = striped_dat_obs->toArray();
    task->dat_obs = StripedArray<NPAR>::fromFileToArray(fid, task->N);
    task->dat_obs_stacked = init1D<NPAR>(task->Nst);
    task->dat_predict = initToValue2D<NUMBER>(task->N, task->nO, 0);
//    delete striped_dat_obs;

    
//    if(v==1) { // older NCAT of unsigned short
//        StripedArray<short> *dat_group_legacy = NULL;
//        StripedArray<short> *dat_skill_legacy = NULL;
//        StripedArray<short*> *dat_multiskill_legacy = NULL;
//        dat_group_legacy = new StripedArray<short>(fid, task->N);
//        for(t=0; t<task->N; t++)
//            task->dat_group[t] = (NCAT)dat_group_legacy->get(t);
//        if(task->multiskill == 0) {
//            dat_skill_legacy = new StripedArray<short>(fid, task->N);
//            for(t=0; t<task->N; t++)
//                task->dat_skill[t] = (NCAT)dat_skill_legacy->get(t);
//            delete dat_skill_legacy;
//        } else {
//            task->dat_multiskill = new StripedArray<NCAT*>(task->N,true);
//            nread = readMultiSkill(fid, param, v);
//            delete dat_multiskill_legacy;
//        }
//        delete dat_group_legacy;
//    } else {
        // dat_group
//        StripedArray<NCAT> *striped_dat_group = new StripedArray<NCAT>(fid, task->N);
//        task->dat_group = striped_dat_group->toArray();
//        delete striped_dat_group;
        task->dat_group = StripedArray<NCAT>::fromFileToArray(fid, task->N);
//    }
    
    // dat_item
//    StripedArray<NCAT> *striped_dat_item = new StripedArray<NCAT>(fid, task->N);
//    task->dat_item = striped_dat_item->toArray();
//    delete striped_dat_item;
    task->dat_item = StripedArray<NCAT>::fromFileToArray(fid, task->N);
    
    // dat_skill
    if(task->multiskill == 0) {
//        StripedArray<NCAT> *striped_dat_skill = new StripedArray<NCAT>(fid, task->N);
//        task->dat_skill = striped_dat_skill->toArray();
//        delete striped_dat_skill;
        task->dat_skill = StripedArray<NCAT>::fromFileToArray(fid, task->N);
    } else {
//            task->dat_multiskill = new StripedArray< NCAT* >(task->N,true);
//            nread = readMultiSkill(fid, param, v);
//        StripedArray<NCAT> *striped_dat_skill_stacked = new StripedArray<NCAT>(fid, task->Nst);
//        task->dat_skill_stacked = striped_dat_skill_stacked->toArray();
//        StripedArray<NCAT> *striped_dat_skill_rcount = new StripedArray<NCAT>(fid, task->N);
//        task->dat_skill_rcount = striped_dat_skill_rcount->toArray();
//        StripedArray<NCAT> *striped_dat_skill_rix = new StripedArray<NCAT>(fid, task->N);
//        task->dat_skill_rix = striped_dat_skill_rix->toArray();
//        delete striped_dat_skill_stacked;
//        delete striped_dat_skill_rcount;
//        delete striped_dat_skill_rix;
        task->dat_skill_stacked = StripedArray<NCAT>::fromFileToArray(fid, task->Nst);
        task->dat_skill_rcount = StripedArray<NCAT>::fromFileToArray(fid, task->N);
        task->dat_skill_rix = StripedArray<NCAT>::fromFileToArray(fid, task->N);
    }
    // dat_slices, only of nZ > 1
    if(task->nZ > 1) {
        NDAT szZ = (task->multiskill == 0)?task->N:task->Nst;
//        StripedArray<NPAR> *striped_dat_slice = new StripedArray<NPAR>(fid, szZ);
//        task->dat_slice = striped_dat_slice->toArray();
//        delete striped_dat_slice;
        task->dat_slice = StripedArray<NPAR>::fromFileToArray(fid, szZ);
    }
        
    string str;
    task->map_group_fwd = new map<string,NCAT>();
    task->map_group_bwd = new map<NCAT,string>();
    task->map_skill_fwd = new map<string,NCAT>();
    task->map_skill_bwd = new map<NCAT,string>();
    task->map_step_fwd = new map<string,NCAT>();
    task->map_step_bwd = new map<NCAT,string>();
    // voc_group
    for(NCAT g=0; g<task->nG; g++) {
        str = readString(fid);
        task->map_group_fwd->insert(pair<string,NCAT>(str, g));
        task->map_group_bwd->insert(pair<NCAT,string>(g, str));
    }
    
    // voc_skill
    for(NCAT k=0; k<task->nK; k++) {
        str = readString(fid);
        task->map_skill_fwd->insert(pair<string,NCAT>(str, k));
        task->map_skill_bwd->insert(pair<NCAT,string>(k, str));
    }
    
    // voc_item
    for(NCAT i=0; i<task->nI; i++) {
        str = readString(fid);
        task->map_step_fwd->insert(pair<string,NCAT>(str, i));
        task->map_step_bwd->insert(pair<NCAT,string>(i, str));
    }
    
    // build dat_obs_stacked
    NDAT co = 0;
    if(task->multiskill!=0) {
        for(NDAT t=0;t<task->N;t++) {
            for(NDAT tt=0; tt<task->dat_skill_rcount[t]; tt++) {
                task->dat_obs_stacked[c] = task->dat_obs[t];
                co++;
            }
        }
    } else {
        memcpy( task->dat_obs_stacked, task->dat_obs , sizeof(NPAR)*(size_t)task->N );
    }

    //
    // create connectivities: skill-skill, student-skill
    //
    createConnectivities(task);

    fclose(fid);
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rsi, %rbx
movq %rdi, %r15
leaq 0x8853(%rip), %rsi      # 0x10fa2
callq 0x3220
movq %rax, %r12
leaq 0x6(%rsp), %rdi
pushq $0x1
popq %rdx
movq %rdx, %rsi
movq %rax, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8d28
movsbl 0x6(%rsp), %ecx
cmpl $0x4, %ecx
jge 0x8d3e
movq %rsp, %rdi
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8d60
movq %rsp, %rdi
movl (%rdi), %eax
movl %eax, 0x8f8(%rbx)
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8d76
movq %rsp, %rdi
movl (%rdi), %eax
movl %eax, 0x8fc(%rbx)
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8d8c
movq %rsp, %rdi
movl (%rdi), %eax
movl %eax, 0x914(%rbx)
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8da2
movq %rsp, %rdi
movb (%rdi), %al
movb %al, 0x901(%rbx)
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8db5
movq %rsp, %rdi
movl (%rdi), %eax
movl %eax, 0x904(%rbx)
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8dc8
movq %rsp, %rdi
movl (%rdi), %eax
movl %eax, 0x90c(%rbx)
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8ddb
movq %rsp, %rdi
movl (%rdi), %eax
movl %eax, 0x908(%rbx)
pushq $0x4
popq %rsi
pushq $0x1
popq %rdx
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8dee
movb (%rsp), %al
movb %al, 0x910(%rbx)
testb %al, %al
jle 0x8e01
leaq 0x7(%rsp), %rdi
pushq $0x1
popq %rdx
movq %rdx, %rsi
movq %r12, %rcx
callq 0x32f0
cmpl $0x1, %eax
jne 0x8e22
movsbq 0x7(%rsp), %r14
movb %r14b, 0x920(%rbx)
movl 0x8f8(%rbx), %esi
movq %r12, %rdi
callq 0x94da
movq %rax, 0x880(%rbx)
movl 0x8fc(%rbx), %edi
callq 0x92ec
movq %rax, 0x888(%rbx)
movl 0x8f8(%rbx), %edi
movsbl 0x901(%rbx), %esi
xorps %xmm0, %xmm0
callq 0x92f7
movq %rax, 0x8c8(%rbx)
movl 0x8f8(%rbx), %esi
movq %r12, %rdi
callq 0x9530
movq %rax, 0x890(%rbx)
movl 0x8f8(%rbx), %esi
movq %r12, %rdi
callq 0x9530
movq %rax, 0x8b8(%rbx)
cmpb $0x0, 0x920(%rbx)
je 0x896b
movl 0x8fc(%rbx), %esi
movq %r12, %rdi
callq 0x9530
movq %rax, 0x8a0(%rbx)
movl 0x8f8(%rbx), %esi
movq %r12, %rdi
callq 0x9530
movq %rax, 0x8a8(%rbx)
movl $0x8b0, %r15d           # imm = 0x8B0
jmp 0x8971
movl $0x898, %r15d           # imm = 0x898
movl 0x8f8(%rbx), %esi
movq %r12, %rdi
callq 0x9530
movq %rax, (%rbx,%r15)
cmpb $0x2, 0x910(%rbx)
jl 0x89ae
xorl %eax, %eax
cmpb $0x0, 0x920(%rbx)
setne %al
movl 0x8f8(%rbx,%rax,4), %esi
movq %r12, %rdi
callq 0x94da
movq %rax, 0x8c0(%rbx)
movq %r12, 0x8(%rsp)
leaq 0x48(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
pushq $0x30
popq %rdi
callq 0x31c0
movq %rax, %rcx
addq $0x8, %rcx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rax)
movaps %xmm0, (%rax)
movq %rcx, 0x18(%rax)
movq %rcx, 0x20(%rax)
andq $0x0, 0x28(%rax)
movq %rax, 0x928(%rbx)
pushq $0x30
popq %rdi
callq 0x31c0
movq %rax, %rcx
addq $0x8, %rcx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rax)
movaps %xmm0, (%rax)
movq %rcx, 0x18(%rax)
movq %rcx, 0x20(%rax)
andq $0x0, 0x28(%rax)
movq %rax, 0x930(%rbx)
pushq $0x30
popq %rdi
callq 0x31c0
movq %rax, %rcx
addq $0x8, %rcx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rax)
movaps %xmm0, (%rax)
movq %rcx, 0x18(%rax)
movq %rcx, 0x20(%rax)
andq $0x0, 0x28(%rax)
movq %rax, 0x948(%rbx)
pushq $0x30
popq %rdi
callq 0x31c0
movq %rax, %rcx
addq $0x8, %rcx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rax)
movaps %xmm0, (%rax)
movq %rcx, 0x18(%rax)
movq %rcx, 0x20(%rax)
andq $0x0, 0x28(%rax)
movq %rax, 0x950(%rbx)
pushq $0x30
popq %rdi
callq 0x31c0
movq %rax, %rcx
addq $0x8, %rcx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rax)
movaps %xmm0, (%rax)
movq %rcx, 0x18(%rax)
movq %rcx, 0x20(%rax)
andq $0x0, 0x28(%rax)
movq %rax, 0x938(%rbx)
pushq $0x30
popq %rdi
callq 0x31c0
movq %rax, %rcx
addq $0x8, %rcx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rax)
movaps %xmm0, (%rax)
movq %rcx, 0x18(%rax)
movq %rcx, 0x20(%rax)
andq $0x0, 0x28(%rax)
movq %rax, 0x940(%rbx)
xorl %r15d, %r15d
leaq 0x10(%rsp), %r12
leaq 0x38(%rsp), %r13
cmpl 0x904(%rbx), %r15d
jge 0x8b6c
movq %r12, %rdi
movq 0x8(%rsp), %rsi
callq 0x7662
movq %r13, %rdi
movq %r12, %rsi
callq 0x3250
movq %r12, %rdi
callq 0x30e0
movq 0x928(%rbx), %rbp
movq %r12, %rdi
movq %r13, %rsi
callq 0x32b0
movl %r15d, 0x30(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
callq 0x9756
movq %r12, %rdi
callq 0x30e0
movq 0x930(%rbx), %rbp
movl %r15d, 0x10(%rsp)
leaq 0x18(%rsp), %rdi
movq %r13, %rsi
callq 0x32b0
movq %rbp, %rdi
movq %r12, %rsi
callq 0x9942
leaq 0x18(%rsp), %rdi
callq 0x30e0
incl %r15d
jmp 0x8adf
xorl %r15d, %r15d
leaq 0x10(%rsp), %r12
leaq 0x38(%rsp), %r13
cmpl 0x908(%rbx), %r15d
jge 0x8c06
movq %r12, %rdi
movq 0x8(%rsp), %rsi
callq 0x7662
movq %r13, %rdi
movq %r12, %rsi
callq 0x3250
movq %r12, %rdi
callq 0x30e0
movq 0x948(%rbx), %rbp
movq %r12, %rdi
movq %r13, %rsi
callq 0x32b0
movl %r15d, 0x30(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
callq 0x9756
movq %r12, %rdi
callq 0x30e0
movq 0x950(%rbx), %rbp
movl %r15d, 0x10(%rsp)
leaq 0x18(%rsp), %rdi
movq %r13, %rsi
callq 0x32b0
movq %rbp, %rdi
movq %r12, %rsi
callq 0x9942
leaq 0x18(%rsp), %rdi
callq 0x30e0
incl %r15d
jmp 0x8b79
xorl %r15d, %r15d
leaq 0x10(%rsp), %r12
leaq 0x38(%rsp), %r13
cmpl 0x90c(%rbx), %r15d
jge 0x8ca0
movq %r12, %rdi
movq 0x8(%rsp), %rsi
callq 0x7662
movq %r13, %rdi
movq %r12, %rsi
callq 0x3250
movq %r12, %rdi
callq 0x30e0
movq 0x938(%rbx), %rbp
movq %r12, %rdi
movq %r13, %rsi
callq 0x32b0
movl %r15d, 0x30(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
callq 0x9756
movq %r12, %rdi
callq 0x30e0
movq 0x940(%rbx), %rbp
movl %r15d, 0x10(%rsp)
leaq 0x18(%rsp), %rdi
movq %r13, %rsi
callq 0x32b0
movq %rbp, %rdi
movq %r12, %rsi
callq 0x9942
leaq 0x18(%rsp), %rdi
callq 0x30e0
incl %r15d
jmp 0x8c13
cmpb $0x0, 0x920(%rbx)
je 0x8ce8
xorl %eax, %eax
movq 0x8(%rsp), %r15
movslq 0x8f8(%rbx), %rcx
cmpq %rcx, %rax
jge 0x8d07
xorl %ecx, %ecx
movq 0x8a8(%rbx), %rdx
cmpl (%rdx,%rax,4), %ecx
jge 0x8ce3
movq 0x880(%rbx), %rdx
movq 0x888(%rbx), %rsi
movb (%rdx,%rax), %dl
movb %dl, (%rsi,%r14)
incl %ecx
jmp 0x8cbe
incq %rax
jmp 0x8cb0
movq 0x880(%rbx), %rsi
movq 0x888(%rbx), %rdi
movslq 0x8f8(%rbx), %rdx
callq 0x3180
movq 0x8(%rsp), %r15
movq %rbx, %rdi
callq 0x851a
movq %r15, %rdi
callq 0x31b0
leaq 0x38(%rsp), %rdi
callq 0x30e0
movb $0x1, %bl
jmp 0x8e3f
movq 0xd2a9(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x826c(%rip), %rsi      # 0x10fa5
jmp 0x8e33
movq 0xd293(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x827a(%rip), %rsi      # 0x10fc9
xorl %ebx, %ebx
pushq $0x3
popq %rdx
xorl %eax, %eax
callq 0x32d0
jmp 0x8e3f
movq 0xd271(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x8290(%rip), %rsi      # 0x11001
jmp 0x8e33
movq 0xd25b(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x82a0(%rip), %rsi      # 0x11027
jmp 0x8e33
movq 0xd245(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x82ba(%rip), %rsi      # 0x11057
jmp 0x8e33
movq 0xd22f(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x82db(%rip), %rsi      # 0x1108e
jmp 0x8e33
movq 0xd21c(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x82f6(%rip), %rsi      # 0x110bc
jmp 0x8e33
movq 0xd209(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x8316(%rip), %rsi      # 0x110ef
jmp 0x8e33
movq 0xd1f6(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x832a(%rip), %rsi      # 0x11116
jmp 0x8e33
movq 0xd1e3(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x833f(%rip), %rsi      # 0x1113e
jmp 0x8e33
movq 0xd1d0(%rip), %rax      # 0x15fd8
movq (%rax), %rcx
leaq 0x8354(%rip), %rdi      # 0x11166
pushq $0x26
popq %rsi
pushq $0x1
popq %rdx
callq 0x3400
jmp 0x8d21
movq 0xd1af(%rip), %rax      # 0x15fd8
movq (%rax), %rdi
leaq 0x835a(%rip), %rsi      # 0x1118d
xorl %ebx, %ebx
movq %r15, %rdx
xorl %eax, %eax
callq 0x32d0
movl %ebx, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x8e85
jmp 0x8e85
jmp 0x8e68
jmp 0x8e85
jmp 0x8e76
jmp 0x8e85
jmp 0x8e85
jmp 0x8e68
jmp 0x8e85
jmp 0x8e85
jmp 0x8e76
jmp 0x8e85
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
jmp 0x8e7e
jmp 0x8e85
jmp 0x8e85
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x30e0
jmp 0x8e88
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x30e0
movq %rbx, %rdi
callq 0x3390