Erstmal vorneweg zu OpenCL:
http://www.java-forum.org/codeschnipsel-u-projekte/86140-jocl-java-bindings-opencl.html 
Ich bin gerade am basteln: AMD hat inzwischen sein Stream-SDK rausgebracht, wo OpenCL schon unterstützt wird - aber da gibt's mit der JNI-Anbindung noch einige Probleme, die ich hoffentlich mit Unterstützung einiger AMDler schon bald klären kann.
Zu CUDA: CUDA ist definitiv
nicht "sehr speziell". Im Gegenteil: Man kann mit CUDA grundsätzlich fast alles machen, was man auch mit C machen kann (abgesehen von Details wie Rekursionen, Funktionspointern usw.). CUDA ist eine ganz allgemeine Programmiersprache - und sie ist so gesehen eine "Obermenge" von C.
Der wichtigste Unterschied ist, dass man in CUDA eine Funktion als "kernel" definieren kann, und diese Funktion dann parallel ausgeführt wird. Und eben nicht mit den lächerlichen 4 oder 8 Threads, die auf einem Quad-Core Sinn machen. Nein, mit CUDA kann so ein Funktionsblock (je nach Hardware) von 10000 (zehntausend) Threads gleichzeitig ausgeführt werden, und das Erstellen und verwalten dieser Threads ist praktisch kostenlos. Also auch wenn man sagt, dass ein Problem mit 1000000 (1 Million) Threads gelöst werden soll, entsteht dadurch kein nennenswerter Overhead.
Trotzdem gibt es natürlich bestimmte Bereiche, in denen CUDA mehr Sinn macht als in anderen. Im speziellen ist die Speicherverwaltung eine Herausforderung. (Für die Hardware, und für den Programmierer - wobei die Herausforderung für den Programmierer darin besteht, die Speicherverwaltung für die Hardware keine zu große Herausforderung werden zu lassen

). Der Transfer von Daten vom Host (also dem RAM im PC) auf das Device (also den Grafikkartenspeicher) ist i.a. der Bottleneck. Zusätzlich hat jeder Zugriff auf den Grafikkartenspeicher nochmal einen Overhead von ca. 400-600 Zyklen.
Richtig schnell ist dagegen der "Shared Memory" - eine Art Cache. Wenn man es schafft, seine Berechnungen NUR im shared memory zu machen, ist einem ein Speedup fast sicher. CUDA ist also (etwas pauschalisiert) insbesondere dort von Vorteil, wo auf "wenigen" Daten "viel" gerechnet werden muss, und diese Berechnungen parallel ablaufen können.
Das ist z.B. bei der Matrizenmultiplikation der Fall: Der Aufwand ist etwa O(n^3), und kann sehr gut von vielen Threads gleichzeigig bearbeitet werden - also lohnt es sich, den Speicher für diese Berechnung an die Grafikkarte zu schicken. Was dagegen keinen großen Vorteil bringt, ist etwa, die Suche nach dem maximalen Element eines Arrays in CUDA zu machen - einmal mit einem Thread über viele Daten laufen, dabei praktisch nichts rechnen - das macht man besser auf der CPU (außer, wenn die Daten sowieso schon auf der GPU liegen).
Aber ich muss noch erwähnen, dass ich das alles auch nicht gut kann: Ich habe selbst noch nicht viel mit CUDA programmiert - in erster Linie die Anbindung (also JCuda) geschrieben, und ein paar Geschwindigkeitsvergleiche mit JCufft/JCublas gemacht. "Gut" in CUDA zu programmieren ist eine Wissenschaft für sich. Und keine überflüssige, weil die gleichen "Regeln" auch bei OpenCL gelten werden - es geht um die grundsätzliche Frage, wie man Probleme für VIELE Threads optimiert, und dabei die Speicherzugriffe optimiert.
Trotzdem nochmal: CUDA eignet sich für alle Arten von "aufwändigen" Berechnungen, die nicht zu "memory bound" sind. Wie viel man bei welchem Anwendungsfeld rausholen kann, erkennt man an den "Speedups", die bei den Beispielen auf
CUDA Zone -- The resource for CUDA developers dabeistehen.
Und WIE man diese Speedups erreicht - geht z.B. aus dem
CUDA Best Practives Guide (PDF-Datei) hervor, der mit CUDA 2.3 veröffentlicht wurde.