Skip to content

Commit

Permalink
#37 Added out-of-core CPU parallel connected components
Browse files Browse the repository at this point in the history
  • Loading branch information
carljohnsen committed Mar 18, 2024
1 parent 433cf87 commit dd57486
Show file tree
Hide file tree
Showing 7 changed files with 750 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ cpu_seq_FLAGS=-Wno-unknown-pragmas -Wno-comment -Wconversion #-Weffc++
cpu_CXX=$(cpu_seq_CXX)
cpu_FLAGS=$(cpu_seq_FLAGS) -fopenmp

LIBS=io geometry morphology diffusion histograms
LIBS=io geometry morphology diffusion histograms connected_components
TARGETS = $(foreach PLATFORM, $(PLATFORMS), $(foreach LIB, $(LIBS), $(CPP_FOLDER)/$(PLATFORM)/$(LIB)$(PYBIND_SUFFIX)))
CLEANUP = $(TARGETS) $(foreach PLATFORM, $(PLATFORMS), $(CPP_FOLDER)/$(PLATFORM)/__pycache__)
PIP_INSTALL = pip_generic
Expand Down
664 changes: 664 additions & 0 deletions src/lib/cpp/cpu/connected_components.cc

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions src/lib/cpp/cpu_seq/connected_components.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "connected_components.hh"

namespace cpu_seq {

#pragma GCC diagnostic ignored "-Wunused-parameter"
int64_t connected_components(const std::string &base_path, std::vector<int64_t> &n_labels, const idx3d &global_shape, const bool verbose) {
throw std::runtime_error("Not implemented");
}

}
10 changes: 10 additions & 0 deletions src/lib/cpp/gpu/connected_components.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "connected_components.hh"

namespace gpu {

#pragma GCC diagnostic ignored "-Wunused-parameter"
int64_t connected_components(const std::string &base_path, std::vector<int64_t> &n_labels, const idx3d &global_shape, const bool verbose) {
throw std::runtime_error("Not implemented");
}

}
31 changes: 31 additions & 0 deletions src/lib/cpp/include/connected_components.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef connected_components_h
#define connected_components_h

#include "datatypes.hh"

namespace NS {

// External Functions
int64_t connected_components(const std::string &base_path, std::vector<int64_t> &n_labels, const idx3d &global_shape, const bool verbose = false);

// Internal Functions
void apply_renaming(std::vector<int64_t> &img, const std::vector<int64_t> &to_rename);
void apply_renaming(int64_t *__restrict__ img, const int64_t n, const std::vector<int64_t> &to_rename);
void canonical_names_and_size(const std::string &path, int64_t *__restrict__ out, const int64_t n_labels, const idx3d &total_shape, const idx3d &global_shape);
std::tuple<mapping_t, mapping_t> get_mappings(const std::vector<int64_t> &a, const int64_t n_labels_a, const std::vector<int64_t> &b, const int64_t n_labels_b, const idx3d &global_shape);
std::vector<int64_t> get_sizes(const std::vector<int64_t> &img, const int64_t n_labels);
std::vector<std::vector<std::tuple<int64_t, int64_t>>> generate_adjacency_tree(const int64_t chunks);
std::vector<idx3d> merge_canonical_names(const std::vector<idx3d> &names_a, const std::vector<idx3d> &names_b);
std::vector<int64_t> merge_labels(mapping_t &mapping_a, const mapping_t &mapping_b, const std::vector<int64_t> &to_rename_b);
int64_t recount_labels(const mapping_t &mapping_a, mapping_t &mapping_b, std::vector<int64_t> &to_rename_a, std::vector<int64_t> &to_rename_b);
std::tuple<std::vector<int64_t>, std::vector<int64_t>, int64_t> relabel(const std::vector<int64_t> &a, const int64_t n_labels_a, const std::vector<int64_t> &b, const int64_t n_labels_b, const idx3d &global_shape, const bool verbose);
void rename_mapping(mapping_t &mapping_a, const std::vector<int64_t> &to_rename_other);

// Debugging functions
void print_canonical_names(const std::vector<idx3d> &names_a);
void print_mapping(const mapping_t &mapping_);
void print_rename(const std::vector<int64_t> &to_rename);

}

#endif // connected_components_h
12 changes: 12 additions & 0 deletions src/lib/cpp/include/datatypes.hh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ typedef struct {
int64_t z, y, x;
} shape_t;

// Struct for a 3d index
typedef struct {
int64_t z, y, x;
} idx3d;

// Struct for a 3d index range
struct idx3drange {
int64_t z_start, z_end, y_start, y_end, x_start, x_end;
};

// Struct for accessing the raw bits of a 32-bit float
typedef struct {
union {
Expand All @@ -81,4 +91,6 @@ typedef struct {

#define GB_VOXEL ((1024 / sizeof(voxel_type)) * 1024 * 1024)

typedef std::vector<std::unordered_set<int64_t>> mapping_t;

#endif
22 changes: 22 additions & 0 deletions src/pybind/connected_components-pybind.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "connected_components.cc"

namespace python_api {

void connected_components(const std::string &base_path, np_array<int64_t> &py_n_labels, const std::tuple<int64_t, int64_t, int64_t> &py_global_shape, const bool verbose = false) {
auto n_labels_info = py_n_labels.request();
int64_t *n_labels = static_cast<int64_t*>(n_labels_info.ptr);

std::vector<int64_t> n_labels_vec(n_labels, n_labels + n_labels_info.size);

const idx3d global_shape = {std::get<0>(py_global_shape), std::get<1>(py_global_shape), std::get<2>(py_global_shape)};

NS::connected_components(base_path, n_labels_vec, global_shape, verbose);
}

}

PYBIND11_MODULE(connected_components, m) {
m.doc() = "Connected Components"; // optional module docstring

m.def("connected_components", &python_api::connected_components, py::arg("base_path"), py::arg("np_n_labels"), py::arg("global_shape"), py::arg("verbose") = false);
}

0 comments on commit dd57486

Please sign in to comment.