Edit
Thanks to all who have responded! I now have plenty of information on the GeForce 650M GPU as found in most new, mid-range Mac laptops; the Mandelbrot code below runs in comfortably under a tenth of a second. I'm still quite curious how that compares to the GeForce 675MX GPU, which comes in new, high end iMacs. If someone provides that information as an answer, I'll happily accept!
Original
When V8 came out, I was very excited about the introduction of GPU support. So far, however, I've not really been able to take advantage of it the way I would like to, simply because I haven't had a computer with an adequate GPU. Even when CUDA and/or OpenCL are supported, one might not see significant gains when using the GPU due (I think) to limited block size.
Well, now it appears that I'll be getting a new computer in the not so distant future and I'd like to make sure that I'm happy with the GPU. To that end, I wonder if I could receive some feedback on actual user experiences. I am specifically interested in how CUDA and OpenGL work with midline Mac Laptops and Desktops. Laptops seem to run NVIDIA GeForce 640M or 650M GPUs, while desktops are more flexible going up to the 675 or higher in iMacs.
So, does CUDA run on these machines? Specifically, does at least the following return True:
(* Warning - a large package is loaded from Wolfram Research *)
Needs["CUDALink`"];
CUDAQ[]
(* Out: False *)
I am aware, of course, of the systems requirements documentation here: http://reference.wolfram.com/mathematica/CUDALink/tutorial/Reference.html#1803279895
That page indicates that CUDA does not run on 600 level GeForce GPUs, but I have a hard time believing that CUDA still is not running on main-line Macs at this point. Furthermore, NVIDIA's information seems to conflict with this here: https://developer.nvidia.com/cuda-gpus
Hence, the question.
Also, I wonder if folks wouldn't mind trying a little test - say, generate a Mandelbrot set, since I'm quite curious about the relative speed of GPUs as accessed through Mathematica. To that end, here's a simple OpenCL program that generates escape times counts to generate a Mandelbrot image. Note that the blockSize
parameter can be changed. I'm not an expert on GPU programming, but I believe that higher end GPUs generally allow higher block sizes and that larger block sizes permit more parallelization. My computer allows a blockSize
of 16 or lower; lowering the blockSize
generally slows down the computation.
Needs["OpenCLLink`"];
blockSize = 16;
code = "
__kernel void mandel_kernel(__global Real_t *mSet, int xRes, int yRes,
Real_t xMin, Real_t xMax, Real_t yMin, Real_t yMax) {
int xIndex = get_global_id(0);
int yIndex = get_global_id(1);
int i;
Real_t cx = xMin + xIndex*(xMax-xMin)/xRes;
Real_t cy = yMin + yIndex*(yMax-yMin)/yRes;
Real_t x = cx;
Real_t y = cy;
Real_t tmp;
if (xIndex < xRes && yIndex < yRes) {
for (i = 0; i < MAX_ITERATIONS && x*x + y*y <= BOUND_SQUARED; i++) {
tmp = x*x - y*y + cx;
y = 2*x*y + cy;
x = tmp;
}
mSet[xIndex + yIndex*yRes] = i;
}
}
";
If[OpenCLQ[] === True,
mandelCalculate = OpenCLFunctionLoad[code, "mandel_kernel", {{_Real, _, "Output"},
_Integer, _Integer, _Real, _Real, _Real, _Real}, {blockSize, blockSize},
"Defines" -> {"MAX_ITERATIONS" -> 100, "BOUND_SQUARED" -> "4.0"}],
Print["I'm sorry, your computer is even lamer than Mark's!"]
];
Assuming your computer actually passes the test, the following will actually run the program for an xRes
by yRes
square.
xRes = 1500; yRes = 1500;
(mSet = OpenCLMemoryAllocate[Real, {xRes, yRes}];
mandelCalculate[mSet, xRes, yRes, -2.0, 0.6, -1.3, 1.3];
data = OpenCLMemoryGet[mSet]); // AbsoluteTiming
(* Out: {0.065236, Null} *)
Yeah, that's pretty fast. The computation was performed on the following GPU.
"Renderer" /. ("OnScreen" /. ("OpenGL" /.
SystemInformation["Devices", "GraphicsDevices"]))
(* Out: "ATI Radeon HD 6750M OpenGL Engine" *)
Again, the point is to compare GPUs but, if you want to generate an image, here's one way to do so:
colors = Map[{(100 - #)^2/10000, (100 - #)^3/1000000, (100 - #)/100} &, data, {2}];
Image[colors]
(* Out: Groovy picture *)
CUDAQ[]
repeatedly gaveFalse
even after installing the necessary packages from WRI. In the case of my old laptop, I had to manually install an update from NVIDIA, and in my retina MBP, I had to force the graphics card to always use the NVIDIA card and not the integrated one before I could get them to work (returnTrue
). $\endgroup$xRes=...
$\endgroup$CUDAQ
to returnTrue
when this stuff first came out. My impression is that this is the reason that Wolfram's data paclets are accessed when first loadingCUDALink
. $\endgroup$