View Full Version : nnedi3 - OpenCL rewrite
SEt
18th November 2013, 07:15
It's time to move to modern image processing platforms, i.e. OpenCL. Here is my rewrite of one of the most used and the most heavy AviSynth plugins: nnedi3.
Current (2013.12.08-beta) version: https://www.dropbox.com/s/bmemjsu7jqnlk65/nnedi3ocl_20131208.7z
Syntax: nnedi3ocl(int field, bool dh, bool Y, bool U, bool V, int nsize, int nns, int qual, int etype, int dw)
Most parameters are the same as for nnedi3. Changes:
dw - controls scaling in horizontal direction: -1 no scaling; 0 and 1 scale like field 0 and 1 with dh=true, but horizontally. Default: -1.
Default for field is dw.
Default for dh is false when dw=-1 and true otherwise.
Only nsize=0 implemented, other values are silently ignored.
pscrn, threads, opt, fapprox: removed.
nnedi3ocl is AviSynth 2.5 plugin, but supports all new planar colorspaces when used with AviSynth 2.6. For YUY2 and RGB24 support script function nnedi3x is provided; it also doesn't complain if you feed it with now removed parameters of original nnedi3.
Basic image 2x scaling is done by call nnedi3ocl(dw=1). For advanced scaling with chroma and center correction and support for YUY2 and RGB24 colorspaces use provided nnedi3x_rpow2 script function.
MTMode to use: 2.
Major speed note 1.
Original nnedi3 process not all pixels with its nnedi3 algorithm: first it runs prescreener that decides should each pixel go through nnedi3 or through cubic scaling. This is the main reason that nnedi3 works relatively fast one time and slows to a crawl some other time (for example, on grass and leaves).
Prescreener concept works welll on CPU, but quite alien to extremely parallel GPU code and was not implemented. This means that nnedi3ocl works always with constant speed and will be slower than original nnedi3 with prescreener on simple frames, but faster on complex ones.
TLDR: nnedi3ocl always does best quality mode, so can be both faster and slower than original nnedi3.
Do notice that you can combine CPU and OpenCL processing in one script by using both.
Major speed note 2.
The OpenCL code is quite optimized, but memory transfers are not. So, much time is lost there. Using high number of threads with MTMode 2 (even more than physical threads your CPU has) is the best workaround for now.
Major speed note 3.
Unlike original nnedi3 where speed mostly depended on image complexity, speed of nnedi3ocl is direct result of your hardware speed and settings used.
Each increase of nns by 1 results in speed dropping by 2x. qual=2 also around 2x slower than qual=1. This means that from fastest to slowest parameters there is 32x difference in speed.
OpenCL device preferences.
Don't bother with running the code on CPU OpenCL devices – original nnedi3 would be way faster simply due to prescreener.
For GPU AMD cards with GCN architecture are recommended. Nvidia does ok, but has disadvantage of completely using one of your CPU cores on heavy GPU computations. Intel integrated... it works there too!
Theoretical FLOPS should be good indication of performance as long as you factor in the efficiency of particular architecture. Table below provides some useful coefficients how TFLOPS scale to FPS for cards of different architectures.
In case of multiple OpenCL platforms the order of preference: AMD GPU -> any GPU -> the rest. No manual choice yet.
Multi-GPU are not supported yet, todo.
OpenCL part is open source, license is... LGPLv3? Subject to change. Host code isn't open yet; there is nothing interesting there anyway.
Somewhat unknown issue is nnedi3 nn coefficients data: no idea how they are related to licenses since it's not a code. Preprocessed but conceptually unchanged version of them is currently embeded in dll. If tritical has any issues with current situation – I'm ready to listen.
Hacking.
As you can notice, the main OpenCL part is not just open source, but actually read and realtime compiled from separate text file. You can change it and the next restart changes will be applied.
Feel free to poke at code: sometimes just adding dummy if lines (that always processed or skipped, but compiler can't deduce it) can greatly change the speed in both ways.
Another interesting speed point is #pragma unroll statements.
As for correctness, I haven't noticed the importance of several checks, so they are removed under EXTRA_CHECKS define – uncomment the line if you think you see precision-related errors.
Benchmark.
As it would be useful to get speed estimates with different hardware and speed should differ insignificantly due to non-hardware reasons, let's make "benchmark" section.
In case some modification of nnedi3ocl.cl provides you better (but still correct) result – would be interesting to see such numbers too.
The target is 1280x720 YV12 upscaling to 2560x1440 with medium settings.
FPS with no MTMode, FPS with MTMode(2,4), FPS per theoretical TFLOPS, GPU name, GPU core clock during test MHz, PCIe version (and width if not x16), CPU, nnedi3ocl version
On version 2013.12.08: (the same as 2013.11.21)
32.89 37.53 13.3 Radeon HD7870, 1100, 2, FX8350
18.33 18.82 6.9 Radeon HD5870, 850, 2, i7-920@4.0
14.68 14.96 6.9 GeForce GTX 660, 1137, 3x8, i7-3770@4.0
On version 2013.11.21: (+12% on Nvidia from 2013.11.18)
20.40 23.93 8.8 Radeon HD6950 (unlocked), 885, 2, i7-930@4.0
12.20 12.93 10.4 GeForce GTX 590 (half of dual card), 608, 2, i7-930@4.0
8.44 8.73 8.0 GeForce GTX 560, 810, ?, ?
5.28 5.48 7.4 GeForce GT 750M, 967, 1.1, i7-4700HQ@2.4
2.47 2.55 2.1 Radeon HD4870, 750?, ?, ?
2.44 2.45 2.3 GeForce GTX 275, 666, 2, i7-920@3.4
1.97 2.00 8.1 Quadro 600, 640, 2, i7-930@4.0
0.91 0.91 2.4 GeForce GT 240, 550, 2, i5-2500K@4.0
1.66 1.71 4.5 Intel HD4600, 1200, -, i7-4770@3.7
On version 2013.11.18:
35.50 48.00 12.7 Radeon HD7970, 925, 3, i7-3930K@3.2
20.40 23.93 8.8 Radeon HD6950 (unlocked), 885, 2, i7-930@4.0
20.29 22.68 4.9 GeForce GTX 780, 1006, 2, i7-3930K@3.8
17.72 22.47 8.3 Radeon HD6950 (unlocked), 885, 1.1 x4, i7-930@4.0
18.43 21.21 8.9 Radeon HD6950, 850, 2, i7-930@4.0
14.24 15.78 6.4 GeForce GTX 660 Ti, 915?, ?, ?
10.89 11.48 9.2 GeForce GTX 590 (half of dual card), 608, 2, i7-930@4.0
9.33 9.60 6.3 GeForce GTX 650 Ti Boost, 1006, 3, i7-4770k@4.3
4.65 4.90 6.6 GeForce GT 750M, 967, 1.1, i7-4700HQ@2.4
2.61 2.72 9.4 GeForce GT 555M (GDDR5), 1506, 2, i7-2670QM@2.2
1.30 1.85 6.9 GeForce GT 430, 700, 2, i7-860@2.8
1.72 1.74 7.1 Quadro 600, 640, 2, i7-930@4.0
1.66 1.71 4.5 Intel HD4600, 1200, -, i7-4770@3.7
1.38 1.38 1.3 GeForce GTX 275, 666, 2, i7-920@3.4
FPS is measured as average FPS in AVSMeter 1.7.2 at the end of this script:
SetMTMode(2,4)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl(dw=1, nns=2, qual=1)
or for versions 2013.11.22 and older:
SetMTMode(2,4)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl_rpow2(2, nns=2, qual=1)
If your FPS is terrible and you don't want to wait till the end – reduce first number in BlankClip to 100, but don't interrupt the script in the middle.
Some conclusions:
Even severely limiting PCIe bandwidth from 2 x16 to 1.1 x4 (= 8x less bandwidth) for quite fast card Radeon HD6950 doesn't change overall speed much: only 6% slower with MTMode and 13% without. So, anything starting from PCIe 2 x8 should not affect current implementation much.
There is clear correlation between FPS, theoretical FLOPS and architecture of GPUs.
TurboPascal7
18th November 2013, 07:53
So this is what you were talking about. Fancy. :)
5-15 times faster than the original here, which is a really nice benefit. i7 860 vs gtx760 connected via pci-e 2. Which is compute capability 3.0. Also, noting what version is actually required would be a good idea, imho.
dh=false being the default when it doesn't work yet seems a bit confusing though.
easyfab
18th November 2013, 10:57
Major speed note 2.
The OpenCL code is quite optimized, but memory transfers are not. So, much time is lost there. Using high number of threads with MTMode 2 (even more than physical threads your CPU has) is the best workaround for now.
Will the next generations APU resolve the memory transfer problem, as the memory will be shared between CPU and GPU ?
bcn_246
18th November 2013, 14:27
No cshift yet, ignored. Probably should be done in external script anyway.
Could somebody post such a script?
TIA
SEt
18th November 2013, 14:52
Update: dh=false should work now.
Also added "benchmark" section to first post, as it would be useful for people to get estimates what speed they can expect with different hardware.
TurboPascal7
It's unexpectedly nice that you get good speed on just CC3.0 hardware – I thought register pressure there would be too much. As for minimum required hardware – no idea, probably anything that can run OpenCL 1.1 (maybe even 1.0) will do. Just older hardware would have worse theoretical_FLOPS / real_speed ratio.
easyfab
This problem – yes, but due to their TDP constraints likely it'll still be faster to use powerful GPU on separate card even with all the transfer overhead.
DJATOM
18th November 2013, 18:32
2.61 2.72 GeForce GT 555M (GDDR5), 1506 MHz, 2, i7-2670QM@2.2GHz, 2013.11.18
lansing
18th November 2013, 18:37
9.33 9.60 Nvidia Geforce GTX 650 Ti Boost, 1006MHz, 3, i7-4770k@4.3GHz, 2013.11.18
very slow for my card, and on mt mode, only one thread out of the 8 is working, I suspect the bottleneck on the gpu side.
SEt
18th November 2013, 22:26
Updated first post, added some results of cards I have access to. Also added important clarification about relations of speed and parameters.
There is now enough results to start drawing some conclusions. Unlike what I expected in the beginning, NV cards do relatively well, but their architecture (Compute Capability) does affect the efficiency. NV CC2.0 hardware slightly more efficient than AMD VLIV4, but CC2.1 and CC3.0 are around 1.5x less efficient (btw, this inefficiency in compute workload is quite known for those CC).
Also I remembered nasty habit of NV drivers to consume one CPU core during GPU computations. It's not normal and AMD drivers don't suffer from that: during test CPU load should be insignificant.
wOxxOm
18th November 2013, 23:28
SEt, it'd be nice to have fwidth/fheight gpu-scaling (requires cshift as well), thus the scripts with nnedi3_rpow2(...).downscale_to_final_resolution(...) will run faster, and hopefully by a considerable margin, because of the reduced gpu->cpu copyback data amount.
SEt
19th November 2013, 00:15
wOxxOm, not very likely for near future – there are better places to spend effort of optimizing, cubic level downscalers are computationally cheap. As for copyback, it's slow not because it saturates PCIe bandwidth (do read first post benchmarks) but because it's implemented not quite efficiently.
wOxxOm
19th November 2013, 00:19
SEt, got it. What about combining it with some gpu-assisted degrain then?
SEt
19th November 2013, 00:20
wOxxOm, that's way more likely. No promises though.
PetitDragon
19th November 2013, 02:25
OMG! This is so fxcking greate. Thanks SEt.:thanks:
mikeyakame
19th November 2013, 10:19
20.29 22.68 Nvidia Geforce GTX780, 1006Mhz, 2, i7-3930K@3.8Ghz, 2013.11.18
GPU Load Avg. No MT was ~91%.
GPU Load Avg. MT was ~97%.
So not much headroom left for my card, and CPU load was ~8-9% for both tests.
Geforce drivers => 331.58
Terka
19th November 2013, 13:58
SEt, great job! Thank you!
Now implement phase correlation to mvtools under OpenCL and Avisynth users can celebrate.
Mystery Keeper
19th November 2013, 14:15
There are other more modern motion estimation methods around. MVTools might benefit not from just phase correlation, but from integrating more different algorythms. Also, modern motion estimation uses segmentation. MVTools could give more accurate results with currently used method combined with segmentation.
SEt
19th November 2013, 14:42
mikeyakame, your result is too low looking at FPS/TFLOPS ratio. I had much better expectations for CC3.5 hardware...
Terka, Mystery Keeper, this work is far from finished and I haven't said I'm taking MVTools rewrite... Though recently exposed through OpenCL motion estimators on Intel videocards did look interesting as you can get motion estimation basically for free from dedicated hardware, my cards have nothing like that.
olcifaraga
19th November 2013, 15:09
4.65 4.90 Nvidia Geforce GT750M, 967Mhz, 1.1, i7-4700HQ@2.4GHz, 2013.11.18
Bloax
19th November 2013, 16:54
I get ~0.2 fps upscaling 640x480 to 1280x960 on a Geforce 9800 GT (you can imagine my surprise that it could actually run this!), and I think we can easily conclude what happens on 720p->1440p :p
zero9999
19th November 2013, 17:03
Could somebody post such a script?
TIA
use this mod of nnedi3_resize16 (https://gist.github.com/line0/7547526)
yup
20th November 2013, 06:44
SEt :thanks:
Test for GTX560
GPU 1: NVIDIA GeForce GTX 560
OpenCL 1.1, GeForce GTX 560 compute units:7@1620MHz
FPS (min | max | average): 1.84 | 416268.26 | 7.43
CPU usage (average): 13%
SetMTMode(2,4), version 18 November
yup.
SEt
20th November 2013, 08:18
yup, was it with MT or without? Need both for statistics.
Selur
21st November 2013, 12:45
using a NVIDIA GeForce GTX 660 ti and
LoadPlugin("nnedi3ocl.dll")
SetMTMode(2,8)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl_rpow2(2, nns=2, qual=1)
I got:
AVSMeter 1.7.2 [AVS2.6] by Groucho2004
AviSynth 2.60, build:Sep 28 2013 [15:09:12]
Active MT Mode: 2
Number of frames: 1000
Length (hhh:mm:ss.ms): 000:00:41.708
Frame width: 2560
Frame height: 1440
Framerate: 23.976 (24000/1001)
Interlaced: No
Colorspace: YV12
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 1.93 | 419534.11 | 15.70
CPU usage (average): 13%
Thread count: 22
Physical Memory usage (peak): 569 MB
Virtual Memory usage (peak): 552 MB
Time (elapsed): 000:01:03.714
using:
LoadPlugin("nnedi3ocl.dll")
#SetMTMode(2,8)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl_rpow2(2, nns=2, qual=1)
I got:
Active MT Mode: 0
Number of frames: 1000
Length (hhh:mm:ss.ms): 000:00:41.708
Frame width: 2560
Frame height: 1440
Framerate: 23.976 (24000/1001)
Interlaced: No
Colorspace: YV12
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 11.83 | 14.50 | 14.24
CPU usage (average): 12%
Thread count: 8
Physical Memory usage (peak): 540 MB
Virtual Memory usage (peak): 535 MB
Time (elapsed): 000:01:10.224
using:
LoadPlugin("nnedi3ocl.dll")
SetMTMode(2,4)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl_rpow2(2, nns=2, qual=1)
I got:
Active MT Mode: 2
Number of frames: 1000
Length (hhh:mm:ss.ms): 000:00:41.708
Frame width: 2560
Frame height: 1440
Framerate: 23.976 (24000/1001)
Interlaced: No
Colorspace: YV12
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 3.71 | 419534.11 | 15.78
CPU usage (average): 13%
Thread count: 12
Physical Memory usage (peak): 544 MB
Virtual Memory usage (peak): 540 MB
Time (elapsed): 000:01:03.379
Cu Selur
SEt
21st November 2013, 17:18
Given how many people here turned out to use Nvidia cards, I spent some effort optimizing for them. Result is pretty consistent 15% speed boost: https://www.dropbox.com/s/exz8knrygkoznji/nnedi3ocl_update20131121.7z Don't know why I bothered though, given how Nvidia treats OpenCL (really bad, if you didn't know).
Here you can see how quite minor changes can have noticeable impact on the speed.
If you want your results included in first page table: please provide all the info! Third number (the "efficiency") is computed as your avg FPS with MTMode divided by theoretical TFLOPS on your frequency (so, lookup the reference FLOPS for your card, multiply it by your core frequency and divide by reference core frequency).
Sparktank
21st November 2013, 17:29
Was trying to participate, but Nvidia just had an update recently and it seems to give me BSOD after benchmark completes.
Currently, siphoning through the Nvidia forum for details and provide input and then falling back to previous version which didn't give me BSOD with this plugin.
And hopefully will be able to get some results up by the end of the day.
SEt
21st November 2013, 17:41
Yeah, that's Nvidia drivers today. That they are more stable than AMD is pure myth. I also got BSODs recently only from Nvidia ones.
Speed of nnedi3ocl really depends on how wise/stupid OpenCL compiler in driver was, so it's worth trying several driver versions and see if it changes anything.
Groucho2004
21st November 2013, 18:15
0.91, 0.91, 2.35, GeForce GT 240, 550, 2, i5-2500K@4GHz, 2013.11.21
I grabbed the number for FLOPS from here (http://en.wikipedia.org/wiki/GeForce_200_Series), I hope that's the right place.
olcifaraga
21st November 2013, 20:29
5.28 5.48 GeForce GT 750M, 967, 1.1, i7-4700HQ@2.4 2013.11.21
mikeyakame
21st November 2013, 20:51
@SEt
I get about a 1.6% speed increase with the 2013.11.21 build and 331.82 drivers.
I'll check more later, off to work.
lansing
22nd November 2013, 00:14
well mine went from 9.60fps to 10.69fps with mt on with the new build, 11% increase, not bad
Overdrive80
22nd November 2013, 05:16
Hi, when I execute this code:
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\nnedi3ocl.dll")
SetMTMode(2,4)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl_rpow2(2, nns=2, qual=1)
I get this error message:
http://img6.imageshack.us/img6/9097/b2vm.png
Build used is 2013.11.18. Graphic: AMD Radeon HD 4870.
What am I doing wrong??
Keiyakusha
22nd November 2013, 05:42
Did a quick test on GTX 570 with latest stable drivers, no MT mode and default settings, but there are no speed differences between the old and new version. The difference is always within 0.03 fps plus or minus with around 14.46 in total. I checked 3 times. Maybe later I'll check once more after I'll get some sleep...
BTW I used real 720p video. blankclip is a up to 80% faster even though source filter is capable of providing input with more than 500fps
yup
22nd November 2013, 07:35
Hi all!
I was out my working horse, testing both version
GPU 1: NVIDIA GeForce GTX 560
OpenCL 1.1, GeForce GTX 560 compute units:7@1620MHz
18 November cl code
SetMTMode(2,4)
FPS (min | max | average): 1.84 | 416268.26 | 7.43
CPU usage (average): 13%
noMT
FPS (min | max | average): 6.83 | 7.29 | 7.20
CPU usage (average): 13%
20 November cl code
SetMTMode(2,4)
FPS (min | max | average): 2.17 | 416267.00 | 8.73
CPU usage (average): 13%
noMT
FPS (min | max | average): 7.95 | 8.53 | 8.44
CPU usage (average): 14%
Last version give speed up more than 10%.
yup.
SEt
22nd November 2013, 12:13
Overdrive80, try this version: https://www.dropbox.com/s/oz1xz9k8mxp1nhb/nnedi3ocl_fixocl10.7z Your card only supports OpenCL 1.0 while I used 1.1 feature on it. Also note that Radeon HD4xxx not fully OpenCL "capable" (their local memory isn't conformant and emulated with global memory), so "efficiency" will be less than newer Radeons.
Keiyakusha, your speed is faster than it should be on previous version but slower than it should be on new one, huh...
The problem with real scripts is that even with MTMode Avisynth scheduling is pretty bad and you likely see not 100% GPU load. Try putting source in MTMode 2 and/or increasing number of threads.
Overdrive80
23rd November 2013, 00:00
Ok, thanks SEt. Here go my results:
- Four Threads:
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\nnedi3ocl.dll")
SetMTMode(2,4)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl_rpow2(2, nns=2, qual=1)
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 0.63 | 325290.06 | 2.55
CPU usage (average): 6%
Thread count: 9
Physical Memory usage (peak): 1123 MB
Virtual Memory usage (peak): 1123 MB
Time (elapsed): 000:06:32.524
- Eight Threads:
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\nnedi3ocl.dll")
SetMTMode(2,8)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl_rpow2(2, nns=2, qual=1)
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 0.31 | 325290.06 | 2.52
CPU usage (average): 6%
Thread count: 17
Physical Memory usage (peak): 1169 MB
Virtual Memory usage (peak): 1178 MB
Time (elapsed): 000:06:37.608
- None Threads:
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 1.95 | 2.50 | 2.47
CPU usage (average): 2%
Thread count: 2
Physical Memory usage (peak): 298 MB
Virtual Memory usage (peak): 292 MB
Time (elapsed): 000:06:44.659
Gser
23rd November 2013, 00:22
Anybody tried putting this into QTGMC yet?
Selur
23rd November 2013, 00:32
Anybody tried putting this into QTGMC yet?
"Only nsize=0 implemented, other values silently ignored."
and iirc. at least all presets use nsize 1 and up,...
checked:
# Very Very Super Ultra
# Preset groups: Placebo Slow Slower Slow Medium Fast Faster Fast Fast Fast Draft
...
EdiMode = default( EdiMode, Select( pNum, "NNEDI3", "NNEDI3", "NNEDI3", "NNEDI3", "NNEDI3", "NNEDI3", "NNEDI3", "NNEDI3", "NNEDI3", "RepYadif","Bob" ) )
NNSize = default( NNSize, Select( pNum, 1, 1, 1, 1, 5, 5, 4, 4, 4, 4, 4 ) )
-> atm. it's not really that interesting for QTGMC
SEt
23rd November 2013, 01:24
nsize=0 should be better than nsize=4, so shouldn't hurt using 0 instead of it. For other nsize it's effectively quality of connecting horizontal lines, so you can use 0 instead but quality will be worse than expected.
bcn_246
24th November 2013, 20:37
use this mod of nnedi3_resize16 (https://gist.github.com/line0/7547526)
Thanks a million. I assume it's just the nnedi3_resize16_rpow2 part thats been modded for OCL?
zero9999
26th November 2013, 01:36
Thanks a million. I assume it's just the nnedi3_resize16_rpow2 part thats been modded for OCL?
yes, ofc also calls to this function to pass on the gpu parameter.
madshi
26th November 2013, 15:08
Great work, SEt. I was planning to look into implementing NNEDI3 with OpenCL/CUDA myself for madVR. I was also considering dropping the prescreener, but I'm not sure. The prescreener might still be effective. I was thinking of splitting the processing into lines, so that one thread processes one image line. This way I hoped to be able to cache the source reads so that I have to read only 4 new source pixels for each new output pixel (if there are enough registers to store the other source pixels in). With this design maybe the prescreener would then allow each thread to finish faster if there are some pixels in the line which don't need full NNEDI3 processing. Well, anyway. I haven't even started yet, so these were just some ideas I'd been playing with in my head. Haven't looked at your OpenCL code yet, but I'll definitely do when I find some time. And thanks for going with LGPL instead of GPL. That would allow me to reuse your code for madVR, too, if I decide that your implementation idea is better than mine... :)
One thing that bothers me a bit about NNEDI3 is that it sometimes "finds" things to connect in trees, leaves and grass which makes things look a bit artificial, fractal like. So I'm wondering whether it wouldn't be a good idea to write a separate prescreener which categorizes the image into parts which have clear edge directions and other parts with rather random edge directions (= grass, leaves etc). Thoughts?
FWIW, many months ago I had asked tritical about implementing NNEDI3 in madVR, even though madVR is closed source, and he allowed it. So it seems to me he's quite generous with licensing issues, so I don't think you need to worry about that part. Haven't heard from him in a while, though. Not sure if he's still around...
wOxxOm
26th November 2013, 15:19
One thing that bothers me a bit about NNEDI3 is that it sometimes "finds" things to connect in trees, leaves and grass which makes things look a bit artificial, fractal like. So I'm wondering whether it wouldn't be a good idea to write a separate prescreener which categorizes the image into parts which have clear edge directions and other parts with rather random edge directions (= grass, leaves etc). Thoughts?
I noticed it too a long time ago and that's why I always use prescreener and then apply masked AA (sometimes nnedi-AA) where needed. Not sure if the universal content recognition algorithm is possible, but it would be great.
SEt
6th December 2013, 14:30
New version: added support for all new planar colorspaces of AviSynth 2.6 (but plugin still uses AviSynth 2.5 interfaces and still can be used with AviSynth 2.5). YUY2, RGB24 and center correction are supported by script functions nnedi3x and nnedi3x_rpow2. No changes on OpenCL side.
In would be really nice if someone can confirm/correct center correction magic in nnedi3x_rpow2 (btw, original nnedi3 does it wrong). Script tries to minimize center shift while satisfying two conditions with no/empty cshift:
1) For non-YV12 chroma must be correctly aligned with no resize.
2) For YV12 luma is not resized, but chroma is to be correctly aligned (original nnedi3_rpow2 also does it even with empty cshift).
Luma and chroma are resized no more than once (original nnedi3_rpow2 would resize chroma 2 times with YV12 and center correction), script tries to minimize resize offsets to subpixel values. For now only Spline36Resize method.
nekosama
7th December 2013, 13:40
Radeon HD7950, 930, I7-4770k@stock
[General info]
Log file created with: AVSMeter 1.5.7
Avisynth version: AviSynth 2.60, build:Sep 28 2013 [15:09:12]
Active MT Mode: 2
[Clip info]
Number of frames: 1000
Length (hhh:mm:ss.ms): 000:00:41.708
Frame width: 2560
Frame height: 1440
Framerate: 23.976 (24000/1001)
Interlaced: No
Colorspace: YV12
[Runtime info]
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 18.40 | 35.26 | 26.00
CPU usage (average): 1%
Thread count: 13
Physical Memory usage (peak): 597 MB
Virtual Memory usage (peak): 622 MB
Time (elapsed): 000:00:38.461
[Script]
SetMTMode(2,4)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl(dh=true, dw=1, nns=2, qual=1)
https://db.tt/0Sf3myc2
SEt
8th December 2013, 16:13
Minor update: better default for dh parameter and completely implemented nnedi3x_rpow2 with all fancy cases.
nekosama, your result looks too low: comparing to very similar Radeon HD7970 you should be getting around 36 fps average with MT.
Groucho2004
8th December 2013, 16:31
nekosama, your result looks too low: comparing to very similar Radeon HD7970 you should be getting around 36 fps average with MT.
His test is with a 7950, not 7970. Not sure how much difference this makes.
SEt
8th December 2013, 17:24
Of course I've scaled expected fps by their theoretical FLOPS. Radeon HD7970 is getting 48 fps as you can see in summary tables.
nekosama
9th December 2013, 19:17
nope SEt, I couldn't get higher results on my 7950 but I tried with an overclock to 1150 MHz core clock and 1350 MHz memory clock and managed to get these reults [General info]
Log file created with: AVSMeter 1.5.7
Avisynth version: AviSynth 2.60, build:Sep 28 2013 [15:09:12]
Active MT Mode: 2
[Clip info]
Number of frames: 1000
Length (hhh:mm:ss.ms): 000:00:41.708
Frame width: 2560
Frame height: 1440
Framerate: 23.976 (24000/1001)
Interlaced: No
Colorspace: YV12
[Runtime info]
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 27.38 | 46.77 | 35.56
CPU usage (average): 0%
Thread count: 13
Physical Memory usage (peak): 599 MB
Virtual Memory usage (peak): 622 MB
Time (elapsed): 000:00:28.118
[Script]
SetMTMode(2,4)
BlankClip(1000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl(dh=true, dw=1, nns=2, qual=1)
just not 36 fps :p
I even clocked my 7950 to 1170 core just to see a difference and I managed to get 50 max fps but same average speed (yeah 0.2 fps difference but that's practically none-existent)
[General info]
Log file created with: AVSMeter 1.5.7
Avisynth version: AviSynth 2.60, build:Sep 28 2013 [15:09:12]
Active MT Mode: 2
[Clip info]
Number of frames: 10000
Length (hhh:mm:ss.ms): 000:06:57.083
Frame width: 2560
Frame height: 1440
Framerate: 23.976 (24000/1001)
Interlaced: No
Colorspace: YV12
[Runtime info]
Frames processed: 10000 (0 - 9999)
FPS (min | max | average): 25.65 | 50.00 | 35.92
CPU usage (average): 0%
Thread count: 10
Physical Memory usage (peak): 620 MB
Virtual Memory usage (peak): 622 MB
Time (elapsed): 000:04:38.409
[Script]
SetMTMode(2,4)
BlankClip(10000, 1280, 720, "YV12", 24000, 1001, 0)
nnedi3ocl(dh=true, dw=1, nns=2, qual=1)
Groucho2004
9th December 2013, 19:26
@nekosama
try with the latest version of AVSMeter. The version you're using is rather old (although it should not make much difference).
SEt
10th December 2013, 00:06
nekosama, another guess: are you using old drivers? Try with latest beta ones.
madshi
23rd December 2013, 18:35
@SEt,
tried for 2 days to find a faster implementation than yours, but I have to admit that I failed. Tried lots of different approaches, but none of them were faster than yours. So congrats, you seem to have done a very good job!
Have been working with AMD's CodeXL. Surprisingly, your kernels only run at 20% occupancy on GCN, due to using too many registers. But after those 2 days of trying for myself, I have to say that AMD's OpenCL compiler pretty much sucks. It wastes registers like crazy, often without any sense. For example, I tried modifying your "float8" logic to "float4" in order to save a few registers, in the hope that this might improve occupancy and performance. But after my changes AMD's OpenCL compiler actually spent *MORE* registers on the code than before. Which makes absolutely no sense. Argh... I suppose in a few months/years, when hopefully the OpenCL compiler has matured a bit, maybe there's hope in improving the kernels further to decrease occupancy and improve performance. But for now I've given up on finding a faster/different approach.
So I've played with your kernel a bit and found a small performance improvement. You're doing:
#if defined(__GPU__) && defined(__AMD__) && __OPENCL_VERSION__ >= 110
float8 t = (float8)((*(__local float3*)&in[j][0]).s0012, *(__local float4*)&in[j][3]);
#else
float8 t = (float8)(0, in[j][0], in[j][1], in[j][2], in[j][3], in[j][4], in[j][5], in[j][6]);
#endif
#pragma unroll
for (uint i = 0; i < xdia; i++)
{
t = (float8)(t.s1234, t.s567, in[j][i+7]);
sum1 += t*w[i];
sum2 += t*w[i+8];
}
By replacing that code with the following code I got a ~ 5% performance improvement on my GCN card:
float8 t = *((__local float8*) &in[j][0]);
#pragma unroll
for (uint i = 0; i < xdia - 1; i++)
{
sum1 += t*w[i];
sum2 += t*w[i + 8];
t = (float8) (t.s1234, t.s567, in[j][i + 8]);
}
sum1 += t*w[xdia - 1];
sum2 += t*w[xdia - 1 + 8];
I haven't actually tested if my code is correct, though, so you might want to double check. Just been benchmarking so far...
One more thing: In all my image upscaling tests I've always preferred 8x4 over 8x6. I've found that 8x4 produces less weird artifacts. And my preference for 8x4 had nothing to do with performance, it was based purely on overall image quality. So I would suggest switching to 8x4 (or to offer it as an option). At least for image upscaling. Don't know if the situation is maybe different for deinterlacing. Switching to 8x4 of course also gives another nice performance boost. When only testing the "y" kernel on only one color channel, I got from 95fps to about 130fps by doing the small code change posted above, and by going from 8x6 to 8x4.
SEt
23rd December 2013, 19:23
Occupancy doesn't matter if you know what you are doing. The code was optimized for Cayman architecture, but not to the point to hurt others much. So +5% for GCN from that change is reasonable but likely hurts something else if I didn't use that obvious implementation, don't remember exact cases though. Also, your code won't run on non-AMD cards.
8x4 - maybe, it was designed to be easy subcase.
madshi
23rd December 2013, 20:43
A while ago when testing resampling algorithms with various test images I tried all the options NNEDI3 offered and to my eyes 8x4 produced the overall best results. Anyway, just my 2 cents. Feel free to ignore... :)
Personally, I think optimizing for the latest generation of GPUs makes more sense than optimizing for older generations. Of course that's only true if the gain on newer generations is not lower than the cost on older generations. So it's a balance act, of course. FWIW, I can't see a reason why the original code should be faster on any GPU than the modified code I suggested. My code simply does less work. But after my experience with the AMD OpenCL compiler I've lost trust in what appears logical, so I can't be sure.
Having only tested Y resampling before, I've now switched over to X testing. FYI, I've found that simply "reusing" the Y kernel for X (meaning: I copied the X kernel and just swapped the X/Y coordinates when reading/writing pixels) produces faster results on my GCN GPU compared to the special X kernel. However, I'm not using OpenCL buffers. Instead I'm using OpenCL image objects (D3D9 interop is based on image objects). Maybe using image objects reduces the stride memory access pattern problem? I don't know. I think I read somewhere that GPUs can optimize the cache for stride access when using image objects, so using image objects can work better than buffers for 2D data. Not sure if that is of any use to you, but wanted to mention it, just in case you want to try. If you do try, you may want to use a single channel image format ("CL_R"). That gives me similar performance to buffers (maybe a tiny bit slower), while CL_RGBA is (naturally) slower than CL_R.
SEt
23rd December 2013, 22:12
Optimizing makes most sense for what hardware you have. Your code does 1 more load or the same work depending on compiler. Data shuffles are free.
The code isn't memory bound – load/store shouldn't matter much, though x kernel does have more work.
madshi
23rd December 2013, 22:25
Why would my code use one more load? I don't see that. As far as I can see, my code should have the same number of loads, or one less, depending on compiler. And it should have one less shuffle. Please note that the loop is 1 shorter in my ocde ompared to yours.
SEt
23rd December 2013, 22:41
Ah, indeed 1 shorter – then it's the same and we are looking at compiler difference. There are no shuffles: compiler just renames registers. I guess I'll retest such sequence when resume my work on the code: there is at least one more feature I want to implement.
Tested: indeed, it's a bit slower on Cayman. Roughly the same on NV. Also, NV bluescreened during testing – and you say AMD OpenCL implementation is bad? :rolleyes:
madshi
28th December 2013, 22:40
Yeah, I've now tested my changes on all Intel, AMD and NVidia. And I have to say, NVidia's OpenCL implementation is by far the worst. Not only is it limited to OpenCL 1.1, but it also has weird effects. E.g. I wondered why you stored 68 weight floats per nnst, instead of 66 (2 empty). Now I know why: When using 66 floats, NVidia produces a corrupted image (AMD and Intel don't). Furthermore, using write_imagef() with out of range coordinates makes NVidia go bonkers. So I now basically had to add a couple "if"s just to make NVidia play nice. In comparison AMD's and Intel's OpenCL implementation worked flawless right from the start. And the latest AMD driver now also supports D3D9 interop (finally!). Still not happy with AMD's OpenCL compiler optimizations, though.
Just in case you're interested (if you want to benchmark using the y kernel for x when using image objects), here's the code I've currently ended up with. It contains several changes, though, so it might not be useful to you:
http://madshi.net/nnedi3ocl.zip
JFYI:
> your code won't run on non-AMD cards
It did run just fine on NVidia on Intel GPUs, too.
SEt
29th December 2013, 14:26
AMD interops are buggy (at least with OpenGL) and not so great speed-wise. NV works... while you have only 1 card; add second and it becomes extremely slow.
Ok if it works, but its memory accesses are not-compliant. AMD hardware allows you to break many restrictions, but NV and Intel are less forgiving as you've seen.
It looks like you are using clamp-to-edge padding instead of original mirroring. Is there much difference? I've faithfully implemented original behavior without experiments in this area.
Your code has 4 or 8 times more memory accesses then mine when reading and writing image data. I believe the kernels are not memory-bound in mine implementation, so it would be interesting to see how much speed impact it has.
madshi
29th December 2013, 16:44
I guess I could use CLK_ADDRESS_MIRRORED_REPEAT instead of CLK_ADDRESS_CLAMP. Haven't tried that yet. Will double check if that produces better edges and whether it affects performance. Thanks for the hint.
Yeah, I have to issue 8 separate image_read/writef instructions for what you're doing with one float8 assignment. However, my code doesn't seem to execute slower than yours on my GCN card. I'm not sure why. Maybe it's simply because the kernel is not memory-bound. I do notice a (small) slowdown, though, when using 16bit images instead of 8bit.
SEt
29th December 2013, 16:53
Would be interesting to see if CLK_ADDRESS_MIRRORED_REPEAT works: first of all you will have to use normalized coordinates (the question is accuracy of course) and even still repeat won't be the same type as in original nnedi3.
tObber166
30th December 2013, 16:58
When uisng nnedi3x_rpow2() , why do I get "there is no function named "lsY8" error?
madshi
30th December 2013, 18:32
Would be interesting to see if CLK_ADDRESS_MIRRORED_REPEAT works: first of all you will have to use normalized coordinates (the question is accuracy of course) and even still repeat won't be the same type as in original nnedi3.
I've double checked the mirroring, and you were right. The bottom and right most lines were black with my kernel, while they were valid image content with yours. Thanks again for bringing this to my attention. So now I added some code to my kernels to internally mirror the image_readf() calls. I liked that better than to switch to normalized coords. Seems to work fine. Image output now looks more or less identical compared to your kernel.
http://madshi.net/nnedi3ocl.zip
Do you happen to remember from the top of your head whether with a 480 height image, the first "invalid" line number 480 should it map to 479 (so that lines 479 and 480 are identical), or should it map to 478? I wasn't sure about that.
FWIW, I've done a small benchmark comparison between your and my kernels. But let me start by saying that the comparison is not fair, because my kernel only does 8x4, while yours does 8x6. So your kernel does about 50% more work. So your kernel is expected to run slower. Anyway, with my AMD 7770 GPU, my kernel runs with 92.7fps while yours runs with 64.0fps. With my Intel HD4000, mine produces 8.546fps, while yours produces 6.056fps. Would be interesting to compare the kernels with the same workload.
madshi
31st December 2013, 03:22
P.S: Tried to modify your kernel to run 8x4, too. Not sure if I did it correctly, though. At least I changed ydia to 4 and decreased the y kernel reads. Wasn't sure how to change the x kernel, though, on a quick check. So probably my edit was not complete (too many reads for x kernel). Anyway, with the changes I did I got 7.720fps with HD4000 and 85.0fps with the AMD 7770. So it seems to me that my modification of your kernels might not be slower than your original kernels, maybe even a tiny bit faster (maybe due to 2D texture cache). I'm not 100% sure, though. But it might be worth trying on your side. My code also has the following advantages:
(1) No ugly buffer stride/offset calculations.
(2) No extra padding kernels.
(3) x and y kernels are almost identical. And both kernels use the same "process_local" function.
(4) Input/output pixel bitdepth can be changed via runtime APIs, using the same kernels.
SEt
31st December 2013, 03:42
It should be -478-479-478-.
I don't have time now for comparisons, but I had plans for trying textures so definitely will test this way later.
tObber166, nnedi3x_rpow2() is AviSynth26 function and you are likely running it on 2.5. Only base plugin call nnedi3ocl() is 2.5 compatible.
madshi
31st December 2013, 10:19
It should be -478-479-478-.
Thanks.
madshi
31st December 2013, 13:37
Sorry for flooding this thread with posts. I think this will be the last one for now. At least I think I'm now done with polishing my nnedi code. The latest version now only uses one kernel for everything (padding/mirroring, x and y resampling). Which cuts down OpenCL initialization time:
http://madshi.net/nnedi3ocl.zip
I've also now run benchmarks with my kernel patched to 8x6, so I can finally deliver fair results:
AMD 7770:
x only, buffer vs image: 161.8 fps vs 199.3 fps
y only, buffer vs image: 103.8 fps vs 109.3 fps
x + y, buffer vs image: 64.0 fps vs 71.5 fps
Intel HD4000:
x only, buffer vs image: 23.22 fps vs 19.07 fps
y only, buffer vs image: 8.10 fps vs 10.36 fps
x + y, buffer vs image: 6.05 fps vs 6.77 fps
I find it interesting that your special x kernel runs noticeably faster with the HD4000, but noticeably slower with the 7770, compared to my solution which reuses the y kernel for x upscaling.
SEt
31st December 2013, 15:34
Initialization time is reduced by totally different means: dropping the compilation step. nnedi3ocl actually has code for it but it's currently disabled to allow free and intuitive modification of OpenCL part.
Also, why are you putting LGPLv2.1 license in the archive when the code is under LGPLv3?
madshi
31st December 2013, 15:36
Sorry, didn't notice the version difference. Your download didn't contain a license file, so I copied the first LGPL file I found. Will replace it with LGPLv3 right way.
DrZine
8th January 2014, 04:14
I don't have MT installed. Using Avs+ So I did the fps/tflops calculation from the none mt mode. Close to a stock 7970 :)
32.85, no MT, 11.66, Radeon HD7870, 1100, 2, FX8350, 2013.8.12
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 31.78 | 33.17 | 32.85
CPU usage (average): 0%
Thread count: 3
Physical Memory usage (peak): 62 MB
Virtual Memory usage (peak): 66 MB
Time (elapsed): 000:00:30.444
Kinda funny seeing a script run with 0% cpu usage.
SEt
8th January 2014, 11:56
Really nice result for Radeon HD7870. Though I would like to also have MTMode result to add it to the table (because without MTMode you likely don't see 100% GPU load so the fps is somewhat arbitrary lower).
0% CPU usage is exactly what you should see: all the work is on the GPU side and nothing heavy should occupy the CPU.
tObber166
8th January 2014, 20:19
i7 4770K @ Stock, GTX 780 SLI
http://i44.tinypic.com/2irucxx.jpg
SEt
8th January 2014, 20:51
tObber166, just so you know SLI or other multi-gpu configurations are not used so far, so your result is by single GTX 780.
tObber166
8th January 2014, 21:19
Yes, I am fully aware of that :)
It's just a odd habit to post full spec sometimes =)
DrZine
9th January 2014, 00:05
Really nice result for Radeon HD7870. Though I would like to also have MTMode result to add it to the table (because without MTMode you likely don't see 100% GPU load so the fps is somewhat arbitrary lower).
Ok Set, I reinstalled Alpha5 and swapped in your newest build of MT and reran the script. It should be noted that the stock clock speed on the card is 1000 mhz. I am running a small overclock. 2.56 is the stock TFLOPS for the card so that gets adjusted up to 2.816 with the overclock.
32.89, 37.53, 13.327, Radeon HD7870, 1100, 2, FX8350, 2013.12.8
SEt
9th January 2014, 00:49
So, Pitcairn takes the efficiency crown now.
You don't need to reinstall anything to switch versions of Avisynth or Avisynth+: replacing avisynth.dll is enough.
kasper93
24th January 2014, 06:37
Results on my HD5870
https://gist.github.com/kasper93/ef7b3a0b2165d56b5b0a
https://gist.github.com/kasper93/de93cad4d410a9bcb575
I find it quite strange that with SetMTMode(2,4) I get unstable fps. Is that measurements error or my GPU doesn't like MT mode? HD5870 is not newest one but well it's still quite powerful.
pie1394
24th January 2014, 11:12
My code also has the following advantages:
(1) No ugly buffer stride/offset calculations.
(2) No extra padding kernels.
(3) x and y kernels are almost identical. And both kernels use the same "process_local" function.
(4) Input/output pixel bitdepth can be changed via runtime APIs, using the same kernels.
I guess you have known about Tahiti (HD97x0) architecture, which has 12 memory channels. It is interleaved in 256 bytes with a specially designed mapping. The same channel mapping mechanism is repeated every 16KB address -- 1/3 channel conflict rate every 2KB jumping, 1/6 rate every 256bytes. Yet Pitcairn(HD78x0) has 8 channels, and Verde(HD77x0) has 4 channels --- cycled every 2KB.
After a little bit study about AMD GCN architecture's memory controller design, I think non-linear-strided frame buffer design could utilize more memory bandwidth between L2 cache and GDDR5 memory and reduce latency on fetching particular 4x4 or 8x8 2D pixel data from VRAM...
How do you think about 32-bit-pixel component with 4x4 or 8x8 tile temporary frame-buffer design? With the 8-tap filtering in both X and Y-direction, 8x8-tile seems a better choice on 256-byte-per-bank design w/o copying pixel data into CU's local memory and out again.
Groucho2004
24th January 2014, 12:21
I find it quite strange that with SetMTMode(2,4) I get unstable fps. Is that measurements error or my GPU doesn't like MT mode? HD5870 is not newest one but well it's still quite powerful.
These wild fluctuations can be observed in many multi-threaded scenarios involving SEt's Avisynth MT and I think it has to do with Avisynth's caching algorithm. It's not a measurement error and your GPU is not responsible for it.
kasper93
26th January 2014, 04:16
I see my results are in first post. To fill remaining informations, it was on i7 920@4.0, PCI-E 2.0 and GPU on stock 850 clock.
jmac698
28th January 2014, 03:31
Just to note that I got this running on a lowly GT620, GPU load was 83%, cpu went up 20% (core duo 2.66Ghz), GPU core 700MHz, GPU mem 300MHz, function 2x scale nnedi3ocl(dw=1)
Looks like I need to get avsmeter. Will update later.
BeNooL
6th February 2014, 19:17
Results running version 2013.12.08-beta on a GTX 660 (1137MHz core clock, PCIe 3.0 @ x8) with an i7 3770 @ 4.0 GHz
FPS with MTMode(2,4):
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 3.689 | 474957 | 14.96
CPU usage (average): 12%
Thread count: 16
Physical Memory usage (peak): 563 MB
Virtual Memory usage (peak): 550 MB
Time (elapsed): 000:01:06.858
FPS with no MTMode:
Frames processed: 1000 (0 - 999)
FPS (min | max | average): 10.59 | 14.93 | 14.68
CPU usage (average): 12%
Thread count: 12
Physical Memory usage (peak): 276 MB
Virtual Memory usage (peak): 272 MB
Time (elapsed): 000:01:08.134
dajaja
1st July 2014, 16:12
Hi everybody. I am am using nnedi3 with the ffdshow Avisynth plugin to deinterlace live TV (SD). The setup works pretty well, but performance is limiting nns to 0 or 1 and I would like to speed it up by switching to nnedi3ocl. My regular script is the following:
temp=nnedi3(field=3,nsize=6,nns=1,qual=1,etype=0,threads=16)
yadifmod(order=1, mode=1, field=0, edeint=temp)
I modified this to use nnedi3ocl as follows:
temp=nnedi3ocl(field=3,nsize=0,nns=1,qual=1,etype=0)
yadifmod(order=1, mode=1, field=0, edeint=temp)
Now, all I get is an interlaced image with strong ghosting. Screenshots are attached. I played with many settings, but nothing eliminates the ghosting. Avisynth is version 2.6 MT, video card is a Radeon 7790 on Catalyst 14.4.
What could be the problem?
BeNooL
2nd July 2014, 09:58
At the risk of being off topic, have you given QTGMC a try ? see http://forum.doom9.org/showthread.php?t=156028
Given it is SD content, running it live might work with moderate quality preset.
dajaja
2nd July 2014, 21:51
At the risk of being off topic, have you given QTGMC a try ? see http://forum.doom9.org/showthread.php?t=156028
Given it is SD content, running it live might work with moderate quality preset.
Yes, thanks. I have tried it before and it works with the "Very Fast" preset - but only until it crashes :D Seems to be an MT problem and I was not able to find a stable setting, yet. If I did, nnedi3ocl could be used in QTGMC, too to speed it up.
huhn
14th July 2014, 17:20
i see about 5 times blended?? frame in the one frame you showed can you post a 5 sec sample?
dajaja
20th July 2014, 20:24
i see about 5 times blended?? frame in the one frame you showed can you post a 5 sec sample?
I think I'd have to install extra software to capture it. But I don't see the advantage of looking at the video. The still shows the problem perfectly. The only thing missing is the info that if there is no movement in the video, there are of course no artifacts visible :)
Seedmanc
23rd August 2014, 04:57
Is there any chance of this plugin going x64 bit? I'm using it in a chain of graphedit-ffdshow-avisynth as a custom upscaler for ps2 emulator and having both graphedit and ffdshow available in x64, this is the only thing keeping me in 32bit.
Also noticed a weird thing, there is no nnedi3ocl_rpow2, so I have to use that nnedi3x_rpow2 from .avsi, but at the same time AVSPmod suggests that there exist a "nnedi3ocl_nnedi3ocl" function and avisynth accepts it, so it indeed exist (does the same as nnedi3ocl).
I tried all 3 custom .cl files for NVidia posted here earlier, first two made no difference in speed for me, while 3rd (posted by madshi) gave error "Unable to allocate OpenCL resources". Is there no hope for GTX 560?
SEt
23rd August 2014, 16:03
As there is no usable x64 Avisynth – no x64 version for now. This plugin wouldn't benefit from it anyway.
nnedi3ocl is basic functionality implemented as plugin. nnedi3x and nnedi3x_rpow2 – scripts that extended beyond that. Basically, what is reasonable to do in script – should be done in script.
GTX 560 should work just fine. Slower than similar Radeons or CC2.0 cards, but still ok.
huhn
23rd August 2014, 23:21
As there is no usable x64 Avisynth – no x64 version for now. This plugin wouldn't benefit from it anyway.
so this doesn't work with avisynth+ ?
SEt
24th August 2014, 00:37
It should work without problems, but Avisynth+ has no stable multithreading yet. Speed-wise now I would recommend AviSynth 2.6 with MTMode (in general, not for this plugin in particular).
huhn
24th August 2014, 05:26
my question was more about 64 bit avisynth+.
or is it still not usable and I'm just lucky the hole time?
Groucho2004
24th August 2014, 10:38
my question was more about 64 bit avisynth+.
32 Bit plugins don't work with 64 Bit Avisynth and vice versa.
or is it still not usable and I'm just lucky the hole time?
:confused:
huhn
24th August 2014, 18:23
32 Bit plugins don't work with 64 Bit Avisynth and vice versa.
i know that's why I ask.
As there is no usable x64 Avisynth – no x64 version for now. This plugin wouldn't benefit from it anyway.
my question was more about 64 bit avisynth+.
or is it still not usable and I'm just lucky the hole time?
or in short. avisynth+ 64 works fine for me but there is no 64 bit nnedi3 openCL.
and the reason is this:
As there is no usable x64 Avisynth – no x64 version for now. This plugin wouldn't benefit from it anyway.
SEt
25th August 2014, 09:58
For me Avisynth is not usable without threading.
SamKook
25th August 2014, 17:05
There is a version of avisynth+ with MT that apparently works(haven't tried it myself), there's just no official release for it.
I haven't really seen any more big reports of MT failing in the months since it appeared (in terms of its actual stability), save for the bounds checking issue with the audio cache that I reported in here and on Github. If I'm correct about that assessment, perhaps it's time to just bite the bullet and merge it to master and bump the version number to 0.2. The psychological effect of just going ahead and releasing it might help too.
P.S. It was a subtitle filter(SupTitle) that was failing in this case.
SEt
27th August 2014, 20:06
Last version of Avisynth+ I've tried had speed issues with threading rather than stability. My usual post-processing script run on it significantly slower (realtime -> not realtime). Maybe it's not hard to tweak the existing implementation for similar or better speeds, but regrettably I have absolutely no time now to dedicate there.
yup
10th December 2014, 14:06
Hi All!
how I can use nnedi3ocl for conversion 25 Hz interlaced source to 50 Hz progressive. When using nnedi3 it is simple
nnedi3(field=-2)
When I use
nneedi3ocl(field=-2)
I see doubling framerate and frame quantity, frame from 1 to N see fine, but from N+1 to 2*N it is not changed, freeze frame N.
N number frame in interlaced source.
yup.
SEt
10th December 2014, 17:56
yup, see pm.
Note: it looks like new AMD driver 14.12 broke some part of used OpenCL on HD6xxx hardware, so check other driver versions if you get corrupted results.
TheProfileth
12th January 2015, 23:14
After updating my driver on my 7970 it also no longer works and instead produces weird results where only a fraction of the screen is actually intelligible.
Asmodian
16th January 2015, 00:54
Note: it looks like new AMD driver 14.12 broke some part of used OpenCL on HD6xxx hardware, so check other driver versions if you get corrupted results.
Sounds like they broke it on the 7970 as well. :(
SEt
26th January 2015, 00:51
They confirmed the issue – let's hope it's fixed in next version. The most stable so far is 14.4 btw.
anonymlol
7th March 2015, 13:23
The script below crashes sometimes. The error points to nnedi3ocl.avsi.
(I originally posted this here (http://forum.doom9.org/showthread.php?t=162656&page=3) because I thought avs4x26x was causing the crashes.)
DGSource("src.dgi")
mrdaa2(resharpen=0)
flash3kyuu_deband_f3kdb(grainY=0, grainC=0, output_mode=2, output_depth=16)
mrdaa2 is a slightly modified version of MrdaaLame(). (http://forum.doom9.org/showthread.php?t=167480)
# modified version of mandarinka's MrdaaLame (http://forum.doom9.org/showthread.php?t=167480) by anonymlol
# Based on Daa: Anti-aliasing with contra-sharpening by Didée, modded by Terranigma for nnedi and by thetoof for merge
# fixed chroma shift by OnDeed
function Mrdaa2(clip c, float "resharpen", bool "OpenCL") {
resharpen = Default(resharpen, 0)
OpenCL = Default(OpenCL, true)
dblshift = (OpenCL) ? c.nnedi3x(field=1, dh=true).fturnright().nnedi3x(field=1, dh=true).fturnleft()
\ : c.nnedi3(field = 1,dh=true).fturnright().nnedi3(field = 1,dh=true).fturnleft()
dbl = dblshift.Spline36Resize(c.width,c.height,-0.5,-0.5,c.width*2,c.height*2).MergeChroma(dblshift.Spline36Resize(c.width,c.height,-1.0,-1.0,c.width*2,c.height*2))
dblD = mt_makediff(c,dbl,U=3,V=3)
shrpD = mt_makediff(dbl,dbl.blur(resharpen*0.2,MMX=false),U=3,V=3)
DD = shrpD.repair(dblD,13)
return dbl.mt_adddiff(DD,U=3,V=3)
}
edit: Got some errors in cmd this time: http://puu.sh/gpUdx/c37b6d35e5.png
This crashes:
dblshift = (OpenCL) ? c.nnedi3x(field=1, dh=true).fturnright().nnedi3x(field=1, dh=true).fturnleft()
\ : c.nnedi3(field = 1,dh=true).fturnright().nnedi3(field = 1,dh=true).fturnleft()
It doesn't crash when I remove the condition:
dblshift = c.nnedi3x(field=1, dh=true).fturnright().nnedi3x(field=1, dh=true).fturnleft()
I'll remove the condition for now and use it with nnedi3ocl as default.
Remove that fturn perversion – this filter can scale both height and width in one step.
MysteryX
11th July 2015, 17:35
I'm curious about something with the NNEDI3 OpenCL implementation. It has been reported to not perform any better than the standard version. Shouldn't that depend purely on the graphic card, or is the CPU still the bottleneck?
I'm currently writing code to run HLSL shaders in AviSynth, and I wonder how the NNEDI3 HLSL implementation, which runs entirely on the GPU, would compare to this performance-wise
https://github.com/zachsaw/MPDN_Extensions/tree/master/Extensions/RenderScripts/NNEDI3
Ghostlamer
15th August 2015, 16:11
Can anyone check current nnedi3 under Windows 10, works or not?, with the latest nvidia drivers.
DJATOM
12th September 2015, 16:53
Can anyone check current nnedi3 under Windows 10, works or not?, with the latest nvidia drivers.
Yup, it works on my win10pro with gtx750.
yup
13th January 2016, 08:06
Hi All!
I am upgrade my PC using Nvidia GTX 960 card (before use Intel HD4000).
Now my script with nnedi3ocl do not work, I see green output.
Any suggestions and advice please.
yup.
yup
10th February 2016, 15:17
I am try reinstall Avisynth, problem do not go.
I am also try check on another PC under Windows 10, opencl version nnedi3 work without problem.
Please advice roadmap for solving problem. If need additional info I can send.
My sytem Windows 7 64 home premium, 8 Gb, i7, GTX 960 (before internal Intel Graphics). Sytem and drivers updated.
yup.
SSH4
14th February 2016, 17:35
What with field= -2, 2 and 3?
nnedi3ocl do not have them?
-2 = double rate (alternates each frame), uses avisynth's internal parity value to start
2 = double rate (alternates each frame), starts with bottom
3 = double rate (alternates each frame), starts with top
without this not possible use nnedi3ocl in QTGMC :(
SSH4
15th February 2016, 08:05
Well. Find workaround for field=-2 in old nnedi thread.
Function nnedi3xFieldMinus2(clip Input)
{
Input.SeparateFields()
GetParity(Input) ? Interleave( SelectEven().nnedi3ocl(dh=true,Field = 1), SelectOdd().nnedi3ocl(dh=true,Field = 0) )
\ : Interleave( SelectEven().nnedi3ocl(dh=true,Field = 0), SelectOdd().nnedi3ocl(dh=true,Field = 1) )
AssumeFrameBased()
GetParity(Input) ? AssumeTFF() : AssumeBFF()
}
yup
27th February 2016, 07:54
Hi All!
I am upgrade my PC using Nvidia GTX 960 card (before use Intel HD4000).
Now my script with nnedi3ocl do not work, I see green output.
Any suggestions and advice please.
yup.
I am try reinstall Avisynth, problem do not go.
I am also try check on another PC under Windows 10, opencl version nnedi3 work without problem.
Please advice roadmap for solving problem. If need additional info I can send.
My sytem Windows 7 64 home premium, 8 Gb, i7, GTX 960 (before internal Intel Graphics). Sytem and drivers updated.
yup.
I am upgrade my PC up to Windows 10 and problem gone, now nnedi3 OpenCL plugin work fine.
Probably adding new video card broken some relations.
yup.
yup
16th March 2016, 12:07
High all!
Lucky life continue until Geforce driver updated to 362.00.
See error during load simle script in VirtyualDub
https://www.dropbox.com/s/k4gsunhr29bcwoc/nnediocl.png?dl=0
Language my windows is Russian.
Translation Video driver do not respond and was recovered,
Video driver Nvidia Windows Kernel Mode Driver , Version 362.00 do not respond and was recovered.
Any suggesrtions, please.
yup.
Bloax
16th March 2016, 16:33
Can you run other GPU-calculated things - like this (https://github.com/lltcggie/waifu2x-caffe/releases/) - without driver crashes?
If not then I can only suggest wiping (http://www.guru3d.com/files-details/display-driver-uninstaller-download.html) the drivers and installing an older version that still works.
yup
16th March 2016, 18:22
Bloax!
I spent some time for finding gui
http://forum.videohelp.com/threads/372157-New-upscaling-algorithm-waifu2x?p=2423628&viewfull=1#post2423628
I am try upscale image to 2-4 time using CUDA (not cuDNN) all work.
Also for me work without problem KNlmeansCL plugin.
yup.
Atak_Snajpera
21st March 2016, 19:12
Am I blind or this plugin does not have device_id switch like KNLMeansCL ? What opencl device will this plugin use if user has AMD APU + Dedicated AMD GPU?
Atak_Snajpera
3rd April 2016, 17:45
In case of multiple OpenCL platforms the order of preference: AMD GPU -> any GPU -> the rest. No manual choice yet.
Manual choice is a big "must have" in my opinion. I wanted to test this plugin on CPU because OpenCL support on my Radeon 4850 is very very limited (OpenCL 1.0 only). Unfortunately plugin automatically uses my GPU and this what I get
http://i.cubeupload.com/yIGcZb.png
Two options should be added device_type and device_id
Tormaid
15th April 2016, 20:06
Really great work. Any chance you'd consider making a vapoursynth version down the line?
Mangix
16th April 2016, 00:43
Manual choice is a big "must have" in my opinion. I wanted to test this plugin on CPU because OpenCL support on my Radeon 4850 is very very limited (OpenCL 1.0 only). Unfortunately plugin automatically uses my GPU and this what I get
http://i.cubeupload.com/yIGcZb.png
Two options should be added device_type and device_id
acceptable performance on CPU depends on SSE optimizations, which are not present. OpenCL is not magic.
Groucho2004
16th April 2016, 12:58
I wanted to test this plugin on CPU because OpenCL support on my Radeon 4850 is very very limited (OpenCL 1.0 only).
What's the point in using this filter instead of the "normal" nnedi3 when it's not supported by the GPU?
Atak_Snajpera
17th April 2016, 11:08
For science!
Groucho2004
17th April 2016, 11:25
For science!
Ah, OK. I can relate to that. :)
asarian
17th April 2016, 15:31
Is this still in development? I could see myself 'hack' a copy of the QTGMC script to use this OpenCL-nnedi3, instead of the original one. Seems it's 3 years old, though.
luigizaninoni
19th June 2016, 15:33
and still no 64-bit version ? Avisynth+ 64-bit is very stable now
yup
16th August 2016, 18:24
High all!
Lucky life continue until Geforce driver updated to 362.00.
See error during load simle script in VirtyualDub
https://www.dropbox.com/s/k4gsunhr29bcwoc/nnediocl.png?dl=0
Language my windows is Russian.
Translation Video driver do not respond and was recovered,
Video driver Nvidia Windows Kernel Mode Driver , Version 362.00 do not respond and was recovered.
Any suggesrtions, please.
yup.
After upgrade to Avisynth+, I am try this plugin one more and find in old plugin directory file nnedi3ocl.clb. I am copy all files excluding one, and now all work fine.
yup.
edcrfv94
30th September 2016, 02:33
anti-aliasing need nsize=6, qual=2, pscrn=4, nns=4, nnedi3ocl will any plan completely relaced nnedi3?
TheProfosist
5th November 2016, 09:49
I cant seem to get this to do anything it just crashes AvsPmod everytime I add it.
misakitchi
11th January 2021, 12:49
I modded Santiag script (Anti-Aliasing) to use NNEDI3ocl and its very good! Thanks! :)
Is there a new version of NNEDI3ocl since 2013...??
I find this page:
https://github.com/zachsaw/MPDN_Extensions/tree/master/Extensions/RenderScripts/OCL_NNEDI3
Are thoses 2 files updated/better?
Edit:
I tested the "new" version of MPDN from zachsaw
And i have Error! :(
"nnedi3ocl: can't allocate OpenCL Resources"
So i keep the original version
PS: My Computer: AMD FX-8350 + Radeon HD 7800 Series
If someone is interested in my modded Santiag script, i can give the code here
# santiag v1.6
# Simple antialiasing
# OpenCL MOD
# santiagocl(strh=0, strv=0, type="nnedi3", nns=1, nsize=0, halfres=false, scaler_post="Spline36Resize")
# Note: variable "threads" was removed
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
# type = "nnedi3", "eedi2", "eedi3" or "sangnom"
# "eedi3" requires v0.9.2 or later
# "sangnom" requires sangnom2
Function santiagocl (clip c, int "strh", int "strv", string "type", int "nns", int "aa", int "aac", int "nsize", int "vcheck", int "fw", int "fh", bool "halfres", string "scaler_post", int "maskt", string "typeh", string "typev")
{
strh = Default (strh, 1)
strv = Default (strv, 1)
type = Default (type, "nnedi3")
typeh = Default (typeh, type)
typev = Default (typev, type)
halfres = Default (halfres, false)
scaler_post = Default (scaler_post, "Spline36Resize")
c
w = Width ()
h = Height ()
fwh = (strv < 0) ? fw : w
fhh = (strv < 0) ? fh : h
(strh >= 0) ? santiag_dir (strh, typeh, halfres, scaler_post, nns=nns, aa=aa, aac=aac, nsize=nsize, vcheck=vcheck, maskt=maskt, fw=fwh, fh=fhh) : last
(strv >= 0) ? TurnLeft ().santiag_dir (strv, typev, halfres, scaler_post, nns=nns, aa=aa, aac=aac, nsize=nsize, vcheck=vcheck, maskt=maskt, fw=fh, fh=fw ).TurnRight () : last
fwx = Default (fw, w)
fhx = Default (fh, h)
(strh < 0 && strv < 0) ? Eval (scaler_post + " (fwx, fhx)") : last
}
Function santiag_dir (clip c, int strength, string type, bool halfres, string scaler_post, int "nns", int "aa", int "aac", int "nsize", int "vcheck", int "maskt", int "fw", int "fh")
{
c
w = Width ()
h = Height ()
fw = Default (fw, w)
fh = Default (fh, h)
multi = (IsYUV () && ! IsYV12 ())
c_y = (multi ) ? ConvertToYV12 () : last
c_u = (multi && ! IsY8 ()) ? UToY ().ConvertToYV12 () : last
c_v = (multi && ! IsY8 ()) ? VToY ().ConvertToYV12 () : last
c_y = c_y.santiag_stronger (strength, type, halfres, multi, nns=nns, aa=aa, aac=aac, nsize=nsize, vcheck=vcheck, maskt=maskt)
c_u = (multi && ! IsY8 ()) ? c_u.santiag_stronger (strength, type, halfres, true , nns=nns, aa=aa, aac=aac, nsize=nsize, vcheck=vcheck, maskt=maskt) : c_u
c_v = (multi && ! IsY8 ()) ? c_v.santiag_stronger (strength, type, halfres, true , nns=nns, aa=aa, aac=aac, nsize=nsize, vcheck=vcheck, maskt=maskt) : c_v
(multi && ! IsY8 ()) ? YToUV (c_u, c_v, c_y)
\ : IsY8 () ? c_y.ConvertToY8 ()
\ : c_y
Eval (scaler_post + " (fw, fh, src_left=0, src_top=(halfres)?0:0.5, src_width=Width (), src_height=Height ())")
}
Function santiag_stronger (clip c, int strength, string type, bool halfres, bool lumaonly, int "nns", int "aa", int "aac", int "nsize", int "vcheck", int "maskt")
{
strength = (strength < 0) ? 0 : strength
field = strength % 2
dh = (strength <= 0 && ! halfres)
(strength > 0) ? c.santiag_stronger (strength - 1, type, halfres, lumaonly, nns=nns, aa=aa, aac=aac, nsize=nsize, vcheck=vcheck, maskt=maskt) : c
(type == "nnedi3" ) ? santiag_nnedi3 (dh, field, lumaonly, nns=nns, nsize=nsize)
\ : (type == "eedi2" ) ? santiag_eedi2 (dh, field)
\ : (type == "eedi3" ) ? santiag_eedi3 (dh, field, lumaonly, nns=nns, nsize=nsize, vcheck=vcheck, maskt=maskt)
\ : (type == "sangnom") ? santiag_sangnom (dh, field, aa=aa, aac=aac)
\ : Assert (false, "Santiag: unexpected value for type.")
}
# NNEDI3 OpenCL
Function santiag_nnedi3 (clip c, bool dh, int field, bool lumaonly, int "nns", int "nsize")
{
c.nnedi3ocl (dh=dh, field=field, nns=nns, nsize=nsize, u=!lumaonly, v=!lumaonly)
}
Function santiag_eedi2 (clip c, bool dh, int field)
{
c
w = Width ()
h = Height ()
(dh) ? last : PointResize (w, h / 2, 0, 1-field, w, h)
eedi2 (field=field)
}
# maskt = 24
Function santiag_eedi3 (clip c, bool dh, int field, bool lumaonly, int "nns", int "nsize", int "vcheck", int "maskt")
{
chroma = (lumaonly) ? 1 : 3
sclip = c.santiag_nnedi3 (dh, field, lumaonly, nns=nns, nsize=nsize)
mclip_flag = (Defined (maskt) && maskt > 0)
mclip = (mclip_flag && dh) ? sclip.BicubicResize (c.Width (), c.Height (), src_top=0.5-field) : sclip
mclip = (mclip_flag)
\ ? mclip.mt_edge (mode="1 2 1 0 0 0 -1 -2 -1 1", thY1=0, thY2=255, u=chroma, v=chroma)
\ .mt_binarize (threshold=maskt, y=3, u=chroma, v=chroma)
\ .mt_expand (y=3, u=chroma, v=chroma)
\ : santiag_undef ()
c.eedi3 (dh=dh, field=field, vcheck=vcheck, sclip=sclip, mclip=mclip, u=!lumaonly, v=!lumaonly)
}
Function santiag_sangnom (clip c, bool dh, int field, int "aa", int "aac")
{
c
w = Width ()
h = Height ()
(dh) ? Spline36Resize (w, h * 2, 0, -0.25, w, h) : last
SangNom2 (order=field, aa=aa, aac=aac)
}
Function santiag_undef () { }
Kisa_AG
12th January 2021, 17:44
If someone is interested in my modded Santiag script, i can give the code here
Yes, please!
kedautinh12
13th January 2021, 01:28
Yes, please!
Code he was posted above
mogobime
20th June 2022, 16:00
As there is no usable x64 Avisynth – no x64 version for now. This plugin wouldn't benefit from it anyway.
nnedi3ocl is basic functionality implemented as plugin. nnedi3x and nnedi3x_rpow2 – scripts that extended beyond that. Basically, what is reasonable to do in script – should be done in script.
GTX 560 should work just fine. Slower than similar Radeons or CC2.0 cards, but still ok.
Hi,
First a few words to myself and why I try to contact you. I'm currently writing a script, which tries to calculate prefetches for every single filter (which is worth to be "extra" prefetched) in an avisynth+ script with the help of a constantly growing database which contains how many threads a filter normally creates per prefetch to not overload the cpu in complex scripts.
Such AviSynth+ scripts with prefetches set after every filter sometimes seem to be even faster than VapourSynth scripts using the same filters.
So I think AviSynth+ is still noteworthy nowadays, especially for non high end systems.
Since times have changed and AviSynth+ 64 bit works great and is really fast if filter prefetching is used correctly, I wanted to ask you if you see any chance to port nnedi3ocl to 64 bit, so it can be used in an 64 bit environment which can address more than 3 GB of memory, which is necessary in times of 4K.
With current basic GPU hardware this might speed up many nnedi3 based filters in 64 bit AviSynth+ and also improve quality of filtering by abandoning the prescreener.
So it would be nice to hear from you.
cu, mogobime
kedautinh12
19th November 2022, 06:41
NNEDI3CL 1.0.5
https://github.com/Asd-g/AviSynthPlus-NNEDI3CL/releases
kedautinh12
28th November 2022, 04:21
NNEDI3CL 1.0.6
https://github.com/Asd-g/AviSynthPlus-NNEDI3CL/releases
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.