Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix memory leak in regions(cpu backend) & rgb2ycbcr(api level) #1666

Merged
merged 2 commits into from Dec 19, 2016

Conversation

9prady9
Copy link
Member

@9prady9 9prady9 commented Dec 7, 2016

@9prady9 9prady9 added the fix label Dec 7, 2016
@9prady9 9prady9 added this to the v3.4.2 milestone Dec 7, 2016
@@ -178,6 +178,9 @@ void regions(Array<T> out, const Array<char> in, af_connectivity connectivity)
}
}

for (auto& mapElem: lmap)
delete mapElem.second;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better if you stored unique_ptrs in the lmap so you don't have to do this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about unique pointers, but then i thought why add another abstraction instead of just cleaning them off at the end since this object's definition and usage is local to that function. Will using unique pointers make it more efficient ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unique ptrs aren't abstractions. They are there to make this type of thing from not happening again. You should almost never use raw pointers

@@ -103,7 +104,8 @@ void regions(Array<T> out, const Array<char> in, af_connectivity connectivity)
T *out_ptr = out.get();

// Map labels
typedef typename std::map<T, LabelNode<T>* > label_map_t;
typedef typename std::unique_ptr< LabelNode<T> > UnqLabelPtr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use consistent naming conventions within a file.

// Insert new label in map
LabelNode<T> *node = new LabelNode<T>(label);
lmap.insert(std::pair<T, LabelNode<T>* >(label, node));
lmap.insert(std::pair<T, UnqLabelPtr>(label, UnqLabelPtr(new LabelNode<T>(label))));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use make_pair instead of the pair constructor.

@9prady9
Copy link
Member Author

9prady9 commented Dec 14, 2016

build arrayfire windows cpu ci

@9prady9 9prady9 requested a review from umar456 December 14, 2016 11:52
@9prady9 9prady9 changed the title fix memory leak in regions cpu backend fix memory leak in regions(cpu backend) & rgb2ycbcr(api level) Dec 14, 2016
@9prady9 9prady9 dismissed umar456’s stale review December 14, 2016 16:20

Please look at the updated changes.

indices[2] = {1, 1, 1};
Array<T> Y = createSubArray(input, indices, false);

indices[2] = {2, 2, 1};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are making another commit in this PR, can you add a comment saying why you are only assigning to indices[2] in all the 3 cases. I think it would help code readability.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shehzan10 Because he is reading the three channels into 3 different arrays ?

@9prady9 Can you check if something like createSubArray(input, {af_span, af_span, {1,1,1}}, false); works.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have left comments before the beginning of extraction of channels. In any case, i don't have any other commits left in this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know why he is doing it, but it took me a bit to realize it. That's why I said "if you are making another commit", because its not that much of a priority. It just helps anyone in the future who is going to read it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pavanky I checked by running the existing tests, why would we need copy's of original Array ? Just indexed Array's are sufficient right ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a possibility that the meta-data may not be properly altered ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@9prady9 Check my comment again. I did not say anything about copy, I was wondering if array initializers work instead of using vectors.

@9prady9
Copy link
Member Author

9prady9 commented Dec 16, 2016 via email

@9prady9 9prady9 requested a review from pavanky December 19, 2016 14:49
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only used once. It is an unnecessary indirection but not a big deal. Your call

Also. Use the using keyword for type aliasing. They are easier to read and more powerful.

using LabelMap = typename std::map<T, UnqLabelPtr>;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just one character smaller..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's easier (for me) to read because it uses the assignment style to define the alias, not because it is shorter.

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better if this was a std::array instead of a std::vector. Since std::arrays are allocated on the stack, you don't get the penalty of calling malloc.

I know its not part of this PR. Perhaps in another issue.

Copy link
Member

@pavanky pavanky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@shehzan10 shehzan10 merged commit ac943db into arrayfire:hotfix-3.4.2 Dec 19, 2016
@9prady9 9prady9 deleted the cpu_regions_mem_leak branch December 23, 2016 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants