-
Notifications
You must be signed in to change notification settings - Fork 49
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
Are the allocations from imfilter!
expected?
#76
Comments
It's due to padding to handle the boundary conditions. At last check it was faster to copy the entire array than it was to exploit the otherwise-clever "interior vs exterior" logic that I built into this package: ImageFiltering.jl/src/imfilter.jl Lines 709 to 724 in 920947d
A possible detail is that you might need to be careful about your kernel. If you still discover allocations try something like this: kernel = (ImageFiltering.ReshapedOneD{2,1}(centered([-1,0,1])),) If you find that necessary but opaque, I can explain later. |
Oh, BTW, also consider |
I have no idea why but calling the function with the kernel you wrote is about 5 times faster
Additional comments
|
In case I would like to use I have tried an example from the documentation:
but returns
There are many |
First some preliminaries: understand that ImageFiltering was "written against" older versions of julia; while it has been ported to 0.7/1.0 it does not take advantage of every aspect of more recent capabilities of Julia. For example, ImageFiltering places a huge premium on type-stability which was critically important in older versions of Julia. This is not as important as it used to be, but until someone spends several days taking a close look at every aspect of ImageFiltering we're stuck with the original design choices. So comments below are definitely relevant, but in some cases may only be a reflection of the current state of ImageFiltering rather than universal truths.
interesting, for me it's about 2x faster. Still a good thing, obviously, but a much smaller improvement. (It's also much slower on my machine, and that may be relevant.)
When you put
A few hints of this are in the docs but probably not with sufficient detail. Would love help fixing that, naturally.
Actually the example I gave was working along dimension 2 (which is actually "horizontal" as viewed by e.g., ImageView). For filtering along the 1st dimension just use
|
Thank you for your detailed explanation.
I get the following error:
Is it because there is no way for imfilter to know if the kernel has to be applied in the X or Y axis? (since the image is 2D but the kernel is 1D)
Actually It's a bit odd you created a tuple when you created the kernel but If I don't do it it does not work.
Thank you for your comments :) |
Looks like you need kernel = (ImageFiltering.ReshapedOneD{2,0}(centered([-1,0,1])),) (note this is Pro-tip: to understand what all this means, be aware that ImageFiltering has a lot of internal documentation accessible with help?> ImageFiltering.ReshapedOneD
ReshapedOneD{N,Npre}(data)
Return an object of dimensionality N, where data must have dimensionality 1. The axes are 0:0 for the first Npre dimensions, have the axes of data for dimension Npre+1, and are 0:0 for the remaining dimensions.
data must support eltype and ndims, but does not have to be an AbstractArray.
ReshapedOneDs allow one to specify a "filtering dimension" for a 1-dimensional filter. The trickiest part is that ImageFiltering has several sub-modules so you often have to figure out which one you need.
Regarding tuples for the kernel, see that link to the documentation about factored kernels and above about the "filter cascade." But we should add methods that support single kernels of custom type. In principle it shouldn't be necessary to mess around with this level of manual optimization; you're digging into the private interface of ImageFiltering, so expect to have to dive into the code for some explanations. |
I'm sure much has changed since, but just to let anyone landing here know, it is entirely possible to using ImageFiltering, ComputationalResources, BenchmarkTools
fun1(n, img, buff, kernel) = for i in 1:n
imfilter!(buff, img, kernel)
end
fun2(n, img, buff, kernel) = for i in 1:n
imfilter!(CPU1(Algorithm.FIR()), buff, img, kernel, NoPad(), (40:60, 40:60))
end
sz = (100, 100)
img = rand(sz...)
buff = rand(sz...)
kernel = Kernel.DoG(1)
times = (1, 1000)
bytes1 = map(times) do n
@ballocated fun1($n, $img, $buff, $kernel)
end
bytes2 = map(times) do n
@ballocated fun2($n, $img, $buff, $kernel)
end where: julia> bytes1
(1205280, 1205280000)
julia> bytes2
(0, 0)
(imfilter) pkg> st
Status `~/mwe/imfilter/Project.toml`
[ed09eef8] ComputationalResources v0.3.2
[6a3955dd] ImageFiltering v0.7.9 |
Hello,
I was trying to use
imfilter!
with an arraygx
preallocated before calling the function with the hope of not allocating memory. I see 2.31 MiB allocated. Why is it happening? (should I expect it? I did not expect any allocations if the output array was preallocated)thank you
A minimal working example:
Prints the following:
The text was updated successfully, but these errors were encountered: