void PEG(LDPC *ldpc) { int i, j; int idx; int *indicator_c = isalloc(ldpc->n_row); // 既に伸ばしたかどうか int *indicator_v = isalloc(ldpc->n_col); // 既に伸ばしたかどうか ldpc->VC_1 = isalloc_p(ldpc->n_col); ldpc->CV_1 = isalloc_p(ldpc->n_row); for(i=0;i<ldpc->n_col;i++){ ldpc->VC_1[i] = isalloc(1000); } for(i=0;i<ldpc->n_row;i++){ ldpc->CV_1[i] = isalloc(1000); } ldpc->VC_1p = isalloc(ldpc->n_col); ldpc->CV_1p = isalloc(ldpc->n_row); for(i=0;i<ldpc->n_col;i++){ for(j=0;j<ldpc->weight_col;j++){ init_iarray(indicator_c, 0, ldpc->n_row); init_iarray(indicator_v, 0, ldpc->n_col); subgraph(ldpc, i, indicator_c, indicator_v); idx = find_iminidx(ldpc->CV_1p, indicator_c, random()%ldpc->n_row, ldpc->n_row); ldpc->VC_1[i][ldpc->VC_1p[i]] = idx; ldpc->CV_1[idx][ldpc->CV_1p[idx]] = i; ldpc->VC_1p[i]++; ldpc->CV_1p[idx]++; } } free(indicator_c); free(indicator_v); }
mem_t AllocBigArray_GenConc(Proc_t *proc, Thread_t *thread, ArraySpec_t *spec) { mem_t region; ptr_t obj = NULL; /* Double length for PointerField to make MirrorPtrArray */ int specByteLen = spec->byteLen; int i, segments = (specByteLen <= arraySegmentSize) ? 0 : DivideUp(specByteLen, arraySegmentSize); int tagByteLen = specByteLen + 4 + 4 * segments; Align_t align = (spec->type == DoubleField) ? ((segments & 1) ? EvenWordAlign : OddWordAlign) : NoWordAlign; /* Allocate the space */ assert(spec->type != PointerField); if (spec->type == MirrorPointerField) { region = AllocFromHeap(fromSpace, thread, tagByteLen, align); if (region == NULL) { GCFromC(thread, tagByteLen + 4, 1); region = AllocFromHeap(fromSpace, thread, tagByteLen, align); } } else { region = gc_large_alloc(proc, tagByteLen, align); if (region == NULL) { GCFromC(thread, 4, 1); /* not bytelen since object is not from tenured space */ region = gc_large_alloc(proc, tagByteLen, align); } } /* Should do work proportional to size of array */ /* if (GCStatus != GCOff && GCStatus != GCPendingOn && GCStatus != GCPendingAgressive) do_work(proc, CollectionRate * tagByteLen); */ assert(region != NULL); proc->segUsage.bytesAllocated += tagByteLen; /* Allocate object; update stats; initialize */ obj = region + 1 + segments; for (i=0; i<segments; i++) obj[-(2+i)] = SEGPROCEED_TAG; switch (spec->type) { case IntField : init_iarray(obj, spec->elemLen, spec->intVal); break; case PointerField : DIE("pointer array"); case MirrorPointerField : init_double_ptr_array(obj, spec->elemLen, spec->pointerVal); SetPush(&proc->work.backObjs, obj); SetPush(&proc->work.nextBackObjs, obj); break; case DoubleField : init_farray(obj, spec->elemLen, spec->doubleVal); break; } return obj; }
ptr_t AllocBigArray_Semi(Proc_t *proc, Thread_t *thread, ArraySpec_t *spec) { mem_t region; ptr_t obj; int tagByteLen = spec->byteLen + 4; /* Allocate the space */ region = AllocFromThread(thread, tagByteLen, (spec->type == DoubleField) ? OddWordAlign : NoWordAlign); if (region == NULL) { GCFromC(thread, tagByteLen + 4, 0); region = AllocFromThread(thread, tagByteLen, (spec->type == DoubleField) ? OddWordAlign : NoWordAlign); } assert(region != NULL); proc->segUsage.bytesAllocated += tagByteLen; /* Allocate object; update stats; initialize */ obj = region + 1; switch (spec->type) { case IntField : init_iarray(obj, spec->elemLen, spec->intVal); break; case PointerField : init_parray(obj, spec->elemLen, spec->pointerVal); break; case DoubleField : init_farray(obj, spec->elemLen, spec->doubleVal); break; } return obj; }
void subgraph(LDPC *ldpc, int idx, int *indicator_c, int *indicator_v) { int i, j, k, l; int cidx, vidx; static int *indicator_cl; static int *indicator_vl; static int flg = 0; int size; int psize = 0; if(!flg){ indicator_cl = isalloc(ldpc->n_row); // 伸ばし元 indicator_vl = isalloc(ldpc->n_col); // 伸ばし元 flg = 1; } init_iarray(indicator_cl, 0, ldpc->n_row); init_iarray(indicator_vl, 0, ldpc->n_col); indicator_vl[idx] = 1; // 根っこ l = 0; while(1){ // 伸ばし元の変数ノードから行くチェックノードを集める for(j=0;j<ldpc->n_col;j++){ // 伸ばし元対象じゃない場合は伸ばさない if(!indicator_vl[j]){ continue; } for(i=0;i<ldpc->VC_1p[j];i++){ cidx = ldpc->VC_1[j][i]; // 既に伸ばしたチェックノードには伸ばさない if(indicator_c[cidx]){ continue; } // そうでない場合は伸ばし元対象に加える indicator_cl[cidx] = 1; } indicator_v[j] = 1; // 伸ばしました } init_iarray(indicator_vl, 0, ldpc->n_col); // 伸ばし元のチェックノードから行く変数ノードを集める for(i=0;i<ldpc->n_row;i++){ // 伸ばし元対象でない場合は伸ばさない if(!indicator_cl[i]){ continue; } for(j=0;j<ldpc->CV_1p[i];j++){ vidx = ldpc->CV_1[i][j]; // 既に伸ばした変数ノードには伸ばさない if(indicator_v[vidx]){ continue; } // そうでない場合は伸ばし元対象に加える indicator_vl[vidx] = 1; } indicator_c[i] = 1; // 伸ばしました } // インジケータサイズ size = indicator_size(indicator_c, ldpc->n_row); // インジケータサイズが変わってない(かつldpc->n_rowより小さい) if(size==psize){ break; } // インジケータサイズがMAX(全チェックノードにいっちゃった) if(size==ldpc->n_row){ // 最後に伸ばされたインデックスは引く for(i=0;i<ldpc->n_row;i++){ indicator_c[i] -= indicator_cl[i]; } /* printf("b: %d %d\n", size, 2*l); */ break; } init_iarray(indicator_cl, 0, ldpc->n_row); psize = size; l++; } }