int main() { Buffer buffer1(10); Buffer buffer2(10); LeftToRight l2r(&buffer1, &buffer2); RightToLeft r2l(&buffer1, &buffer2); pthread_t threads[2]; pid_t pid = getpid(); printf("main pid=%d\n", pid); int rc = pthread_create(&threads[0], 0, startThread, (void *)&l2r); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(1); } rc = pthread_create(&threads[1], 0, startThread, (void *)&r2l); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(1); } pthread_join(threads[0], 0); threads[0] = 0; pthread_join(threads[1], 0); threads[1] = 0; return 0; }
/*------------------------------------------------------------------ dp_pass0 линейный проход в растре r на множестве ncut точек cut_list; vers_list - результаты для отдельных сегментов; LC - cell слева от растра ------------------------------------------------------------------*/ void dp_pass0(cell *CP, raster *rp, struct cut_elm *cutp, seg_vers **versp, int16_t n) { int16_t i,j,x; int16_t i1,i2; uchar let; int16_t cc; struct cut_elm *cut; SVERS *vers; int16_t pass; // seg_vers *cur_vers; if ((ncut=n)<2) return; LC=CP; r=rp; cut_list=cutp; vers_list=versp; iemax=ncut-1; right_dust=0; fl_b=0; connect_=1; ie1=iemax; vers=&cut_list[ie1].versm; ie2=ir=(let(vers) || dust(vers)) ? ie1-1 : ie1; ib1=ib2=0; vers=&cut_list[1].versm; if (let(vers)) ib2=1; else if (cut_list->gvarm & c_cg_cutdone) ib2=on_path(0,ie2,cut_list); iec=ib2; ibc=ie2; w1=sym_width-(sym_width>>2); w2=sym_width+(sym_width>>2); h2=r->h<<1; cut=cut_list+ie1; /* //отщепляем правые dust'ы if (dust(&cut->versm) && cut->duflm==0) { right_dust=1; iemax--; cut--; // if (dust(&cut->versm) && cut->duflm==0) iemax--; ir=ie1=ie2=iemax; } */ //крайние хорошие распознаем с сопутствующими dust'ами if (ie1 != ie2 && cut->duflm) addij(LC,r,cut_list,vers_list,ncut,ie2,ie1,0); if (ib1 != ib2) { cut=cut_list+ib2; if (cut->duflm) addij(LC,r,cut_list,vers_list,ncut,ib1,ib2,0); if ((let=cut->versm.vers[0].let)==(uchar)'ь' && !is_russian_baltic_conflict(let) || // 17.07.2001 E.P. let==(uchar)'Ь' ) fl_b=1; } if (ib2>=ie2) { addij(LC,r,cut_list,vers_list,ncut,ib1,ie1,0); goto test_right_dust; } do { if (!fl_b && iec != iemax) { #ifndef MY_DEBUG if (det_trace) #endif cg_show_rast(LC,r,"left to right",cut_list); //растр - на экран cc=l2r(&ib1,&ib2,&il); if (cc) goto finish; if (il<iemax && iec>il && (cut=cut_list+il)->dh==0 && (x=cut->x-cut_list->x) < h2 && x > sym_width>>1 && cut->versm.vers[0].prob>=190 && !not_connect_sect(0,il,cut_list)) { //оставим, как есть, и попробуем дальше i1=i2=il; cc=l2r(&i1,&i2,&i); if (cc) //дальше - хорошо, вернемся к подозрительному участку { if (debug_on) #ifndef MY_DEBUG if (det_trace) #endif { sprintf(snap_text,"right side reached, return %d-%d",0,il); cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран } ib1=i1; ib2=i2; i1=i2=il; il=i; cc=r2l(&i,&i2,&i1,0); goto finish; } } } if (ibc != 0 && abs(cut_list[ie2].x-cut_list[ib2].x)>minw) { //слева не вышло, пробуем справа налево if (debug_on) #ifndef MY_DEBUG if (det_trace) #endif { sprintf(snap_text,"left: reliable=%d advance=%d; try right",ib2,il); cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран } cc=r2l(&ir,&ie2,&ie1,2); if (cc) goto finish; if (ir>0 && ibc<ir && (cut=cut_list+ir)->dh==0 && (x=cut_list[iemax].x-cut->x) < h2 && x > sym_width>>1 && cut_list[iemax].versm.vers[0].prob>=190 && !not_connect_sect(ir,iemax,cut_list)) { //оставим, как есть, и попробуем дальше i1=i2=ie2; cc=r2l(&i,&i2,&i1,2); if (cc) //дальше - хорошо, вернемся к подозрительному участку { if (debug_on) #ifndef MY_DEBUG if (det_trace) #endif { sprintf(snap_text,"left side reached, return %d-%d",ir,iemax); cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран } ie1=i1; ie2=i2; i1=i2=ir; ir=i; cc=l2r(&i1,&i2,&i); goto finish; } } } if (abs(cut_list[ie2].x-cut_list[ib2].x)<=minw) { j=on_path(ie2,iemax,cut_list); if (j==0) break; if (ib2==0) addij(LC,r,cut_list,vers_list,ncut,0,j,0); else one_cut(cut_list[ib2].px,ib2,ie2,j); goto test_right_dust; } if (il==ie2 && (iec>il || iec==iemax) && ir==ib2 && (ibc<ir || ibc==0) && cut_list[ie2].versm.vers[0].prob>MINlet) goto finish; if (il==ie2 && (iec>il || iec==iemax) || ir==ib2 && (ibc<ir || ibc==0)) if (cut_list[ie2].versm.vers[0].prob>=190) goto finish; if (il==ir) { version *vers0; char *ilet; if (connect_ && cut_list[il].dh==0) { addij(LC,r,cut_list,vers_list,ncut,ib2,ie2,0); if (cut_list[ie2].versm.vers[0].prob>trs2) goto finish; } if (ir != ie2 && cut_list[ie2].x-cut_list[ir].x > w2) { i1=i2=ir; if ( l2r(&i1,&i2,&i) || i>0 && on_path(i,iemax,cut_list) && cut_list[i].versm.vers[0].prob>=190) { j=on_path(ir,iemax,cut_list); vers0=&cut_list[j].versm.vers[0]; if ( (let=vers0->let)==(uchar)'т' && !is_russian_baltic_conflict(let) && // 17.07.2001 E.P. !is_russian_turkish_conflict(let) // 21.05.2002 E.P. ) ie1=j; else if ( (ilet=strchr(letters_right_to_bad,let))!=0 && !is_russian_baltic_conflict(let) // 17.07.2001 E.P. ) if (vers0->prob < prob_right_to_bad[(uchar*)ilet-letters_right_to_bad]) ie1=j; //может быть частью буквы ie2=ir; } } if (il != ib2 && cut_list[il].x-cut_list[ib2].x > w2) { i2=il; i1 = (ie2==il) ? ie1 : i2; if (r2l(&i,&i2,&i1,0) || on_path(i,ib2,cut_list) && cut_list[i2].versm.vers[0].prob>=190) { cut=cut_list+il; vers0=&cut->versm.vers[0]; if ((let=vers0->let)==(uchar)'т' && !is_russian_baltic_conflict(let) && // 17.07.2001 E.P. !is_russian_turkish_conflict(let) // 21.05.2002 E.P. ) ib1=cut->px; else if ( (ilet=strchr(letters_right_to_bad,let)) !=0 && !is_russian_baltic_conflict(let) // 17.07.2001 E.P. ) if (vers0->prob < prob_right_to_bad[(uchar*)ilet-letters_right_to_bad]) ie1=cut->px; //может быть частью буквы ib2=il; } } if (ib2==ie2) goto finish; } // if (il>ir) break; // if (iec==iemax || ibc==0 || iec<ibc) break; if (iec==iemax && ibc==0) break; connect_ = 1-connect_; } while (!connect_); if (right_dust) if (glue_right_dust()) { spec_pairs(); return; } if (debug_on) #ifndef MY_DEBUG if (det_trace) #endif { sprintf(snap_text,"right: reliable=%d advance=%d; ",ie2,ir); cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран } //не сошлись, запускаем ДП между ними if (ie1-ib1 <= 2) if (!good_path(cut_list,ncut)) { ib1=ib2=0; ie2=ie1=ncut-1; } DP: if (ie1-ib1 <= 2) { spec_pairs(); return; } il=ib1; ir=ie1; for (pass=1; pass<=4; pass++) { dp_bound(cut_list,vers_list,pass,&il,&ir); if (ir<=il) { if (ib1 != 0 || ie1 != ncut-1) spec_pairs(); //неполное ДП return; } #ifndef MY_DEBUG if (det_trace) #endif { sprintf(snap_text,"try DP %d-%d pass=%d",il,ir,pass); cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран } for ( i=il+1; i<=ir; i++ ) { if ( !ben_cut(cut_list+i) ) //разрешен на данном проходе { snap_newpoint(i); for (j=i-1; j>=il; j--) if ( !ben_cut(cut_list+j) ) if (addij(LC,r,cut_list,vers_list,ncut,j,i,0) & 8) break ; } //8-широк ий } } //pass if (ib1==0 && ie1==ncut-1) return; //полное ДП - больше нечего делать if (good_path(cut_list,ncut)) { spec_pairs(); return; } //ДП по всему участку il=0; ir=ncut-1; for (pass=1; pass<=4; pass++) { dp_bound(cut_list,vers_list,pass,&il,&ir); if (ir<=il) return; if (il>=ib1 && ir<=ie1) return; //на этом интервале уже считали /* { struct cut_elm *cute=cut_list+ir; for (cut=cut_list+(il+1); cut<cute; cut++) if ((cut->var & 0x7F)==40) break; if (cut==cute) return; //новых точек не будет } */ #ifndef MY_DEBUG if (det_trace) #endif { sprintf(snap_text,"try DP %d-%d pass=%d",il,ir,pass); cg_show_rast(LC,r,snap_text,cut_list); //растр - на экран } for ( i=il+1; i<=ir; i++ ) { if ( !ben_cut(cut_list+i) ) //разрешен на данном проходе { snap_newpoint(i); for (j=i-1; j>=il; j--) if ( !ben_cut(cut_list+j) ) if (addij(LC,r,cut_list,vers_list,ncut,j,i,0) & 8) break ; } //8-широк ий } } //pass return; test_right_dust: if (right_dust) glue_right_dust(); if (!good_path(cut_list,ncut)) { ib1=ib2=0; ie2=ie1=ncut-1; goto DP; } spec_pairs(); return; finish: if (right_dust) glue_right_dust(); spec_pairs(); return; }
/** * Constructs local part of distributed matrix. Each process holds * continuous strip of the matrix rows. * \param comm MPI communicator. * \param queue vector of command queues. * \param n Number of rows in the local part of the matrix. * \param m Local size of a vector that the matrix will be * multiplied by. Should be equal to n if the matrix is * square. * \param row Index into col and val vectors. * \param col Global column numbers of the local non-zero entries. * \param val Values of the local non-zero entries. */ SpMat(MPI_Comm comm, const std::vector<cl::CommandQueue> &queue, size_t n, size_t m, const idx_t *row, const col_t *col, const real *val ) : mpi(comm) { // Split into local and remote parts; renumber columns. std::vector<idx_t> loc_row(n + 1, 0); std::vector<idx_t> rem_row(n + 1, 0); std::vector<col_t> loc_col; std::vector<col_t> rem_col; std::vector<real> loc_val; std::vector<real> rem_val; auto col_part = mpi.restore_partitioning(m); auto part_beg = col_part[mpi.rank]; auto part_end = col_part[mpi.rank + 1]; std::set<col_t> remote_cols; for(size_t i = 0; i < n; ++i) { for(size_t j = row[i], e = row[i + 1]; j < e; ++j) { col_t c = col[j]; if (static_cast<col_t>(part_beg) <= c && c < static_cast<col_t>(part_end)) { ++loc_row[i + 1]; } else { remote_cols.insert(c); ++rem_row[i + 1]; } } } std::partial_sum(loc_row.begin(), loc_row.end(), loc_row.begin()); std::partial_sum(rem_row.begin(), rem_row.end(), rem_row.begin()); loc_col.reserve(loc_row.back()); loc_val.reserve(loc_row.back()); rem_col.reserve(rem_row.back()); rem_val.reserve(rem_row.back()); std::unordered_map<col_t,col_t> r2l(2 * remote_cols.size()); { col_t idx = 0; for(auto c = remote_cols.begin(); c != remote_cols.end(); c++) { r2l[*c] = idx++; } } for(size_t i = 0; i < n; ++i) { for(size_t j = row[i], e = row[i + 1]; j < e; ++j) { col_t c = col[j]; real v = val[j]; if (static_cast<col_t>(part_beg) <= c && c < static_cast<col_t>(part_end)) { loc_col.push_back(c - static_cast<col_t>(part_beg)); loc_val.push_back(v); } else { rem_col.push_back(r2l[c]); rem_val.push_back(v); } } } if (loc_row.back()) { loc_mtx.reset( new vex::SpMat<real, col_t, idx_t>( queue, n, m, loc_row.data(), loc_col.data(), loc_val.data()) ); } if (rem_row.back()) { rem_x.resize(queue, remote_cols.size()); rem_mtx.reset( new vex::SpMat<real, col_t, idx_t>( queue, n, remote_cols.size(), rem_row.data(), rem_col.data(), rem_val.data()) ); } exc.reset(new exchange<real>(mpi.comm, queue, col_part, remote_cols)); }