Skip to content

Commit

Permalink
fix memory leak in regions cpu backend
Browse files Browse the repository at this point in the history
  • Loading branch information
9prady9 committed Dec 14, 2016
1 parent de9ba33 commit f8590d4
Showing 1 changed file with 43 additions and 43 deletions.
86 changes: 43 additions & 43 deletions src/backend/cpu/kernel/regions.hpp
Expand Up @@ -9,6 +9,7 @@

#pragma once
#include <Array.hpp>
#include <memory.hpp>

namespace cpu
{
Expand Down Expand Up @@ -98,78 +99,77 @@ static void setUnion(LabelNode<T>* x, LabelNode<T>* y)
template<typename T>
void regions(Array<T> out, const Array<char> in, af_connectivity connectivity)
{
const af::dim4 in_dims = in.dims();
const char *in_ptr = in.get();
T *out_ptr = out.get();
const af::dim4 inDims = in.dims();
const char *inPtr = in.get();
T *outPtr = out.get();

// Map labels
typedef typename std::map<T, LabelNode<T>* > label_map_t;
typedef typename label_map_t::iterator label_map_iterator_t;
typedef typename std::unique_ptr< LabelNode<T> > UnqLabelPtr;
typedef typename std::map<T, UnqLabelPtr > LabelMap;
typedef typename LabelMap::iterator LabelMapIterator;

label_map_t lmap;
LabelMap lmap;

// Initial label
T label = (T)1;

for (int j = 0; j < (int)in_dims[1]; j++) {
for (int i = 0; i < (int)in_dims[0]; i++) {
int idx = j * in_dims[0] + i;
if (in_ptr[idx] != 0) {
for (int j = 0; j < (int)inDims[1]; j++) {
for (int i = 0; i < (int)inDims[0]; i++) {
int idx = j * inDims[0] + i;
if (inPtr[idx] != 0) {
std::vector<T> l;

// Test neighbors
if (i > 0 && out_ptr[j * (int)in_dims[0] + i-1] > 0)
l.push_back(out_ptr[j * in_dims[0] + i-1]);
if (j > 0 && out_ptr[(j-1) * (int)in_dims[0] + i] > 0)
l.push_back(out_ptr[(j-1) * in_dims[0] + i]);
if (i > 0 && outPtr[j * (int)inDims[0] + i-1] > 0)
l.push_back(outPtr[j * inDims[0] + i-1]);
if (j > 0 && outPtr[(j-1) * (int)inDims[0] + i] > 0)
l.push_back(outPtr[(j-1) * inDims[0] + i]);
if (connectivity == AF_CONNECTIVITY_8 && i > 0 &&
j > 0 && out_ptr[(j-1) * in_dims[0] + i-1] > 0)
l.push_back(out_ptr[(j-1) * in_dims[0] + i-1]);
j > 0 && outPtr[(j-1) * inDims[0] + i-1] > 0)
l.push_back(outPtr[(j-1) * inDims[0] + i-1]);
if (connectivity == AF_CONNECTIVITY_8 &&
i < (int)in_dims[0] - 1 && j > 0 && out_ptr[(j-1) * in_dims[0] + i+1] != 0)
l.push_back(out_ptr[(j-1) * in_dims[0] + i+1]);
i < (int)inDims[0] - 1 && j > 0 && outPtr[(j-1) * inDims[0] + i+1] != 0)
l.push_back(outPtr[(j-1) * inDims[0] + i+1]);

if (!l.empty()) {
T minl = l[0];
for (size_t k = 0; k < l.size(); k++) {
minl = min(l[k], minl);
label_map_iterator_t cur_map = lmap.find(l[k]);
LabelNode<T> *node = cur_map->second;
LabelMapIterator currentMap = lmap.find(l[k]);
LabelNode<T> *node = currentMap->second.get();
// Group labels of the same region under a disjoint set
for (size_t m = k+1; m < l.size(); m++)
setUnion(node, lmap.find(l[m])->second);
setUnion(node, lmap.find(l[m])->second.get());
}
// Set label to smallest neighbor label
out_ptr[idx] = minl;
}
else {
outPtr[idx] = minl;
} else {
// Insert new label in map
LabelNode<T> *node = new LabelNode<T>(label);
lmap.insert(std::pair<T, LabelNode<T>* >(label, node));
out_ptr[idx] = label++;
lmap.insert(std::make_pair(label, UnqLabelPtr(new LabelNode<T>(label))));
outPtr[idx] = label++;
}
}
}
}

std::set<T> removed;

for (int j = 0; j < (int)in_dims[1]; j++) {
for (int i = 0; i < (int)in_dims[0]; i++) {
int idx = j * (int)in_dims[0] + i;
if (in_ptr[idx] != 0) {
T l = out_ptr[idx];
label_map_iterator_t cur_map = lmap.find(l);
for (int j = 0; j < (int)inDims[1]; j++) {
for (int i = 0; i < (int)inDims[0]; i++) {
int idx = j * (int)inDims[0] + i;
if (inPtr[idx] != 0) {
T l = outPtr[idx];
LabelMapIterator currentMap = lmap.find(l);

if (cur_map != lmap.end()) {
LabelNode<T>* node = cur_map->second;
if (currentMap != lmap.end()) {
LabelNode<T>* node = currentMap->second.get();

LabelNode<T>* node_root = find(node);
out_ptr[idx] = node_root->getMinLabel();
LabelNode<T>* nodeRoot = find(node);
outPtr[idx] = nodeRoot->getMinLabel();

// Mark removed labels (those that are part of a region
// that contains a smaller label)
if (node->getMinLabel() < l || node_root->getMinLabel() < l)
if (node->getMinLabel() < l || nodeRoot->getMinLabel() < l)
removed.insert(l);
if (node->getLabel() > node->getMinLabel())
removed.insert(node->getLabel());
Expand All @@ -179,11 +179,11 @@ void regions(Array<T> out, const Array<char> in, af_connectivity connectivity)
}

// Calculate final neighbors (ensure final labels are sequential)
for (int j = 0; j < (int)in_dims[1]; j++) {
for (int i = 0; i < (int)in_dims[0]; i++) {
int idx = j * (int)in_dims[0] + i;
if (out_ptr[idx] > 0) {
out_ptr[idx] -= distance(removed.begin(), removed.lower_bound(out_ptr[idx]));
for (int j = 0; j < (int)inDims[1]; j++) {
for (int i = 0; i < (int)inDims[0]; i++) {
int idx = j * (int)inDims[0] + i;
if (outPtr[idx] > 0) {
outPtr[idx] -= distance(removed.begin(), removed.lower_bound(outPtr[idx]));
}
}
}
Expand Down

0 comments on commit f8590d4

Please sign in to comment.