Skip to content

Commit 03bb45a

Browse files
committed
use paryfor, update ips4o to avoid a sorting bug
1 parent 3927ac9 commit 03bb45a

File tree

6 files changed

+79
-56
lines changed

6 files changed

+79
-56
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@
3434
[submodule "deps/odgi"]
3535
path = deps/odgi
3636
url = https://github.com/vgteam/odgi.git
37+
[submodule "deps/paryfor"]
38+
path = deps/paryfor
39+
url = https://github.com/ekg/paryfor.git

CMakeLists.txt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,16 @@ ExternalProject_Add(cgranges
165165
ExternalProject_Get_property(cgranges SOURCE_DIR)
166166
set(cgranges_INCLUDE "${SOURCE_DIR}/cpp")
167167

168+
# paryfor parallel_for
169+
ExternalProject_Add(paryfor
170+
SOURCE_DIR "${CMAKE_SOURCE_DIR}/deps/paryfor"
171+
UPDATE_COMMAND ""
172+
INSTALL_COMMAND ""
173+
BUILD_COMMAND ""
174+
CONFIGURE_COMMAND "")
175+
ExternalProject_Get_property(paryfor SOURCE_DIR)
176+
set(paryfor_INCLUDE "${SOURCE_DIR}")
177+
168178
add_subdirectory(deps/spoa EXCLUDE_FROM_ALL)
169179
set(spoa_INCLUDE "${CMAKE_SOURCE_DIR}/deps/spoa/include")
170180

@@ -187,6 +197,7 @@ add_dependencies(smoothxg_objs tayweeargs)
187197
add_dependencies(smoothxg_objs gfakluge)
188198
add_dependencies(smoothxg_objs ips4o)
189199
add_dependencies(smoothxg_objs cgranges)
200+
add_dependencies(smoothxg_objs paryfor)
190201

191202
set_target_properties(smoothxg_objs PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
192203

@@ -228,7 +239,8 @@ set(smoothxg_INCLUDES
228239
"${dynamic_INCLUDE}"
229240
"${hopscotch_map_INCLUDE}"
230241
"${sparsepp_INCLUDE}"
231-
"${flathashmap_INCLUDE}")
242+
"${flathashmap_INCLUDE}"
243+
"${paryfor_INCLUDE}")
232244

233245
set(smoothxg_LIBS
234246
"${sdsl-lite_LIB}/libsdsl.a"

deps/paryfor

Submodule paryfor added at 509b28a

src/smooth.cpp

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -115,63 +115,68 @@ odgi::graph_t smooth_and_lace(const xg::XG& graph,
115115
std::vector<path_position_range_t> path_mapping;
116116
std::vector<path_position_range_t> consensus_mapping;
117117
bool add_consensus = !consensus_base_name.empty();
118-
#pragma omp parallel for schedule(dynamic, 1)
119-
for (uint64_t block_id = 0; block_id < blocks.size(); ++block_id) {
120-
//for (auto& block : blocks) {
121-
auto& block = blocks[block_id];
122-
std::string consensus_name = consensus_base_name + std::to_string(block_id);
123-
//std::cerr << "on block " << block_id+1 << " of " << blocks.size() << std::endl;
124-
block_graphs[block_id] = smooth(graph, block, consensus_name);
125-
auto& block_graph = block_graphs[block_id];
126-
if (block_graph.get_node_count() > 0) {
127-
//auto& block_graph = block_graphs.back();
128-
// record the start and end paths
129-
// nb: the path order is the same in the input block and output graph
130-
uint64_t path_id = 0;
131-
for (auto& path_range : block.path_ranges) {
132-
auto path_handle = graph.get_path_handle_of_step(path_range.begin);
133-
auto last_step = graph.get_previous_step(path_range.end);
134-
#pragma omp critical (path_mapping)
135-
path_mapping.push_back({
136-
path_handle, // target path
137-
graph.get_position_of_step(path_range.begin), // start position
138-
(graph.get_position_of_step(last_step) // end position
139-
+ graph.get_length(graph.get_handle_of_step(last_step))),
140-
path_range.begin,
141-
path_range.end,
142-
as_path_handle(++path_id),
143-
block_id
144-
});
145-
}
146-
// make the graph
118+
std::mutex path_mapping_mutex, consensus_mapping_mutex;
119+
paryfor::parallel_for<uint64_t>(
120+
0, blocks.size(),
121+
odgi::get_thread_count(),
122+
[&](uint64_t block_id, int tid) {
123+
auto& block = blocks[block_id];
124+
std::string consensus_name = consensus_base_name + std::to_string(block_id);
125+
//std::cerr << "on block " << block_id+1 << " of " << blocks.size() << std::endl;
126+
auto& block_graph = block_graphs[block_id];
127+
block_graph = smooth(graph, block, consensus_name);
128+
if (block_graph.get_node_count() > 0) {
129+
//auto& block_graph = block_graphs.back();
130+
// record the start and end paths
131+
// nb: the path order is the same in the input block and output graph
132+
uint64_t path_id = 0;
133+
for (auto& path_range : block.path_ranges) {
134+
auto path_handle = graph.get_path_handle_of_step(path_range.begin);
135+
auto last_step = graph.get_previous_step(path_range.end);
136+
{
137+
std::lock_guard<std::mutex> guard(path_mapping_mutex);
138+
path_mapping.push_back({
139+
path_handle, // target path
140+
graph.get_position_of_step(path_range.begin), // start position
141+
(graph.get_position_of_step(last_step) // end position
142+
+ graph.get_length(graph.get_handle_of_step(last_step))),
143+
path_range.begin,
144+
path_range.end,
145+
as_path_handle(++path_id),
146+
block_id
147+
});
148+
}
149+
}
150+
// make the graph
147151

148-
// record the consensus path
149-
if (add_consensus) {
150-
auto consensus_handle = block_graph.get_path_handle(consensus_name);
151-
uint64_t path_end = 0;
152-
step_handle_t empty_step;
153-
as_integers(empty_step)[0] = 0;
154-
as_integers(empty_step)[1] = 0;
155-
block_graph.for_each_step_in_path(
156-
consensus_handle,
157-
[&](const step_handle_t& step) {
158-
path_end += block_graph.get_length(block_graph.get_handle_of_step(step));
159-
});
160-
#pragma omp critical (consensus_mapping)
161-
consensus_mapping.push_back({
162-
as_path_handle(0), // consensus = 0 path handle
163-
0, // start position
164-
path_end, // end position
165-
empty_step,
166-
empty_step,
152+
// record the consensus path
153+
if (add_consensus) {
154+
auto consensus_handle = block_graph.get_path_handle(consensus_name);
155+
uint64_t path_end = 0;
156+
step_handle_t empty_step;
157+
as_integers(empty_step)[0] = 0;
158+
as_integers(empty_step)[1] = 0;
159+
block_graph.for_each_step_in_path(
167160
consensus_handle,
168-
block_id
169-
});
161+
[&](const step_handle_t& step) {
162+
path_end += block_graph.get_length(block_graph.get_handle_of_step(step));
163+
});
164+
{
165+
std::lock_guard<std::mutex> guard(consensus_mapping_mutex);
166+
consensus_mapping.push_back({
167+
as_path_handle(0), // consensus = 0 path handle
168+
0, // start position
169+
path_end, // end position
170+
empty_step,
171+
empty_step,
172+
consensus_handle,
173+
block_id
174+
});
175+
}
176+
}
170177
}
171-
// increment our block id
172-
//++block_id;
173-
}
174-
}
178+
});
179+
175180
// sort the path range mappings by path handle id, then start position
176181
// this will allow us to walk through them in order
177182
ips4o::parallel::sort(

src/smooth.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <algorithm>
77
#include <cmath>
88
#include <sstream>
9+
#include <mutex>
910
#include "spoa/spoa.hpp"
1011
#include "xg.hpp"
1112
#include "blocks.hpp"
@@ -14,6 +15,7 @@
1415
#include "odgi/unchop.hpp"
1516
#include "odgi/topological_sort.hpp"
1617
#include "odgi/dna.hpp"
18+
#include "paryfor.hpp"
1719

1820
namespace smoothxg {
1921

0 commit comments

Comments
 (0)