size_t infer_edges(size_t nthreads, bool add_all_edges, const dBGraph *db_graph) { ctx_assert(db_graph->node_in_cols != NULL); ctx_assert(db_graph->col_edges != NULL); size_t i, num_nodes_modified = 0; status("[inferedges] Processing stream"); InferEdgesWorker *wrkrs = ctx_calloc(nthreads, sizeof(InferEdgesWorker)); for(i = 0; i < nthreads; i++) { InferEdgesWorker tmp = {.threadid = i, .nthreads = nthreads, .add_all_edges = add_all_edges, .db_graph = db_graph, .num_nodes_modified = 0}; memcpy(&wrkrs[i], &tmp, sizeof(InferEdgesWorker)); } util_run_threads(wrkrs, nthreads, sizeof(InferEdgesWorker), nthreads, infer_edges_worker); // Sum up nodes modified for(i = 0; i < nthreads; i++) num_nodes_modified += wrkrs[i].num_nodes_modified; ctx_free(wrkrs); return num_nodes_modified; }
static void run_exp_abc(const dBGraph *db_graph, bool prime_AB, size_t nthreads, size_t num_repeats, size_t max_AB_dist, bool print_failed_contigs) { ExpABCWorker *wrkrs = ctx_calloc(nthreads, sizeof(ExpABCWorker)); size_t i, j; if(max_AB_dist == 0) max_AB_dist = SIZE_MAX; for(i = 0; i < nthreads; i++) { wrkrs[i].colour = 0; wrkrs[i].nthreads = nthreads; wrkrs[i].db_graph = db_graph; wrkrs[i].prime_AB = prime_AB; wrkrs[i].num_limit = num_repeats / nthreads; wrkrs[i].max_AB_dist = max_AB_dist; wrkrs[i].print_failed_contigs = print_failed_contigs; db_node_buf_alloc(&wrkrs[i].nbuf, 1024); graph_walker_alloc(&wrkrs[i].gwlk, db_graph); rpt_walker_alloc(&wrkrs[i].rptwlk, db_graph->ht.capacity, 22); // 4MB } util_run_threads(wrkrs, nthreads, sizeof(ExpABCWorker), nthreads, run_exp_abc_thread); // Merge results size_t num_tests = 0, results[NUM_RESULT_VALUES] = {0}; size_t ab_fail_state[GRPHWLK_NUM_STATES] = {0}; size_t bc_fail_state[GRPHWLK_NUM_STATES] = {0}; for(i = 0; i < nthreads; i++) { num_tests += wrkrs[i].num_tests; for(j = 0; j < NUM_RESULT_VALUES; j++) results[j] += wrkrs[i].results[j]; for(j = 0; j < GRPHWLK_NUM_STATES; j++) ab_fail_state[j] += wrkrs[i].ab_fail_state[j]; for(j = 0; j < GRPHWLK_NUM_STATES; j++) bc_fail_state[j] += wrkrs[i].bc_fail_state[j]; db_node_buf_dealloc(&wrkrs[i].nbuf); graph_walker_dealloc(&wrkrs[i].gwlk); rpt_walker_dealloc(&wrkrs[i].rptwlk); } // Print results char nrunstr[50]; ulong_to_str(num_tests, nrunstr); status("Ran %s tests with %zu threads", nrunstr, nthreads); const char *titles[] = {"RES_ABC_SUCCESS", "RES_AB_WRONG", "RES_AB_FAILED", "RES_BC_WRONG", "RES_BC_FAILED", "RES_BC_OVERSHOT", "RES_LOST_IN_RPT", "RES_NO_TRAVERSAL"}; util_print_nums(titles, results, NUM_RESULT_VALUES, 30); status("AB_FAILED:"); graph_step_print_state_hist(ab_fail_state); status("BC_FAILED:"); graph_step_print_state_hist(bc_fail_state); ctx_free(wrkrs); }
/** * Save paths to a file. * @param gzout gzFile to write to * @param path path of output file * @param save_path_seq if true, save seq= and juncpos= for links, requires * exactly one colour in the graph * @param hdrs is array of JSON headers of input files */ void gpath_save(gzFile gzout, const char *path, size_t nthreads, bool save_path_seq, const char *cmdstr, cJSON *cmdhdr, cJSON **hdrs, size_t nhdrs, const ZeroSizeBuffer *contig_hists, size_t ncols, dBGraph *db_graph) { ctx_assert(nthreads > 0); ctx_assert(gpath_set_has_nseen(&db_graph->gpstore.gpset)); ctx_assert(ncols == db_graph->gpstore.gpset.ncols); ctx_assert(!save_path_seq || db_graph->num_of_cols == 1); // save_path => 1 colour char npaths_str[50]; ulong_to_str(db_graph->gpstore.num_paths, npaths_str); status("Saving %s paths to: %s", npaths_str, path); status(" using %zu threads", nthreads); // Write header cJSON *json = gpath_save_mkhdr(path, cmdstr, cmdhdr, hdrs, nhdrs, contig_hists, ncols, db_graph); json_hdr_gzprint(json, gzout); cJSON_Delete(json); // Print comments about the format gzputs(gzout, ctp_explanation_comment); // Multithreaded GPathSaver *wrkrs = ctx_calloc(nthreads, sizeof(GPathSaver)); pthread_mutex_t outlock; size_t i; if(pthread_mutex_init(&outlock, NULL) != 0) die("Mutex init failed"); for(i = 0; i < nthreads; i++) { wrkrs[i] = (GPathSaver){.threadid = i, .nthreads = nthreads, .save_seq = save_path_seq, .gzout = gzout, .outlock = &outlock, .db_graph = db_graph}; } // Iterate over kmers writing paths util_run_threads(wrkrs, nthreads, sizeof(*wrkrs), nthreads, gpath_save_thread); pthread_mutex_destroy(&outlock); ctx_free(wrkrs); status("[GPathSave] Graph paths saved to %s", path); }