(1367,1,'2011-06-22 16:41:58','2011-06-22 20:41:58','Active Contours are mathematical models that enable detection of objects within images, and are extensively used in Computer Vision as self-adapting frameworks for the delineation and tracking of objects.\n\nTo demonstrate Jacket\'s cross-platform versatility, we implemented the Chan Vese contour tracking app on Android. The video can be viewed <a title=\"Jacket Mobile\" href=\"http://www.accelereyes.com/products/mobile\">here</a>.\n\nToday, however, we\'d like to use a MATLAB implementation of active contours as an example of how to take a large project, and with minimal changes, achieve speedups with Jacket.\n\nWe\'ll dangle the proverbial carrot first: the GPU Chan-Vese implementation contains only <em>three kinds of changes overall,</em> and the computational code is <em>exactly the same</em> for both CPU and GPU versions. Plus, take a look at the speed-ups below! How did we accomplish that?\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/06/chanvese-jacket-1.8-benchmark-chart.png\"><img class=\"aligncenter size-full wp-image-1394\" title=\"Runtimes for Chan-Vese Contours \" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/06/chanvese-jacket-1.8-benchmark-chart.png\" alt=\"\" width=\"700\" height=\"512\" /></a></p>\nBefore we jump into the code, you might want to read up on Jacket\'s <a href=\"http://wiki.accelereyes.com/wiki/index.php/CLASS\">CLASS</a> functionality and a <a href=\"http://blog.accelereyes.com/blog/2011/03/17/write_once_run_everywhere/\">blog post</a> that discusses how to exploit it.\n\n<span style=\"text-decoration: underline;\"><em>0. Identify the bottleneck</em></span>\n\nAs with any project, the biggest question is where to begin. Fortunately, MATLAB\'s Profiler will give you a good sense of where the bottlenecks are:\n\n[caption id=\"attachment_1371\" align=\"aligncenter\" width=\"668\" caption=\"MATLAB Profile for CPU Chan-Vese function\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/06/profile-overall.png\"><img class=\"size-full wp-image-1371\" title=\"MATLAB Profile for CPU Chan-Vese function\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/06/profile-overall.png\" alt=\"Shows kappa.m to be the bottleneck\" width=\"668\" height=\"86\" /></a>[/caption]\n\nFrom the profile, we have our target: the function kappa() that consumes about 60% of the time.\n\nWe now formulate a set of objectives to ensure proper Jacketization:\n<ul>\n	<li>Change CPU code as necessary to ensure optimized GPU performance. Target bottleneck first.</li>\n	<li>Ensure that all <em>large</em> intermediate variables are generated on the GPU</li>\n	<li>Minimize operations between mixed CPU and GPU types (scalars and small-sized variables are okay)</li>\n	<li>Keep the computational chunk of code exactly the same between CPU and GPU runs.</li>\n</ul>\n<span style=\"text-decoration: underline;\"><em>1. Change CPU code</em></span>\n\nSome investigation reveals that in kappa.m:\n<ul>\n	<li>The same matrix, P, is indexed in many different patterns (an operation called \"<a href=\"http://wiki.accelereyes.com/wiki/index.php?title=SUBSREF\"><span style=\"font-family: monospace;\">subsref</span></a>\")</li>\n	<li>Some index patterns repeat themselves.</li>\n</ul>\nWhile straight-up subsrefs are generally fast, the GPU starts to slow-down when it\'s asked to make \"uncoalesced\" memory accesses. This most often happens during an indexing operation like in kappa.m. Other examples include conditional indexing, such as <span style=\"font-family: monospace;\">A(A&lt;1)</span>.\n\nJacket has many built-in workarounds for commonly-used subsrefs where the GPU is slow, but a piece of code with lesser indexing operations might win over code that has more.\n\nHere is the original kappa.m:\n<pre>fy = P(3:end,2:n+1)-P(1:m,2:n+1);\nfx = P(2:m+1,3:end)-P(2:m+1,1:n);\nfyy = P(3:end,2:n+1)+P(1:m,2:n+1)-2*I;\nfxx = P(2:m+1,3:end)+P(2:m+1,1:n)-2*I;\nfxy = 0.25.*(P(3:end,3:end)-P(1:m,3:end)+P(3:end,1:n)-P(1:m,1:n));</pre>\nAnd here\'s the modified version:\n<pre>subP1 = P(3:end,2:n+1); subP2 = P(1:m,2:n+1);\nsubP3 = P(2:m+1,3:end); subP4 = P(2:m+1,1:n);\nsubP5 = P(3:end,3:end); subP6 = P(1:m,3:end);\nsubP7 = P(3:end,1:n); subP8 = P(1:m,1:n);\nfy = subP1-subP2; fx = subP3-subP4;\nfyy = subP1+subP2-2*I; fxx = subP3+subP4-2*I;\nfxy = 0.25.*(subP5-subP6+subP7-subP8);</pre>\n<em><span style=\"text-decoration: underline;\">2. Generate intermediate variables on GPU</span>\n</em>\n\nHaving changed our M code, we now need to ensure that all <em>large</em> helper variables are generated on the GPU. This is where the CLASS construct comes in handy.\n\nWhen using CLASS,  the focus is on keeping the functional part of the code identical for both CPU and GPU. To accomplish that, we need to follow the control flow through the code and change variables as necessary.\n\nAt a very high level, the flow proceeds as shown:\n<ol>\n	<li>Generate inputs</li>\n	<li>Call chenvese() on those inputs</li>\n	<li>Generate masks if necessary (maskcircle2)</li>\n	<li>Call heaviside(), kappa()</li>\n	<li>Plot images</li>\n</ol>\nSome careful inspection of the code will show that the helper functions (<span style=\"font-family: monospace;\">maskcircle2, heaviside, kappa</span>) all contain helper variables that are hard-coded to be CPU variables. You can make them change their data-types according to the primary input, as follows:\n\nIn function heaviside():\n<pre>H=zeros(size(z,1),size(z,2));</pre>\nis modified to follow the data type of that function\'s primary input, z:\n<pre>H=zeros(size(z,1),size(z,2),class(z));</pre>\n<span style=\"text-decoration: underline;\"><em>3. Minimize operations between mixed types</em></span>\n\nThe original M-code contained lots of hard-coded casts to <span style=\"font-family: monospace;\">uint8</span>. For example, in function chenvese():\n<pre>P = rgb2gray(uint8(I));</pre>\nHere, I is the input image. You need P to be of type <span style=\"font-family: monospace;\">uint8</span> or <span style=\"font-family: monospace;\">guint8</span>, depending on whether I is CPU or GPU respectively. How do you make this statement follow the data-type of I?\n\nThis is accomplished using a simple function, smartcast(), with the syntax:\n<pre>op = smartcast(ip, type)</pre>\nFor example,\n<pre>op = smartcast(ip, \'uint8\')</pre>\nwill mean that OP is a <span style=\"font-family: monospace;\">guint8</span> or <span style=\"font-family: monospace;\">uint8</span>, depending on whether IP is GPU or CPU, respectively.\nYou can download <span style=\"font-family: monospace;\">smartcast.m</span> <a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/06/smartcast.zip\">here</a>.\n\nAnd that\'s it! Lather, rinse, repeat.\n\n<span style=\"text-decoration: underline;\"><em>4. Keep CPU and GPU code same</em></span>\n\nOur fourth objective is automatically achieved if we follow the steps outlined above!\n\nThis code was run on two different CPUs with a Tesla C2070 and Jacket 1.8rc (downloadable <a href=\"http://www.accelereyes.com/nightly\">here</a>). It gave a <strong>12x</strong> speedup on a 1500x1200 image.\n\nYou can download the Jacketized versions <a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/06/chanvese.zip\">here</a>. Run <span style=\"font-family: monospace;\">demochanvesecpu</span> for the CPU code, and <span style=\"font-family: monospace;\">demochanvesegpu</span> for the GPU version (they both call the same functions). You can also search the M-files for the word \"accelereyes\" for the points where the original code was modified.\n\nThe original M-code implementation of Chan-Vese active contours was written by Yue Wu at Tufts University. Yue maintains a <a href=\"http://sites.google.com/site/rexstribeofimageprocessing/\">Google page</a> on Image Processing research, where the original, unmodified code can be downloaded. We would like to thank Yue for his efforts and wish him all the best in his research endeavors.\n\n<em>References:</em>\n\n<em>Chan, T. F., &amp; Vese, L. A. Active contours without edges. IEEE TRANSACTIONS ON IMAGE PROCESSING, VOL. 10, NO. 2, FEBRUARY 2001</em>','Chan-Vese Active Contours on the GPU','','publish','open','open','','chan-vese-active-contours-on-the-gpu','','','2011-06-22 16:41:58','2011-06-22 20:41:58','',0,'http://blog.accelereyes.com/blog/?p=1367',0,'post','',1),(1412,4,'2011-06-27 13:31:51','2011-06-27 17:31:51','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/06/L05_multi-gpu-progr_Page_01.png\"><img class=\"alignright size-medium wp-image-1414\" title=\"L05_multi-gpu-progr_Page_01\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/06/L05_multi-gpu-progr_Page_01-300x200.png\" alt=\"\" width=\"300\" height=\"200\" /></a>We are pleased to share 6 in-depth Jacket lectures, helpful both in learning and teaching Jacket.  Download the lectures (PDF format), here:  <a href=\"http://www.accelereyes.com/support/lectures\">http://www.accelereyes.com/support/lectures</a>\n\nJacket is used in course instruction at many universities around the world. Professors and course instructors use Jacket to provide engineering students with GPU acceleration of MATLAB® algorithms and to bring HPC to MATLAB courses.\n\nThe six lectures are entitled \"Parallel High Performance Computing with Emphasis on Jacket Based GPU Computing\" and have topics including:\n<ol>\n	<li>Parallel computing introduction</li>\n	<li>Jacket introduction</li>\n	<li>Basic programming with Jacket</li>\n	<li>Advanced programming with Jacket</li>\n	<li>Multiple GPU programming</li>\n	<li>Benchmarking</li>\n</ol>\nIf you are looking at accelerating MATLAB code or parallel computing with MATLAB, you definitely will want to add these lectures to your arsenal of resources.\n\nThese lectures come from Jacket guru, Professor Torben Larsen (also known for his work on <a href=\"http://wiki.accelereyes.com/wiki/index.php/Torben\'s_Corner\">Torben\'s Corner</a> and for his answers as <a href=\"http://forums.accelereyes.com/forums/search.php?author_id=4378&amp;sr=posts\">Lars1</a> on the forums).  Many thanks to him and his colleagues for sharing this content.\n\nEnjoy!','Jacket Lectures - Learn and Teach GPU computing','','publish','open','open','','jacket-lectures-learn-and-teach-gpu-computing','','','2011-06-27 13:31:51','2011-06-27 17:31:51','',0,'http://blog.accelereyes.com/blog/?p=1412',0,'post','',0),(1435,1,'2011-07-20 16:43:46','2011-07-20 20:43:46','Antenna array design involves repeated simulation to tune the many parameters involved, and waiting around for simulations to finish is no fun. Offloading the optimization problem onto the GPU cuts that time down significantly.\n\nIn their recent paper, Capozzoli, Curcio, and Liseno (<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/PWS_GPU.pdf\">pdf</a>, <a href=\"http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=5782219\">citation</a>) of University of Naples Federico II demonstrated how a simple modification to their echo generator array simulation took advantage of the GPU to bring immediate speedups. Checkout this figure from their paper showing CPU simulation time growing prohibitively slow while the GPU grows little as more data is fed. <img src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/tomography_fig3.png\" alt=\"CPU time versus GPU time\" width=\"50%\" align=\"right\" />\n\nTheir simulation is designed around optimizing an energy functional. Using <a href=\"http://www.mathworks.com/help/toolbox/optim/ug/fminunc.html\">fminunc</a> to drive the optimization problem on the CPU, they simply modified their functional evaluation to take place on the GPU with Jacket. The most expensive part of their computation is the <a href=\"http://wiki.accelereyes.com/wiki/index.php/SVD\">singular value decomposition</a>, an algorithm for which Jacket <a href=\"http://www.accelereyes.com/products/benchmarks_jacket\">easily beats the CPU</a>.\n\nBelow is the core energy functional. It\'s slightly modified from the original paper to take advantage of features in the <a href=\"http://wiki.accelereyes.com/wiki/index.php/Release_Notes#Version_1.8\">latest release (v1.8)</a> so that only a few lines need modification to GPU-enable the application.\n\nThe paper is a quick read with a solid intro to formulating the optimization problem. Thanks to Drs. Capozzoli, Curcio, and Liseno for sharing their work!\n<pre>function Fun=functional(Coeff_legendre)\n  global k0 dq LEG_csi LEG_eta LEG_csi_qz LEG_eta_qz a b jk0dab Num_x_prime Num_y_prime Nx_qz Ny_qz max_degree\n\n  Coeff_legendre = gdouble(Coeff_legendre); % (1) cast to GPU\n\n  t=size(Coeff_legendre,1)/4;\n\n  Coeff_legendre_x = Coeff_legendre(1:t,:);\n  Coeff_legendre_y = Coeff_legendre((t+1):(2*t),:)\';\n  Coeff_leg_x_qz   = Coeff_legendre((2*t+1):(3*t),:);\n  Coeff_leg_y_qz   = Coeff_legendre((3*t+1):(4*t),:)\';\n\n  gfor m=1:Num_x_prime*Num_y_prime  % (2) for-loop -&gt; gfor-loop\n      X_PRIME(m) = sum(flat(Coeff_legendre_x.*(LEG_csi(2:2:end,m)*LEG_eta(1:2:end-1,m).\')));\n      Y_PRIME(m) = sum(flat(Coeff_legendre_y.*(LEG_csi(1:2:end-1,m)*LEG_eta(2:2:end,m).\')));\n  gend\n\n  gfor m=1:Nx_qz*Ny_qz  % (3) for-loop -&gt; gfor-loop\n      X(m) = sum(flat(Coeff_leg_x_qz.*(LEG_csi_qz(2:2:end,m)*LEG_eta_qz(1:2:end-1,m).\')));\n      Y(m) = sum(flat(Coeff_leg_y_qz.*(LEG_csi_qz(1:2:end-1,m)*LEG_eta_qz(2:2:end,m).\')));\n  gend\n\n  [XX XX_PRIME]=meshgrid(X,X_PRIME);\n  [YY YY_PRIME]=meshgrid(Y,Y_PRIME);\n  Rmn=sqrt(dq+(XX-XX_PRIME).^2+(YY-YY_PRIME).^2);\n  Kx = k0*(XX-XX_PRIME)./Rmn;\n  Ky = k0*(YY-YY_PRIME)./Rmn;\n  A  = jk0dab./(Rmn.^2).*sinc(Ky*b/(2*pi)).*cos(Kx*a/2)./(pi^2-(Kx*a).^2).*exp(-1i*k0*Rmn);\n\n  S=svd(A);\n  Fun=double(1/(sum(S)/S(1)));  % (4) ensure back on CPU for fminunc\n\nend\n\nfunction x = flat(x)\n  x = x(:);\nend</pre>','Using Jacket to design and simulate echo generators','','publish','open','open','','echo-generators','','','2011-07-20 16:43:46','2011-07-20 20:43:46','',0,'http://blog.accelereyes.com/blog/?p=1435',0,'post','',0),(1467,1,'2011-07-27 14:00:05','2011-07-27 18:00:05','A few weeks ago, we published a <a title=\"blog entry\" href=\"http://blog.accelereyes.com/blog/2011/05/05/speeding-up-compressed-sensing-algorithms/\">blog entry</a> that demonstrated the ability of Jacket to speed up \"compressive sensing\", a technology that has wide applications in areas such as Image processing, reconstruction and spectroscopy. Here, we discuss the work of Nabor Reyna Jr. and Wotao Yin from Rice University using Jacket to speed up \"compressive sensing\" algorithms in reconstruction.\n\nThis work deals with reconstruction of signals using partial Fourier matrices (RecPF).  The major computational components of the algorithm involve shrinkage and FFTs.  Jacket is employed to accelerate this compute-heavy code, and the resultant version (gRecPF) was about <span style=\"color: #ff0000;\">5x faster!</span>\n<p style=\"padding-left: 30px;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/gRecPF.jpg\"><img class=\"size-medium wp-image-1468 aligncenter\" title=\"gRecPF\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/gRecPF-300x242.jpg\" alt=\"\" width=\"300\" height=\"242\" /></a></p>\nTo reduce the cost involved in generating the random matrices involved in the above method, a second method (RecPC) that employed Circulant matrices in place of the Fourier matrices was developed. A Jacket version of the same was also implemented (gRecPC) and this led to a <span style=\"color: #ff0000;\">3X speedup!</span>\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/gRecPC.png\"><img class=\"size-medium wp-image-1472 aligncenter\" title=\"gRecPC\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/gRecPC-300x213.png\" alt=\"\" width=\"300\" height=\"213\" /></a>\n\nHere are some sample reconstructed images using  gRecPC\n\n[caption id=\"attachment_1473\" align=\"aligncenter\" width=\"300\" caption=\"MRI Image Reconstruction using 20% sample mask\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/gRecPC_sample.png\"><img class=\"size-medium wp-image-1473\" title=\"gRecPC: MRI example\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/gRecPC_sample-300x144.png\" alt=\"\" width=\"300\" height=\"144\" /></a>[/caption]\n\n[caption id=\"attachment_1474\" align=\"aligncenter\" width=\"300\" caption=\"Reconstructed Image of Great Wall of China using 30% partial circulant samples\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/thegreatwall_rcv.png\"><img class=\"size-medium wp-image-1474\" title=\"thegreatwall_rcv\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/thegreatwall_rcv-300x225.png\" alt=\"\" width=\"300\" height=\"225\" /></a>[/caption]\n\nA more detailed summary of the work may be found <a title=\"here\" href=\"http://www.caam.rice.edu/~optimization/L1/RecPF/\">here</a> and <a title=\"here\" href=\"http://www.caam.rice.edu/~optimization/L1/RecPC/\">here</a>.  We thank Nabor Reyna and Wotao Yin from Rice University for exploring Jacket as a solution to important computational problems of today, and look forward to hearing more from them as they continue this line of research!\n\n&nbsp;','High Performance Compressive Sensing','','publish','open','open','','high-performance-compressive-sensing','','','2011-07-27 14:00:05','2011-07-27 18:00:05','',0,'http://blog.accelereyes.com/blog/?p=1467',0,'post','',0),(1483,1,'2011-08-19 10:58:35','2011-08-19 14:58:35','Researchers at the Stanford Artificial Intelligence Laboratory (SAIL) have had more success (building on <a href=\"http://blog.accelereyes.com/blog/2011/04/09/feature_learning_architectures/\">previous work</a>) using Jacket to speed up their algorithm.\n\nIn a paper at this year\'s CVPR 2011, entitled “<a href=\"http://ai.stanford.edu/~quocle/LeZouYeungNg11.pdf\" target=\"_blank\">Learning hierarchical invariant spatio-temporal features for action recognition with independent subspace analysis</a>”, they explain how their unsupervised feature learning algorithm competes with other algorithms that are hand crafted or use learned features.\n<table width=\"576\" cellspacing=\"0\" cellpadding=\"7\"><colgroup> <col width=\"100\" /> <col width=\"101\" /> <col width=\"101\" /> <col width=\"101\" /> <col width=\"100\" /> </colgroup>\n<tbody>\n<tr valign=\"TOP\">\n<td bgcolor=\"#ffffff\" width=\"100\"></td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\"><strong>KTH</strong></span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\"><strong>Hollywood2</strong></span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\"><strong>UCF</strong></span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"100\">\n<p align=\"CENTER\"><span style=\"color: #000000;\"><strong>Youtube</strong></span></p>\n</td>\n</tr>\n<tr valign=\"TOP\">\n<td bgcolor=\"#ffffff\" width=\"100\">\n<p align=\"CENTER\"><span style=\"color: #000000;\"><em>Best published Results</em></span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\">92.1%</span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\">50.9%</span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\">85.6%</span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"100\">\n<p align=\"CENTER\"><span style=\"color: #000000;\">71.2%</span></p>\n</td>\n</tr>\n<tr valign=\"TOP\">\n<td bgcolor=\"#ffffff\" width=\"100\">\n<p align=\"CENTER\"><span style=\"color: #000000;\"><em>Stanford group Results</em></span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\">93.9%</span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\">53.3%</span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"101\">\n<p align=\"CENTER\"><span style=\"color: #000000;\">86.5%</span></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"100\">\n<p align=\"CENTER\"><span style=\"color: #000000;\">75.8%</span></p>\n</td>\n</tr>\n</tbody>\n</table>\nTesting their algorithm on four well-known benchmark datasets, they were able to achieve better performance than existing results that have been published so far.\n\nFor their training purposes, they used a multi-layered stacked convolutional ISA (Independent subspace analysis) network. An ISA is used for learning features from image patches without supervision.\n\n[caption id=\"attachment_1489\" align=\"aligncenter\" width=\"404\" caption=\"The architecture of an Independent Subspace Analysis network\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/ISA.png\"><img class=\"size-full wp-image-1489  \" title=\"ISA\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/ISA.png\" alt=\"\" width=\"404\" height=\"170\" /></a>[/caption]\n<p style=\"text-align: left;\" align=\"CENTER\"> The standard ISA algorithm however becomes computationally inefficient when the size of the image patches is scaled up. To overcome this problem, they developed a convolutional neural network which makes use of PCA and ISA at alternating levels. The output of the ISA at the a particular level was used to convolve a larger region of the image. The results of this convolution step were fed into the PCA layer for pre-processing before being passed on to the next ISA layer.</p>\n\n\n[caption id=\"attachment_1492\" align=\"aligncenter\" width=\"406\" caption=\"Architecture of a Stacked Convolutional ISA network\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/ISA_Stacked.png\"><img class=\"size-full wp-image-1492 \" title=\"ISA_Stacked\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/ISA_Stacked.png\" alt=\"\" width=\"406\" height=\"259\" /></a>[/caption]\n<p align=\"LEFT\">Learning spatio-temporal features from video signals was done by using their model to learn features from 3D video blocks rather than 2D image samples.</p>\n\n\n[caption id=\"attachment_1493\" align=\"aligncenter\" width=\"344\" caption=\"Modified architecture for 3D video blocks\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/ISA_3D.png\"><img class=\"size-full wp-image-1493  \" title=\"ISA_3D\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/ISA_3D.png\" alt=\"\" width=\"344\" height=\"267\" /></a>[/caption]\n<p style=\"text-align: left;\" align=\"CENTER\">The trained networks appear to have learned features that are robust to translation, but sensitive to frequency and rotation (at the first level). The features learned at the second level appear to represent more complex shapes such as corners.</p>\n\n\n[caption id=\"attachment_1494\" align=\"aligncenter\" width=\"356\" caption=\"Features learnt from the Hollywood2 database at first and second layers\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/Learned_Filters.png\"><img class=\"size-full wp-image-1494 \" title=\"Learned_Filters\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/Learned_Filters.png\" alt=\"\" width=\"356\" height=\"214\" /></a>[/caption]\n<p align=\"LEFT\"> The performance of their algorithm, as mentioned earlier, not beats the best published results in accuracy, but is also generally faster both while training and testing. The times taken for feature extraction of their algorithm are given below.</p>\n\n<table width=\"779\" cellspacing=\"0\" cellpadding=\"7\"><colgroup> <col width=\"177\" /> <col width=\"178\" /> <col width=\"177\" /> </colgroup>\n<tbody>\n<tr valign=\"TOP\">\n<td style=\"text-align: left;\" bgcolor=\"#ffffff\" width=\"50%\">\n<p align=\"CENTER\"><strong>Algorithm</strong></p>\n</td>\n<td style=\"text-align: left;\" bgcolor=\"#ffffff\" width=\"20%\">\n<p align=\"CENTER\"><strong>Frames per Second</strong></p>\n</td>\n<td bgcolor=\"#ffffff\" width=\"20%\">\n<p align=\"CENTER\"><strong>Speedup</strong></p>\n</td>\n</tr>\n<tr valign=\"TOP\">\n<td bgcolor=\"#ffffff\">\n<p align=\"left\">HOG3D</p>\n</td>\n<td bgcolor=\"#ffffff\">\n<p align=\"CENTER\">4.54</p>\n</td>\n<td bgcolor=\"#ffffff\">\n<p align=\"CENTER\">1.0</p>\n</td>\n</tr>\n<tr valign=\"TOP\">\n<td bgcolor=\"#ffffff\">\n<p align=\"left\">Stacked ISA  (layer 1 only)</p>\n</td>\n<td bgcolor=\"#ffffff\">\n<p align=\"CENTER\">7.14</p>\n</td>\n<td bgcolor=\"#ffffff\">\n<p align=\"CENTER\">1.6</p>\n</td>\n</tr>\n<tr valign=\"TOP\">\n<td bgcolor=\"#ffffff\">\n<p align=\"left\">Stacked ISA  (flayers 1 and 2)</p>\n</td>\n<td bgcolor=\"#ffffff\">\n<p align=\"CENTER\">2.27</p>\n</td>\n<td bgcolor=\"#ffffff\">\n<p align=\"CENTER\">0.5</p>\n</td>\n</tr>\n<tr valign=\"TOP\">\n<td style=\"text-align: left;\" bgcolor=\"#ffffff\">\n<p align=\"left\">Stacked ISA with Jacket  (layers 1 and 2)</p>\n</td>\n<td style=\"text-align: left;\" bgcolor=\"#ffffff\">\n<p align=\"CENTER\">10</p>\n</td>\n<td bgcolor=\"#ffffff\">\n<p align=\"CENTER\">2.2</p>\n</td>\n</tr>\n</tbody>\n</table>\n<p align=\"LEFT\">As you can see, using Jacket for their algorithm (dominated by matrix vector and convolution problems), a <span style=\"color: #ff0000;\">4.4X speedup</span> was achieved over the CPU implementation!</p>\n<p align=\"LEFT\">Special thanks to <a href=\"http://ai.stanford.edu/~quocle/\">Quoc V. Le</a>, <a href=\"http://ai.stanford.edu/~wzou/\">Will Y. Zou</a>, Serena Y. Yeung and <a href=\"http://www.cs.stanford.edu/people/ang/\">Andrew Y. Ng</a> from SAIL for sharing their research. We have more success stories from their group. Keep an eye out for more blog posts!</p>','Action Recognition with Independent Subspace Analysis','','publish','open','open','','action-recognition','','','2011-08-19 10:58:35','2011-08-19 14:58:35','',0,'http://blog.accelereyes.com/blog/?p=1483',0,'post','',0),(1522,1,'2011-08-08 04:00:09','2011-08-08 08:00:09','Simulation in MATLAB is a driving force in several research projects. However, the accompanying long simulation times can tend to be a drag in many of these  projects. In this article, we shall bring up the example of the work on 3GPP LTE System Simulation by Yuan Gao et al (from Tsinghua University, Beijing) and demonstrate how the use of Jacket can significantly improve the simulator performance and lead to faster validation times in simulation projects.\n\n3GPP\'s <a title=\"LTE\" href=\"http://www.3gpp.org/LTE\">LTE </a>(Long Term Evolution) and LTE-Advanced are important telecommunication standards pertaining to 3G and 4G communication networks. With networks worldwide beginning to adopt them for consumer usage,  a great need has come up for several novel link and system-level communication techniques developed by researchers to validated on these systems.  Needless to say, such a need implies fast and reliable simulation.\n\nResearchers from Tsinghua University have found that the MATLAB-based LTE System simulator they were using was of \"low efficiency\" and \"insufficient to support further extension of the standardization process\".  As a result,  a part of the simulator was re-engineered using Jacket to speed up the process. The figure below describes the LTE system-simulator. The parts in yellow were targeted for parallelization: The Base Station Cycle block (labeled as BS Cycle) performs adaptive modulation and coding (AMC), scheduling,  and mapping from system level to link level (SL-LL mapping) for several users, each independently. The parallelism inherent here was exploited to generate a faster simulator using Jacket.\n\n[caption id=\"attachment_1524\" align=\"aligncenter\" width=\"300\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/3gpp_acc.png\"><img class=\"size-medium wp-image-1524 \" title=\"3gpp_acc\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/3gpp_acc-300x213.png\" alt=\"\" width=\"300\" height=\"213\" /></a> Design of LTE System-level Simulator[/caption]\n\nThe graph below shows benchmark timings (in seconds) as a function of the number of users participating in the network. The Jacket-based simulator beats the previous MATLAB based simulator by a <span style=\"color: #ff0000;\">speed-factor of 3X!</span>\n\n&nbsp;\n\n[caption id=\"attachment_1526\" align=\"aligncenter\" width=\"300\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/Simulation-REsults.png\"><img class=\"size-medium wp-image-1526\" title=\"Timing Results\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/Simulation-REsults-300x195.png\" alt=\"\" width=\"300\" height=\"195\" /></a> Performance of GPU-based LTE System Simulator[/caption]\n\n&nbsp;\n\nThe results were generated using the much-older Jacket 1.3 against MATLAB R2010a (64-bit). The hardware used involved an Intel Core i7-860 CPU, 4GB memory and a GeForce GTX 260 GPU. We would encourage that this experiment be retried with a superior GPU and the latest version of <a href=\"http://www.accelereyes.com/download_jacket\">Jacket </a>to take advantage of the latest improvements in GPU computing and enjoy much higher speedups.\n\nWe would like to thank the researchers from Tsinghua University for taking the time to explore Jacket to speed up this simulator, which we are sure, will help several other research projects involving LTE run faster in turn! To find more details about this work, please refer to<a href=\"http://www.scientific.net/AMM.58-60.1596\"> this publication</a>.\n\n&nbsp;','Accelerating LTE Simulation','','publish','open','open','','accelerating-simulation','','','2011-08-08 04:00:09','2011-08-08 08:00:09','',0,'http://blog.accelereyes.com/blog/?p=1522',0,'post','',0),(1531,1,'2011-09-20 13:41:58','2011-09-20 17:41:58','Researchers at SAIL (Stanford Artificial Intelligence Laboratory), have done it again. They have successfully used Jacket to speed up the training part of Deep Learning algorithms. In their paper titled “<a href=\"http://ai.stanford.edu/~quocle/LeNgiCoaLahProNg11.pdf\">On Optimization Methods for Deep Learning</a>”, they experiment with some of the well known training algorithms and demostrate their scalability across parallel architectures (GPUs as well as multi-machine networks). The algorithms include SGDs (Stochastic Gradient Descent) L-BFGS (Limited BFGS used for solving non-linear problems), CG (Conjugate Gradient).\n\nWhile SGDs are easy to implement, they require manual tuning. Add to that their sequential nature, they are hard to tune, scale and parallelize making them difficult to use with Deep Learning algorithms.  L-BFGS and CG algorithms can be harder to implement and are more computationally intensive. For speed benefits, they use approximated second order information for L-BFGS, and use the conjugacy information during the optimization step for CG. To overcome the scalability problems of L-BFGS and CG, which require gradient of the entire data set, they utilized mini-batch training which results in a faster algorithm for larger data sizes.\n\nFollowing are few of the results they achieved using these algorithms for various problems. Each machine is equipped with 4 Intel CPU cores (at 2.67GHz) and a GeForce GTX 285 GPU.\n\n[caption id=\"attachment_1532\" align=\"aligncenter\" width=\"545\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/Autoencoder_Training.png\"><img class=\"size-full wp-image-1532\" title=\"Autoencoder_Training\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/Autoencoder_Training.png\" alt=\"\" width=\"545\" height=\"421\" /></a> Autoencoder training on the CPU[/caption]\n\n&nbsp;\n\n[caption id=\"attachment_1533\" align=\"aligncenter\" width=\"527\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/Autoencoder_Training_GPU.png\"><img class=\"size-full wp-image-1533\" title=\"Autoencoder_Training_GPU\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/Autoencoder_Training_GPU.png\" alt=\"\" width=\"527\" height=\"396\" /></a> Autoencoder training on the GPU vs CPU[/caption]\n\nIt can be seen that LBFGS and CG algorithms converge nearly twice as fast on the GPU compared to the CPU. SGD methods though neither improve nor degrade the performance. This behavior can be explained by the large number mini batch sizes preferred by LBFGS / CG compared to SGDs, making them more parallelized for the GPUs.\n<p align=\"LEFT\"> For the next experiment, they used the algorithms for training supervised Convoluted neural networks. They then split the workload of calculating the gradient across multiple machines with GPUs.</p>\n\n\n[caption id=\"attachment_1534\" align=\"aligncenter\" width=\"452\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/CNN_Multimachine_Training.png\"><img class=\"size-full wp-image-1534\" title=\"CNN_Multimachine_Training\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/CNN_Multimachine_Training.png\" alt=\"\" width=\"452\" height=\"345\" /></a> Training Supervised CNNs on a cluster of computers (with GPUs)[/caption]\n<p align=\"LEFT\">As it can be seen, the rate of convergence for LBFGS scales well all the way up to 8 machines!</p>\n<p align=\"LEFT\">They also talks about other optimization techniques, usage of these algorithms for sparse auto encoding and locally connected networks, and uitility / accuracy of the the LBFGS algorithm for Deep learning.</p>\n<p align=\"LEFT\">We would like to thank <a href=\"http://ai.stanford.edu/~quocle/\">Quoc V. Le</a>, <a href=\"http://cs.stanford.edu/~jngiam/\">Jiquan Ngiam</a>, <a href=\"http://www.stanford.edu/~acoates/\">Adam Coates</a>, Abhik Lahiri, Bobby Prochnow,<a href=\"http://www.cs.stanford.edu/people/ang/\"> Andrew Y. Ng</a> and everyone at their group for letting us use and share their work.</p>','Optimization methods for deep learning','','publish','open','open','','optimization-methods-for-deep-learning','','','2011-09-20 13:41:58','2011-09-20 17:41:58','',0,'http://blog.accelereyes.com/blog/?p=1531',0,'post','',0),(1540,4,'2011-07-22 11:42:53','2011-07-22 15:42:53','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/accelereyes_logo_small.jpg\"><img class=\"aligncenter size-full wp-image-1542\" title=\"accelereyes_logo_small\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/accelereyes_logo_small.jpg\" alt=\"\" width=\"600\" height=\"100\" /></a>\n<table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"5\">\n<tbody>\n<tr valign=\"top\">\n<td style=\"color: #000000; font-size: 12pt; background-color: #ffffff; font-family: arial;\" width=\"650\"><span style=\"font-size: 12pt;\"><span style=\"font-weight: bold;\">Annou</span></span><span style=\"font-size: 12pt;\"><span style=\"font-weight: bold;\"><span>ncements</span></span></span>\n<ul>\n	<li><a href=\"http://wiki.accelereyes.com/wiki/index.php/Release_Notes#Version_1.8\" target=\"_blank\">Jacket v1.8</a> for MATLAB<span style=\"font-size: 12pt;\">®</span> now available</li>\n	<li><a href=\"http://www.accelereyes.com/wiki/libjacket/release_notes.htm\" target=\"_blank\">LibJacket v1.1</a> for C/C++/Python/Fortran now available</li>\n	<li><span style=\"font-size: 12pt;\">Request a <a href=\"mailto:support@accelereyes.com?subject=FREE%20GPU%20Computing%20Consultation&amp;body=I%20would%20like%20to%20request%20a%20FREE%20GPU%20computing%20consultation%20session%20with%20one%20of%20your%20GPU%20experts.%20%20I%20am%20available%20for%20a%20phone%20call%20during%20the%20following%20times%3A%0A%0A%3Clist%20available%20times%3E%0A\" target=\"_blank\">FREE GPU computing consultation</a></span></li>\n</ul>\n</td>\n</tr>\n<tr valign=\"top\">\n<td style=\"color: #000000; font-size: 12pt; background-color: #ffffff; font-family: arial;\" width=\"650\"><span style=\"font-size: 12pt;\"><span style=\"font-weight: bold;\">Introduction </span></span>Enhance<span style=\"font-size: 12pt;\"> your code with the fastest, most comprehensive library for GPU computing:</span>\n<ul>\n	<li><span style=\"font-size: 12pt;\"><strong>Jacket</strong> - the best GPU computing in MATLAB®.  <a href=\"http://accelereyes.com/jacket_tour\" target=\"_blank\">Take a tour</a> and <a href=\"http://accelereyes.com/compare\" target=\"_blank\">compare</a>!</span></li>\n	<li><span style=\"font-size: 12pt;\"><strong>LibJacket</strong> - the best way to kick start your CUDA development.  <a href=\"http://accelereyes.com/libjacket_tour\" target=\"_blank\">Take a tour</a>!</span></li>\n</ul>\n<span style=\"font-size: 12pt;\">Both products enable:</span>\n<ul>\n	<li><span style=\"font-size: 12pt;\">Manipulating vectors, matrices, and ND arrays</span></li>\n	<li><span style=\"font-size: 12pt;\">Support for single- and double-precision, boolean, real, and complex numbers</span></li>\n	<li><span style=\"font-size: 12pt;\">Hundreds of routines for arithmetic, linear algebra, statistics, imaging, signal processing, and more (full list: <a href=\"http://wiki.accelereyes.com/wiki/index.php/Function_List\" target=\"_blank\">Jacket</a>, <a href=\"http://wiki.accelereyes.com/wiki/libjacket/modules.htm\" target=\"_blank\">LibJacket</a>)</span></li>\n	<li><span style=\"font-size: 12pt;\">Thousands of lines of optimized code for any CUDA-capable GPU</span></li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\n<table style=\"width: 636px; height: 609px;\" border=\"0\" cellspacing=\"5\" cellpadding=\"5\">\n<tbody>\n<tr valign=\"top\">\n<td style=\"color: #000000; font-size: 12pt; background-color: #ffffff; font-family: arial;\" width=\"50%\"><span style=\"font-size: 12pt;\"><span style=\"font-weight: bold;\">New Product Features</span></span>\n<ul>\n	<li><span style=\"font-size: 12pt;\">Expanded support for the Signal Processing, Image Processing, and Statistics Libraries included with both Jacket and LibJacket</span></li>\n	<li><span style=\"font-size: 12pt;\">Faster linear algebra for special systems (e.g. symmetric, positive definite, triangular, etc.)</span></li>\n	<li><span style=\"font-size: 12pt;\">Enhanced visualizations</span></li>\n</ul>\n</td>\n<td style=\"color: #000000; font-size: 12pt; background-color: #ffffff; font-family: arial;\" width=\"50%\">\n<ul>\n	<li><img style=\"width: 75px; height: 102px;\" title=\"jacket_logo\" src=\"https://03cd632607-custmedia.vresp.com/114431ae68/jacket_logo.jpg\" alt=\"jacket_logo\" width=\"75\" height=\"102\" align=\"right\" border=\"0\" hspace=\"0\" vspace=\"0\" /><span style=\"font-size: 12pt;\">New and updated examples: FDTD, Mandelbrot fractals, maximum-likelihood neural segmentation, MDS for genomics</span></li>\n	<li><span style=\"font-size: 12pt;\">Built with CUDA 4.0 for peak performance</span></li>\n</ul>\n</td>\n</tr>\n<tr valign=\"top\">\n<td style=\"color: #000000; font-size: 12pt; background-color: #ffffff; font-family: arial;\" width=\"50%\"><span style=\"font-size: 12pt;\"><span style=\"font-weight: bold;\">Examples &amp; Benchmarks</span></span>\n<ul>\n	<li><span style=\"font-size: 10pt;\">Recent case studies: video feature learning (<a href=\"../2011/04/09/feature_learning_architectures/\" target=\"_blank\">Stanford</a>), digital holography (<a href=\"../2011/04/30/digital-holograms-faster-than-ever/\" target=\"_blank\">REAL3d</a>), hybrid LU decomposition (<a href=\"../2011/02/18/hybrid_gpu_multicore_matlab_lu_decompositions/\" target=\"_blank\">SAIC</a>), GPU Computing seminar (<a href=\"../2011/06/27/jacket-lectures-learn-and-teach-gpu-computing/\" target=\"_blank\">U Aalborg</a>), and more</span></li>\n	<li><span style=\"font-size: 10pt;\"><a href=\"../2011/01/31/stanford_gpu_benchmarks/\" target=\"_blank\"><span style=\"text-decoration: underline;\">Stanford benchmarks</span></a> show Jacket outperforms the Parallel Computing Toolbox.</span></li>\n	<li><span style=\"font-size: 10pt;\"><a href=\"http://www.accelereyes.com/products/benchmarks_libjacket\" target=\"_blank\">Benchmarks</a> showing how LibJacket outperforms <a href=\"http://software.intel.com/en-us/articles/intel-mkl/\" target=\"_blank\">MKL</a>, <a href=\"http://software.intel.com/en-us/articles/intel-ipp/\" target=\"_blank\">IPP</a>, and other CPU libraries.</span></li>\n</ul>\n</td>\n<td style=\"color: #000000; font-size: 12pt; background-color: #ffffff; font-family: arial;\" width=\"50%\"><span style=\"font-size: 12pt;\"><span style=\"font-weight: bold;\">Quick links</span></span>\n<ul>\n	<li><span style=\"font-size: 10pt;\"> <a href=\"http://www.accelereyes.com/resources/whitepapers\" target=\"_blank\">Technical Whitepapers</a> to learn how Jacket works</span></li>\n	<li><span style=\"font-size: 10pt;\">Documentation for <a href=\"http://wiki.accelereyes.com/\" target=\"_blank\"><span style=\"text-decoration: underline;\">Jacket</span></a> and <a href=\"http://accelereyes.com/wiki/libjacket\" target=\"_blank\">LibJacket</a></span></li>\n	<li><span style=\"font-size: 10pt;\"><a href=\"http://www.accelereyes.com/support\" target=\"_blank\">Online help</a> for getting started and optimizing the performance of your code</span></li>\n</ul>\n</td>\n</tr>\n<tr valign=\"top\">\n<td style=\"color: #000000; font-size: 12pt; background-color: #ffffff; font-family: arial;\" colspan=\"2\" width=\"50%\"><span style=\"font-size: 8pt;\">* MATLAB® is a registered trademark of The MathWorks, as if you didn\'t know that already :)</span></td>\n</tr>\n</tbody>\n</table>','New Product Updates - Jacket v1.8, LibJacket v1.1','','publish','open','open','','new-product-updates','','','2011-07-22 11:42:53','2011-07-22 15:42:53','',0,'http://blog.accelereyes.com/blog/?p=1540',0,'post','',0),(1569,1,'2011-08-16 12:30:13','2011-08-16 16:30:13','<img src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/tomography_fig4.png\" alt=\"\" align=\"right\" />In order to investigate changes of forest biomass, scientists use <a href=\"http://en.wikipedia.org/wiki/Tomography\">microwave tomography</a> to image the vegetation. At the smallest scale, individual plants can be imaged to investigate branching and growth, but even <a href=\"http://en.wikipedia.org/wiki/Synthetic_aperture_radar\">synthetic aperture radar</a> can reveal large-scale changes in regional ecology. To the right, you can see the experimental setup to image an individual plant.\n\n<img src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/07/tomography_fig7.png\" alt=\"\" align=\"right\" />Filtered back-projection is at the core of all of these techniques: using the inverse <a href=\"http://en.wikipedia.org/wiki/Radon_transform\">Radon transform</a> to reconstruct regular images from Fourier samples. Below you can see the final reconstructed image. Since these samples are often not on a uniform Cartesian grid, the <a href=\"http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/PIRODDI1/NUFT/NUFT.html\">non-uniform</a> version of the FFT comes into play (NUFFT), and all of this requires some serious number crunching: bring in the GPU.\n\nBased on their earlier experience using Jacket to <a href=\"http://blog.accelereyes.com/blog/2011/07/20/echo-generators/\">prototype antenna arrays</a>, Drs. Capozzoli, Curcio, di Vico, and Liseno developed a parallel implementation of NUFFT suited for GPUs. Their work was published in <a href=\"http://www.jstage.jst.go.jp/article/transcom/E94.B/7/E94.B_2092/_article\">IEICE Transactions on Communications</a>. As their paper details, NUFFT sampling and reconstruction rely heavily on <a href=\"http://wiki.accelereyes.com/wiki/index.php/Category:Interpolation\">interpolation</a> and <a href=\"http://wiki.accelereyes.com/wiki/index.php/Category:Fourier_Transforms\">FFT</a> -- two things that NVIDIA GPUs are <a href=\"http://www.accelereyes.com/products/benchmarks_jacket_fcns\">great at</a>. Evaluating the performance of various sampling schemes and parallelization techniques, they report <span style=\"color: #ff0000;\">speedups reaching 10x</span> as compared to an 8-core CPU.\n\nThanks to Drs. Capozzoli, Curcio, di Vico, and Liseno for once again sharing their work!','Filtered Back-Projection and Non-Uniform FFTs ','','publish','open','open','','back_projection','','','2011-08-16 12:30:13','2011-08-16 16:30:13','',0,'http://blog.accelereyes.com/blog/?p=1569',0,'post','',0),(1600,4,'2011-08-03 13:45:45','2011-08-03 17:45:45','From time-to-time we stumble across funny quirks while using MATLAB®.  The latest came as one of our developers accidentally mis-keyed a few characters.  With 5 characters on the command line, you too can get a message about tree cats seeing your bad code (<em>followed by a nasty seg fault, so beware</em>).  Try this:\n<pre class=\"lang:default highlight:0 decode:true crayon-selected\">&gt;&gt; a()@a\ntree_cat sees bad code\n* Subsref  [4]\n     * M_ID  0(5) which\n     * M_LRB  5(1)\n     * ExprList  [1]\n         * M_ID  6(1) e\n     * M_RRB  7(1)\ntree_cat sees bad code\n* Subsref  [4]\n     * M_ID  0(5) which\n     * M_LRB  5(1)\n     * ExprList  [1]\n         * M_ID  6(1) e\n     * M_RRB  7(1)</pre>\n<strong>Top Secret</strong>:  Part of Jacket\'s GPU runtime involves monkeys obtaining bananas for optimal performance. While we can\'t verify it, we do believe that our monkeys have formed a synergistic relationship with the cats in the trees, leading to great performance results. The cats look out for bad code, the monkeys use bananas to make it better.\n\nHave you ever stumbled upon interesting programming quirks?\n\n&nbsp;','Tree cats see your code!','','publish','open','open','','tree-cats','','','2011-08-03 13:45:45','2011-08-03 17:45:45','',0,'http://blog.accelereyes.com/blog/?p=1600',0,'post','',0),(1618,1,'2011-08-11 15:37:48','2011-08-11 19:37:48','<p style=\"text-align: justify;\">Did you ever wonder how the music visualizer in your media player works? Watching it pulsate in synchrony with the beats of the song is almost as entertaining as listening to the song itself! Researchers have been attempting to detect beats in audio signals for many years, and there are many techniques available, from the simplest (and least accurate) to more complicated algorithms that are highly accurate. All algorithms, though, perform some form of signal processing and frequency analysis, applications highly suited to GPU Computing.</p>\n<p style=\"text-align: justify;\">The beat visualizer described here was developed by researchers at Rice University, and is simple and fast. An incoming signal is broken down into six frequency bands for analysis. After smoothing out these bands and performing further signal processing steps (such as convolution and filtering), the algorithm proceeds to find the band with the highest energy.</p>\n<p style=\"text-align: justify;\">There are 4 plots shown during the analysis:</p>\n\n<ol style=\"text-align: justify;\">\n	<li>Top Left: Input audio waveform</li>\n	<li>Top Right: Output of a few functions of the input waveform</li>\n	<li>Bottom Left: 6 Spheres corresponding to 6 frequency bands. They expand when a beat is detected in that band.</li>\n	<li>Bottom Right: A sphere that pulses when a beat is detected overall.</li>\n</ol>\n[caption id=\"attachment_1621\" align=\"aligncenter\" width=\"614\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/08/music_visualizer_example.png\"><img class=\"size-large wp-image-1621\" title=\"Music Beats Visualizer\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/08/music_visualizer_example-1024x871.png\" alt=\"\" width=\"614\" height=\"523\" /></a> Music Beat Visualizer with Jacket[/caption]\n<p style=\"text-align: justify;\">Conversion of the MATLAB-based visualizer to Jacket was made possible, mainly through the clever use of two of Jacket\'s functions:</p>\n\n<ol style=\"text-align: justify;\">\n	<li>Use of the <a href=\"http://wiki.accelereyes.com/wiki/index.php/CLASS\">CLASS</a> function to execute code either on CPU or GPU, based on the input</li>\n	<li>Use of the <a href=\"http://wiki.accelereyes.com/wiki/index.php/GFOR\">GFOR</a> function to execute serial loops in parallel.</li>\n</ol>\n<p style=\"text-align: justify;\"><!--more-->The original MATLAB code was adapted for Jacket by Vidhur Vohra, a grad student at Georgia Tech. He shared with us his thoughts on converting the code to Jacket:</p>\n\n<blockquote>...The main reason for the speed up is that previously the bands were put through the functions serially, but with the capabilities of JACKET/CUDA it was possible to put all six bands through most calculations at once, thereby greatly reducing the time for computation.</blockquote>\n<p style=\"text-align: justify;\">As a result of this, the code has been observed to run up to<span style=\"color: #ff6600;\"><strong> 6 times faster</strong></span> on a Tesla C2075 (vs a Core 2 Quad CPU). The computationally-intensive core of the visualizer was observed to run<span style=\"color: #ff6600;\"> <strong>15 times faster</strong>!</span></p>\n<p style=\"text-align: justify;\"><em>Observed times:</em></p>\n<p style=\"text-align: justify;\"><span style=\"text-decoration: underline;\">Computational core (rhythm.m)</span></p>\n\n<ul style=\"text-align: justify;\">\n	<li><em>Core 2 Quad (Q9400):</em> 0.37 s per iteration</li>\n	<li><em>NVIDIA Tesla C2075:</em> 0.024 s per iteration</li>\n</ul>\n<p style=\"text-align: justify;\"><span style=\"text-decoration: underline;\">Overall:</span></p>\n\n<ul style=\"text-align: justify;\">\n	<li><em>Core 2 Quad (Q9400):</em> 11 iterations per second</li>\n	<li><em>NVIDIA Tesla C2075:</em> 64 iterations per second</li>\n</ul>\n<p style=\"text-align: justify;\">The Music Visualizer Example will soon be available with Jacket 1.9!   If you can\'t wait to try it out, you may download and install Jacket\'s nightly installers <a href=\"http://www.accelereyes.com/nightly\">from this link</a> (find out about our Nightlies <a title=\"Jacket Nightly Installers\" href=\"http://wiki.accelereyes.com/wiki/index.php/Nightly\">here</a>) and type:</p>\n\n<pre>cd [Jacket Location]\naddpath examples/music_visualizer_example\nmusic_visualizer_example gpu</pre>\n<p style=\"text-align: justify;\">We would like to thank the following for their efforts:</p>\n\n<ol style=\"text-align: justify;\">\n	<li> Kileen Cheng, Bobak Nazer, Jyoti Uppuluri and Ryan Verret at Rice University</li>\n	<li>MIT Media Lab for the original beat-detection algorithm</li>\n	<li>Vidhur Vohra, Georgia Institute of Technology</li>\n</ol>\n<p style=\"text-align: justify;\"><span style=\"text-decoration: underline;\">References:</span>\nCPU source code: Adapted from \"<a href=\"http://www.clear.rice.edu/elec301/Projects01/beat_sync/beatalgo.html\">Beat This</a>\", a beat-detection algorithm adapted from the MIT Media Lab by researchers at the Rice University.</p>\n<em>This code project won the first prize at the <a href=\"http://www.accelereyes.com/examples/coding_challenge\">Georgia Tech GPU Coding Challenge</a>. AccelerEyes is proud to have hosted this event and engaged the vibrant student community at Georgia Tech. Stay tuned for more such events at http://www.accelereyes.com!</em>','Music Beat Analysis','','publish','open','open','','music-beat-analysis','','','2011-08-11 15:37:48','2011-08-11 19:37:48','',0,'http://blog.accelereyes.com/blog/?p=1618',0,'post','',0),(1629,1,'2011-11-09 16:35:46','0000-00-00 00:00:00','The increasing availability of high performance image processing hardware, such as GPUs, and quality video sensors has opened up exciting possibilities for video processing. One such area of interest is extracting moving targets from real-time video streams, useful for various computer vision applications such as recognition, tracking, video analysis, and surveillance. It is important to have video processing capabilities that can process such large amounts of data for real-time analysis, as conventional methods are computationally expensive.\n\n&nbsp;\n\n[caption id=\"attachment_1650\" align=\"aligncenter\" width=\"615\" caption=\"Processing multiple subwindows in parallel on the GPU; each subwindow processing a moving target candidate\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/08/ngc-gfor-hist-4-e1313092762974.png\"><img class=\"size-full wp-image-1650\" title=\"gfor hist() in action\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/08/ngc-gfor-hist-4-e1313092762974.png\" alt=\"\" width=\"615\" height=\"377\" /></a>[/caption]\n\n&nbsp;\n\n<a href=\"http://www.northropgrumman.com/\" target=\"_blank\">Northrop Grumman Corporation</a> (NYSE: NOC) is a leading global security company with expertise in areas such as unmanned systems, cybersecurity, C4ISR, and logistics. Recently, Northrop Grumman found success using LibJacket to achieve <span style=\"color: #ff0000;\"><em>over <strong>4x</strong> speedup</em></span> of code detecting moving targets in sequenced video frames.\n\nNGC had a video image sequence of size 2000x2000 that needed advanced temporal image processing performed on consecutive frames, but performance on the CPU was currently lacking. Fortunately for NGC, performing image processing on large images is a task well suited for GPUs, and made easy via <a href=\"http://www.accelereyes.com/libjacket_tour?idx=0\" target=\"_blank\">LibJacket</a>.\n\n&nbsp;\n\n[caption id=\"attachment_1651\" align=\"aligncenter\" width=\"634\" caption=\"Mini example of a gfor histogram pipeline processing multiple subwindows\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/08/ngc-gfor-hist-s.png\"><img class=\"size-full wp-image-1651\" title=\"example gfor hist() pipeline\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/08/ngc-gfor-hist-s.png\" alt=\"\" width=\"634\" height=\"356\" /></a>[/caption]\n\n&nbsp;\n\nOne of the biggest performance boosts NGC gained while modifying their existing C++ code to use LibJacket, came from being able to make good use of LibJacket\'s <strong><a href=\"http://wiki.accelereyes.com/wiki/index.php/GFOR_Usage\" target=\"_blank\">gfor</a></strong> functionality.\n\nTo highlight one particular instance:\n<blockquote>Consider the task of extracting hundreds of small subwindows from an image, computing the cumulative histogram for each subwindow, then searching each histogram to find a threshold for that area, all over a 2K x 2K image as fast as possible.</blockquote>\nUsing LibJacket\'s <em>gfor-enabled <a href=\"http://wiki.accelereyes.com/wiki/index.php/Hist\" target=\"_blank\">histogram</a></em>, instead of sequentially performing hundreds of small histograms on the CPU as before, all the subwindowed histograms are combined into a single kernel launch on the GPU to run in parallel. This simple change gained <span style=\"color: #ff0000;\"><em>over <strong>8x</strong> speedup</em></span> for this stage of NGC\'s image processing pipeline, putting the goal of real-time processing within reach.\n\nAt the time of writing, about 90% of NGC\'s existing CPU moving target detection code has been successfully ported to LibJacket, totaling over 4x improvement in processing time so far. We\'re confidant that NGC will see their performance potential continue to grow.\n\n&nbsp;\n\n&nbsp;','Real-Time Moving Target Detection with LibJacket','','draft','open','open','','moving-vehicle-detection-libjacket','','','2011-11-09 16:35:46','0000-00-00 00:00:00','',0,'http://blog.accelereyes.com/blog/?p=1629',0,'post','',0),(1712,4,'2011-08-24 18:27:28','2011-08-24 22:27:28','<em>Update:  While the post below discusses LibJacket (no longer a product), you can do the same thing in the newer, but different, <a href=\"http://accelereyes.com/arrayfire\">ArrayFire library</a>.  Improved performance benchmarks and a simpler API are the results of moving from LibJacket to ArrayFire.</em>\n\nMcclanahoochie just <a href=\"http://mcclanahoochie.com/blog/2011/08/image-processing-with-libjacket-opencv/\" target=\"_blank\">posted</a> some code and instructions for pairing OpenCV with LibJacket to get accelerated computer vision.  You can do really fast image processing on video cam feeds too, see picture below:\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/08/Screen-shot-2011-08-24-at-2.42.52-PM.png\"><img class=\"aligncenter size-large wp-image-1713\" title=\"Screen-shot-2011-08-24-at-2.42.52-PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/08/Screen-shot-2011-08-24-at-2.42.52-PM-1024x640.png\" alt=\"\" width=\"614\" height=\"384\" /></a></p>\n<p style=\"text-align: left;\">Really cool stuff.  Computer vision is really hot with applications emerging in defense, radiology, games, automotive, and other consumer applications.</p>\n<p style=\"text-align: left;\">Computer vision algorithms like these are also going mobile.  For instance, we have started to build <a href=\"http://accelereyes.com/mobile\" target=\"_blank\">LibJacket for Mobile applications</a>, which runs on Tegra, PowerVR, and other mobile GPU chips.  Portable cameras + portable GPU power makes for some fascinating new application possibilities.</p>\n<p style=\"text-align: left;\">Are you working on computer vision applications?  If so, we\'d love to hear from you.</p>\n<p style=\"text-align: left;\">Related: <a title=\"Image Processing with ArrayFire and OpenCV on the GPU\" href=\"http://blog.accelereyes.com/blog/2012/09/19/image-processing-with-arrayfire-and-opencv/\">ArrayFire+OpenCV.</a></p>','Fast Computer Vision with OpenCV and ArrayFire','','publish','open','open','','fast-computer-vision','','\nhttp://mcclanahoochie.com/blog/2011/08/image-processing-with-libjacket-opencv/','2011-08-24 18:27:28','2011-08-24 22:27:28','',0,'http://blog.accelereyes.com/blog/?p=1712',0,'post','',0),(1720,4,'2011-09-01 00:20:42','2011-09-01 04:20:42','To explore the differences between CPU-only computing and GPU-accelerated computing, the new Jacket Demo is really convenient.  The Jacket Demo automatically launches two MATLAB® sessions, one running on the CPU-only and the other running on the GPU with Jacket.\n\nThis side-by-side demo shows the computational speed of each processor as well as a visual depiction of the algorithm\'s progression.  A variety of different demos are provided.\n\nThe Jacket Demo is included in every Jacket installation (found in the examples directory and launchable from the Start Menu in Windows).\n\nCheckout this video of the Jacket Demo in action on an i7 CPU with a Tesla C2050 GPU.  Enjoy!\n\n<iframe src=\"http://www.youtube.com/embed/KeVFm5NriVo\" frameborder=\"0\" width=\"700\" height=\"431\"></iframe>','Jacket Demo - CPU vs GPU runtimes on MATLAB® code','','publish','open','open','','jacket_demo','','','2011-09-01 00:20:42','2011-09-01 04:20:42','',0,'http://blog.accelereyes.com/blog/?p=1720',0,'post','',1),(1747,4,'2011-09-12 22:42:23','2011-09-13 02:42:23','Ever since AccelerEyes began over 4 years ago, naysayers have flippantly tossed out the idea that somehow computing on discrete GPUs will soon go away. Some thought AMD\'s Fusion would become the demise of discrete GPU computing. Others thought that Intel\'s integrated graphics would squeeze high-end GPUs out of the market.\n\nNeither is anywhere close to disrupting the utility of discrete GPUs (especially those currently available from NVIDIA) for solving computational challenges that face domain professionals.\n\nToday, Jon Peddie Research <a href=\"http://jonpeddie.com/media/presentations/an-analysis-of-the-gpu-market/\">introduced a free whitepaper</a> describing the market forces and the sales projections of GPUs.  From the article:\n\n\"The facts speak for themselves. Those who are concerned about graphics performance will buy discrete GPU systems. As good as they are, embedded graphics processors will never be a replacement for a powerful discrete GPU...  Discrete GPUs have, and will continue to hold, a multi-year lead over integrated graphics, and software applications and operating systems aren\'t standing still. Therefore, the notion that the evolution of integration spells the end of discrete GPUs just isn\'t founded.\"\n\nWe continue to see the rise of GPU computing positively impact the growth of AccelerEyes and are delighted to see so many of our customers achieving great acceleration with Jacket technology.\n\nTo the naysayers out there, you might consider giving this a closer look :)','Discrete GPUs are here to stay','','publish','open','open','','discrete-gpus-are-here-to-stay','','','2011-09-12 22:42:23','2011-09-13 02:42:23','',0,'http://blog.accelereyes.com/blog/?p=1747',0,'post','',2),(1756,1,'2011-09-26 18:30:13','2011-09-26 22:30:13','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/09/OpenCV_Logo.png\"><img class=\"alignright size-full wp-image-1777\" title=\"OpenCV_Logo\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/09/OpenCV_Logo.png\" alt=\"\" width=\"239\" height=\"295\" /></a><a title=\"OpenCV\" href=\"http://opencv.willowgarage.com/wiki/\">OpenCV</a> is one of the most popular computer vision toolkits, and over the last year they\'ve been integrating more <a href=\"http://opencv.willowgarage.com/wiki/OpenCV_GPU\">GPU processing</a> into the core.\n\nOne of the most common image processing tasks is convolution. Since LibJacket and <a href=\"http://opencv.itseez.com/modules/imgproc/doc/filtering.html\">OpenCV</a> both support this, one of my coworkers rolled up his sleeves and benchmarked the latest versions from both libraries: OpenCV/CPU, OpenCV/GPU, LibJacket.\n\nJump over to his personal website for the <a href=\"http://mcclanahoochie.com/blog/2011/09/opencv-vs-libjacket-gpu-sobel-filtering/\">full benchmark results and source code</a>.  From the graphs, the GPU implementations from OpenCV and LibJacket both easily outperform the default CPU version in OpenCV, but notice that LibJacket pushes performance even further and dominates OpenCV\'s GPU implementation, especially when using separable filters.\n\nWe\'ve worked really hard the last few years to produce a reliable, high-performance commercial library and run-time.  If you\'re interested in the best software for GPU computing, you might consider buying a license to save yourself time and to boost the end-to-end performance of your code.\n\nTo learn more about LibJacket, <a href=\"http://accelereyes.com/libjacket_tour\">take the tour</a>.\n\n&nbsp;\n\nRelated: <a title=\"Image Processing with ArrayFire and OpenCV on the GPU\" href=\"http://blog.accelereyes.com/blog/2012/09/19/image-processing-with-arrayfire-and-opencv/\">ArrayFire+OpenCV.</a>','Filtering Benchmarks - OpenCV GPU vs LibJacket','','publish','open','open','','opencv','','\nhttp://mcclanahoochie.com/blog/2011/09/opencv-vs-libjacket-gpu-sobel-filtering/','2011-09-26 18:30:13','2011-09-26 22:30:13','',0,'http://blog.accelereyes.com/blog/?p=1756',0,'post','',0),(1791,6,'2011-10-27 16:24:58','2011-10-27 20:24:58','AccelerEyes invites you to participate in series of <a title=\"Register for Webinar Series\" href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?nomenu=true&amp;siteurl=accelereyes&amp;service=6&amp;rnd=0.4385461764274333&amp;main_url=https%3A%2F%2Faccelereyes.webex.com%2Fec0605ld%2Feventcenter%2Fprogram%2FprogramDetail.do%3FtheAction%3Ddetail%26siteurl%3Daccelereyes%26cProgViewID%3D0\" target=\"_blank\"><span style=\"color: #0000ff;\">webinars</span></a> designed to help you learn more about <a title=\"Information on Jacket for MATLAB\" href=\"http://www.accelereyes.com/products/jacket\" target=\"_blank\">Jacket</a> for MATLAB® and <a title=\"Information on LibJacket\" href=\"http://www.accelereyes.com/products/libjacket\" target=\"_blank\">LibJacke</a>t for C/C++/Fortran/Python, a comprehensive library of GPU-accelerated functions.\n\n<strong>Joint Webinar With NVIDIA: LibJacket CUDA Library</strong>\n\nOn October 20th we co-hosted a<a title=\"Recording of NVIDIA Joint Webinar\" href=\"http://developer.download.nvidia.com/CUDA/training/LibJacket_Oct2011.mp4\" target=\"_blank\"> joint webinar with NVIDIA</a>.  During this well-attended event, our GPU computing experts provided a general product overview and usage of the LibJacket CUDA library.  Several impressive <a title=\"demos\" href=\"http://blog.accelereyes.com/blog/2011/09/01/jacket_demo/\" target=\"_blank\">demos</a> of LibJacket in action were provided as well.  LibJacket supports hundreds of <a title=\"LibJacket Functions\" href=\"http://wiki.accelereyes.com/wiki/libjacket/modules.htm\" target=\"_blank\"><span style=\"color: #0000ff;\">GPU computing functions</span></a> and programmers in numerous industries have been able to speedup applications.  Be sure to check out the Q&amp;A session included in the <a title=\"Go to Recorded Webinar\" href=\"http://developer.download.nvidia.com/CUDA/training/LibJacket_Oct2011.mp4\" target=\"_blank\"><span style=\"color: #0000ff;\">recorded webinar</span></a> posted on NVIDIA’s Developer Zone. Thanks again to NVIDIA for co-hosting this informative webinar!\n<div class=\"mceTemp\">\n\n[caption id=\"attachment_1805\" align=\"aligncenter\" width=\"350\" caption=\"Graphics library: Tweaked FDTD (example in LibJacket package)\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/10/Graphics-Lib-1.png\"><img class=\"size-full wp-image-1805\" title=\"Graphics Library 1\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/10/Graphics-Lib-1.png\" alt=\"\" width=\"350\" height=\"205\" /></a>[/caption]\n\n</div>\n<strong>GPU Programming for Defense/Intelligence Apps: </strong><strong><span style=\"color: #0000ff;\"><a title=\"Register for Webinar\" href=\"http://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">November 15, 2011</a> </span></strong><strong>at 3:00 p.m. EST</strong>\n\nMajor defense and intelligence institutions are discovering just how effective GPU computing can be in enabling unique solutions using Jacket and LibJacket.  Come and learn how to accelerate common defense and intelligence algorithms using easy, powerful programming libraries, with Jacket for MATLAB® and LibJacket for C/C++/Fortran.\n\n<strong>LibJacket CUDA Library for Maximus Applications:  </strong><strong><span style=\"color: #0000ff;\"><a title=\"Register for Webinar\" href=\"http://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">December 15, 2011</a></span></strong><strong> at 3:00 p.m. EST</strong>\n\nLearn how to integrate computations with visualizations in a CUDA-based application through simple visualization functions for plotting, image and volume rendering, and more.\n<div class=\"mceTemp\">\n\n[caption id=\"attachment_1807\" align=\"aligncenter\" width=\"350\" caption=\"Graphics library: simulating shallow water equations with reflective\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/10/Graphics-Lib-2.png\"><img class=\"size-full wp-image-1807\" title=\"Graphics Library 2\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/10/Graphics-Lib-2.png\" alt=\"\" width=\"350\" height=\"205\" /></a>[/caption]\n\n</div>\nThe series will be conducted by AccelerEyes’ team of GPU computing experts and will include live demos of Jacket and LibJacket.   We hope you will <a title=\"Register for Webinar\" href=\"http://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\"><span style=\"color: #0000ff;\">join us</span></a> as we discuss exciting developments in GPU computing software!','AccelerEyes Webinar Series','','publish','open','open','','accelereyes-webinar-series','','','2011-10-27 16:24:58','2011-10-27 20:24:58','',0,'http://blog.accelereyes.com/blog/?p=1791',0,'post','',0),(1891,6,'2011-11-23 17:47:52','2011-11-23 21:47:52','<p style=\"text-align: justify;\">Lenovo and AccelerEyes have a joint solution for optimizing M code on Lenovo workstations.  The combined HPC solution combines high Intel Xeon CPU performance for daily productivity with unprecedented NVIDIA graphics (GPU) performance for parallel computing with Jacket. Jacket’s comprehensive benchmark suite, when run on Lenovo ThinkStation systems, shows tremendous amounts of speedups for a wide variety of computationally-intensive applications.</p>\n\n<div class=\"mceTemp\">\n<div class=\"mceTemp\">\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/11/Lenovo-ThinkStations.png\"><img class=\"aligncenter size-full wp-image-1901\" title=\"Lenovo ThinkStations\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/11/Lenovo-ThinkStations.png\" alt=\"\" width=\"682\" height=\"312\" /></a>\n<p style=\"text-align: justify;\">Jacket is the world’s fastest and broadest GPU software accelerating the M-language commonly found in MATLAB®.  Thousands of customers around the world have used Jacket to accelerate their MATLAB code.</p>\n<p style=\"text-align: justify;\">Lenovo ThinkStation systems are ideally suited for running real-world high-performance applications using Jacket. While the high-end CPUs are ideal for daily productivity tasks, Jacket and the Quadro GPUs perform HPC operations with ease.</p>\n<p style=\"text-align: justify;\">To demonstrate the value gained by upgrading to a ThinkStation with an NVIDIA Quadro, benchmarks were run on the E20, S20 and D20 systems with Jacket and a variety of GPUs. We combined each of the three systems with three different GPUs in a good-better-best configuration, to create 9 different hardware test environments for the Jacket benchmark suite.</p>\n<p style=\"text-align: justify;\">The resulting speed-ups achieved over the baseline system show tremendous speed advantages that get wider as the configuration gets better.  It is worth noting that with the Jacket MGL add-on, you can run code on multiple GPUs on the same machine. We observed a performance boost of up to 90% with each additional GPU added to the system.</p>\n<p style=\"text-align: justify;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/11/Lenovo-Measured-Speedups-e1320954198284.png\"><img class=\"aligncenter size-full wp-image-1905\" title=\"Lenovo Measured Speedups\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/11/Lenovo-Measured-Speedups-e1320954198284.png\" alt=\"\" width=\"600\" height=\"348\" /></a></p>\n<p style=\"text-align: justify;\">Jacket has a wide range of domain-specific library functions available for free. Functions for Image, Signal and Video Processing, statistics and graphics are included with the Jacket package. This allows domain professionals to get going right away without the added hassle of choosing which packages to buy.  Jacket combines high-level programmability in M-code with the ability to control the nuts and bolts. Using the Jacket SDK, you can create customized computational kernels for your domain-specific algorithms using the same code that many of Jacket’s functions are written in. Functions that use Jacket SDK plug in effortlessly to Jacket’s core and benefit from Jacket’s automated optimizations.  Jacket code is deployable to machines without a MATLAB or Jacket license. Using the Jacket JMC add-on, your code can be compiled either into an executable package or a library that can be linked into other programs.</p>\n<p style=\"text-align: justify;\">The Lenovo ThinkStation with Jacket is a high-performance, power-efficient advanced workstation HPC platform solution that brings supercomputing power to MATLAB users for a fraction of the cost. With its demonstrated ability to achieve high speedups across a variety of applications, Jacket for MATLAB will help you harness the ThinkStation’s full computing potential.</p>\n<p style=\"text-align: justify;\"></p>\n\n</div>\n</div>','Jacket on Lenovo Systems','','publish','open','open','','jacket-on-lenovo-systems','','','2011-11-23 17:47:52','2011-11-23 21:47:52','',0,'http://blog.accelereyes.com/blog/?p=1891',0,'post','',1),(1933,6,'2011-11-21 14:39:22','2011-11-21 18:39:22','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/11/array_fire_mini_logo_krunal1.png\"><img class=\"aligncenter size-medium wp-image-1940\" title=\"array_fire_mini_logo_krunal\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/11/array_fire_mini_logo_krunal1-300x64.png\" alt=\"\" width=\"300\" height=\"64\" /></a><strong><strong>A free, fast, and simple GPU library for CUDA and OpenCL devices.</strong></strong>\n<p style=\"text-align: justify;\">AccelerEyes announces the launch of ArrayFire, a freely-available GPU software library supporting CUDA and OpenCL devices.</p>\n<p style=\"text-align: justify;\">ArrayFire supports C, C++, Fortran, and Python languages on AMD, Intel, and NVIDIA hardware.  Learn more by visiting the ArrayFire <a title=\"ArrayFire Product Info\" href=\"http://www.accelereyes.com/products/ArrayFire\">product page</a>.</p>\n<p style=\"text-align: justify;\">\"ArrayFire is our best software yet and anyone considering GPU computing can benefit,\" says James Malcolm, VP Engineering at AccelerEyes.  \"It is fast, simple, GPU-vendor neutral, full of functions, and free for most users.\"</p>\n<p style=\"text-align: justify;\">Thousands of paying customers currently enjoy AccelerEyes’ GPU software products.  With ArrayFire, everyone developing software for GPUs has an opportunity to enjoy these benefits without the upfront expense of a developer license.</p>\n\n<h4>Reasons to use ArrayFire:</h4>\n<ul>\n	<li><strong>Fast.</strong>  It beats other CPU and GPU acceleration software.  Benchmark it yourself!</li>\n	<li><strong>Friendly.</strong>  You can learn it in minutes.  It is super easy to use.</li>\n	<li><strong>Useful.</strong>  It will benefit your code.  It contains the largest set of GPU software functions in the world.</li>\n	<li><strong>HW-neutral.</strong>  Run on your favorite hardware.  ArrayFire code runs on any CUDA or OpenCL device.</li>\n	<li><strong>Proven.</strong>  AccelerEyes’ software is relied upon by thousands of active users.  You can tap great support on the ArrayFire <a href=\"http://forums.accelereyes.com/\" target=\"_blank\">forums</a>.</li>\n	<li><strong>GFOR.</strong>  You get the powerful and only GPU FOR-loop in the world.</li>\n	<li><strong>Multi-GPU Scalable.</strong>  You can scale from one to multiple GPUs in minutes with one simple function call.</li>\n	<li><strong>Graphics.</strong>  Beautiful OpenGL visualizations, adding eye-candy to your acceleration.</li>\n</ul>\n<p style=\"text-align: justify;\">\"We are excited to make ArrayFire free to most customers,\" says John Melonakos, CEO of AccelerEyes.  \"We see too many organizations frustrated by the difficulty of programming GPUs today.  ArrayFire removes that frustration, enabling GPU tire-kickers to realize the true benefits of the powerful GPU hardware.\"</p>\n<p style=\"text-align: justify;\">It is well-supported commercial software at open-source prices.  Visit <a title=\"AccelerEyes\" href=\"http://www.accelereyes.com/\">our website</a> to download the new software today!</p>\n<p style=\"text-align: justify;\"><strong>Pricing and Availability</strong><strong> </strong></p>\n<p style=\"text-align: justify;\">ArrayFire is free for most users.  To learn more about ArrayFire licensing, visit the ArrayFire <a title=\"ArrayFire Licensing\" href=\"http://www.accelereyes.com/products/arrayfire_licensing\">licensing page</a>.</p>\n<p style=\"text-align: justify;\"><strong>Try our Professional Services</strong></p>\n<p style=\"text-align: justify;\">AccelerEyes provides professional GPU consulting services.  Our team of engineers guarantees great results from GPU computing.  Equipped with ArrayFire and years of experience, our experts deliver results in fewer hours than any other consulting firms.  Set up a free GPU consultation today by emailing us at <a href=\"mailto:sales@accelereyes.com\">sales@accelereyes.com</a>.</p>\n<p style=\"text-align: justify;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2010/08/accelereyes_logo_small_nobg_w180px.jpg\"><img class=\"aligncenter size-full wp-image-619\" title=\"accelereyes_logo_small_nobg_w180px\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2010/08/accelereyes_logo_small_nobg_w180px.jpg\" alt=\"AccelerEyes Logo\" width=\"180\" height=\"70\" /></a></p>','AccelerEyes Releases ArrayFire GPU Software','','publish','open','open','','accelereyes-releases-arrayfire-gpu-software','','','2011-11-21 14:39:22','2011-11-21 18:39:22','',0,'http://blog.accelereyes.com/blog/?p=1933',0,'post','',1),(1984,6,'2011-12-08 15:03:23','2011-12-08 19:03:23','<p style=\"text-align: left;\" align=\"center\"><strong><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/12/jacket_logo.png\"><img class=\"alignright\" title=\"jacket_logo\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/12/jacket_logo-300x235.png\" alt=\"\" width=\"240\" height=\"188\" /></a></strong></p>\n<p style=\"text-align: left;\" align=\"center\"><strong>New Multi-GPU functionality <strong>, added support for OpenCL devices, and much more...</strong></strong></p>\n<p style=\"text-align: left;\" align=\"center\"><strong><strong></strong></strong>AccelerEyes announces the release of Jacket version 2.0, adding GPU computing capabilities for use with MATLAB®.  Version 2.0 delivers even more speed through a host of new improvements, maximizing GPU device performance and utilization.</p>\nNotable new features include a multi-GPU interface and support for OpenCL devices. With Jacket v2.0, your M-code is now portable across all major GPU devices, including AMD/ATI, Intel, and NVIDIA chips.\n\n<a title=\"About Jacket\" href=\"http://www.accelereyes.com/products/jacket\">Jacket</a> is the premier GPU software plugin for MATLAB®, <a title=\"Compare Jacket\" href=\"http://www.accelereyes.com/products/compare\">better</a> than alternative solutions.  It is relied upon by thousands of organizations for rapid prototyping and problem solving across a range of government, manufacturing, energy, media, biomedical, financial, and scientific research applications.\n\n<strong>Multi-GPU Details:</strong>\n<ul>\n	<li>Control over all GPUs in your program through simple, fast GPU selection functions.  Jacket automatically handles communication between the GPU devices, without the need to launch bulky parallel computing workers</li>\n	<li>GINFO, GSELECT, GSYNC all extended to handle multiple devices</li>\n</ul>\n<strong>OpenCL Details:</strong>\n<ul>\n	<li>Supports single precision, floating point, real, and complex types</li>\n	<li>Supports array math, FFTs, element-wise operations, and more</li>\n	<li>Selection of any OpenCL compliant device listed in GINFO</li>\n	<li>Currently available as a FREE beta feature, <a title=\"Download Jacket\" href=\"https://accelereyes.com/licenses_jacket\">download now</a></li>\n</ul>\n<strong>Other Notable Improvements:</strong>\n<ul>\n	<li>New Base Jacket Functions, such as MEDIAN and PROD</li>\n	<li>Additional Image Processing Library functions</li>\n	<li>Additional Statistics Library functions</li>\n	<li>Additional Signal Processing Library functions</li>\n	<li>Support for binary to decimal conversion with BI2DE, DE2BI</li>\n	<li>New Demos (included in every download):\n<ul>\n	<li>Defense Optical Flow Tracking example, Music Visualizer example, and new Jacket CPU v. GPU demo</li>\n</ul>\n</li>\n	<li>Financial example of Black-Scholes with GCOMPILE is 35X faster than CPU<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/12/jacket_logo.png\">\n</a></li>\n</ul>\nVisit our <a href=\"http://www.accelereyes.com/\">company website</a> and see the <a href=\"http://wiki.accelereyes.com/wiki/index.php/Release_Notes\">v2.0 release notes</a> for the full list of enhancements.\n\n<strong>Pricing and Availability</strong>\n\nJacket v2.0 is available for download on the AccelerEyes website.  Pricing for a Jacket base license with support for a single GPU is $999.00 USD for commercial and $350.00 USD for academic customers.  AccelerEyes provides 12 months of software maintenance and updates with each software license.  Volume packages and development bundles are also <span style=\"color: #0000ff;\">now available</span> at special price points.\n\n<strong>Try our Professional Services</strong>\n\nAccelerEyes provides professional GPU consulting services.  Our team of engineers guarantees great results from GPU computing.  Equipped with Jacket and years of experience, our experts deliver results in fewer hours than any other consulting firms.  Set up a <a href=\"mailto:support@accelereyes.com?subject=FREE%20GPU%20Computing%20Consultation&amp;body=I%20would%20like%20to%20request%20a%20FREE%20GPU%20computing%20consultation%20session%20with%20one%20of%20your%20GPU%20experts.%20%20I%20am%20available%20for%20a%20phone%20call%20during%20the%20following%20times%3A%0A%0A%3Clist%20available%20times%3E%0A\">free GPU consultation</a> today.','Jacket v2.0 Now Available','','publish','open','open','','jacket-version-2-0','','','2011-12-08 15:03:23','2011-12-08 19:03:23','',0,'http://blog.accelereyes.com/blog/?p=1984',0,'post','',0),(2133,6,'2012-01-12 11:51:10','2012-01-12 15:51:10','AccelerEyes invites you to participate in series of <a title=\"Register for Webinar Series\" href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?nomenu=true&amp;siteurl=accelereyes&amp;service=6&amp;rnd=0.4385461764274333&amp;main_url=https%3A%2F%2Faccelereyes.webex.com%2Fec0605ld%2Feventcenter%2Fprogram%2FprogramDetail.do%3FtheAction%3Ddetail%26siteurl%3Daccelereyes%26cProgViewID%3D0\" target=\"_blank\">webinars</a> designed to help you learn more about <a title=\"Learn about Jacket for MATLAB\" href=\"http://www.accelereyes.com/products/jacket\" target=\"_blank\">Jacket</a> for MATLAB® and <a title=\"Learn about ArrayFire\" href=\"http://www.accelereyes.com/products/arrayfire\" target=\"_blank\">ArrayFire</a> for C/C++/Fortran/Python, a comprehensive library of GPU-accelerated functions.\n\n<strong>GPU Programming for Medical Image Segmentation: <a title=\"Register for Webinar\" href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">January </a></strong><strong><a title=\"Register for Webinar\" href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">18, 2012</a> </strong><strong>at 3:00 p.m. EST</strong>\n<p style=\"text-align: justify;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/01/brainimagesm.jpg\"><img class=\"alignright  wp-image-2054\" title=\"brainimagesm\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/01/brainimagesm-225x300.jpg\" alt=\"\" width=\"203\" height=\"270\" /></a>There\'s a huge volume of data generated using acquisition modalities like computer tomography (CT), magnetic resonance imaging (MRI), positron emission tomography or nuclear medicine. A common need is to manipulate and transmit this data using compression techniques in as little time as possible. During this webinar we will show Jacket’s superior speed and handling volumes from subscripting to convolutions.  Come and learn how to accelerate common medical imaging applications using an easy, powerful programming library with Jacket for MATLAB®.</p>\n<strong>OpenCL and CUDA Trade-Offs and Comparison: <a title=\"Register for Webinar\" href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">February 15</a></strong><strong><a title=\"Register for Webinar\" href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">, 2012</a></strong><strong> at 3:00 p.m. EST</strong>\n<p style=\"text-align: justify;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/12/raindrop.png\"><img class=\"alignleft size-medium wp-image-2040\" title=\"raindrop\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/12/raindrop-300x140.png\" alt=\"\" width=\"300\" height=\"140\" /></a>The OpenCL standard continues to mature and is now (or soon will be) supported by a variety of GPUs and manycore processors. At AccelerEyes, we remain at the forefront of OpenCL development. ArrayFire OpenCL is a fast software library for GPU computing with a simple API.  In this informative webinar, our team of GPU experts will discuss OpenCL and CUDA trade-offs and comparisons.  In addition, you\'ll get to see ArrayFire OpenCL in action with real code.</p>\n<strong>GPU Programming for Financial Computing:  <a title=\"Register for Webinar\" href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">March 15</a><a title=\"Register for Webinar\" href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">, 2012</a> at 3:00 p.m. EST</strong>\n<p style=\"text-align: justify;\">Quantitative analysts are discovering the benefits of leveraging GPUs in tackling complex financial computing models. Using Jacket\'s computational horsepower, analysts can employ a variety of functions to achieve speedups in trade signal generation, complex derivative pricing, evaluating risk scenarios, and more. In this webinar, we\'ll discuss the latest developments in GPU programming for financial computing.</p>\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/01/financial_modeling-300x225.jpg\"><img class=\"aligncenter size-full wp-image-2069\" title=\"financial_modeling-300x225\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/01/financial_modeling-300x225.jpg\" alt=\"\" width=\"300\" height=\"225\" /></a>\n<p style=\"text-align: justify;\">Each webinar will be conducted by AccelerEyes’ team of GPU computing experts and will include live demos of Jacket and ArrayFire.   We hope you will <a title=\"Register for Webinar\" href=\"http://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\" target=\"_blank\">join us</a> as we discuss exciting developments in GPU computing software!</p>','AccelerEyes Webinar Series','','publish','open','open','','accelereyes_webinars_2012q1','','','2012-01-12 11:51:10','2012-01-12 15:51:10','',0,'http://blog.accelereyes.com/blog/?p=2133',0,'post','',1),(2166,1,'2012-01-17 18:19:30','2012-01-17 22:19:30','<p style=\"text-align: justify;\">We recently reported that Jacket <a title=\"CUDA over Remote Desktop now available for Tesla GPUs\" href=\"http://blog.accelereyes.com/blog/2011/02/10/cuda_remote_desktop_for_tesla_gpus/\">could be used over</a> Windows Remote Desktop connections as long as you had an NVIDIA Tesla device in TCC mode. With the latest NVIDIA driver updates, Tesla <em>and</em> Quadro devices can be put into TCC mode, making it possible to use Jacket over Remote Desktop with both Tesla <em>and</em> Quadro devices.</p>\n<p style=\"text-align: justify;\">We have tested this out with the NVIDIA Quadro 4000 as well as Quadro 6000 GPUs. The system had a Tesla C2050 connected to the display, and the Quadro in TCC mode. Here\'s the ginfo output:</p>\n\n<pre class=\"lang:default highlight:0 decode:true crayon-selected\">&gt;&gt; ginfo\nJacket v2.0 (build 80c7ba4) by AccelerEyes (64-bit Windows)\nLicense Type: Designated Computer ([JACKET_ROOT]jacketenginejlicense.dat)\nAddons: MGL4, JMC, SDK, DLA, SLA\nCUDA toolkit 4.0, driver 285.62\nGPU1 Quadro 4000, 2048 MB, Compute 2.0 (single,double)\nMemory Usage: 1977 MB free (2048 MB total)</pre>\n<p style=\"text-align: justify;\">Jacket over Remote Desktop is documented extensively on the <a title=\"AccelerEyes Wiki - Jacket Over Remote Connections\" href=\"http://wiki.accelereyes.com/wiki/index.php/Jacket_Over_Remote_Connections\">AccelerEyes Wiki</a>. Please check that page for more information.</p>\n<p style=\"text-align: justify;\"></p>','Jacket over Remote Desktop for Tesla and Quadro GPUs','','publish','open','open','','jacket-over-remote-desktop-for-tesla-and-quadro-gpus','','','2012-01-17 18:19:30','2012-01-17 22:19:30','',0,'http://blog.accelereyes.com/blog/?p=2166',0,'post','',1),(2173,1,'2012-01-19 17:59:37','2012-01-19 21:59:37','In case you missed it, we recently held a webinar on how to accelerate common medical imaging applications using an easy, powerful programming library with Jacket for MATLAB®.\n\nThis webinar was part of an ongoing <a href=\"http://blog.accelereyes.com/blog/2012/01/12/accelereyes_webinars_2012q1/\">series of webinars</a> that will help you learn more about the many applications of Jacket and ArrayFire, while interacting with AccelerEyes GPU computing experts.  Gallagher Pryor, CTO of AccelerEyes, used the Bayesian Image Segmentation algorithm as a simple use-case to show how easy it is to convert CPU code to GPU code with Jacket (only 4 lines of CPU code needed to be changed!).\n\nFor those of you who missed it, we uploaded the webinar on Youtube. We hope to see you at <a href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\">the next one</a>!\n\n<center><iframe src=\"http://www.youtube.com/embed/yWaibjgdOEg\" frameborder=\"0\" align=\"center\" width=\"420\" height=\"315\"></iframe></center>','Webinar - Jacket for Medical Image Segmentation','','publish','open','open','','accelereyes-webinar-video-medica','','','2012-01-19 17:59:37','2012-01-19 21:59:37','',0,'http://blog.accelereyes.com/blog/?p=2173',0,'post','',0),(2200,4,'2012-02-15 17:58:52','2012-02-15 21:58:52','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/maria_tweet1.png\"><img class=\"aligncenter size-full wp-image-2202\" title=\"maria_tweet\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/maria_tweet1.png\" alt=\"\" width=\"525\" height=\"76\" /></a>\n\nThe question above comes from María (<a href=\"http://twitter.com/turbonegra\">@turbonegra</a>).  She follows us <a href=\"http://twitter.com/accelereyes\">@accelereyes</a>.  Many of you are wondering when ArrayFire support for new CUDA version 4.1 will be released.  The answer: work is currently under way.\n\nCUDA 4.1 includes a <a href=\"http://www.tomshardware.com/news/nvidia-cuda-gpu-developer-llvm,14579.html\">new Fermi compiler</a>, and many people in the GPU ecosystem have <a href=\"http://forums.nvidia.com/index.php?showtopic=222547\">reported slowdowns</a> from upgrading to the new CUDA version. So we\'ve delayed releasing ArrayFire and Jacket support for CUDA 4.1 because we want to verify performance and reliability across all our unit tests, performance regressions, and customer code samples.  Our tests sweep across various driver versions and everything from mobile GeForce cards through server-grade Tesla and Fermi chips.\n\nWe are still working through the testing and verification at the moment. While <a href=\"http://developer.download.nvidia.com/CUDA/training/CUDA_4_1_Webinar_v11-11-22.pdf\">NVIDIA\'s general claim of 10% performance benefit</a> are a bit fluffy, things do look <strong>good</strong> overall, and we believe CUDA 4.1 is ready for prime time. Various FFT, BLAS, and LAPACK routines show solid performance enhancements. In the few places where we have observed a performance degradation (e.g. linear texturing), we are working closely with NVIDIA to ensure these are addressed in coming driver and toolkit releases.\n\nWe\'ll post here and on <a href=\"http://twitter.com/accelereyes\">twitter</a> when CUDA 4.1 support ready in ArrayFire and Jacket. Stay tuned!\n\n&nbsp;\n\nPS:  Thanks to María for prompting this post :)','ArrayFire Support for CUDA 4.1','','publish','open','open','','arrayfire-support-for-cuda-4-1','','','2012-02-15 17:58:52','2012-02-15 21:58:52','',0,'http://blog.accelereyes.com/blog/?p=2200',0,'post','',0),(2227,1,'2012-02-17 13:44:45','2012-02-17 17:44:45','In case you missed it, we recently held an ArrayFire Webinar, focused on exploring the tradeoffs of OpenCL vs CUDA.\n\nThis webinar is part of an ongoing <a href=\"http://blog.accelereyes.com/blog/2012/01/12/accelereyes_webinars_2012q1/\">series of webinars</a> held each month to present new GPU software topics as well as programming techniques with Jacket and ArrayFire.\n\nFor those of you who missed it, we provide a recap here. Lots of questions were fielded by our team, so it\'s a must-watch. We hope to see you at <a href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\">the next one</a>!\n<h3>Recap</h3>\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/CUDAvsOpenCL.pdf\">Download the slides</a>.  Here is a transcript of the content portion of the webinar:\n\nAccelerEyes is pleased to present today\'s ArrayFire webinar looking at OpenCL and CUDA Trade-offs and Comparisons. Everyday, we interact with many programmers in various stages of GPU development projects. In making GPU project decisions, there is a lot of information to absorb from a variety of sources. The intent of this webinar is to condense this information into the key points that matter, to help you digest GPU computing software decisions.\n\nOver the last 5 years, as we\'ve collected information from our GPU computing customers, we\'ve determined that there are 5 core GPU software features that programmers seek in a technology. These include:\n<ul>\n	<li>Performance:  This is the core motivation for GPU computing and relates to quality. \"How good will my code end up?\" is the question here. \"How fast can I push it?\"</li>\n	<li>Scalability:  This is related to labor costs and quality of results. \"If I develop my code on a workstation, can I launch it on a cluster without major headaches?\" is the question here.</li>\n	<li>Portability:  This is related to flexibility and costs, both labor costs and fixed hardware costs. It can also lead to a question of quality and freedom to move code to better or newer hardware that emerges.</li>\n	<li>Community:  This is a broad term meant to encompass other terms like support, logevity, commitment, etc. It is important that the technology platform has a lot of users and momentum. It is important that investments made today persist and pay dividends down the road.</li>\n	<li>Programmability:  A sense of how much labor and effort are required to get good performance. This includes a sense of the software platform\'s robustness to bugs, availability of functionality, and time to get from project start to successful project end.</li>\n</ul>\n<div><!--more--></div>\nWe\'ve arranged this webinar to address these five GPU Software Features for the two major GPU computing platforms, CUDA and OpenCL. For each of these features, we will share some of our thoughts on how CUDA and OpenCL compare. Then we will conclude the discussion of each feature with some comments on how the feature relates to ArrayFire (those slides have an ArrayFire logo in the upper right hand corner of the slide).\n\n<strong>Performance</strong>\n\nThe first feature is Performance. Both CUDA and OpenCL are fast, and on GPU devices they are much faster than the CPU for data-parallel codes, with 10X speedups commonly seen on data-parallel problems.\n\nBoth CUDA and OpenCL <em>can</em> fully utilize the hardware. They are both entirely sufficient to extract all the performance available in whatever hardware device. But we italicized the word \"<em>can</em>\" here, because the devil is really in the details. Performance depends upon a slew of variables, including hardware type, algorithm type, and code quality. It is nearly impossible to guess how much speedup you can extract from a piece of code. In our experience, nearly all science, engineering, and financial codes can get great benefit out of GPU hardware, but the big question is how difficult is it to transform your algorithm to realize those benefits.  We\'ll discuss programmability later on.\n\nWe will present ArrayFire performance results in CUDA and OpenCL at the end of the webinar.\n\n<strong>Scalability</strong>\n\nThe second feature we\'ll discuss is Scalability. Scalability can mean many things, so we\'ve broken this discussion down into 3 kinds of scaling.\n\nFrom Laptops to Single GPU machines, both CUDA and OpenCL codes scale without any code change. This is a very common use case. We see nearly half of GPU computing users leverage a laptop at some stage of GPU development and later move the code to a different \"performance\" hardware setup, like a workstation or cluster. Both CUDA and OpenCL make life easy for this use case.\n\nFrom a Single GPU Machine to a Multi-GPU Machine, both CUDA and OpenCL require user managed code for low-level synchronization of communication between the multiple GPUs. This is a headache, but with patience, it is manageable in both CUDA and OpenCL.\n\nFrom a Multi-GPU machine to a Cluster, neither CUDA nor OpenCL really offer much assistance. Rather, programmers tend to write their own MPI code that handles all the cluster communication and then use CUDA and OpenCL directly in each node.\n\nWith respect to Scability, there are some other interesting developments of note. The first is that there is new technology in CUDA called GPUDirect that is aimed at reducing memory transfer overheads when communicating between multiple GPUs. It has optimizations to reduce overhead by allowing peer-to-peer memory transfers between GPUs on the same PCI express bus. It also has optimization to reduce the overhead of moving data from GPU memory to a network interface card. This is certainly an interesting development, but it is too new for us to say if it offers enough benefit to be an important technology.\n\nThe second interesting development is in mobile GPU computing. OpenCL has quickly become the most pervasive way to do GPU computing on mobile devices, including smartphones and tablets. Companies like ARM, Imagination Technologies, Freescale, Qualcomm, Samsung, and others are all enabling their mobile GPUs to run OpenCL codes. There are more mobile devices sold each year than there are PCs, so this is a huge community that is beginning to put its support behind OpenCL. At AccelerEyes, we have done several GPU consulting projects on mobile GPUs and are believers that there is big benefit to accelerating apps, especially computer vision and video processing apps, directly on the phone or tablet.\n\nIn scaling from Laptops to Single GPU machines, ArrayFire\'s just-in-time compiler automatically makes optimizations for the GPU type, without any code change. In this sense, both the CUDA and OpenCL versions of ArrayFire enjoy scalability here.\n\nFrom a single GPU machine to a multi-GPU machine, ArrayFire has a big advantage. The ArrayFire deviceset() function makes mutli-GPU computing super simple. No need to mess with synchronization issues. ArrayFire automatically manages memory and queues up all GPUs in your system with a full workflow, ensuring good resource utilization.\n\nFrom multi-GPU machines to clusters, ArrayFire is the same as CUDA and OpenCL. There is not really any added benefit, and users write and manage their own MPI code.\n\n<strong>Portability</strong>\n\nThe third feature is Portability. This is perhaps the most reconizable difference between CUDA and OpenCL. CUDA only runs on NVIDIA GPUs, while OpenCL is the open industry standard and runs on AMD, Intel, NVIDIA, and other hardware devices.\n\nWith respect to CUDA, there was a recent announcement at NVIDIA\'s GPU Technology Conference in Asia that said CUDA would become more open, and the press carried it as saying that CUDA would become open source. This is definitely a step that GPU programmers are happy to see. But it remains to be seen what this actually means. There are two comments that we\'ll make on this announcement:\n<ol>\n	<li>From what we can tell, parts of the CUDA compiler will be open sourced to a limited number of groups. These groups will likely try to build compiler adaptations that enable CUDA code to run on other devices, if you use their compilers. From the announcement, it appears that the CUDA libraries, like CUBLAS and CUFFT, will not be open sourced. This is a critical disctinction, because as we\'ll show later on, libraries are key.</li>\n	<li>Creating a compiler that can automatically generate tuned code for various hardware devices with very different architectures is extremely difficult. These kinds of projects continue to remain popular in hardcore academic research, but have yet to mature their way into actually widespread utility. Ocelot is an example research project in this category.</li>\n</ol>\nAlso, with respect to portability, CUDA does not provide CPU fallback. Currently, developers using CUDA typically put if-statements in their code that distinguish between the presense or absense of a GPU device at runtime. In contract, with OpenCL, CPU fallback is supported and makes code maintenance much easier.\n\nArrayFire is fully portable. The same ArrayFire code runs on CUDA or OpenCL. The only difference is the version of the ArrayFire library that you link against in your code.\n\nThe main caveat here is that today, the OpenCL version of ArrayFire only supports a subset of the functionality available in the CUDA version. This is due to the fact that our CUDA code base has been around much longer. It is also due to the fact that there is less of an OpenCL software ecosystem, as we\'ll discuss next.\n\n<strong>Community</strong>\n\nThe fourth feature is Community. This is the feature that encompasses support, longevity, commitment, etc. As those things are hard to measure, we put together a proxy. It is interesting to look at the number of forum topics on NVIDIA\'s CUDA forms at nearly 27,000 and AMD\'s OpenCL forums at 4,000. Also, the neutral 3rd party site Stackoverflow has tags for CUDA and OpenCL, with the number of CUDA tags being over 3X the number of OpenCL tags. As you would expect, there are many more people doing CUDA programming today due to the great investment NVIDIA has put into building the ecosystem for GPU computing.\n\nWith respect to AccelerEyes, we have over 1,400 GPU topics on our forums, which is the largest community of GPU programmers supported by any software company. The next largest is the veteran HPC company, PGI, which has 485 topics on their GPU forums.\n\nCommunity also has to do with ecosystem and other tools. We will cover a discussion of those as they relate to libraries in a moment.\n\n<strong>Programmability</strong>\n\nThe fifth and final feature is Programmability. Both CUDA and OpenCL are low-level. It is time consuming to do GPU kernel development in either of those platforms. The bulk of that time is often spent in redesigning algorithms to exploit data-parallelism.\n\nThis is why the entire GPU computing market has lately shifted a major focus towards programmability.\n\nTo understand the landscape, let\'s look at the simple two-by-two below, where we have Faster vs Slower technologies on the y-axis, and time-consuming vs easy-to-use technologies on the x-axis. As a baseline, you can consider SSE or AVX instructions on the CPU as something that is time consuming to write and won\'t end up giving you the data-parallel performance that you can expect out of a GPU.\n\nWriting GPU kernels in CUDA or OpenCL leads to much faster code, but is likewise very time-consuming to develop.\n\nIn the opposite corner, compiler directives have recent become popular. The claim of these is that you can sprinkle a few pragmas into your code and that the compiler will figure out how to get the code to run well on the GPU. While in some simple cases you might get a little benefit, there is simply no compiler today that is capable of automatically generating good, fast code for GPUs from standard serial CPU code. Compilers simply can\'t figure out how to morph serial algorithms into data-parallel algorithms.\n\nWhich is why libraries are so key to GPU computing. In a library, you get access to a set of functions that have already been hand-optimized and tuned to exploit data-parallelism. Libraries include within them the benefits of speed that come from writing kernels. But they are also written with ease-of-use in mind and merely require a similar level of intrusion as is required by the compiler directive. This is why ArrayFire has been and continues to be so successful.\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/CUDAvsOpenCL_Page_171.png\"><img class=\"aligncenter size-full wp-image-2298\" title=\"CUDAvsOpenCL_Page_17\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/CUDAvsOpenCL_Page_171.png\" alt=\"\" width=\"650\" height=\"366\" /></a>\n\nLibraries really make all the difference in GPU computing. To compare and contract CUDA versus OpenCL, it is important to look at the comparison of libraries available.\n\nRaw math libraries available in CUDA include CUBLAS, CUFFT, CULA, and Magma. These are pretty much complete providing the majority of all routines necessary for raw dense linear algebra and FFT.  CUDA also has CUSPARSE which is a good start for sparse linear algebra routines, but still needs to mature.  CUDA libraries only run on NVIDIA GPUs.  NVIDIA does not provide libraries for OpenCL.\n\nRaw math libraries in AMD\'s OpenCL have matured a lot recently. With clAmdBlas and clAmdFft, you get most of the important BLAS routines, radix 2, 3, and 5 FFT routines, which covers the most common cases. There is no LAPACK function support and there are no sparse data support libraries.\n\nBut a very important point is that AMD\'s libraries run not only on AMD devices, but on all OpenCL-compliant devices, including NVIDIA GPUs.\n\nDue to these developments at AMD, AccelerEyes is proud to have recently supported OpenCL in both our Jacket product (which applies to MATLAB® code) and our ArrayFire product (which applies to C/C++, Fortran, and Python).\n\nOur OpenCL support is new and not nearly as mature as our support of CUDA. But our initial OpenCL support is better than our initial CUDA support was when we first launched our CUDA products. And we expect OpenCL to continue to mature rapidly in the near future.\n\nThis concludes the slide portion of the presentation. In what follows, we will spend some time showing benchmarks of OpenCL versus CUDA in ArrayFire code, with a particular focus on the raw math libraries we just discussed.\n\nCheckout the video below for the benchmarks and Q/A session.  Enjoy!\n<h3>Video</h3>\n<center><iframe src=\"http://www.youtube.com/embed/Pp8tTIIfVvU\" frameborder=\"0\" width=\"560\" height=\"315\"></iframe></center>','Webinar - OpenCL vs CUDA Comparisons','','publish','open','open','','opencl_vs_cuda_webinar_recap','','','2012-02-17 13:44:45','2012-02-17 17:44:45','',0,'http://blog.accelereyes.com/blog/?p=2227',0,'post','',4),(2249,4,'2012-02-20 22:27:52','2012-02-21 02:27:52','Today was Day 1 of the <a href=\"http://keeneland.gatech.edu/2012-02-20-workshop\">Keeneland Workshop</a>.  Many great talks were given, across a broad range of GPU computing topics.\n\nWith last week\'s <a href=\"http://blog.accelereyes.com/blog/2012/02/17/opencl_vs_cuda_webinar_recap/\">ArrayFire Webinar</a> fresh in mind, it was interesting to see similar conclusions drawn in a presentation by Kyle Spafford of Oak Ridge National Laboratory.  Kyle independently ran a number of benchmarks over a period of time which show how quickly OpenCL has matured and where it yet has room for improvement.  The slide below comes from Kyle\'s <a href=\"http://www.cc.gatech.edu/~vetter/keeneland/tutorial-2012-02-20/13-shoc.pdf\">presentation</a>.  For numbers &gt;1, CUDA is faster.  For numbers &lt;1, OpenCL is faster.  Performance in most cases is close to equivalent.\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/190-shoc_Page_071.png\"><img class=\"aligncenter size-full wp-image-2251\" title=\"190-shoc_Page_07\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/190-shoc_Page_071.png\" alt=\"\" width=\"600\" height=\"450\" /></a>\n\nJust as we showed in the ArrayFire webinar, OpenCL performance is quite comparable with CUDA performance.  The Achilles heel for OpenCL right now seems to be in the FFT and a few other cases related to texture memory optimizations.\n\nMany other great talks were given at the workshop. ArrayFire and Jacket were also covered in the library talks.\n\nIf you are looking at solving HPC type problems with GPUs, you should follow the activities of the Keeneland group.  These guys are leaders in GPU computing for HPC.\n\n&nbsp;','CUDA and OpenCL Benchmarks - Keeneland Workshop Day 1','','publish','open','open','','cuda-and-opencl-benchmarks','','','2012-02-20 22:27:52','2012-02-21 02:27:52','',0,'http://blog.accelereyes.com/blog/?p=2249',0,'post','',3),(2258,4,'2012-02-22 14:05:46','2012-02-22 18:05:46','This morning, I woke up to find the following comment in the <a href=\"http://groups.google.com/group/comp.soft-sys.matlab/browse_thread/thread/3f96dbdffc13cb23\">MATLAB® Newsgroup</a>:\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/bsxfun_post.png\"><img class=\"aligncenter size-full wp-image-2259\" title=\"bsxfun_post\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/bsxfun_post.png\" alt=\"\" width=\"572\" height=\"400\" /></a>\n\nOver two years ago, MathWorks® started to build a clone of Jacket, which you now know as the GPU computing support in the Parallel Computing Toolbox (TM).  At the time, there were many naysayers suggesting that Jacket would somehow be eclipsed by the clone.  Made sense, right?\n\nWrong!  Here we are 2 years later and the clone is still a poor imitation. There are <a href=\"http://accelereyes.com/compare\">several technical reasons</a> for this, but if you are serious about getting great performance from your GPU, Jacket is the better option.  Look at all the <a href=\"http://accelereyes.com/examples\">real customers</a> that are getting big benefit. Here are some other recent benchmarks from the <a href=\"http://www.walkingrandomly.com/?p=4062\">Walking Randomly Blog</a> that show Jacket on a laptop is faster than PCT (TM) on a Tesla:\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/wr_bench.png\"><img class=\"aligncenter size-full wp-image-2285\" title=\"wr_bench\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/wr_bench.png\" alt=\"\" width=\"532\" height=\"121\" /></a>\n\nIf it were easy to imitate Jacket, then MathWorks® would have siphoned away all the Jacket users.  The truth is that it is not easy to build great GPU software, and the Jacket user base continues to explode.  Jacket is not only better than PCT (TM) but is also getting better at a <a href=\"http://wiki.accelereyes.com/wiki/index.php/Release_Notes\">faster rate</a>.  Here\'s to another 2, 5, and 10+ years of great speeds for all of you Jacket programmers!\n\nTo Juliette and others out there, if you really want PCT (TM) to get better, you might consider asking MathWorks® to spending less time cloning and more time working with others who are adding value to the MATLAB® ecosystem.','Jacket Continues to Crush the Clone','','publish','open','open','','crushing-the-clone','','','2012-02-22 14:05:46','2012-02-22 18:05:46','',0,'http://blog.accelereyes.com/blog/?p=2258',0,'post','',6),(2306,4,'2012-02-28 15:22:09','2012-02-28 19:22:09','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/q1_2012_cover_home.jpg\"><img class=\"alignright size-full wp-image-2307\" title=\"q1_2012_cover_home\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/02/q1_2012_cover_home.jpg\" alt=\"\" width=\"281\" height=\"400\" /></a>\n\nThe Q1 2012 issue of Automated Trader contains an excellent \"Mashup!\" piece reviewing software for algorithmic trading.  The article provides a wonderful glimpse into the 1-2 month adventure of Andy Webb, Automated Trader\'s Founder, and Wrecking Crew building a fast trading platform from several technologies.  We heartily recommend that those of you in financial computing <a href=\"http://www.automatedtrader.net/articles/software-review/107768/mashup\">go subscribe</a> to get the full story and access to ongoing developments from these Automated Trader thought leaders!\n\nThe full trading platform they built was quite extensive.  The part that caught our eye was the core computational component of the pipeline.  That component involved permuting 1,000 potential pairs with cointegration tests for 350 time windows on each potential pair.\n\nThe single core MATLAB® version took <strong>70 minutes</strong> to run.  Then, using the Parallel Computing Toolbox (™) on 4 CPU cores, the time reduced to <strong>22 minutes</strong>.  Next, using Jacket\'s <a href=\"http://wiki.accelereyes.com/wiki/index.php/GFOR_Usage\">GFOR loop</a> on a single GPU, execution time dropped to <strong>5 minutes</strong>.  Finally, using Jacket MGL to run the loop iterations on 3 GPUs, the execution time dropped to <strong>1 minute, 52 seconds</strong>.\n<table width=\"100%\" border=\"1\" cellspacing=\"0\">\n<tbody>\n<tr>\n<td><strong>Software Tool</strong></td>\n<td><strong>Performance</strong></td>\n<td><strong>Speedup</strong></td>\n</tr>\n<tr>\n<td>MATLAB® on a single core</td>\n<td>70 minutes</td>\n<td>n/a</td>\n</tr>\n<tr>\n<td>Parallel Computing Toolbox (™) on 4 cores</td>\n<td>22 minutes</td>\n<td>3.2X</td>\n</tr>\n<tr>\n<td>Jacket on a single GPU</td>\n<td>5 minutes</td>\n<td>14X</td>\n</tr>\n<tr>\n<td>Jacket MGL on 3 GPUs</td>\n<td>1 minute, 52 seconds</td>\n<td><strong>37.5X</strong></td>\n</tr>\n</tbody>\n</table>\n&nbsp;\n\nThe author\'s state that this <strong>37.5X speedup was achieved in \"less than half a day.\"</strong>  We\'re always impressed by how quickly Jacket programmers are able to achieve success.\n\nYou too can get great acceleration with Jacket and GPUs for financial trading problems.  Learn more about Jacket and get started with a trial by taking the <a href=\"http://accelereyes.com/jacket_tour\">Jacket Tour</a>.','GPU Computing with Jacket in Automated Trader','','publish','open','open','','automated-trader','','','2012-02-28 15:22:09','2012-02-28 19:22:09','',0,'http://blog.accelereyes.com/blog/?p=2306',0,'post','',0),(2354,1,'2012-03-14 14:19:08','2012-03-14 18:19:08','<a title=\"ArrayFire\" href=\"http://www.accelereyes.com/products/arrayfire\">ArrayFire</a> is a fast GPU library that off-loads compute intensive tasks onto many-core GPUs, thereby reducing application runtime and accelerating it many times. ArrayFire is built on top of NVIDIA CUDA software stack which is currently the best and most stable GPU Software Development Kit available for GPU-based computing.\n\nArrayFire comes with a huge set of <a title=\"functions\" href=\"http://www.accelereyes.com/arrayfire/c/modules.htm\">functions</a> that span across various domains like image processing, signal processing, financial modeling, applications requiring <a title=\"graphics\" href=\"http://www.accelereyes.com/arrayfire/c/page_gfx.htm\">graphics</a> support. ArrayFire has an <a title=\"array\" href=\"http://www.accelereyes.com/arrayfire/c/page_quickref.htm\">array</a> based notation (supports N-dimensional arrays) and allows <a title=\"subs-referencing &amp; subs-assignment\" href=\"http://www.accelereyes.com/arrayfire/c/page_quickref.htm#quickref_indexing\">sub-referencing and assignment</a> into these multi-dimensional arrays. The following code snippet shows how you can index into array objects.\n<pre>// Generate a 3x3 array of random numbers on the GPU\narray A = randu(3,3);\narray a1 = A(0);   // first element\narray a2 = A(0,1); // first row, second column\n\nA(end);   // last element\nA(-1);    // also last element\nA(end-1); // second-to-last element\n\nA(1,span);       // second row\nA.row(end);      // last row\nA.cols(1,end);   // all but first column\n\n// setting entries in an array to a constant\nA(span) = 4;        // fill entire array\nA.row(0) = -1;      // first row\nA(seq(3)) = 3.1415; // first three elements\n\n// copy in another matrix\narray B = ones(4,4,f64);\nB.row(0) = randu(1,4,f32); // set a row to random values (also upcast)</pre>\nArrayFire also has a premium version called <a title=\"ArrayFire Pro\" href=\"http://www.accelereyes.com/products/arrayfire_licensing\">ArrayFire Pro</a> that adds other capabilities to the basic version, which includes scaling up to multi-GPUs, dense and sparse linear algebra on GPUs and sparse support in general. These add-ons play a significant role porting critical sections of the code onto the GPUs for improving performance. Reason being most of the code in scientific applications involve algorithms that do some kind of linear algebra, eg: solving a system of linear equations. These addons therefore give the overall application a big performance boost.\n\nAdded to this is the <a title=\"multi_GPU\" href=\"http://www.accelereyes.com/arrayfire/c/group__device__mat.htm\">multi-GPU</a> capability that delivers cost to performance benefit over multi-core CPU approach and is also \"greener\" as GPUs deliver more floating point operations per second per Watt (FLOPS / Watt). Multi-GPU capability is also important for scaling up the performance from a single GPU version, and is the most effective way of doing distributed computing in a cluster employing multiple GPUs. This capability in some cases gives users an opportunity to obtain results in real time, for example, estimating price of a stock in real time doing a multi-GPU Monte Carlo simulation. ArrayFire Pro enables these functionalities by providing a simple set of functions to switch between GPUs and compute simultaneously launching CUDA functions on each GPU in parallel. The follwing code snippet shows how you can do multi-GPU FFT using ArrayFire.\n<pre>// This is the input buffer\nfloat * data_h[1000*4];\narray data[4];\narray result[4];\n\nfor (int i = 0; i &lt; NGPU; i++) {\n   // Switch to GPU \'i\'\n   device(i);\n\n   // Create Array object using host (CPU)pointer\n   // and move data to GPU memory\n   data[i] = array(1000,1, A_h + i * 1000);\n}\n\n// Compute FFTs on all GPUs in parallel\nfor (int i = 0; i &lt; NGPU; i++) {\n   device(i);\n   result[i] = fft(data[i]));\n}\n\n// Global synchronization barrier between GPU and host(CPU) thread.\n// Blocks CPU thread till all GPUs finish computing FFTs.\naf::sync();</pre>\nArrayFire Pro also offers <a title=\"DLA\" href=\"http://www.accelereyes.com/arrayfire/c/page_quickref.htm#quickref_la\">double-precision linear algebra</a> (DLA) on GPU which forms the basis of most calculations in scientific computing. The DLA add-on provides functions that are common to matrix analysis, linear systems solutions, eigen value problems and singular value decompositions.\n\nMost of the algorithms either involve operating on dense matrices or sparse matrices. ArrayFire Pro addresses both these classes of algorithms and can handle dense as well as sparse inputs. ArrayFire <a title=\"sparse functionality\" href=\"http://www.accelereyes.com/arrayfire/c/group__sp__build.htm\">sparse functionality</a> has typical use cases like Power systems simulations, chemical processes simulation problems, optimization problems, etc. ArrayFire Pro provides both dense and sparse solvers, constructs sparse arrays with standard sparse storage formats and gels quite well with other libraries and user applications following standard storage formats like Compressed-Row(CSR), Compressed Column (CSC), etc.\n\nArrayFire Pro adds powerful and advanced capabilities to ArrayFire free version and is worth the cost. With ever evolving GPU architectures and software stack, GPU-based computing has proved to be quite challenging, laborious and a costly process in terms of development and maintenance. ArrayFire helps customers save a lot of their development time and maintenance costs. ArrayFire offloads all the computations onto the GPUs hiding all low level CUDA constructs and gives users a chance to concentrate on their problem rather than worrying about writing CUDA code and exploring various optimization strategies for peak performance on GPUs. ArrayFire engineers work day and night to attain the best performance across different GPU architectures, giving its customers value for every dollar spent.','ArrayFire Pro : Features and Scalability','','publish','open','open','','arrayfire-pro-features-and-scalability','','','2012-03-14 14:19:08','2012-03-14 18:19:08','',0,'http://blog.accelereyes.com/blog/?p=2354',0,'post','',0),(2416,1,'2012-03-19 17:51:17','2012-03-19 21:51:17','<p style=\"text-align: justify;\">In case you missed it, we recently held a webinar on how to accelerate financial computing applications using Jacket.  The performance advantages brought to financial computing algorithms through Jacket and GPUs represents the best way to accelerate MATLAB® code.</p>\n<p style=\"text-align: justify;\">This webinar was part of an ongoing <a href=\"http://blog.accelereyes.com/blog/2012/01/12/accelereyes_webinars_2012q1/\">series of webinars</a> that will help you learn more about the many applications of Jacket and ArrayFire, while interacting with AccelerEyes GPU computing experts.  Scott Blakeslee, our Director of Business Development, introduced Jacket and talked about some exciting recent customer successes in the field of financial computing. Gallagher Pryor, CTO of AccelerEyes, then demoed some financial code speedups on one of our office machines. The major takeaway from the webinar video was that Jacket is an excellent and proven choice for financial analysts looking to get the maximum performance per dollar invested.</p>\n<p style=\"text-align: justify;\">During the webinar, Gallagher and Scott also offered a sneak preview of some of the most exciting features we unveiled with Jacket 2.1, namely, an Optimization Library, and extended support for Sparse functionality.  You can download the webinar slidedeck from <a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/03/Jacket-Webinar_March-2012.pdf\">this link</a>.</p>\n<p style=\"text-align: justify;\">For those of you who missed it, we uploaded the webinar on Youtube. We hope to see you at <a href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\">the next one</a>!</p>\n\n<center><iframe src=\"http://www.youtube.com/embed/__Gd_f6Hr7E\" frameborder=\"0\" width=\"560\" height=\"315\"></iframe></center>','Webinar - Jacket for Financial Computing Applications','','publish','open','open','','jacket-for-financial-computing','','','2012-03-19 17:51:17','2012-03-19 21:51:17','',0,'http://blog.accelereyes.com/blog/?p=2416',0,'post','',0),(2448,4,'2012-03-22 15:42:57','2012-03-22 19:42:57','Kepler is here.  And it\'s fantastic!\n\nThe news came out today that the first Kepler GPU, the <a href=\"http://www.geforce.com/hardware/desktop-gpus/geforce-gtx-680\">GeForce GTX 680</a>, has been launched.  A single GPU has 1,536 CUDA Cores.  This means that those high-end workstations with 8 PCIe slots will be able to pack <strong>12,288 CUDA cores into a single computer</strong>.  That\'s some serious computational power.\n\nCurrent high-end Fermi cards have 512 cores, so this new Kepler architecture boasts 3X the number of computation cores.\n\n<img class=\"alignright size-medium wp-image-2449\" title=\"geforce-gtx-680-style3-1000x580_gallery_preview\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/03/geforce-gtx-680-style3-1000x580_gallery_preview-300x174.png\" alt=\"\" width=\"300\" height=\"174\" />\n\nNormally we focus on the higher-end Tesla products because those more aptly fit the needs of our science, engineering, and financial computing readers.  But we are excited nonetheless by this GeForce GPU.  It is a major step forward in GPU technology.  And this GeForce card portends great stuff for the technical-computing-focused Tesla revamp due out later this year.\n\nAs <a href=\"http://twitter.com/#!/codedivine/statuses/182876979354284034\">@codedivine points out on Twitter</a>, \"The only disappointment is that FP64 rate is very poor at 1/24 of FP32.\"  So we look forward to the Tesla parts boosting the relative double-precision allocation for compute purposes.\n\nA whitepaper describing the new GeForce card is <a href=\"http://www.geforce.com/Active/en_US/en_US/pdf/GeForce-GTX-680-Whitepaper-FINAL.pdf\">available for download</a>.  The default version comes with 2GB of memory.  Also, a big emphasis was placed on making it lower power.  These specs, combined with the big leap forward in computation cores, makes this a big day indeed for GPU computing.','12,288 CUDA Cores in One Computer','','publish','open','open','','12288-cuda-cores-in-one-computer','','','2012-03-22 15:42:57','2012-03-22 19:42:57','',0,'http://blog.accelereyes.com/blog/?p=2448',0,'post','',3),(2458,6,'2012-04-04 12:11:27','2012-04-04 16:11:27','<p style=\"text-align: left;\" align=\"center\"><strong><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/12/jacket_logo.png\"><img class=\"alignright\" title=\"jacket_logo\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/12/jacket_logo-300x235.png\" alt=\"\" width=\"240\" height=\"188\" /></a></strong></p>\n<p style=\"text-align: left;\" align=\"center\"><strong><strong><strong>Optimization Library, Sparse Functionality, Graphics Library Improvements</strong>, CUDA 4.1 Enhancements, and much more...</strong></strong></p>\n<p style=\"text-align: left;\" align=\"center\">AccelerEyes announces the release of Jacket v2.1, adding GPU computing capabilities for use with MATLAB®. Jacket v2.1 delivers even more speed through a host of new improvements, maximizing GPU device performance and utilization..</p>\nNotable new features include an <a href=\"http://wiki.accelereyes.com/wiki/index.php/Optimization_Library\">Optimization Library</a> and additional functions to our <a href=\"http://wiki.accelereyes.com/wiki/index.php/Graphics_Library\">Graphics Library</a>. With Jacket v2.1, we have also extended support for sparse matrix subscripting and made improvements to host-to-device and device-to-host data transfer speeds for complex data. In addition, we have included various <a href=\"http://wiki.accelereyes.com/wiki/index.php/GFOR_Usage\">GFOR</a> enhancements.\n<p style=\"text-align: left;\">Jacket v2.1 now includes NVIDIA CUDA 4.1 enhancements to provide improved functionality and performance (requires <a href=\"http://www.nvidia.com/Download/indexsg.aspx?lang=en-us\">latest drivers</a>).</p>\n<p style=\"text-align: left;\"><a title=\"About Jacket\" href=\"http://www.accelereyes.com/products/jacket\">Jacket</a> is the premier GPU software plugin for MATLAB®, <a title=\"Compare Jacket\" href=\"http://www.accelereyes.com/products/compare\">better</a> than alternative solutions.  It is relied upon by thousands of organizations for rapid prototyping and problem solving across a range of government, manufacturing, energy, media, biomedical, financial, and scientific research applications.</p>\n<strong>Optimization Library Functions:</strong>\n<ul>\n	<li><a href=\"http://wiki.accelereyes.com/wiki/index.php/MINGD\">MINGD</a> minimizes an objective utilizing gradient-descent coupled with an Armijo line search</li>\n	<li><a href=\"http://wiki.accelereyes.com/wiki/index.php/MINBFGS\">MINBFGS</a> minimizes an objective utilizing the BFGS method coupled with line search</li>\n</ul>\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/Scattercolors_example.png\"><img class=\"alignright size-medium wp-image-2460\" title=\"Scattercolors Example\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/Scattercolors_example-300x191.png\" alt=\"\" width=\"300\" height=\"191\" /></a>\n\n<strong>Graphics Library New Features:</strong>\n<ul>\n	<li><a href=\"http://wiki.accelereyes.com/wiki/index.php/VOLUME\">VOLUME</a> for volume rendering 3d arrays</li>\n	<li><a href=\"http://wiki.accelereyes.com/wiki/index.php/SCATTERCOLORS\">SCATTERCOLORS</a> for rendering colored scatter plots</li>\n	<li><a href=\"http://wiki.accelereyes.com/wiki/index.php/IMAGESC\">IMAGESC</a> can now display color imagery if passed a 3d matrix</li>\n</ul>\n<div><strong>Other New Features and Notable Improvements:</strong></div>\n<ul>\n	<li>Sparse matrix subscripting</li>\n	<li>NULL added</li>\n	<li>CIRCSHIFT now supports shift argument as a GPU type</li>\n	<li>Improved host-to-device and device-to-host data transfer speeds while operating on complex data</li>\n	<li>CONV2 Improved performance for small kernel sizes</li>\n	<li>NACCUMARRAY implemented using a faster algorithm</li>\n	<li>All examples have been simplified for easier understanding and faster performance<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2011/12/jacket_logo.png\">\n</a></li>\n</ul>\nVisit our company website to <a href=\"http://www.accelereyes.com/download_jacket\">download Jacket</a> and see the Jacket v2.1 <a href=\"http://wiki.accelereyes.com/wiki/index.php/Release_Notes\">release notes</a> for the full list of enhancements.\n\n<strong>Pricing and Availability</strong>\n\nJacket v2.1 is available for download on the AccelerEyes website.  Pricing for a Jacket base license with support for a single GPU is $999.00 USD for commercial and $350.00 USD for academic customers.  AccelerEyes provides 12 months of software maintenance and updates with each software license.  Volume packages and development bundles are also <span style=\"color: #0000ff;\">now available</span> at special price points.\n\n<strong>Hire us For GPU Coding Services and Training Courses</strong>\n\nAccelerEyes provides professional GPU <a href=\"http://www.accelereyes.com/products/consulting\">consulting</a> services and <a href=\"http://www.accelereyes.com/products/training\">training</a> courses.  Our team of engineers guarantees great results from GPU computing.  Equipped with Jacket and years of experience, our experts deliver results in fewer hours than any other consulting firms.  Set up a <a href=\"mailto:sales@accelereyes.com?subject=FREE%20GPU%20Computing%20Consultation&amp;body=I%20would%20like%20to%20request%20a%20FREE%20GPU%20computing%20consultation%20session%20with%20one%20of%20your%20GPU%20experts.%20%20I%20am%20available%20for%20a%20phone%20call%20during%20the%20following%20times%3A%0A%0A%3Clist%20available%20times%3E%0A\">free GPU consultation</a> today.','Jacket v2.1 Now Available','','publish','open','open','','jacket-v2-1-now-available','','','2012-04-04 12:11:27','2012-04-04 16:11:27','',0,'http://blog.accelereyes.com/blog/?p=2458',0,'post','',2),(2493,4,'2012-04-11 12:00:17','2012-04-11 16:00:17','Last week, Steve Scott at NVIDIA <a href=\"http://blogs.nvidia.com/2012/04/no-free-lunch-for-intel-mic-or-gpus/\">put up a viral post</a> entitled, \"No Free Lunch for Intel MIC (or GPU’s).\"  It was a great read and a big hit in technical computing circles.\n\nThe centrepiece of Scott\'s piece was to say that <strong>there are no magic compilers</strong>.  GPUs don\'t have them, and neither will MIC.  No compiler will be able to automatically recompile existing code and get great performance from MIC or GPUs.  Rather, it takes a good amount of elbow grease to write high-performance code.\n\nWe totally agree.  The problem Scott addresses is real.  Despite marketing spin to the contrary, developing code for GPUs requires work.\n\nHowever, we don\'t agree with Scott\'s conclusion that compiler directives are a good solution. <strong>You can\'t fight magic compilers with more magic compilers</strong>. Directives are simply not a good option for most problems. A <a href=\"https://plus.google.com/113073392273431041299/posts/aAjqTtSSDUQ\">Google+ post</a> by Derek Gerstmann sums this up well, saying that the fine tuning process with compiler directives quickly erodes the programmability advantages that were the point in the first place.\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/derek_gplus.png\"><img class=\"aligncenter size-full wp-image-2539\" title=\"derek_gplus\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/derek_gplus.png\" alt=\"\" width=\"512\" height=\"276\" /></a>\n\nFortunately, <a href=\"http://accelereyes.com/arrayfire\">ArrayFire</a> offers a better way forward.  It is easier and more intuitive to use than directives, and it is full of hand-tuned CUDA code. Not just regular hand-tuned CUDA code; many man-years worth of elbow-greased CUDA code. <a href=\"http://accelereyes.com/arrayfire_tour\">Download it</a> and you will smile.\n\nThere is no free lunch for any technology, including compiler directives. If you have experience with compiler directives for GPUs, let us know what you think.\n\n&nbsp;\n\nRelated links:\n<ul>\n	<li><a href=\"http://www.hpcwire.com/hpcwire/2012-04-03/nvidia_pokes_holes_in_intel_s_manycore_story.html\">HPCwire, \"NVIDIA Pokes Holes in Intel\'s Manycore Story\"</a></li>\n	<li><a href=\"http://www.theregister.co.uk/2012/04/03/nvidia_scott_coprocessor_programming/\">The Register, \"Nvidia: No magic compilers for HPC coprocessors\"</a></li>\n</ul>','No Free Lunch for GPU Compiler Directives','','publish','open','open','','no-free-lunch-for-gpu-compiler-directives','','','2012-04-11 12:00:17','2012-04-11 16:00:17','',0,'http://blog.accelereyes.com/blog/?p=2493',0,'post','',3),(2548,1,'2012-04-19 15:59:51','2012-04-19 19:59:51','In case you missed it, we recently held a webinar on the ArrayFire GPU Computing Library and its applications to Defense and Intelligence functions. Defense projects often have hard deadlines and definite speed targets, and ArrayFire is a fast and easy-to-use choice for these applications.\n\nThis webinar was part of an ongoing <a href=\"http://blog.accelereyes.com/blog/2012/01/12/accelereyes_webinars_2012q1/\">series of webinars</a> that will help you learn more about the many applications of Jacket and ArrayFire, while interacting with AccelerEyes GPU computing experts.  John Melonakos, our CEO, introduced ArrayFire and talked about some exciting recent customer successes in the field of defense. He then ran through the mechanics of compiling and running code on a machine with 2 Quadro 6000 GPUs, and talked about customer success stories.\n\nThe major takeaway from the webinar video was that ArrayFire is an excellent and proven choice for anyone looking to get the maximum performance per dollar.\n\nFor those of you who missed it, we uploaded the webinar on Youtube. We hope to see you at <a href=\"https://accelereyes.webex.com/mw0306ld/mywebex/default.do?siteurl=accelereyes\">the next one</a>!\n\n<center><iframe src=\"http://www.youtube.com/embed/PNUp8zIs1L8\" frameborder=\"0\" width=\"560\" height=\"315\"></iframe></center>','Webinar - ArrayFire for Defense and Intelligence Applications','','publish','open','open','','accelereyes-webinar-arrayfire-for-defense-and-intelligence-functions','','','2012-04-19 15:59:51','2012-04-19 19:59:51','',0,'http://blog.accelereyes.com/blog/?p=2548',0,'post','',0),(2557,17728,'2012-04-26 14:35:35','2012-04-26 14:35:35','NVIDIA has launched their next generation GPU based on their <a title=\"Kepler news release\" href=\"http://nvidianews.nvidia.com/Releases/NVIDIA-Launches-First-GeForce-GPUs-Based-on-Next-Generation-Kepler-Architecture-79b.aspx\" target=\"_blank\">Kepler Architecture</a>. They followed it up with a rather quick update to their <a title=\"CUDA toolkit\" href=\"http://developer.nvidia.com/cuda-downloads\" target=\"_blank\">CUDA toolkit</a>. Considering that we have access to 3 generations of their GTX cards (480, 580 and 680), we thought we would show case how the performance has changed over the generations.\n\n<strong> Matrix multiplication</strong>:\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/matmul.png\"><img class=\"aligncenter size-full wp-image-2561\" title=\"matmul\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/matmul.png\" alt=\"One terra flops!\" width=\"600\" height=\"300\" /></a>\n\nIt can be seen that the GTX 680 breaches the 1 Terraflop mark comfortably for single precision, while the GTX 580 barely scratches it. However the performance seems to peak around 2048 x 2048 and then rallies downward to match the performance of the GTX 580 at larger sizes. The high end Tesla C2070 finishes last for single precision behind the third placed GTX 480.\n\nFor double precision, as expected the C2070 is well ahead of the pack. The most interesting snippet here is that the GTX 680, finishes <em>dead last</em> compared to its predecessors. At about 1/10 th  of its single precision performance, <em>the 680 is about twice as slow as the 580</em> which settles down a ~ 1/5th the single precision performance.\n\n<strong>Fast Fourier Transform</strong>:\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/fft2d1.png\"><img class=\"aligncenter size-full wp-image-2575\" title=\"fft2d\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/fft2d1.png\" alt=\"Fast fast aww no more memory!\" width=\"600\" height=\"300\" /></a>The performance gains moving from 480 to a 580 is significant (~20%), while the 680 does not seem to have huge wins over its immediate predecessor. The Fast Fourier Transform is an interesting benchmark in that, it is a case of these cards running out of memory before the peak performance is reached. At 2GB, the 680 can hold two 8192x8192 single precision, complex matrices, but the scratch space required for this algorithm is more than the free space available. All the transformations were 2D , Real to complex transforms.\n\n<strong>SORT</strong>:\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/sort.png\"><img class=\"aligncenter\" title=\"sort\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/04/sort.png\" alt=\"\" width=\"600\" height=\"300\" /></a>Here the GTX 680 starts off strong before losing out to the GTX 580, and eventually to the 480.  We are using the same <a href=\"http://code.google.com/p/back40computing/wiki/RadixSorting\" target=\"_blank\">radix-sort</a> algorithm for all the benchmarks.  It is really astonishing that the 680 is more than 20% slower at peak.\n\nResources:\n\n<a href=\"https://gist.github.com/2493843\" target=\"_blank\">Benchmark Code</a>\n\n<a href=\"https://docs.google.com/spreadsheet/ccc?key=0AitC5fE6lOMzdHB3eGxNQzlidlFLbjBzSlZtbG8zLWc\" target=\"_blank\">Benchmark Results </a>\n\nRelated links:\n\n<a href=\"http://www.tomshardware.com/reviews/geforce-gtx-680-review-benchmark,3161-15.html\" target=\"_blank\">Tom\'s hardware: LuxMark Benchmarks</a>\n\n<a href=\"http://www.anandtech.com/show/5699/nvidia-geforce-gtx-680-review\" target=\"_blank\">Anandtech: Retaking the performance crown</a>\n\n&nbsp;\n\n&nbsp;','Benchmarking the new Kepler (GTX 680)','','publish','open','open','','benchmarking-kepler-gtx-680','','','2014-06-17 21:08:57','2014-06-17 21:08:57','',0,'http://blog.accelereyes.com/blog/?p=2557',0,'post','',13),(2588,4,'2012-05-15 03:59:37','2012-05-15 07:59:37','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/05/gtc2012-banner.jpg\"><img class=\"aligncenter size-full wp-image-2590\" title=\"gtc2012-banner\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/05/gtc2012-banner.jpg\" alt=\"\" width=\"600\" height=\"75\" /></a>\n\nIt\'s going to be hard to sleep tonight.  So much GPU goodness awaits the coming 3 days of the GPU Technology Conference.  Here are my top 10 things to do at GTC 2012:\n\n<strong>Sessions to Attend</strong>\n\n#1:  S0287 - Jacket for Multidimensional Scaling in Genomics - This is a great opportunity to learn about accelerating MATLAB® on the GPU.  Come learn why thousands of scientists, engineers, and analysts are using Jacket to do more with less coding hassle.\n(Day: Tuesday, 05/15; Time: 5:30 pm - 5:55 pm; Location: Room K)\n\n#2:  S0415 - An Accelerated Weeks Method for Numerical Laplace Transform Inversion - Learn how the researchers have been able to utilize Jacket in MATLAB® to more efficiently and robustly implement the Weeks method.\n(Day: Wednesday, 05/16; Time: 9:30 am - 9:55 am; Location: Marriott Ballroom 3)\n\n#3:  S0325 - ArrayFire Graphics: A Tutorial - Come learn about how ArrayFire will complement your GPU coding projects.\n(Day: Wednesday, 05/16; Time: 10:00 am - 10:25 am; Location: Room A3)\n\n#4:  S0133 - Improving Mars Rover Image Compression Via GPUs And Genetic Algorithms - By using MATLAB® and Jacket to perform 2D convolution on the GPU, we have greatly reduced the total computation time needed.\n(Day: Thursday, 05/17; Time: 9:00 am - 9:25 am; Location: Room A3)\n\n<strong>Visit the AccelerEyes\' Booth</strong>\n\n#5:  AccelerEyes - Come see how Jacket compares to the R2012a Parallel Computing Toolbox™ (Hint: Jacket is &gt;2X faster).  Come see how ArrayFire complements other GPU development efforts, including raw CUDA/OpenCL development, OpenACC, and other GPU libraries like Thrust.\n\n<strong>Watch &amp; Meet Jen-Hsun Huang</strong>\n\n#6:  Jen-Hsun\'s keynote is always a treat.  He is a dynamic speaker and delivers well-executed keynotes, with plenty of eye-candy demos as well as nuggets of exciting new GPU news.  He is also surprisingly available during the rest of the conference.  He walks the show floor and attends the after parties.  If you hang out, you might just get the opportunity to meet him in person.\n\n<strong>Get a GPU Coding Job</strong>\n\n#7:  AccelerEyes is hiring!  Come to our booth to meet us and get a leg up on other people that don\'t get to meet us in person.\n\n<strong>Meetup with other GPU Developers</strong>\n\n#8:  GTC is a great place to connect with other GPU developers working on similar problems.  Be friendly and talk to people at the show.  It\'s a great place to build mutually beneficial relationships that catalyze GPU development projects.\n\n<strong>Show Off</strong>\n\n#9:  GTC is a great place to show off your latest GPU projects.  If you have something cool you\'ve developed, bring it by the AccelerEyes booth.  We\'d love to see it and chat about your GPU work together.\n\n<strong>Stay in Touch</strong>\n\n#10:  Be sure to keep in touch after the show.  Follow-up on discussions.  Connect on <a href=\"http://twitter.com/accelereyes\">Twitter</a>, <a href=\"http://facebook.com/accelereyes\">Facebook</a>, or <a href=\"http://blog.accelereyes.com\">GPU Software blogs</a> to stay tuned with the constantly evolving landscape of GPU computing software.\n\nWe look forward to seeing you at GTC 2012!','Top 10 List at GTC 2012','','publish','open','open','','gtc-2012-top-ten','','','2012-05-15 03:59:37','2012-05-15 07:59:37','',0,'http://blog.accelereyes.com/blog/?p=2588',0,'post','',0),(2594,4,'2012-05-15 16:13:05','2012-05-15 20:13:05','Do you want to code GPUs daily?  Do you want to build software that actually gets used by real people, solving real problems?  Do you want to join the whirlwind of a startup where you own projects and determine success or failure?\n\nThen come work at AccelerEyes.  AccelerEyes is hiring for 3 positions:  Inside Salespersons, Fulltime Engineers, and Remote Contract Developers.\n\nCheckout <a href=\"http://www.accelereyes.com/company/careers\">our Careers page</a> or swing by our booth at GTC for more info.','AccelerEyes is Hiring at GTC 2012','','publish','open','open','','accelereyes-is-hiring-at-gtc-2012','','','2012-05-15 16:13:05','2012-05-15 20:13:05','',0,'http://blog.accelereyes.com/blog/?p=2594',0,'post','',0),(2616,17728,'2012-05-22 14:33:05','2012-05-22 14:33:05','With the rise of GPU computing over the last few years, it is not surprising that <a href=\"http://blogs.nvidia.com/2011/11/gpu-supercomputers-show-exponential-growth-in-top500-list/\">more than 30</a> super computers are now powered by GPUs. Add to that Amazon ECC now offers <a href=\"http://aws.amazon.com/ec2/\">GPU instances</a> that have two GPUs per node, it is now easy to set up a cluster of your own and run simulations using a large number of GPUs. The availability of these clusters and the proven performance of GPUs over the last couple of years has led many researchers, and businesses to move from testing GPUs to scaling their problems to multiple GPUs.\n\nAs a consequence of this,  we have a lot of our customers want to know how to scale our products across multiple GPUs. So in this post we would like to show you a brief description of what is happening when you call gpu enabled functions. We will then discuss how this knowledge can be used to scale you problems in the best possible manner.\n\nWha\n\n&nbsp;','Multi GPU programming','','draft','open','open','','','','','2014-06-17 21:15:28','2014-06-17 21:15:28','',0,'http://blog.accelereyes.com/blog/?p=2616',0,'post','',0),(2621,1,'2012-06-01 14:28:14','2012-06-01 18:28:14','As we engage with GPU programmers everywhere, we find ourselves each day assisting others in configuring NVIDIA drivers.  This post is aimed at Ubuntu users.<!--more-->\n\nThe details below describe the steps to install the NVIDIA driver on Ubuntu Desktop.  We\'re using version 11.10, but the same steps are useful for other Ubuntu versions as well.  Here are the steps:\n\n<hr />\n\n&nbsp;\n\nDownload the latest <a href=\"http://nvidia.com/drivers\">NVIDIA driver</a>.  Make sure the download has execute permission.\n\n<pre class=\"lang:default highlight:0 decode:true\">chmod u+x NVIDIA-Linux-x86_64-285.05.33.run</pre>\nDisable the default driver on the next start up.  In your favorite editor open /etc/modprobe.d/blacklist.conf.  I prefer nano:\n\n<pre class=\"lang:default highlight:0 decode:true\">sudo nano /etc/modprobe.d/blacklist.conf</pre>\nAdd to the end of this file the following lines:\n<pre class=\"lang:default highlight:0 decode:true\">blacklist nouveau\nblacklist lbm-nouveau\nalias nouveau off\nalias lbm-nouveau off</pre>\nThis will make sure that the default NVIDIA driver (nouveau) will not be allowed to run on the next start up.\n\nReboot now.\n\nBefore the driver can be installed the X window server needs to be shutdown.  After rebooting go to the terminal. This can be done before or after logging in.\n\n<code>Ctrl + Alt + F3</code>\n\nYou will have to login again even if you have already done so.\n\nNow shutdown the X window server.\n\n<pre class=\"lang:default highlight:0 decode:true\">sudo service lightdm stop</pre>\nNote: on different distributions such as Kubuntu there will be a different display manager.  Look in /etc/init.d/ for which program is installed.  It may be kdm or gdm.\n\nNow that the window server is down and the nouveau driver is disabled the NVIDIA driver may now be installed. Navigate back to your download directory and run this command:\n\n<pre class=\"lang:default decode:true\">sudo ./NVIDIA-Linux-x86_64-285.05.33.run</pre>\nNavigate through the text interface.  Once you are done and the driver is successfully installed you many now reactivate the window manager.\n\n<pre class=\"lang:default highlight:0 decode:true\">sudo service lightdm start</pre>\nand if you wish to go back to your desktop\n\n<code>Ctrl + Alt + F7</code>\n\nNow to make sure that the NVIDIA drivers are working and find your GPU.  Open up the NVIDIA X server settings GUI either by searching for it or using this command\n\n<pre class=\"lang:default highlight:0 decode:true\">nvidia-settings</pre>\nYou should see in the list on the left all of your GPU(s) on the computer.\n\nAlternatively you can view the information through the command line\n\n<pre class=\"lang:default highlight:0 decode:true\">nvidia-settings -q gpus</pre>\nSuccess!\n\n<hr />\n\n&nbsp;\n\nGood luck!','Installing NVIDIA drivers on Ubuntu 11.10','','publish','open','open','','installing-nvidia-drivers-on-ubuntu-11-10','','','2012-06-01 14:28:14','2012-06-01 18:28:14','',0,'http://blog.accelereyes.com/blog/?p=2621',0,'post','',1),(2628,1,'2012-05-24 18:26:56','2012-05-24 22:26:56','What do you get when you offer the world\'s most comprehensive <a href=\"https://sandbox.arrayfire.com/download\">GPU library</a> available for free? Excited users who go the extra mile and give back to the community.\r\n\r\nAndrzej Chrzȩszczyk from Jan Kochanowski University recently wrote an <a href=\"https://sandbox.arrayfire.com/wp-content/uploads/2012/05/Matrix_WP_ArrayFire_2017.pdf\" target=\"_blank\">awesome whitepaper</a>, entitled \"Matrix Computations on the GPU with ArrayFire for Python and C/C++.\" The whitepaper contains many GPU computing tutorial examples as well as performance timings for each example.\r\n\r\nAndrzej notes, \"The purpose of this document is to make the first steps in using modern graphics cards to general purpose computations simpler.\"  This document is especially beneficial for programmers looking to accelerate Python or C/C++ codes.\r\n\r\nWe thank Andrzej this fine contribution to the ArrayFire community.  His documentation on ArrayFire will be beneficial to all new users of the library.','ArrayFire Examples and Benchmarks Whitepaper','','publish','open','open','','arrayfire-examples-and-benchmarks-whitepaper','','','2018-01-22 17:55:37','2018-01-22 22:55:37','',0,'http://blog.accelereyes.com/blog/?p=2628',0,'post','',0),(2707,4,'2012-06-07 15:19:24','2012-06-07 19:19:24','<img class=\"alignright size-medium wp-image-2708\" title=\"hiring\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/hiring-300x232.png\" alt=\"\" width=\"300\" height=\"232\" />\n\n<a href=\"http://accelereyes.com/company/careers\">Join</a> the hottest GPU software company. We\'re rapidly expanding and looking for talented developers who are passionate about making the programming world more efficient. The things we work on at AccelerEyes provide orders of magnitude more productivity for other developers, greatly increasing the amount of science, engineering, and analytics which are produced each year, across the globe, and across every technical computing industry.\n\nSpecifically, we are looking to hire many developers in the following two roles:\n<ul>\n	<li><strong>Application Engineering</strong> - the most vital job. It requires an ability to produce applications in a variety of disciplines, such as healthcare, finance, oil &amp; gas, defense, etc). You will be the most expert users of ArrayFire and Jacket, and will spread your understanding throughout the ecosystem. It requires the tact of interfacing with customers smoothly, while also requiring the brains to get into the CUDA/OpenCL code to enhance, improve, and extend features required by the applications. This role produces the roadmap for future product features, engages directly in highly visible technical activities (such as technical tradeshows, technical blog posts, technical customer emails, etc), and works closely with CUDA/OpenCL developers to build new versions of products.</li>\n	<li><strong>CUDA/OpenCL development</strong> - we only hire the most talented developers. More than half of new hires wash out in this role. The other half go on to have marvellous careers and build the best GPU software in the world. It is tough stuff. Only the strong need apply. No previous experience in CUDA/OpenCL required, but you will get grilled during the interview process about your coding talents.</li>\n</ul>\nWe are also seeking to expand our sales presence in the Washington DC/Baltimore area, as follows:\n<ul>\n	<li><strong>Salespeople in Baltimore</strong> - play an integral role within our inside sales team through marketing and sales efforts directly to customers. Manage customer accounts using customer relationship management software. Coordinate many marketing and sales related projects.  Looking for highly motivated individuals with an interest in entrepreneurship. Strong communication and interpersonal skills are essential. Exuding enthusiasm for technical computing is perfect for this job.</li>\n</ul>\nGood luck and we look forward to brining many of you on board in the near future.\n\nTO APPLY: send resume to <a href=\"mailto:jobs@accelereyes.com\">jobs@accelereyes.com</a> to initiate the interviewing process','Hiring Tons','','publish','open','open','','hiring-tons','','','2012-06-07 15:19:24','2012-06-07 19:19:24','',0,'http://blog.accelereyes.com/blog/?p=2707',0,'post','',0),(2715,4,'2012-06-19 14:02:13','2012-06-19 18:02:13','AccelerEyes just marked its 5th year in business.  What better way to celebrate than by releasing new products!\n\nWe are pleased to present <strong>ArrayFire v1.2</strong> and <strong>Jacket v2.2</strong> for NVIDIA CUDA-based GPUs. These new products support the latest Kepler architecture and include an array of new features and performance boosts, especially for image processing functions. Learn more in the <a href=\"http://www.accelereyes.com/arrayfire/c/release_notes.htm\">ArrayFire release notes</a> and <a href=\"http://wiki.accelereyes.com/wiki/index.php/Release_Notes\">Jacket release notes</a>.\n\nAccelerEyes started up in 2007 with the mission to make productive performance accessible to engineers, scientists, and financial analysts. Our core leadership has been to provide great libraries that are easy-to-use and faster than alternative approaches. The coolest part about working at AccelerEyes is getting to play a part in the awesome projects of our customers. From tracking missiles, to solving complex molecular dynamics, to figuring out how to beat the next guy on a financial trading algorithm, these interactions bring a vibrant spark to the work we do everyday. BTW, if you want to join in, <a href=\"http://blog.accelereyes.com/blog/2012/06/07/hiring-tons/\">we\'re hiring</a>:)\n\nEspecially awesome is the community of developers on the <a href=\"http://forums.accelereyes.com\">GPU software forums</a>.  Big shouts out to grubin698, Lars1, mgstauffer, and the too-numerous-to-mention other regulars that constantly make life interesting for us!\n<table width=\"60%\" border=\"1\" cellspacing=\"0\" cellpadding=\"4\" align=\"right\">\n<tbody>\n<tr>\n<td align=\"center\">\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/20073.jpg\"><img class=\" wp-image-2741 aligncenter\" title=\"2007\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/20073.jpg\" alt=\"\" width=\"412\" height=\"260\" /></a></p>\n</td>\n</tr>\n<tr>\n<td align=\"center\">\n<h6 style=\"text-align: left;\">The early days.  A 2007 photo of a trip to Santa Clara. AccelerEyes introduced NVIDIA to GPU computing in MATLAB® with Jacket v0.1, built by tricking OpenGL shaders to do compute workloads.</h6>\n</td>\n</tr>\n</tbody>\n</table>\nPeople tell us that a large fraction of new businesses don\'t make it to 5 years old, let alone make it that long in the relatively hum-drum HPC market. Thanks in large measure to the excellence of my engineering colleagues at AccelerEyes, the marketplace success of ArrayFire and Jacket have spurred tremendously rapid growth for our business.\n\nHelp us celebrate today by downloading some software:\n<ul>\n	<li><a href=\"http://accelereyes.com/download_arrayfire\">grab an ArrayFire Free license</a> to make your GPU computing experience better in C, C++, Fortran, or Python</li>\n	<li><a href=\"http://accelereyes.com/download_jacket\">download a free 15-day trial of Jacket</a> to accelerate your MATLAB® code</li>\n</ul>\nWhat is our plan for the next 5 years? It\'s simply to make wonderful acceleration accessible to everyone, which will become even more important as chipmakers continue to diverge in programming models and approaches. With ArrayFire and Jacket, you can program your code once, and take advantage of all the best hardware available. Give it a whirl, and then come let us know how it goes on the <a href=\"http://forums.accelereyes.com\">forums</a>. See you there!\n\n&nbsp;','AccelerEyes Celebrates 5 Years with New Product Releases','','publish','open','open','','accelereyes-celebrates-5-years','','','2012-06-19 14:02:13','2012-06-19 18:02:13','',0,'http://blog.accelereyes.com/blog/?p=2715',0,'post','',0),(2775,4,'2012-06-26 18:02:41','2012-06-26 22:02:41','Researchers at the University of Quebec have developed high-performance gene predictors using Jacket to accelerated their MATLAB® code.  This work has been published in BMC Research Notes and is freely <a href=\"http://www.biomedcentral.com/1756-0500/5/183/abstract\">available here</a>.\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/1756-0500-5-183_Page_18.png\"><img class=\"alignright size-medium wp-image-2779\" title=\"1756-0500-5-183_Page_18\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/1756-0500-5-183_Page_18-300x283.png\" alt=\"\" width=\"300\" height=\"283\" /></a>Computerized approaches to studying the human genome are challenged by the exploding amount of data, which doubles roughly every 6 months.  In order to deal with this burgeoning datasets, demands for faster processing power continue to arise.\n\nThis work focuses on predicting genes using frequency analysis with FFTs and with an equivalent technique known as Goertzel’s algorithm.  In these applications, the emphasis of this paper is to propose tools to geneticists and molecular biologists for the prediction or identification of new genes using existing complementary strategies. The criteria for these tools are speed, reliability, accuracy and ease of use, thus requiring little training.<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/1756-0500-5-183_Page_21.png\"><img class=\"alignleft size-medium wp-image-2780\" title=\"1756-0500-5-183_Page_21\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/1756-0500-5-183_Page_21-300x272.png\" alt=\"\" width=\"300\" height=\"272\" /></a>\n\nThe results were impressive.  At the larger sizes of sequences, <strong>Jacket is 43X faster than the Parallel Computing Toolbox®</strong> (PCT)\'s PARFOR loop with 8 CPU worker threads.\n\nThe authors avoided the use of the GPU functionality available in PCT(tm), because \"there are no commands that are equivalent to PARFOR that can execute multiple FOR loops in parallel on the GPU. While the command arrayfun does offer similar functionality, it removes some of the flexibility needed for this particular algorithm given our need for processing a sliding window within an array. This method was therefore not considered further.\"  This is yet another example that <a href=\"http://accelereyes.com/compare\">PCT(tm) gives poor performance</a>.\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/1756-0500-5-183_Page_121.png\"><img class=\"aligncenter size-full wp-image-2786\" title=\"1756-0500-5-183_Page_12\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/06/1756-0500-5-183_Page_121.png\" alt=\"\" width=\"650\" height=\"183\" /></a>\n\nSpecial thanks to the authors, Sylvain Robert Rivard, Jean-Gabriel Mailloux, Rachid Beguenane, and Hung Tien Bui, for their great work and sharing their insights with the rest of us.  We look forward to seeing the continued developments that come out of this group!','Parallelized Gene Predictors with Jacket','','publish','open','open','','parallelized-gene-predictors','','','2012-06-26 18:02:41','2012-06-26 22:02:41','',0,'http://blog.accelereyes.com/blog/?p=2775',0,'post','',0),(2805,1,'2012-07-31 18:02:57','0000-00-00 00:00:00','','Convolution kernels for fast computation of isotropic gradients','','draft','open','open','','','','','2012-07-31 18:02:57','0000-00-00 00:00:00','',0,'http://blog.accelereyes.com/blog/?p=2805',0,'post','',0),(2807,4,'2012-08-06 16:59:22','2012-08-06 20:59:22','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/S0133-GTC2012-Mars-GPU-Genetic_Page_04.png\"><img class=\"alignright size-medium wp-image-2808\" title=\"S0133-GTC2012-Mars-GPU-Genetic_Page_04\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/S0133-GTC2012-Mars-GPU-Genetic_Page_04-300x226.png\" alt=\"\" width=\"300\" height=\"226\" /></a>\n\nThe Curiosity Mars rover landing reminded us of a recent talk by Brendan Babb of NASA and UAA in Anchorage about <a href=\"http://www.gputechconf.com/gtcnew/on-demand-gtc.php?sessionTopic=999&amp;searchByKeyword=&amp;submit=&amp;select=+&amp;sessionEvent=&amp;sessionYear=&amp;sessionFormat=#1541\">Jacket-accelerated Mars research</a>. The talk was given at GTC 2012 in May.\n\nThe main thrust of this research is improving mars rover image compression via GPUs and genetic algorithms. With Jacket and GPUs, the researchers were able to achieve <strong>5X speedups</strong> on the larger data sizes.\n\nThe algorithm works by pairing neighboring pixels with a random one and then adjusting the random pixel based on whether it incrementally improves the original image. Babb described the algorithm as an “embarrassingly” parallel process, ideally suited to GPU acceleration. He estimates he has been able to achieve a 20 to 30 percent error reduction in subjects like fingerprints and satellite imagery. More information is available on the <a href=\"http://blogs.nvidia.com/2012/05/gpus-processing-images-from-the-red-planet/\">NVIDIA blog</a>.\n\nWe had a geek-party at our office last night to watch the Mars rover landing! To learn more about what just happened, check out these videos: <a href=\"http://www.nasa.gov/multimedia/videogallery/index.html?media_id=146903741\">Seven minutes of Terror</a> (introductory material) and <a href=\"http://www.youtube.com/watch?v=wnG-rFFpP8A\">NASA Lands Car-Size Rover Beside Martian Mountain</a> (today\'s landing event). How did you celebrate the rover landing?\n\n&nbsp;','Powering Mars Research','','publish','open','open','','powering-mars-research','','','2012-08-06 16:59:22','2012-08-06 20:59:22','',0,'http://blog.accelereyes.com/blog/?p=2807',0,'post','',0),(2837,1,'2012-08-13 17:43:16','2012-08-13 21:43:16','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/Koch-Supply-and-Trading1.jpg\"><img class=\"size-full wp-image-2906 alignright\" title=\"Koch Supply and Trading\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/Koch-Supply-and-Trading1.jpg\" alt=\"\" width=\"216\" height=\"60\" /></a>\n\nAndrew Shin, Market Risk Manager of Koch Supply &amp; Trading, achieves significant performance increases on option pricing algorithms using Jacket to accelerate his MATLAB® code with GPUs.\n\nAndrew says, \"My buddy and I are, at best, novice programmers and we couldn\'t imagine having to figure out how to code all this in CUDA.\" But he found Jacket to be straight-forward. With these results, he says he can see Jacket and GPUs populating Koch\'s mark-to-futures cube, which contains its assets, simulations, and simulated asset prices.\n\nModern option pricing techniques are often considered among the most mathematically complex of all applied areas of finance. Andrew shared some exemplary code to demonstrate how much leverage you can get out of Jacket and GPUs for financial computing in MATLAB® and C/C++.\n\nAll option pricing algorithms in this post use a Monte Carlo simulation. The <code>stockpath B</code> version is the option pricing algorithm with a barrier option, and the <code>stockpath A</code> version is without the barrier.\n\nThe execution times and speedups for these algorithms are shown in the charts below:\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/plot2.jpg\"><img title=\"plot2\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/plot2.jpg\" alt=\"\" width=\"760\" height=\"529\" /></a>\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/plots01.jpg\"><img title=\"plots0\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/plots01.jpg\" alt=\"\" width=\"640\" height=\"471\" /></a>\n\nFor <code>stockpath A</code>, Jacket and ArrayFire reach<strong> 40.5x</strong> and <strong>51.8x</strong> speedups respectively over the baseline CPU MATLAB® code. For <code>stockpath B</code>, Jacket and ArrayFire achieve <strong>38.4x</strong> and <strong>47.5x</strong> speedups respectively over the baseline CPU MATLAB® code.\n\nSystem specs:\n\nA single workstation with a 2.66 GHz Intel Core 2 Quad CPU and an 6GB NVIDIA Quadro 6000 GPU, with MATLAB® R2010b.\n\nBelow is example Jacket code of option pricers:\n<pre lang=\"matlab\">function P=stockpath_A(N, K, steps, t, r, vol, cls)\n  payoff = zeros(N, 1, cls);\n  dt = t / (steps - 1);\n  s = K * ones(N, 1, cls);\n\n  randmat = randn(N, steps - 1, cls);\n  d = exp((r - (vol * vol * 0.5)) * dt + vol * sqrt(dt) * randmat);\n  S = [s, d];\n  S = cumprod(S, 2);\n\n  payoff = max(S(:, steps) - K, 0.0);\n  P = double(mean(payoff) * exp(-r * t));\nend\n\nfunction P=stockpath_B(N, K, steps, t, r, vol, cls)\n  payoff = zeros(N, 1, cls);\n  B = 1.15 * K;\n  dt = t / (steps - 1);\n  s = K * ones(N, 1, cls);\n\n  randmat = randn(N, steps - 1, cls);\n  d = exp((r - (vol * vol * 0.5)) * dt + vol * sqrt(dt) * randmat);\n\n  S = [s, d];\n  S = cumprod(S, 2);\n  S(:, steps) = S(:, steps) .* all(S &lt; B, 2);\n\n  payoff = max(S(:, steps) - K, 0.0);\n  P = double(mean(payoff) * exp(-r * t));\nend</pre>\nWhere <code>K</code> is strike price, <code>t</code> is maturity, <code>r</code> is risk free rate, <code>B</code> is barrier and <code>vol</code> is volatility. The <code>cls</code>, which is either <code>\'double\'</code> or <code>gdouble</code>, enables us to run same pieces of code <code>stockpath_A</code> and <code>stockpath_B</code> both on CPU and GPU without actually changing the code. The <code>cls</code> serves as a flag that lets the code know whether it is run on a CPU or a GPU. When <code>cls</code> is set as <code>gdouble</code>, matrix initialization, assignments, calculations including <code>cumprod</code>, <code>mean</code> and <code>all</code>, are all executed in parallel on GPU and therefore you will get a good speedup.\n\nBelow is example ArrayFire code of option pricers:\n<pre>static double stockpath_A(int N)\n{\n    dtype pres = f64;\n    int steps = 180;\n    array payoff = zeros(N, 1, pres);\n    double K = 100.0;\n\n    double t = 0.5;\n    double dt = t / (double)(steps - 1);\n    double vol = .30;\n    double r = .01;\n    array s = 100 * ones(N, 1, pres);\n\n    array randmat = randn(N, steps - 1, pres);\n    randmat = exp((r - (vol * vol * 0.5)) * dt + vol * sqrt(dt) * randmat);\n    array S = join(1, s, randmat);\n    S = accum(S, 1, PROD_T);\n\n    payoff = max(0.0, S.col(steps - 1) - K);\n    double P = mean&lt;double&gt;(payoff) * exp(-r * t);\n\n    return P;\n}\n\nstatic double stockpath_B(int N)\n{\n    dtype pres = f64;\n    int steps = 180;\n    array payoff = zeros(N, 1, pres);\n    double K = 100.0;\n    double B = 115.0;\n\n    double t = 0.5;\n    double dt = t / (double)(steps - 1);\n    double vol = .30;\n    double r = .01;\n    array s = 100 * ones(N, 1, pres);\n\n    array randmat = randn(N, steps - 1, pres);\n    randmat = exp((r - (vol * vol * 0.5)) * dt + vol * sqrt(dt) * randmat);\n\n    array S = join(1, s, randmat);\n    S = accum(S, 1, PROD_T);\n    S(span, end) *= all(S &lt; B, 1);\n\n    payoff = max(0.0, S.col(steps - 1) - K);\n    double P = mean&lt;double&gt;(payoff) * exp(-r * t);\n\n    return P;\n}</pre>\nWhere <code>array</code> is matrix, <code>f64</code> denotes all elements of arrays should be doubles, <code>join(1, s, randmat)</code> joins matrix <code>s</code> and <code>randmat</code> as <code>[s, d]</code> does, and <code>accum(S, 1, PROD_T)</code> calculates cumulative product as <code>cumprod(S, 2)</code> does. ArrayFire functions are straightforward to understand as their names indicate and of course they will be run on GPUs. The ArrayFire code is faster than Jacket because it is C/C++ code and it does not suffer from overheads introduced by MATLAB®.\n\nFrom the above code and charts, you can easily see the simplicity of achieving great speedups. Grab a free <a href=\"http://accelereyes.com/jacket_tour\">Jacket</a> or <a href=\"http://accelereyes.com/arrayfire_tour\">ArrayFire Pro</a> 15-day trial today!','Option Pricing','','publish','open','open','','option-pricing','','','2012-08-13 17:43:16','2012-08-13 21:43:16','',0,'http://blog.accelereyes.com/blog/?p=2837',0,'post','',1),(2931,1,'2012-08-16 15:31:16','2012-08-16 19:31:16','In case you missed it, we recently held a webinar on the ArrayFire GPU Computing Library and its applications to Machine Learning on June 15.\n\nThis webinar was part of a free series of webinars that help you learn about ArrayFire and Jacket (our MATLAB® product). Anyone can attend these webinars, for they are absolutely free and open for anyone to attend and interact with AccelerEyes engineers. Learn more at <a href=\"http://www.accelereyes.com/webinars\">http://www.accelereyes.com/webinars</a>.\n\nChris, a Software Engineer at AccelerEyes, explained ArrayFire\'s position in the GPU computing world, and presented benchmarks where ArrayFire beats GPU libraries such as Thrust in many critical applications. He also mentioned that ArrayFire could be used either standalone, or in combination with other options for GPU computing such as OpenACC, raw CUDA or OpenCL.\n\nChris then proceeded to walk through an example of neural network training on sample images. This example is packaged with ArrayFire and can also be accessed in <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2machine_learning_2neuralnetwork_8cpp-example.htm\">ArrayFire documentation.</a>\n\nThe next example of machine learning with ArrayFire was the K-means algorithm, which is a popular starting point for many machine learning problems. This example can be accessed in the ArrayFire package, and the source code <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2machine_learning_2kmeans_8cpp-example.htm\">is available here.</a>\n\nA popular question we encounter (especially recently) is whether Genetic algorithms can be GPU-accelerated, and the answer is Yes! This class of algorithms use techniques inspired from natural evolution to generate useful solutions to optimization and search problems, and they are well-suited to GPU computing. Some example genetic algorithm code for ArrayFire can be <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2machine_learning_2geneticalgorithm_8cpp-example.htm\">viewed here.</a>\n\nPrincipal component analysis, also called the KL Transform or Hotelling Transform, is another popular algorithm used for creating predictive models. This example can be <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2machine_learning_2pca_8cpp-example.htm\">viewed here.</a> Note that the Linear algebra package is required to run Principal Components Analysis - <a href=\"http://www.accelereyes.com/products/arrayfire_licensing\">read the page</a> on ArrayFire licenses.\n\nAll the examples that Chris discussed, and many many more, are freely available <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\">at the Examples page.</a> ArrayFire\'s single-GPU version is <em>totally free,  no-obligation </em>and has absolutely no performance throttling.\n\nHere\'s the video with detailed discussions on each example:\n\n<center><iframe src=\"http://www.youtube.com/embed/-Ns42G1z2LM\" frameborder=\"0\" width=\"560\" height=\"315\"></iframe></center>','Webinar - Machine Learning with ArrayFire','','publish','open','open','','webinar-machine-learning-with-arrayfire','','','2012-08-16 15:31:16','2012-08-16 19:31:16','',0,'http://blog.accelereyes.com/blog/?p=2931',0,'post','',0),(2933,1,'2012-08-23 15:41:28','2012-08-23 19:41:28','<div style=\"text-align: left;\">\n\nIn case you missed it, we recently held a webinar on the Jacket GPU Computing Engine for MATLAB® and its applications to Optics and Photonics on Aug 1.  From <a href=\"http://blog.accelereyes.com/blog/2010/11/05/beam_propagation_methods/\">beam propagation methods</a> to lens design, optics engineers are enjoying the benefit of GPU computing with Jacket to accelerate MATLAB® codes.\n\nThis was part of a free series of webinars that help you learn about <a href=\"http://accelereyes.com/arrayfire\">ArrayFire</a> (for C/C++/Fortran/Python) and <a href=\"http://accelereyes.com/jacket\">Jacket</a> (for use with MATLAB®). Anyone can attend these webinars, for they are absolutely free and open for anyone to attend and interact with AccelerEyes engineers. Learn more at <a href=\"http://www.accelereyes.com/webinars\">http://www.accelereyes.com/webinars</a>.\n\nJacket allows you to envision really fast applications for GPU computing, and the team at AccelerEyes recently helped Northrop Grumman Corporation achieve better-than real-time performance on a UAV Imaging application. The Northrop group took advantage of AccelerEyes consulting services to achieve a huge acceleration in performance. In this webinar, we presented this application in detail and the benefits that it achieved.\n\nWe really enjoy hosting webinars, for they give us an opportunity to engage with the people that use our product! Plus, every webinar has something for everyone, so make sure you register for the next webinar soon.\n\nWatch the webinar video here:\n\n<center><iframe src=\"http://www.youtube.com/embed/LieZ-gmvlh0\" frameborder=\"0\" width=\"560\" height=\"315\"></iframe></center>&nbsp;\n\nSince the webinar demos were not recorded, we are offering to run special live WebEx demos for anyone interested in Optics or Photonics on the GPU. Simply email us at <a href=\"mailto:support@accelereyes.com\">support@accelereyes.com</a> to setup a WebEx demo session with an AccelerEyes engineer.\n\n</div>','Webinar - Optics MATLAB® Applications with Jacket','','publish','open','open','','webinar-optics-matlab-applications-with-jacket','','','2012-08-23 15:41:28','2012-08-23 19:41:28','',0,'http://blog.accelereyes.com/blog/?p=2933',0,'post','',0),(2954,1,'2012-08-28 09:42:46','2012-08-28 13:42:46','<p style=\"text-align: left;\">Since the 1950s Synthetic aperture radar (SAR) systems have gained extreme popularity in both civilian and military domains due to their all-weather, day-or-night capabilities as well as the ability to render different views of a \"target\". However, the raw SAR data (phase-history data) must be preprocessed  since all point targets at each pulse instance are superimposed  and create a complex interference that is not very useful for target location. SAR image formation algorithms compress this target information in range (frequency) and along-track (azimuth) directions to obtain interpretable images.</p>\n<p style=\"text-align: left;\">In the paper titled \"<a href=\"https://osubp.googlecode.com/hg-history/60095eb90ef2ea48858f3fca37ac09ab41577704/SPIE10toolbox.pdf\">SAR image formation toolbox for MATLAB®</a>\", Gorham L.A. and Moore L.J. of the Air Force Research Lab discuss the implementation of the <em>matched filter</em> and <em>backprojection</em> image formation algorithms in MATLAB®. We demonstrate how easily these algorithms can be accelerated on the GPU using Jacket. For a data set, we have taken November 96 Collection X-band SAR imagery (MSTAR data) available for download at <a href=\"https://www.sdms.afrl.af.mil\">SDMS Public Web Site</a>. Each data set consists of complex phase-history data for 128 azimuth points and 128 frequency samples. Range and cross-range resolutions have been set to 0.304 m. The data is HH-polarimetric with a frequency bandwidth of 0.591 GHz at a center frequency of 9.6 GHz. Two reconstructed SAR images (using both algorithms) are shown below:</p>\n\n\n[caption id=\"attachment_2971\" align=\"aligncenter\" width=\"704\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/HB03333_mf.png\"><img class=\" wp-image-2971   \" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/HB03333_mf.png\" alt=\"\" width=\"704\" height=\"278\" /></a> <span style=\"font-family: Times New Roman MS; font-size: 10pt;\"> Matched filter (<strong>left</strong>) and backprojection (<strong>right</strong>) images using MSTAR dataset</span>[/caption]\n\n[caption id=\"attachment_2982\" align=\"aligncenter\" width=\"701\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/f101HH0_mf.png\"><img class=\" wp-image-2982   \" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/f101HH0_mf.png\" alt=\"\" width=\"701\" height=\"279\" /></a> <span style=\"font-family: Times New Roman MS; font-size: 10pt;\"> Matched filter (<strong>left</strong>) and backprojection (<strong>right</strong>) images using MSTAR dataset</span>[/caption]\n\n&nbsp;\n<p style=\"text-align: left;\">We have conducted experiments on a parallel cluster with the following specs:</p>\n\n<ul>\n	<li>4x Intel(R) Xeon(R) CPU E7-4860 (40 cores / 80 threads via Hyper-Threading)</li>\n	<li>256 GB RAM (32 * 8GB)</li>\n	<li>4x NVIDIA Tesla S2050 (GF100)</li>\n</ul>\nrunning MATLAB® R2012a under 64-bit Linux platform. We have run both reconstruction algorithms on the same data set for increasing resolutions:\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/matched_filter_double_new4.png\"><img class=\"aligncenter  wp-image-3033\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/matched_filter_double_new4.png\" alt=\"\" width=\"683\" height=\"288\" /></a></p>\nNote that, for the matched filter algorithm (left diagram), the default MATLAB® implementation can benefit from the large number of CPU cores available (that is why the running time does not grow linearly with increasing resolution). But, even with this, Jacket achieves about <strong>20-50x</strong> speed-up over the MATLAB® CPU implementation, while ArrayFire achieves even larger speed-up.\n<p style=\"text-align: left;\">The code that was used to produce these results is shared below.</p>\n<p style=\"text-align: left;\"><!--more--></p>\nHere is the implementation for both of these SAR algorithms with ArrayFire:\n<pre>struct SAR_data { //! SAR data structure format\n    double deltaF;  //! step size of frequency data (Hz)\n    double maxWr;   //! maximum scene size in range direction (m)\n    double maxWx;   //! maximum scene size in cross-range direction (m)\n\n    array minF;   //! (Np x 1): Vector containing the start frequency of \n                  //! each pulse (Hz)\n    array x_mat;  //! (Sx x Sy): the x-positions of each pixel (m)\n    array y_mat;  //! (Sx x Sy): the y-positions of each pixel (m)\n    array z_mat;  //! (Sx x Sy): the z-positions of each pixel (m)\n\n    array AntX;   //! (Np x 1): the x-position of the sensor at each pulse (m)\n    array AntY;   //! (Np x 1): the y-position of the sensor at each pulse (m)\n    array AntZ;   //! (Np x 1): the z-position of the sensor at each pulse (m)\n\n    array R0;     //! (Np x 1): the range to scene center (m)\n    array phdata; //! (K x Np): phase history data (frequency domain),\n                  //! fast time in rows, slow time in columns\n    array im_final; //! (Sx x Sy): the complex image value at each pixel\n};       \n\nvoid matched_filter_af(SAR_data&amp; data) {\n\n    double c = 299792458.0; // speed of light\n    // Determine the size of the phase history data\n    int K = data.phdata.dims(0);  //! The number of frequency bins per pulse\n    int Np = data.phdata.dims(1); //! The number of pulses\n    //! Initialize the image with all zero values (complex)\n    data.im_final = zeros(data.x_mat.dims(), c64);\n    array im_slices = zeros(K, data.x_mat.dims(0),\n               data.x_mat.dims(1), c64);\n    array fspan = array(seq(0.0, K-1)) * data.deltaF;\n\n    for(int ii = 0; ii &lt; Np; ii++) {\n        //! Calculate differential range for each pixel in the image (m)\n        array dx = data.AntX(ii)-data.x_mat,\n              dy = data.AntY(ii)-data.y_mat,\n              dz = data.AntZ(ii)-data.z_mat;\n        array dR = sqrt(dx*dx + dy*dy + dz*dz) - data.R0(ii);\n        //! Calculate the frequency of each sample in the pulse (Hz)\n        array freq = data.minF(ii) + fspan;\n        array tt = data.phdata(span,ii);\n        //! Perform the Matched Filter operation\n        gfor(array jj, K) { // parallel gfor loop\n            im_slices(jj,span,span) =\n                    tt(jj)*exp(i*(4.0*Pi/c*freq(jj)*dR));\n        }\n        tt = sum(im_slices,0);\n        data.im_final = data.im_final + reshape(tt, data.x_mat.dims());\n    }\n}\n\nvoid backprojection_af(SAR_data&amp; data) {\n    double c = 299792458.0; // speed of light\n    // Determine the size of the phase history data\n    int K = data.phdata.dims(0);  //! The number of frequency bins per pulse\n    int Np = data.phdata.dims(1); //! The number of pulses\n    int Nfft = K * 10; // set FFT size roughly 10 times larger than K   \n\n    //! Initialize the image with all zero values (complex)\n    data.im_final = zeros(data.x_mat.dims(), c64);\n    //! Calculate the range to every bin in the range profile (m)\n    array r_vec = array(seq(-Nfft/2, Nfft/2-1)) *data.maxWr/Nfft;\n\n    for(int ii = 0; ii &lt; Np; ii++) {\n        //! Form the range profile with zero padding added\n        array rc = shift(ifft(data.phdata(span,ii), Nfft), Nfft/2);\n        //! Calculate differential range for each pixel in the image (m)\n        array dx = data.AntX(ii)-data.x_mat,\n              dy = data.AntY(ii)-data.y_mat,\n              dz = data.AntZ(ii)-data.z_mat;\n        array dR = sqrt(dx*dx + dy*dy + dz*dz) - data.R0(ii);\n        //! Calculate phase correction for image\n        array phCorr = exp(i*(4.0*Pi*data.minF(ii)/c*dR));\n        //! Determine which pixels fall within the range swath\n        array I = where((dR &gt; min(r_vec)) &amp;&amp; (dR &lt; max(r_vec)));\n        //! Update the image using linear interpolation\n        array slice = dR(I).copy();\n        array res = interp(r_vec, rc, slice, af_interp_linear, af::NaN);\n        data.im_final(I) = data.im_final(I) + res * phCorr(I);\n    }\n}</pre>\n<p style=\"text-align: left;\">Here is the implementation for both of these SAR algorithms with Jacket:</p>\n\n<pre> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n % For both algorithms, the following fields need to be populated:\n %\n % data.deltaF (scalar): Step size of frequency data (Hz)\n % data.minF (Np x 1): Vector containing the start frequency of each pulse (Hz) %\n % data.x_mat (Sx x Sy): The x-position of each pixel (m)\n % data.y_mat (Sx x Sy): The y-position of each pixel (m)\n % data.z_mat (Sx x Sy): The z-position of each pixel (m)\n % data.AntX (Np x 1): The x-position of the sensor at each pulse (m)\n % data.AntY (Np x 1): The y-position of the sensor at each pulse (m)\n % data.AntZ (Np x 1): The z-position of the sensor at each pulse (m)\n % data.R0 (Np x 1): The range to scene center (m)\n % data.phdata (K x Np): Phase history data (frequency domain)\n %  Fast time in rows, slow time in columns\n % The output is:\n % data.im_final (Sx x Sy): The complex image value at each pixel\n % data.maxWr (scalar):  maximum scene size in range direction (m)\n % data.Nfft (scalar):  size of the FFT to form the range profile \n %                                     (backprojection only)\n %\n % MATLAB,\" Algorithms for Synthetic Aperture Radar Imagery XVII\n % 7669, SPIE (2010).\n %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n% \'data\' fields must be cast to GPU (gdouble) before calling this function\nfunction data = matched_filter_gpu(data)\n    c = 299792458; % Define speed of light (m/s)\n    % Determine the size of the phase history data\n    data.K = size(data.phdata,1); % The number of frequency bins per pulse\n    data.Np = size(data.phdata,2); % The number of pulses\n\n    % Initialize the image with all zero values\n    data.im_final = gzeros(size(data.x_mat), \'gdouble\');\n    data.im_slices = gzeros([data.K,size(data.x_mat)], \'gdouble\');\n    % Loop through every pulse\n    for ii = 1:data.Np\n        % Calculate differential range for each pixel in the image (m)\n        dR = sqrt((data.AntX(ii)-data.x_mat).^2 + ...\n              (data.AntY(ii)-data.y_mat).^2 + ...\n              (data.AntZ(ii)-data.z_mat).^2) - data.R0(ii);\n        % Calculate the frequency of each sample in the pulse (Hz)\n        freq = data.minF(ii) + (0:(data.K-1)) * data.deltaF;\n        % Perform the Matched Filter operation\n        gfor jj = 1:data.K\n            data.im_slices(jj,:,:) = data.phdata(jj,ii) * exp(1i*4*pi*freq(jj)/c*dR);\n        gend\n        data.im_final = data.im_final + squeeze(sum(data.im_slices,1));\n    end\nend\n\n% \'data\' fields must be cast to GPU (gdouble) before calling this function\nfunction data = backprojection_gpu(data)\n    c = 299792458; % Define speed of light (m/s)\n    % Determine the size of the phase history data\n    data.K = size(data.phdata,1); % The number of frequency bins per pulse\n    data.Np = size(data.phdata,2); % The number of pulses\n    % Calculate the range to every bin in the range profile (m)\n    data.r_vec = linspace(-data.Nfft/2,data.Nfft/2-1,data.Nfft)*data.maxWr/data.Nfft;\n\n    % Initialize the image with all zero values\n    data.im_final = gzeros(size(data.x_mat), \'gdouble\');\n    % Loop through every pulse\n    for ii = 1:data.Np\n        % Form the range profile with zero padding added\n        rc = fftshift(ifft(data.phdata(:,ii), data.Nfft));\n        % Calculate differential range for each pixel in the image (m)\n        dR = sqrt((data.AntX(ii)-data.x_mat).^2 + ...\n              (data.AntY(ii)-data.y_mat).^2 + ...\n              (data.AntZ(ii)-data.z_mat).^2) - data.R0(ii);\n        % Calculate phase correction for image\n        phCorr = exp(1i*4*pi*data.minF(ii)/c*dR);\n        % Determine which pixels fall within the range swath\n        I = find(and(dR &gt; min(data.r_vec), dR &lt; max(data.r_vec)));\n        % Update the image using linear interpolation\n        data.im_final(I) = data.im_final(I) + interp1(data.r_vec,rc,dR(I),\'linear\') .* phCorr(I);\n    end\n end</pre>','SAR Image Formation Algorithms on the GPU','','publish','open','open','','sar-image-formation-algorithms-on-the-gpu','','','2012-08-28 09:42:46','2012-08-28 13:42:46','',0,'http://blog.accelereyes.com/blog/?p=2954',0,'post','',1),(3053,4,'2012-09-19 02:00:39','2012-09-19 06:00:39','<p style=\"text-align: left;\"><a href=\"http://accelereyes.com/arrayfire\">ArrayFire</a> is a great way to supplement OpenCV for faster processing on the GPU.</p>\n<p style=\"text-align: left;\">Mcclanahoochie recently <a href=\"http://mcclanahoochie.com/blog/portfolio/local-contrast-enhancement-with-arrayfire-opencv/\" target=\"_blank\">posted</a> an interactive demo showing the use of OpenCV with ArrayFire for computing Local Contrast Enhancement on the GPU from webcam video.</p>\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-20-at-9.19.21-AM_2.png\"><img class=\"aligncenter  wp-image-3056\" title=\"Screen-Shot-2012-08-20-at-9.19.21-AM_2\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-20-at-9.19.21-AM_2-1024x640.png\" alt=\"\" width=\"552\" height=\"345\" /></a></p>\n<p style=\"text-align: left;\">Mcclanahoochie also shows how easy it is to convert OpenCV Mat images into ArrayFire GPU array images, as seen in the code snippit below:</p>\n<p style=\"text-align: left;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-20-at-7.38.58-PM.png\"><img class=\"aligncenter size-full wp-image-3054\" title=\"Screen-Shot-2012-08-20-at-7.38.58-PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-20-at-7.38.58-PM.png\" alt=\"\" width=\"606\" height=\"439\" /></a></p>\n<p style=\"text-align: left;\">All the source code is available on Google Code, linked to from his website.</p>\n<p style=\"text-align: left;\">Simply download <a href=\"http://www.accelereyes.com/download_arrayfire\" target=\"_blank\">ArrayFire</a> and <a href=\"http://opencv.org/\" target=\"_blank\">OpenCV</a> and <a href=\"http://mcclanahoochie.com/blog/portfolio/local-contrast-enhancement-with-arrayfire-opencv/\" target=\"_blank\">try it out</a> for yourself!</p>','Image Processing with ArrayFire and OpenCV on the GPU','','publish','open','open','','image-processing-with-arrayfire-and-opencv','','\nhttp://mcclanahoochie.com/blog/portfolio/local-contrast-enhancement-with-arrayfire-opencv/','2012-09-19 02:00:39','2012-09-19 06:00:39','',0,'http://blog.accelereyes.com/blog/?p=3053',0,'post','',0),(3064,1,'2012-09-10 16:51:14','2012-09-10 20:51:14','Time delay estimation (TDE) techniques have many diverse signal processing applications: for instance, in such fields as radar, sonar, seismology, geophysics, and ultrasonics for identifying and localizing radiating sources.\n\nIn this case study, we evaluate the performance of two algorithms developed by <a href=\"http://www.dsprelated.com/code.php?submittedby=24789\">Markus Nentwig</a> to find delay and scaling factor between two cyclic signals. The first algorithm uses linear least-squares fitting to estimate the delay. The second algorthm is iterative and relies on FFT-based cross-correlation. A MATLAB® implementation of both approaches can be found in <a href=\"http://www.dsprelated.com/showcode/207.php\">Algorithm 1</a> and <a href=\"http://www.dsprelated.com/showcode/288.php\">Algorithm 2</a>, respectively. As the author pointed out, the algorithms are <em>not</em> suited for real-time applications since the whole signal needs to be known in advance. However, they can be very useful as general-purpose tool for simulations and measurements to align input and output samples: properly used, the attained accuracy can be orders of magnitude higher than that for typical \"ad-hoc\" solutions.\n\nThe following code snippet, provided by the author, has been used to generate delayed signals:\n<pre>% generate random signals of length n: s2 is a delayed replica s1 with (optionally) some noise added  \nfunction [s1,s2] = generate_signals(n)\n   % create first random signal\n   fd = randn(1, n) + 1i * randn(1, n);\n   % apply lowpass filter\n   f = (mod(((0:n-1)+floor(n/2)), n)-floor(n/2))/n;\n   fd(abs(f) &gt; 0.045) = 0;\n   s1 = real(ifft(fd)) * sqrt(n);\n   % create the 2nd delayed signal\n   dTest_samples = 12.3456;\n   cTest = 1.23456;\n   cTest = cTest + 1i; % disp(\'*** test: complex coeff enabled ***\'); \n   % cTest = -cTest; disp(\'*** test: negative coeff enabled ***\'); \n   s2 = cTest * cs_delay(s1, 1, dTest_samples);\n   s2 = s2 + 0.1*randn(size(s2)); disp(\'*** test: noise enabled ***\');\nend\n\n% delay cyclic signal by phase shift\nfunction waveform = cs_delay(waveform, rate_Hz, delay_s)\n    rflag = isreal(waveform);\n    n = numel(waveform);\n    cycLen_s = n / rate_Hz;\n    nCyc = delay_s / cycLen_s();\n    f = 0:(n - 1);\n    f = f + floor(n / 2);\n    f = mod(f, n);\n    f = f - floor(n / 2);\n    phase = -2 * pi * f * nCyc;\n    rot = exp(1i*phase);\n    waveform = ifft(fft(waveform) .* rot);\n    if rflag\n        waveform = real(waveform);\n    end\nend</pre>\nThe next picture demonstrates signal correction using the second iterative algorithm. Here the signal <strong>s2</strong> is a scaled and phase-shifted version of the \"reference\" signal <strong>s1</strong>, with some noise added:\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/09/signal_corrected2.png\"><img class=\"aligncenter size-full wp-image-3093\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/09/signal_corrected2.png\" alt=\"\" width=\"670\" height=\"444\" /></a></p>\nWe have benchmarked both algorithms on the following testing platform:\n<ul>\n	<li>4x Intel(R) Xeon(R) CPU E7-4860 (40 cores / 80 threads via Hyper-Threading)</li>\n	<li>256 GB RAM (32 * 8GB)</li>\n	<li>4x NVIDIA Tesla S2050 (GF100)</li>\n</ul>\nrunning MATLAB® R2012a under 64-bit Linux. The results of experiments with and without GPU acceleration for increasing signal lengths are shown below:\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/09/delay_est_fft.png\"><img class=\"aligncenter  wp-image-3097\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/09/delay_est_fft.png\" alt=\"\" width=\"700\" height=\"314\" /></a></p>\nTo summarize, using Jacket we have been able to achive on the average <strong>2.5x</strong> speed-up for the first algorithm and more than <strong>20x</strong> speed-up for the second approach. We also note that the MATLAB® implementation of both algorithms with Jacket requires only very <em>little</em> effort (up to changing the number types) since they are readily suitable for GPU acceleration.\n\n<!--more-->\n\nLeast-squares based algorithm with Jacket (original comments are provided by the author):\n<pre>% ******************************************************************************\n% delay-matching between two signals (complex/real-valued) M. Nentwig\n%\n% * matches the continuous-time equivalent waveforms of the signal vectors\n% (reconstruction at Nyquist limit =&gt; ideal lowpass filter)\n% * Signals are considered cyclic. Use arbitrary-length zero-padding to turn a\n% one-shot signal into a cyclic one.\n%\n% * output:\n%   =&gt; coeff: complex scaling factor that scales \'ref\' into \'signal\'\n%   =&gt; delay \'deltaN\' in units of samples (subsample resolution)\n%      apply both to minimize the least-square residual\n%   =&gt; \'shiftedRef\': a shifted and scaled version of \'ref\' that\n%      matches \'signal\'\n%   =&gt; (signal - shiftedRef) gives the residual (vector error)\n%\n% ******************************************************************************\nfunction [coeff, shiftedRef, deltaN] = fitSignal_FFT(signal, ref)\n    // cast the input signals to GPU\n    signal = gdouble(signal); ref = gdouble(ref);\n    n = length(signal);\n    forceReal = isreal(signal) &amp;&amp; isreal(ref);\n\n    % Calculate the frequency that corresponds to each FFT bin [-0.5..0.5[\n    binFreq = (mod((gdouble(0:n-1)+floor(n/2)), n)-floor(n/2))/n;\n\n    % Delay calculation starts: Convert to frequency domain...\n    sig_FD = fft(signal); ref_FD = fft(ref, n);\n\n    % ... calculate crosscorrelation between signal and reference...\n    u=sig_FD .* conj(ref_FD);\n    if mod(n, 2) == 0\n        % for an even sized FFT the center bin represents a signal\n        % [-1 1 -1 1 ...] (subject to interpretation). It cannot be delayed.\n        % The frequency component is therefore excluded from the calculation.\n        u(length(u)/2 + 1)=0;\n    end\n    Xcor=abs(ifft(u));\n\n    % Each bin in Xcor corresponds to a given delay in samples. The bin with the\n    % highest absolute value corresponds to the delay where maximum correlation\n    % occurs.\n    integerDelay = find(gdouble(Xcor==max(Xcor)));\n\n    % (1): in case there are several bitwise identical peaks, use the first one\n    % Minus one: Delay 0 appears in bin 1\n    integerDelay=integerDelay(1)-1;\n\n    % Fourier transform of a pulse shifted by one sample\n    rotN = exp(2i*pi*integerDelay .* binFreq);\n    uDelayPhase = -2*pi*binFreq;\n\n    % Since the signal was multiplied with the conjugate of the reference, the\n    % phase is rotated back to 0 degrees in case of no delay. Delay appears as\n    % linear increase in phase, but it has discontinuities. Use the known phase\n    % (with +/- 1/2 sample accuracy) to rotate back the phase. This removes the\n    % discontinuities.\n    u=u .* rotN;\n\n    % Obtain the delay using linear least mean squares fit. The phase is weighted\n    % according to the amplitude. This suppresses the error caused by frequencies\n    % with little power, that may have radically different phase.\n    weight = abs(u);\n    constRotPhase = 1 .* weight;\n    uDelayPhase = uDelayPhase .* weight;\n    ang = angle(u) .* weight;\n    r = [constRotPhase; uDelayPhase] .\'  ang.\'; % linear mean square\n\n    % the same will be obtained via the phase of \'coeff\' further down\n    fractionalDelay=r(2);\n    % Finally, the total delay is the sum of integer part and fractional part.\n    deltaN = integerDelay + fractionalDelay;\n\n    % provide shifted and scaled \'ref\' signal this is effectively time-convolution \n    % with a unit pulse shifted by deltaN\n    rotN = exp(-2i*pi*deltaN .* binFreq);\n    ref_FD = ref_FD .* rotN;\n    shiftedRef = ifft(ref_FD);\n\n    % Again, crosscorrelation with the now time-aligned signal\n    coeff=sum(signal .* conj(shiftedRef)) / sum(shiftedRef .* conj(shiftedRef));\n    shiftedRef=shiftedRef * coeff;\n\n    if forceReal\n        shiftedRef = real(shiftedRef);\n    end\nend</pre>\nThe iterative algorihtm with Jacket:\n<pre>% *****************************************************************************\n% The functions below implement a fallback solution, if the above algorithm\n% fails. This variant performs better at low signal-to-noise ration. The\n% algorithm iteratively determines the crosscorrelation, predicts the peak\n% location between bins, time-shifts and repeats.\n% Documentation: http://www.dsprelated.com/showcode/288.php\n% It is not as accurate and slower as the first algorithm, but should always\n% converge, even if \"the\" delay between two signals is not well-defined because\n% of group delay variations, multiple periods etc.\n% ******************************************************************************\nfunction out = fitSignal_corrSearch(signal, ref)\n   // cast the input signals to GPU\n   signal = gdouble(signal); ref = gdouble(ref);\n   [deltaN, coeff] = iterDelayEst(signal, ref);\n   coeff = 1 / coeff; deltaN = -deltaN;\n   % correct it\n   out.shifted_ref = cs_delay(ref, 1, deltaN);\n   out.shifted_ref = out.shifted_ref * coeff;\nend\n\n% estimates delay and scaling factor\nfunction [delay_samples, coeff] = iterDelayEst(s1, s2)\n    s1 = s1(:) .\'; % force row vectors\n    s2 = s2(:) .\';\n    rflag = isreal(s1) &amp;&amp; isreal(s2);\n    n = numel(s1);  halfN = floor(n/2);\n    assert(numel(s2) == n, \'signals must have same length\');\n\n    thr_samples = 1e-12; % exit if uncertainty below threshold\n    nIter = 250; % exit after fixed number of iterations\n\n    % frequency domain representation of signals\n    fd1 = fft(s1); fd2 = fft(s2);\n\n    tau = []; % first round: No delay was applied\n    fd2Tau = fd2; % delayed s2 in freq. domain\n\n    % frequency corresponding to each FFT bin -0.5..0.5\n    f = (mod((gdouble(0:n-1)+floor(n/2)), n)-floor(n/2))/n;\n    % normalization factor\n    nf = real(sqrt((fd1 * fd1\') * (fd2 * fd2\'))) / n; % normalizes to 1\n\n    % search window: known maximum and two surrounding points\n    x1 = -1; x2 = -1; x3 = -1;\n    y1 = -1; y2 = -1; y3 = -1;\n\n    for count = 1:nIter\n        % crosscorrelation with time-shifted signal\n        xcorr = abs(ifft(fd2Tau .* conj(fd1)))/ nf;\n        % detect peak\n        if isempty(tau)\n            % startup: initialize with three adjacent bins around peak\n            ix = find(gdouble(xcorr == max(xcorr)));\n            ix = ix(1); % use any, if multiple bitwise identical peaks\n\n            % indices of three bins around peak\n            ixLow = mod(ix-1-1, n) + 1; % one below\n            ixMid = ix;\n            ixHigh = mod(ix-1+1, n) + 1; % one above\n\n            % delay corresponding to the three bins\n            tauLow = mod(ixLow -1 + halfN, n) - halfN;\n            tauMid = mod(ixMid -1 + halfN, n) - halfN;\n            tauHigh = mod(ixHigh -1 + halfN, n) - halfN;\n\n            % crosscorrelation value for the three bins\n            xcLow = (xcorr(ixLow));\n            xcMid = (xcorr(ixMid));\n            xcHigh = (xcorr(ixHigh));\n\n            x1 = tauLow; x2 = tauMid; x3 = tauHigh;\n            y1 = xcLow; y2 = xcMid; y3 = xcHigh;\n        else\n            % only main peak at first bin is of interest\n            tauMid = tau;\n            xcMid = xcorr(1);\n            if xcMid &gt; y2 % improve midpoint\n                if tauMid &gt; x2 % midpoint becomes lower point\n                    x1 = x2; y1 = y2;\n                else % midpoint becomes upper point\n                    x3 = x2; y3 = y2;\n                end\n                x2 = tauMid; y2 = xcMid;\n\n            elseif tauMid = x1); % bitwise identical is OK\n                assert(tauMid &gt; x1 || xcMid &gt; y1); % expect improvement\n                x1 = tauMid; y1 = xcMid;\n\n            elseif tauMid &gt; x2 % improve high point\n                assert(tauMid &lt;= x3); % bitwise identical is OK\n                assert((tauMid  y3)); % expect improvement\n                x3 = tauMid; y3 = xcMid;\n            else\n                assert(false, \'?? evaluated for existing tau ??\');\n            end\n        end\n\n        % calculate uncertainty (window width)\n        eIter = abs(x3 - x1);\n        if eIter  x1) &amp;&amp; (tau &lt; x3));\n            else\n                usePoly = 0;\n            end\n        end\n        if ~usePoly\n            % revert to linear interpolation on the side with the less-accurate\n            % outer sample. Note: There is no guarantee that the side with the\n            % more accurate outer sample is the right one, as the samples aren\'t\n            % placed on a regular grid! Therefore, iterate to improve the \"worse\"\n            % side, which will eventually become the \"better side\", and iteration\n            % converges.\n            tauLow = (x1 + x2) / 2;\n            tauHigh = (x2 + x3) / 2;\n            if y1 &lt; y3\n                o = [tauLow, tauHigh];\n            else\n                o = [tauHigh, tauLow];\n            end\n            % don\'t choose point that is identical to one that is already known\n            tau = o(1);\n            if tau == x1 || tau == x2 || tau == x3\n                tau = o(2);\n                if tau == x1 || tau == x2 || tau == x3\n                    break;\n                end\n            end\n        end\n        % advance 2nd signal according to location of maximum\n        % phase shift in frequency domain - delay in time domain\n        fd2Tau = fd2 .* exp(2i * pi * f * tau);\n    end % for\n\n    % the delay estimate is the final location of the delay that\n    % maximized crosscorrelation (center of window).\n    delay_samples = x2;\n    % Coefficient: Turn signal 1 into signal 2\n    coeff = fd2Tau * fd1\' ./ (fd1 * fd1\');\n    % chop roundoff error, if input signals are known to be real-valued.\n    if rflag\n        coeff = real(coeff);\n    end\nend</pre>','Time delay estimation algorithms with Jacket','','publish','open','open','','time-delay-estimation-algorithms-with-jacket','','','2012-09-10 16:51:14','2012-09-10 20:51:14','',0,'http://blog.accelereyes.com/blog/?p=3064',0,'post','',0),(3131,1,'2012-09-26 10:27:51','2012-09-26 14:27:51','<p style=\"text-align: justify;\">Recently, AccelerEyes held a free webinar that dealt with accelerating genomics MATLAB applications on the GPU. We recently added new genomics examples to Jacket, and wanted to use this webinar to showcase these examples and run through some code.</p>\n<p style=\"text-align: justify;\">This was part of the free series of <a href=\"http://www.accelereyes.com/webinars\">AccelerEyes webinars</a> that provide a great opportunity for you to interact with AccelerEyes engineers, see demos executing live on GPUs, and learn about AccelerEyes products and services.</p>\n<p style=\"text-align: justify;\">Over the course of the last decade, GPUs have continued to advance at a large pace, and are leaving CPUs behind in some ways, specifically in terms of their ability to perform massively parallel computations. Jacket is proven to be very efficient at harnessing this ability of GPUs, and has given scientists and engineers many-fold increases in productivity.</p>\n<p style=\"text-align: justify;\">The webinar, like all AccelerEyes webinars, introduced basic Jacket concepts as well as important cornerstones of GPU computing. With respect to Genomics, many different examples and case studies were illustrated.</p>\n<p style=\"text-align: justify;\">At the Centers for Disease Control and Prevention, a US Government organization tasked with the onerous responsibility of protecting public health, researchers used Jacket to explore random genetic mutations in the Hepatitis C virus. On a CPU, this would have taken <em>months</em> to compute! Wisely, however, they exploited parallelism through Jacket and were able to reduce this to less than <em>half a day</em>. The importance of this kind of boost to productivity in preserving public health cannot be understated.</p>\n<p style=\"text-align: justify;\">The hands-on section of the webinar focused on various Genomics applications that have been ported to the GPU to achieve tremendous successes.</p>\n<p style=\"text-align: justify;\">One example, which also happens to be included with every version of Jacket, was the Multi-dimensional scaling example from the Leibniz Institute, that gave about <strong>15x speedup</strong> on Jacket.</p>\n<p style=\"text-align: justify;\">We recently added two more examples to Jacket:</p>\n\n<ul style=\"text-align: justify;\">\n	<li>The Mantel-Haenzel Test example gives a <strong>25x performance improvement</strong> over the CPU.</li>\n	<li>The Log-Fisher Test example gives an immense <strong>400x performance improvement</strong> over the CPU!</li>\n</ul>\n<p style=\"text-align: justify;\">Many more case studies were discussed, and many intelligent questions were asked during the webinar. We thank you for your attendance and interest, and gladly welcome feedback on these case studies and questions on whether your specific applications can be accelerated with Jacket!</p>\n<p style=\"text-align: justify;\">Please view the webinar video here:</p>\n\n<center><iframe src=\"http://www.youtube.com/embed/3K-h5mkuZOw\" frameborder=\"0\" width=\"560\" height=\"315\"></iframe></center>','Genomics MATLAB® applications on the GPU','','publish','open','open','','genomics-matlab-applications-on-the-gpu','','','2012-09-26 10:27:51','2012-09-26 14:27:51','',0,'http://blog.accelereyes.com/blog/?p=3131',0,'post','',0),(3141,1,'2012-09-27 11:30:22','2012-09-27 15:30:22','<dl><dt></dt></dl><dl><dt></dt></dl><dl><dt></dt></dl>Researchers from the École Polytechnique de Montréal showed that Jacket is very efficient to rapidly calculate 2D or 3D isotropic gradients in MATLAB® code. From a mathematical point of view, the isotropic gradients are characterized by their very precise orientation compared to the standard 1D finite difference discretizations. Using convolution functions developed by AccelerEyes, the method becomes very simple to apply and provides a very fast evaluation of isotropic gradients of functions or images.\n\nThis type of isotropic discretization currently has an application in computational fluid dynamics. They are useful for simulating immiscible multiphase flows using the Lattice Boltzmann Method (LBM), where the orientation of the various fluid interfaces has to be computed very frequently and precisely. In multiphase flow simulation using LBM, calculation of a high order isotropic gradient is the most expensive part of the method, and the use of Jacket, has enabled the researchers to reduce the computational cost by an astonishing amount. The researchers from École Polytechnique believe that isotropic gradients could also be useful in other scientific fields.\n\nThe summary of the method with MATLAB examples is presented in the free to download book \"MATLAB - A Fundamental Tool for Scientific Computing and Engineering Applications - Volume 3\" [1]. A direct link to the book chapter published by InTech is also given below [2]. In particular, the kernels required to perform the convolution are explicitly given in MATLAB m-code. It is therefore easier to reproduce some of the results.\n\nThe following figures illustrate the relative speedup to evaluate isotropic gradients of  2D and 3D images using an Nvidia GTX-580 compared to the singlethread MATLAB CPU version (Intel Core-i7 970). The examples have shown gains of 40x to 120x in 2D and 3D respectively!\n\n[caption id=\"attachment_3157\" align=\"aligncenter\" width=\"500\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/09/Fig02b_speedUp_twoD_fourteen-e1348690578714.jpg\"><img class=\"size-full wp-image-3157\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/09/Fig02b_speedUp_twoD_fourteen-e1348690578714.jpg\" alt=\"\" width=\"500\" height=\"474\" /></a> <br /> Speedup with the 14th order 2D isotropic gradient.[/caption]\n\n&nbsp;\n\n[caption id=\"attachment_3158\" align=\"aligncenter\" width=\"500\"]<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/09/Fig03b_speedUp_threeD_eight-e1348690692265.jpg\"><img class=\"size-full wp-image-3158\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/09/Fig03b_speedUp_threeD_eight-e1348690692265.jpg\" alt=\"\" width=\"500\" height=\"474\" /></a> <br /> Speedup with the 8th order 3D isotropic gradient.[/caption]\n\n&nbsp;\n\n[1] Sébastien Leclaire, Maud El-Hachem and Marcelo Reggio (2012). Convolution Kernel for Fast CPU/GPU Computation of 2D/3D Isotropic Gradients on a Square/Cubic Lattice, MATLAB - A Fundamental Tool for Scientific Computing and Engineering Applications - Volume 3, Vasilios N. Katsikis (Ed.), ISBN: 978-953-51-0752-1, InTech.\n\n[2] <a title=\"Convolution Kernel for Fast CPU/GPU Computation of 2D/3D Isotropic Gradients on a Square/Cubic Lattice\" href=\"http://www.intechopen.com/books/matlab-a-fundamental-tool-for-scientific-computing-and-engineering-applications-volume-3/convolution-kernel-for-fast-cpu-gpu-computation-of-2d-3d-isotropic-gradients-on-a-square-cubic-latti\">Convolution Kernel for Fast CPU/GPU Computation of 2D/3D Isotropic Gradients on a Square/Cubic Lattice</a>','Fast Computatio​n of Isotropic Gradients with Jacket\'s Convolutions','','publish','open','open','','fast-computatio%e2%80%8bn-of-isotropic-gradient','','','2012-09-27 11:30:22','2012-09-27 15:30:22','',0,'http://blog.accelereyes.com/blog/?p=3141',0,'post','',0),(3251,4,'2013-01-17 15:53:14','0000-00-00 00:00:00','<a href=\"http://www.hpcnotes.com/2012/10/the-making-of-1000x-unbalanced.html\">http://www.hpcnotes.com/2012/10/the-making-of-1000x-unbalanced.html</a>\n\nWe agree... a bunch of un-utilized HPC systems sitting there due to lack of SW.\n\nhttp://www.hpcwire.com/hpcwire/2012-12-17/open_source_software_in_hpc.html\n\nOpen source isn\'t as cheap as it seems.','Unbalanced Supercomputing','','draft','open','open','','','','','2013-01-17 15:53:14','0000-00-00 00:00:00','',0,'http://blog.accelereyes.com/blog/?p=3251',0,'post','',0),(3253,4,'2012-10-23 14:15:49','2012-10-23 18:15:49','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/10/jacket_logo.png\"><img class=\"alignright size-medium wp-image-3271\" title=\"jacket_logo\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/10/jacket_logo-300x235.png\" alt=\"\" width=\"300\" height=\"235\" /></a>We are pleased to announce the new release of Jacket v2.3.  This new version of Jacket brings even greater performance improvements through GPU computing for MATLAB® codes.  (<a href=\"http://accelereyes.com/download_jacket\">Click here</a> to download v2.3)\n\nWith v2.3, new support has been added for CUDA 5.0.  This newer version of CUDA enables computation on the latest Kepler K20 GPUs of the NVIDIA Tesla product line.\n\nThis morning we received an email from a Jacket user who said, \"V2.3 + CUDA 5 = wow. Just upgraded and re-ran one of the routines that previously took just under 4 minutes - now less than 2 minutes!\"\n\nThis is a must-have release for all Jacket users.  The performance improvements are generally felt across the board.  Existing Jacket codes can be accelerated further merely by downloading and upgrading to this new v2.3 release.  No additional code modifications are required.  Full release notes are <a href=\"http://wiki.accelereyes.com/wiki/index.php/Release_Notes\">here</a>.\n\nAlong with this new Jacket v2.3 release, AccelerEyes offers a variety of technical computing <a href=\"http://accelereyes.com/support\">resources</a>, including monthly GPU computing <a href=\"http://accelereyes.com/webinars\">webinars</a>.  We invite you to learn more about GPU computing by attending one of these webinars.\n\nFurther, AccelerEyes will be exhibiting at the upcoming SC\'12 conference in Salt Lake City.  Come visit us in Booth #2415.\n\nWe look forward to hearing your feedback about this new Jacket v2.3 release!\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2012/08/13/jacket-for-option-pricing/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/118929502_80_80.jpg\" alt=\"\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2012/08/13/jacket-for-option-pricing/\" target=\"_blank\">Jacket for Option Pricing</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2012/09/26/genomics-matlab-applications-on-the-gpu/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/noimg_34_80_80.jpg\" alt=\"\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2012/09/26/genomics-matlab-applications-on-the-gpu/\" target=\"_blank\">Genomics MATLAB applications on the GPU</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2012/08/23/webinar-optics-matlab-applications-with-jacket/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/noimg_38_80_80.jpg\" alt=\"\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2012/08/23/webinar-optics-matlab-applications-with-jacket/\" target=\"_blank\">Webinar - Optics MATLAB Applications with Jacket</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2012/09/27/fast-computatio%e2%80%8bn-of-isotropic-gradient/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/118929493_80_80.jpg\" alt=\"\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2012/09/27/fast-computatio%e2%80%8bn-of-isotropic-gradient/\" target=\"_blank\">Fast Computatio n of Isotropic Gradients with Jacket\'s Convolutions</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.prweb.com/releases/2009/11/prweb3218324.htm\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/noimg_103_80_80.jpg\" alt=\"\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.prweb.com/releases/2009/11/prweb3218324.htm\" target=\"_blank\">Penguin Computing Adds GPU Computing Capabilities to On Demand Service</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://socialbarrel.com/nvidia-releases-cuda-5-from-worlds-most-pervasive-parallel-computing-platform/45152/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/119005429_80_80.jpg\" alt=\"\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://socialbarrel.com/nvidia-releases-cuda-5-from-worlds-most-pervasive-parallel-computing-platform/45152/\" target=\"_blank\">NVIDIA Releases CUDA 5 From World\'s Most Pervasive Parallel Computing Platform</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" src=\"http://img.zemanta.com/pixy.gif?x-id=6b944de8-db75-44c2-92da-0bede78e6e00\" alt=\"\" /></div>','Jacket v2.3 Now Available','','publish','open','open','','jacket-v2-3','','','2012-10-23 14:15:49','2012-10-23 18:15:49','',0,'http://blog.accelereyes.com/blog/?p=3253',0,'post','',1),(3297,1,'2012-12-04 17:51:51','2012-12-04 21:51:51','With the recent news release from NASA about the <a href=\"http://www.nasa.gov/home/hqnews/2012/dec/HQ_12-415_Curiosity_Soil_Samples.html\" target=\"_blank\">Mars Curiosity rover</a>, and as a continuation of our previous post <a href=\"http://blog.accelereyes.com/blog/2012/08/06/powering-mars-research/\" target=\"_blank\">\"Powering Mars Research\"</a>, Brendan Babb is here again to provide us with an exciting look into Jacket\'s role in Mars research from the Curiosity rover . Brendan Babb and colleague Frank Moore, at the University of Alaska in Anchorage, work with NASA’s Jet Propulsion Lab to improve image quality and image compression of the Mars Rover images. Here is what Brendan had to tell us about the use of Jacket in his GPU computing challenges...\n\nBrendan Babb:  I was thrilled to watch the new Mars Rover Curiosity successful landing with my visiting nieces and nephews. The new rover will take pictures, dig for samples, analyze samples onboard, and send the valuable science back to earth. And hopefully our research will allow that science to be sent back more quickly. Our code is in MATLAB and uses Genetic Algorithms to evolve better image compression. The problem is that each experiment takes 27.5 hours to run on the CPU. Luckily, the code is embarrassingly parallel making it a perfect fit for GPU computing. <a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/12/MER13.bmp\"><img class=\"alignright  wp-image-3304\" title=\"MER13\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/12/MER13.bmp\" alt=\"\" width=\"246\" height=\"246\" /></a>I didn\'t have the time available to optimize low-level CUDA, so instead I plugged in <a href=\"http://www.accelereyes.com/products/jacket\" target=\"_blank\">Jacket </a>by AccelerEyes. <strong>Jacket resulted in dropping the simulation time from 27.5 hours to 5.5 hours.</strong> Jacket is easy-to-use and efficiently runs existing MATLAB functions on the GPU. Very little GPU-specific coding is required, often consisting of a single character addition, i.e. single to gsingle. While it is technically tempting to write CUDA myself, I know this could involve at least 2 months of manual code optimization which could be ultimately slower than the latest version of Jacket. Instead I rely on the expertise of others to accelerate my code’s discrete wavelet transform calculations while I focus on the higher-level algorithms. Thanks to NVIDIA GPUs and Jacket I was able to easily accelerate my MATLAB code by 3-4X with minimal effort. For instance, I just recently upgraded from a Fermi-based NVIDIA GTX 560 TI to a new Kepler-based GTX 680 with Jacket v2.2. This upgrade led to <strong>speedups of 6-7X without any code changes.</strong> <a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/12/MER24.bmp\"><img class=\"wp-image-3302 alignleft\" title=\"MER24\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/12/MER24.bmp\" alt=\"\" width=\"246\" height=\"246\" /></a>The rovers use lossless and lossy data compression based on the ICER standard, developed by Aaron Kiely and Matt Klimesh at JPL, to send data down to earth. When lossy data is sent the reconstructed image has some incorrect pixels, measured as the Mean Squared Error (MSE) between the original and reconstructed image. Our research works on recreating images with less MSE than the current method. JPEG2000 and ICER use wavelets to compress images. We use <a href=\"http://en.wikipedia.org/wiki/Genetic_algorithm\" target=\"_blank\">Genetic Algorithms</a> to evolve wavelet coefficients that result in lower MSE on the reconstructed image or smaller files with the same MSE. <img class=\"wp-image-3301 alignright\" title=\"MER30\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2012/12/MER30.bmp\" alt=\"\" width=\"247\" height=\"247\" />\n<div>I strongly recommend MATLAB users to grab a free 15-day trial of Jacket and an inexpensive NVIDIA GPU card. You may find that a few characters changes of your code will yield 2X or more speedup. I also encourage anyone optimizing in a larger parameter space to use Genetic Algorithms, Jacket, and NVIDIA GPUs to quickly evolve better solutions.Soon I will be testing the speedup on Fish, a new Cray XK6m supercomputer at University of Alaska, Fairbanks, that has 48 NVIDIA Tesla GPUs. Improved image compression and quality will allow us to see even more detailed pictures of Mars and hopefully help discover signs of previous life on Mars.</div>\n&nbsp;\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/129885769_80_80.jpg\" alt=\"\" />Mars rover Curiosity: No surprise in 1st soil test</li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.space.com/18741-mars-rover-curiosity-discovery.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/129736498_80_80.jpg\" alt=\"\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.space.com/18741-mars-rover-curiosity-discovery.html\" target=\"_blank\">Curiosity Rover Finds Organic Signal on Mars, But Not Definitive: NASA</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2012/08/06/jacket-powers-mars-research/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" src=\"http://i.zemanta.com/118929503_80_80.jpg\" alt=\"\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2012/08/06/jacket-powers-mars-research/\" target=\"_blank\">Jacket Powers Mars Research</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" src=\"http://img.zemanta.com/pixy.gif?x-id=c309b79f-2ea9-46e5-8506-efa30529047c\" alt=\"\" /></div>','CUDA GPUs Boost Mars Research','','publish','open','open','','cuda-boosts-mars-research','','','2012-12-04 17:51:51','2012-12-04 21:51:51','',0,'http://blog.accelereyes.com/blog/?p=3297',0,'post','',0),(3323,4,'2012-12-12 05:10:44','2012-12-12 09:10:44','We are pleased to announce today that MathWorks and AccelerEyes have started working together to provide the best overall solution for GPU computing in MATLAB® through the <a href=\"http://www.mathworks.com/gpu\">Parallel Computing Toolbox<sup>™</sup></a> and <a href=\"http://www.mathworks.com/gpu\">MATLAB Distributed Computing Server<sup>™</sup></a> from MathWorks. This new relationship will result in great product updates for end users of the Parallel Computing Toolbox<sup>™</sup> and MATLAB Distributed Computing Server<sup>™</sup>.\n\nSince 2007, AccelerEyes has been a leader in developing GPU software, including Jacket.  AccelerEyes has sold Jacket as a 3rd-party add-on to the MathWorks MATLAB® product.  Effective today, AccelerEyes will discontinue new Jacket product sales.   All existing Jacket license holders will continue to receive support and maintenance from AccelerEyes for 1 year. All existing Jacket licenses are perpetual and will not expire.  Future GPU computing updates will be available in MathWorks’ products, providing a path to ease the transition for Jacket customers.\n\nAccelerEyes will continue to build great GPU and accelerator software libraries.  With this transition, we will be able to focus even more energy into the free and premium versions of the <a href=\"http://accelereyes.com/arrayfire\">ArrayFire library</a> for C, C++, and Fortran, as well as continue to provide <a href=\"http://accelereyes.com/consulting\">developer services</a> for code acceleration.  We have an ambitious roadmap of features planned for ArrayFire in 2013 and look forward to rolling those out to the <a href=\"http://forums.accelereyes.com/\">AccelerEyes developer community</a>.\n\nWe believe this is an exciting announcement for everyone, and we look forward to delivering even more productivity and speed to GPU developers through this change of focus and collaboration.\n\nFor questions, please contact us at <a href=\"mailto:sales@accelereyes.com\">sales@accelereyes.com</a>.\n\n&nbsp;\n\n&nbsp;\n\nMATLAB, Parallel Computing Toolbox, and MATLAB Distributed Computing Server are a registered trademark and trademarks of The MathWorks, Inc.','Exciting Updates from AccelerEyes','','publish','open','open','','exciting-updates-from-accelereyes','','','2012-12-12 05:10:44','2012-12-12 09:10:44','',0,'http://blog.accelereyes.com/blog/?p=3323',0,'post','',4),(3371,1,'2013-01-07 18:53:11','2013-01-07 22:53:11','In case you missed it, we recently held a webinar on the ArrayFire GPU Computing Library. This webinar was part of an ongoing <a href=\"http://blog.accelereyes.com/blog/category/webinar/\">series of webinars</a> that will help you learn more about the many applications of ArrayFire, while interacting with AccelerEyes GPU computing experts.\n\nArrayFire is the world\'s most comprehensive GPU software library. In this webinar, James Malcolm, who has built many of ArrayFire\'s core components, walked us through the basic principles and syntax for ArrayFire. He also provided an overview of existing efforts in GPU software, and compared them to the extensive capabilities of ArrayFire.\n\nFor example, the same application that takes <strong>26 lines</strong> to write in Thrust, can be coded up <a href=\"https://www.youtube.com/watch?feature=player_detailpage&amp;v=cNMRJkG-4lc#t=512s\"><em>in just <strong>3 lines</strong> in ArrayFire</em></a>!\n\nArrayFire has supported CUDA-based NVIDIA GPUs for a long time now. AccelerEyes has recently made huge strides in expanding support for OpenCL-based acceleration devices. ArrayFire now has support for recently-introduced chips like the Xeon Phi. Go ahead and download the <a href=\"http://www.accelereyes.com/download_arrayfire\">ArrayFire v2.0 Pre-release for OpenCL</a> today!\n\nHere is the webinar video:\n\n<center><iframe src=\"http://www.youtube.com/embed/cNMRJkG-4lc\" height=\"315\" width=\"560\" allowfullscreen=\"\" frameborder=\"0\"></iframe></center>\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2012/11/29/arrayfire-library-speeds-code-on-intel-xeon-phi/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_70_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2012/11/29/arrayfire-library-speeds-code-on-intel-xeon-phi/\" target=\"_blank\">ArrayFire Library Speeds Code on Intel Xeon Phi</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2012/12/04/cuda-boosts-mars-research/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/131049344_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2012/12/04/cuda-boosts-mars-research/\" target=\"_blank\">CUDA GPUs Boost Mars Research</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.drdobbs.com/parallel/cuda-vs-phi-phi-programming-for-cuda-dev/240144545\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/132836775_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.drdobbs.com/parallel/cuda-vs-phi-phi-programming-for-cuda-dev/240144545\" target=\"_blank\">CUDA vs. Phi: Phi Programming for CUDA Developers</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://semiaccurate.com/2012/11/13/what-will-intel-xeon-phi-do-to-the-gpgpu-market/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_117_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://semiaccurate.com/2012/11/13/what-will-intel-xeon-phi-do-to-the-gpgpu-market/\" target=\"_blank\">What will Intel Xeon Phi do to the GPGPU market?</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://digixav.com/2013/01/07/nvidia-at-ces-2013-tegra-4-project-shield/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/136357440_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://digixav.com/2013/01/07/nvidia-at-ces-2013-tegra-4-project-shield/\" target=\"_blank\">Nvidia at CES 2013 - Tegra 4, Project Shield.</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://entelechyasia.com/2012/11/13/gpu-accelerators-support-enable-faster-simulations/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_72_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://entelechyasia.com/2012/11/13/gpu-accelerators-support-enable-faster-simulations/\" target=\"_blank\">GPU Accelerators support enable faster simulations</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=ca5471e6-a840-437f-bc07-263ff217564b\" /></div>','Getting Started with ArrayFire - a 30-minute Jump Start','','publish','open','open','','getting-started-with-arrayfire-a-30-minute-jump-start','','','2013-01-07 18:53:11','2013-01-07 22:53:11','',0,'http://blog.accelereyes.com/blog/?p=3371',0,'post','',1),(3379,4,'2013-01-17 16:43:16','2013-01-17 20:43:16','As an engineers company, we spend a lot of time wrestling in the weeds of low-level GPU and accelerator codes. This is our battleground, and it can often be dizzying in its complexity. Our whole purpose is to hide that mess and tame those low-level beasts so that ArrayFire users get better performance than anyone else.\n\nThe joy of ArrayFire comes when we get feedback from ArrayFire users, often from different parts of the world. For instance, the week I share excerpts from two recent emails we received in France:\n\n1) From <a href=\"http://www.fr-barep.com/cms\">Barep</a>, a French manufacturing company:  \"I think ArrayFire is a \'must have\' library. It\'s very easy to use and can be used under Linux and Windows. Personally, I\'m happy to have adopted it.\"\n\n2) From <a href=\"http://www.inria.fr/en/\">INRIA</a>, a French university:  \"Your public relations are truly remarkable indeed. This is certainly an investment in customer loyalty. I am touched and I really appreciate this opportunity to work with ArrayFire. It is always nice to work with a company at this level of professionalism. \"\n\nAccelerEyes has value-added resellers around the world. In France, we invite you to meet with <a href=\"http://www.sciworkstech.com/\">Sciworks Technologies</a> to learn more about ArrayFire.\n\nIf you have feedback about ArrayFire, please <a href=\"https://www.accelereyes.com/company/contact_us\">send us a note</a> too or let us know on the <a href=\"http://forums.accelereyes.com\">community forums</a>.\n\nCheers!\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2012/11/29/arrayfire-library-speeds-code-on-intel-xeon-phi/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_70_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2012/11/29/arrayfire-library-speeds-code-on-intel-xeon-phi/\" target=\"_blank\">ArrayFire Library Speeds Code on Intel Xeon Phi</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/01/07/getting-started-with-arrayfire-a-30-minute-jump-start/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/136488742_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/01/07/getting-started-with-arrayfire-a-30-minute-jump-start/\" target=\"_blank\">Getting Started with ArrayFire - a 30-minute Jump Start</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.phoronix.com/vr.php?view=MTI3NjI\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_113_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.phoronix.com/vr.php?view=MTI3NjI\" target=\"_blank\">NVIDIA 313.18 Driver Update Packs A Ton Of Changes</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://openclnews.com/blog/amd_strengthens_opencl_ecosystem_with_new_tools_for_hpc_that_take_advantage\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_9_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://openclnews.com/blog/amd_strengthens_opencl_ecosystem_with_new_tools_for_hpc_that_take_advantage\" target=\"_blank\">AMD strengthens OpenCL ecosystem with new tools for HPC that take advantage of GPU</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://hothardware.com/News/AMDs-New-S10000-GPU-Opterons-Power-Top-EnergyEfficient-Supercomputers-/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/125755380_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://hothardware.com/News/AMDs-New-S10000-GPU-Opterons-Power-Top-EnergyEfficient-Supercomputers-/\" target=\"_blank\">AMD\'s New S10000 GPU, Opterons Power Top Energy-Efficient Supercomputers</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/01/17/intel-xeon-phi-introduction-a-disruptive-move-for-hpc/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/138783279_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/01/17/intel-xeon-phi-introduction-a-disruptive-move-for-hpc/\" target=\"_blank\">Intel Xeon Phi Introduction a Disruptive Move for HPC</a></li>\n</ul>\n&nbsp;\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=52815225-29a4-46a4-8a4a-11d87094573e\" /></div>','ArrayFire Reception in France','','publish','open','open','','arrayfire-reception-in-france','','','2013-01-17 16:43:16','2013-01-17 20:43:16','',0,'http://blog.accelereyes.com/blog/?p=3379',0,'post','',0),(3397,1,'2013-02-07 15:33:33','2013-02-07 19:33:33','In order to get the best performance from your CUDA or OpenCL code, it is helpful to keep in mind some useful tips for optimizing performance.\n\n<em>Note: By \"accelerator\" we refer to GPUs, APUs, co-processors, FPGAs, and any devices capable of running CUDA or OpenCL.</em>\n<ul>\n	<li><b>Vectorized Code</b>: Accelerators perform best with <a href=\"http://en.wikipedia.org/wiki/Vectorization_(parallel_computing)\">vectorized code</a> because the computations map naturally onto arithmetic cores of the hardware. ArrayFire functions are inherently vectorized, so if you are using ArrayFire, you are writing vectorized code.</li>\n</ul>\n<ul>\n	<li><b>Memory Transfers</b>: Avoid excessive memory transfers. Each casting operation to and from the accelerator moves data back and forth between CPU memory and accelerator memory. ArrayFire makes many automatic optimizations to minimize these memory transfers by only transferring data when absolutely needed.</li>\n</ul>\n<ul>\n	<li><b>Serial vs Parallel Operations</b>: CPUs are serial computing devices and accelerators are parallel computing devices. For small or serial operations, the best performance is likely achieved on the CPU. For large or parallel operations, the best performance is likely achieved on the accelerator. Often, a good rule of thumb is to use the CPU if your data is only a few hundred elements and to use the accelerator for processing on &gt;10,000 elements. With ArrayFire, you can control the segments of code that are run on each device through <a href=\"http://www.accelereyes.com/arrayfire/c/page_quickref.htm#quickref_types\">creation of array data types</a>.</li>\n</ul>\n<ul>\n	<li><b>Loops</b>: Loops typically imply serial processing. However, with CUDA or OpenCL it is possible to run all the iterations simultaneously, if there are no data dependencies between iterations. ArrayFire makes this very easy with its <a title=\"GFOR\" href=\"http://www.accelereyes.com/arrayfire/c/page_gfor.htm\">GFOR</a> function.</li>\n</ul>\n<ul>\n	<li><b>Lazy Execution</b>: With CUDA and OpenCL, it is important to construct kernels that contain the right amount of computation, not so much that timeouts occur and not so little that throughput drops. ArrayFire employs a lazy execution design which automatically constructs optimally-sized kernels from your algorithms. Lazy execution also means that ArrayFire does not launch GPU kernels until the results are requested, either in a display or subsequent CPU-based computation. If you wish to force a ArrayFire computation, the ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/namespaceaf.htm#a6d1dbf55ce9dbd67b460eac3a0661d58\">sync and eval functions</a> are available.</li>\n</ul>\n<ul>\n	<li><b>Write Good Timing Code</b>: Badly written timing code can often cause artificially decreased accelerator performance. ArrayFire comes with a convenient <a href=\"http://www.accelereyes.com/arrayfire/c/page_timing.htm\">timing function</a> to ensure proper benchmarks.</li>\n</ul>\n<ul>\n	<li><b>Regular Access Patterns</b>: When performing subscripting, keep in mind that the accelerator memory controllers are not as versatile as those on the CPU. Best performance is achieved when your subscript access patterns are regular and uniform. For example, <tt>A([1 4 2 3 5 1 2 ...])</tt> would be slow while <tt>A([1 2 3 4 5 6 ...])</tt> would be faster. With ArrayFire, subscripting is very easy. ArrayFire is column-major, so it is faster to access columns (<tt>A(span,i)</tt>) rather than rows (<tt>A(i,span)</tt>).</li>\n</ul>\nWhat else? What are good general tips for writing CUDA &amp; OpenCL code?\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/01/21/how-much-speedup-can-you-get-with-cuda-or-opencl/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/139661938_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/01/21/how-much-speedup-can-you-get-with-cuda-or-opencl/\" target=\"_blank\">How much speedup can you get with CUDA or OpenCL?</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/01/29/mark-harris-on-using-shared-memory-in-cuda-cc/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/141565895_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/01/29/mark-harris-on-using-shared-memory-in-cuda-cc/\" target=\"_blank\">Mark Harris on Using Shared Memory in CUDA C/C++</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-02-06/nvidia_announces_new_report_outlining_12x_cuda_performance_gains_over_cpu-only_libraries.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/143351767_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-02-06/nvidia_announces_new_report_outlining_12x_cuda_performance_gains_over_cpu-only_libraries.html\" target=\"_blank\">NVIDIA Report: 12x CUDA Performance Gains Over CPU-Only</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://openclnews.com/blog/amd_strengthens_opencl_ecosystem_with_new_tools_for_hpc_that_take_advantage\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_9_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://openclnews.com/blog/amd_strengthens_opencl_ecosystem_with_new_tools_for_hpc_that_take_advantage\" target=\"_blank\">AMD strengthens OpenCL ecosystem with new tools for HPC that take advantage of GPU</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://perilsofparallel.blogspot.com/2011/09/conversation-with-intels-james-reinders.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/138442047_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://perilsofparallel.blogspot.com/2011/09/conversation-with-intels-james-reinders.html\" target=\"_blank\">A Conversation with Intel\'s James Reinders at IDF 2011</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://devgurus.amd.com/thread/160330\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_97_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://devgurus.amd.com/thread/160330\" target=\"_blank\">A question/appeal to AMD engineers regarding local memory.</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=13d60b87-0726-4202-9f19-dc4c28f900a3\" /></div>','7 Tips for CUDA & OpenCL Programming and How ArrayFire Helps','','publish','open','open','','7-tips-for-cuda-opencl-programming-and-how-arrayfire-helps','','','2013-02-07 15:33:33','2013-02-07 19:33:33','',0,'http://blog.accelereyes.com/blog/?p=3397',0,'post','',0),(3398,6,'2013-01-21 12:32:40','2013-01-21 16:32:40','Everyday developers ask us to predict how much speedup they can get with <a class=\"zem_slink\" title=\"CUDA\" href=\"http://en.wikipedia.org/wiki/CUDA\" target=\"_blank\" rel=\"wikipedia\">CUDA</a> or <a class=\"zem_slink\" title=\"OpenCL\" href=\"http://en.wikipedia.org/wiki/OpenCL\" target=\"_blank\" rel=\"wikipedia\">OpenCL</a>. Rather than gaze mysteriously into a crystal ball, we ask the developers questions to explore pertinent acceleration factors.\n\nNote, we\'ll use the term <em>accelerator</em> to include GPUs, Xeon Phi coprocessor, APUs, FPGAs, and any other CUDA or OpenCL device. The principles we discuss below are equally applicable to all of these accelerators.\n\nThe following are some of the important factors that must be considered when estimating the potential for accelerated speedups:\n<ul>\n	<li><b>Hardware: </b> The more advanced the accelerator hardware, the more the speedup you get (e.g. the NVIDIA Kepler K20 outperforms the previous NVIDIA Fermi C2090 generation).</li>\n</ul>\n<ul>\n	<li><b>Data Sizes:  </b>In general, accelerators will outperform CPUs to a larger degree as data sizes increase. Accelerators are only fast because they can exploit data parallelism. If there is not much data (e.g. only a few hundred elements in a vector), then there is not going to be much gain in performance. However, if there is a lot of data (e.g. more than 10,000 elements or a 100x100 matrix) then accelerators will be able to process those elements in parallel and exploit the data-parallelism. For an example of how speedups increase with data size, see the <a href=\"http://www.accelereyes.com/products/benchmarks_arrayfire\">ArrayFire benchmarks</a>.</li>\n</ul>\n<ul>\n	<li><b>Application:  </b>Speedup figures vary from application to application. Some operations may be computed faster than others on an accelerator. In general, the more parallelizable, the better the accelerator performance. And the fewer trips memory takes across the bus, the better. For examples of real application speedups, see the <a href=\"http://www.accelereyes.com/examples/case_studies\">ArrayFire case studies</a>.</li>\n</ul>\n<ul>\n	<li><b>CPU:  </b>In running speedup comparisons between the CPU and the GPU, the CPU speed matters. The CPU still plays an important role in heterogeneous computing throughput. For example, better CPUs help ArrayFire go faster, because ArrayFire does a lot of things (e.g. JIT compilation) on the CPU to keep the accelerator fully utilized.</li>\n</ul>\n<ul>\n	<li><b>Code Quality:  </b>Better-written CPU code always leads to better CPU + accelerator code.</li>\n</ul>\n<ul>\n	<li><strong>Choice of Software Tools:</strong>  Software tools can affect your potential for speedups. For instance, libraries outperform compilers in <a href=\"http://blog.accelereyes.com/blog/2012/04/11/no-free-lunch-for-gpu-compiler-directives/\">providing productive performance</a> for accelerators.</li>\n</ul>\nWhat factors do you consider when predicting speedups?\n\n&nbsp;\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://withimagination.imgtec.com/index.php/powervr/mythbusters-imaginations-gpu-compute-special-edition-part-1\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/139596145_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://withimagination.imgtec.com/index.php/powervr/mythbusters-imaginations-gpu-compute-special-edition-part-1\" target=\"_blank\">Mythbusters - Imagination\'s GPU Compute special edition (part 1)</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://streamcomputing.eu/blog/2012-10-23/targetting-various-architectures-in-opencl-and-cuda/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/138441772_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://streamcomputing.eu/blog/2012-10-23/targetting-various-architectures-in-opencl-and-cuda/\" target=\"_blank\">Targetting various architectures in OpenCL and CUDA</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2012/11/25/gpu-accelerated-science-applications/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_12_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2012/11/25/gpu-accelerated-science-applications/\" target=\"_blank\">GPU-accelerated Science Applications</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2012/08/13/option-pricing/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/131049345_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2012/08/13/option-pricing/\" target=\"_blank\">Option Pricing</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://openclnews.com/blog/amd_strengthens_opencl_ecosystem_with_new_tools_for_hpc_that_take_advantage\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_9_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://openclnews.com/blog/amd_strengthens_opencl_ecosystem_with_new_tools_for_hpc_that_take_advantage\" target=\"_blank\">AMD strengthens OpenCL ecosystem with new tools for HPC that take advantage of GPU</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2012/12/14/gpu-testing-program-showing-kepler-speedups-of-2x-or-more-on-real-apps/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_0_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2012/12/14/gpu-testing-program-showing-kepler-speedups-of-2x-or-more-on-real-apps/\" target=\"_blank\">GPU Testing Program Showing Kepler Speedups of 2X or More on Real Apps</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=a382331e-bd95-4708-b119-c69d1af27ae8\" /></div>','How much speedup can you get with CUDA or OpenCL?','','publish','open','open','','how-much-speedup-can-you-get-with-cuda-or-opencl','','','2013-01-21 12:32:40','2013-01-21 16:32:40','',0,'http://blog.accelereyes.com/blog/?p=3398',0,'post','',0),(3424,4,'2013-01-24 18:26:59','2013-01-24 22:26:59','We\'re pleased to announce upcoming <a href=\"http://accelereyes.com/training\">CUDA and OpenCL training courses</a>.\n\nOver the past couple of years, we\'ve received numerous requests from around the world to be trained by AccelerEyes engineers. We finally got our act together and now have a nice schedule of CUDA and OpenCL training courses for 2013 within the United States:\n<table width=\"100%\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"50%\">\n<h3>CUDA</h3>\n<ul>\n	<li><a href=\"http://www.eventbrite.com/event/5307097672\">Feb 25-26</a>, Houston, TX</li>\n	<li><a href=\"http://www.eventbrite.com/event/5313859898\">Mar 4-5</a>, Baltimore/Washington D.C.</li>\n	<li><a href=\"http://www.eventbrite.com/event/5313928102\">Mar 25-26</a>, Los Angeles, CA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5313966216\">Apr 9-10</a>, Seattle, WA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314006336\">Apr 15-16</a>, San Francisco, CA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314044450\">May 6-7</a>, Austin, TX</li>\n	<li><a href=\"http://www.eventbrite.com/event/5329669184\">May 27-28</a>, Atlanta, GA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314096606\">Jun 10-11</a>, Baltimore/Washington D.C.</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314116666\">Jul 8-9</a>, San Jose, CA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314144750\">Sep 2-3</a>, Boston, MA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314162804\">Sep 23-24</a>, Baltimore/Washington, D.C.</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314186876\">Oct 7-8</a>, Houston, TX</li>\n	<li><a href=\"http://www.eventbrite.com/event/5329769484\">Oct 21-22</a>, Atlanta, GA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314206936\">Nov 4-5</a>, Baltimore/Washington, D.C.</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314224990\">Dec 2-3</a>, New York, NY</li>\n</ul>\n</td>\n<td valign=\"top\" width=\"50%\">\n<h3>OpenCL</h3>\n<ul>\n	<li><a href=\"http://www.eventbrite.com/event/5313757592\">Feb 27-28</a>, Houston, TX</li>\n	<li><a href=\"http://www.eventbrite.com/event/5313906036\">Mar 6-7</a>, Baltimore/Washington D.C.</li>\n	<li><a href=\"http://www.eventbrite.com/event/5313944150\">Mar 27-28</a>, Los Angeles, CA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5313986276\">Apr 11-12</a>, Seattle, WA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314038432\">Apr 17-18</a>, San Francisco, CA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314052474\">May 8-9</a>, Austin, TX</li>\n	<li><a href=\"http://www.eventbrite.com/event/5329713316\">May 29-30</a>, Atlanta, GA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314106636\">Jun 12-13</a>, Baltimore/Washington D.C.</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314130708\">Jul 10-11</a>, San Jose, CA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314150768\">Sep 4-5</a>, Boston, MA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314178852\">Sep 25-26</a>, Baltimore/Washington, D.C.</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314190888\">Oct 9-10</a>, Houston, TX</li>\n	<li><a href=\"http://www.eventbrite.com/event/5329803586\">Oct 23-24</a>, Atlanta, GA</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314218972\">Nov 6-7</a>, Baltimore/Washington, D.C.</li>\n	<li><a href=\"http://www.eventbrite.com/event/5314231008\">Dec 4-5</a>, New York, NY</li>\n</ul>\n</td>\n</tr>\n</tbody>\n</table>\nHere are reasons to sign up for a training course:\n<ul>\n	<li><span style=\"line-height: 13px;\">It\'s the quickest way to become proficient at CUDA or OpenCL</span></li>\n	<li>Our instructors are excellent; they build <a href=\"http://accelereyes.com/arrayfire\">ArrayFire</a> everyday. They are also interesting and tell jokes to keep you awake!</li>\n	<li>The fee includes:\n<ul>\n	<li>Use of a laptop with CUDA and OpenCL capable GPUs and CPUs</li>\n	<li>Choice of Linux or Windows operating system</li>\n	<li>Printed manual of lecture material</li>\n	<li>Electronic copy of programming exercises</li>\n	<li>Certificate of Completion</li>\n</ul>\n</li>\n	<li>Discounts on ArrayFire Pro licenses (ask your instructor about this perk)</li>\n</ul>\nWe look forward to seeing you at an upcoming training event.\n\nIf you live outside the United States and want to receive a CUDA or OpenCL training course, <a href=\"https://www.accelereyes.com/company/contact_us\">let us know</a>!\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=3028cbed-2b76-44ca-9343-c8df48de36be\" /></div>','Upcoming CUDA & OpenCL Training Courses','','publish','open','open','','upcoming-cuda-opencl-training-courses','','','2013-01-24 18:26:59','2013-01-24 22:26:59','',0,'http://blog.accelereyes.com/blog/?p=3424',0,'post','',0);
INSERT INTO `wp_posts` VALUES (3458,17728,'2013-02-21 14:46:37','2013-02-21 14:46:37','In this blog post, we are going to compare NVIDIA\'s latest high end offering, the <a title=\"Tesla KSeries Overview\" href=\"http://www.nvidia.com/content/PDF/kepler/Tesla-KSeries-Overview-LR.pdf\">Tesla K series</a> (PDF) with their previous offering. In particular we are comparing the Tesla K20C with Tesla C2070/2075.\n\nThis blog post follows a similar post about <a title=\"Benchmarking the GTX 680\" href=\"http://blog.accelereyes.com/blog/2012/04/26/benchmarking-kepler-gtx-680/\">benchmarking the GTX680</a> we did last year. We take a look at similar set of functions (and a little bit more) to see what benefits the newer line brings.\n\nAll of the benchmarks were done using <strong>double precision</strong>. In all of the graphs, higher trendlines are better.\n\n<strong>Matrix Multiplication</strong>\n\n<img class=\"size-full wp-image-3461   aligncenter\" title=\"Matrix_Multiply\" alt=\"\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/02/matmul.png\" width=\"609\" height=\"365\" />\n\nIn house at AccelerEyes, we use matrix multiplication as the gold standard for testing the maximum performance of all new GPUs we end up with. The K20c reaches a peak at about <strong>1 TFLOPs for <strong>Double Precision</strong>.</strong> This is about 85% of maximum theoretical performance of 1.2 TFLOPS ^.  The c2070 reaches about 310 GFLOPS, a mere 60% of maximum theoretical performance of 515 GFLOPS. In effect, <strong>the K20 is 3 times faster than the C2070</strong>.\n\n<strong>Linear Algebra</strong>\n\n<img class=\"size-full wp-image-3460 aligncenter\" alt=\"linalg\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/02/linalg.png\" width=\"605\" height=\"340\" />\n\nContinuing to other linear algebra functions from matrix multiply, we see that the K20 still beats the C2070 by about 2.5x. You may also notice that LU decomposition is slower on the K20 at smaller sizes. We are unsure about the actual reasons, but let us present all the info we have. The GPUs were on different machines using different motherboards with possibly different PCIe speeds.  This is relevant because small chunks of data is transferred to the host for faster computation. At smaller sizes, the data transfers and the computation on the CPU become the bottleneck. Hence it may be unfair to compare the GPUs across various systems at these sizes.\n\n<strong>Fast Fourier Transform</strong>\n\n&nbsp;\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/02/fft21.png\"><img class=\"size-full wp-image-3463 aligncenter\" alt=\"fft2\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/02/fft21.png\" width=\"605\" height=\"340\" /></a>\n\nIn this particular case, the K20c is about <strong>1.6x faster</strong> than the c2070. The absolute numbers are not relevant here because the formula used to calculate GFLOPs for FFTs (5 * N * log(N)) is only approximate, and the constant factor may be higher or lower than 5 depending on the algorithm utilized.\n\n<strong>Sort</strong>\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/02/sort2.png\"><img class=\"size-full wp-image-3465 aligncenter\" alt=\"sort\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/02/sort2.png\" width=\"605\" height=\"340\" /></a>\n\n&nbsp;\n\nAlthough the K20 starts off a little bit slower, the performance keeps increasing at a steeper incline than that of the C2070. The older Tesla seems to be approaching its limit at 165 million keys per second, where as the K20 is still going strong at the end of the test coming in at about 500 million keys per second. This is about <strong>3x faster </strong>than the C2070.\n\nAll the above benchmarks have been done using arrayfire 1.9 which uses cuda 5.0.\n\n^Ref:  <a href=\"http://www.nvidia.com/object/tesla-servers.html\">http://www.nvidia.com/object/tesla-servers.html</a>\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://marchamilton.wordpress.com/2013/02/12/nvida-kepler-gpu-momentum/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/144876549_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://marchamilton.wordpress.com/2013/02/12/nvida-kepler-gpu-momentum/\" target=\"_blank\">Nvida Kepler GPU Momentum</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/02/16/nvidia-adds-new-cuda-education-centers-beefs-up-program-rewards/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/145898865_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/02/16/nvidia-adds-new-cuda-education-centers-beefs-up-program-rewards/\" target=\"_blank\">Nvidia Adds New Cuda Education Centers, Beefs up Program Rewards</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://kotaku.com/5985262/whats-most-impressive-about-nvidias-new-1000-graphics-card-how-it-sounds\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/146477186_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://kotaku.com/5985262/whats-most-impressive-about-nvidias-new-1000-graphics-card-how-it-sounds\" target=\"_blank\">What\'s Most Impressive About Nvidia\'s New $1,000 Graphics Card? How It Sounds.</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-01-31/nvidia_super_sets_energy-efficiency_record.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/142009547_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-01-31/nvidia_super_sets_energy-efficiency_record.html\" target=\"_blank\">NVIDIA Super Sets Energy-Efficiency Record</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-02-05/gpu_wars.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/143200694_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-02-05/gpu_wars.html\" target=\"_blank\">GPU Wars</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=da0522c3-5691-48a0-b749-6c3993bf7ac3\" /></div>','Benchmarking Tesla K20','','publish','open','open','','benchmarking-tesla-k20','','','2014-06-17 21:10:29','2014-06-17 21:10:29','',0,'http://blog.accelereyes.com/blog/?p=3458',0,'post','',1),(3471,1,'2013-03-04 12:05:07','2013-03-04 16:05:07','This is the first in a series of posts looking at our current ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\" target=\"_blank\">examples</a>. The code can be compiled and run from <code>arrayfire/examples/</code> when you <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> and install the ArrayFire library. Today we will discuss the examples found in the <code>getting_started/</code> directory.\n\n<a title=\"Hello World\" href=\"http://www.accelereyes.com/arrayfire/c/examples_2helloworld_2helloworld_8cpp-example.htm\" target=\"_blank\"><strong>Hello World</strong></a>\n\nOf course we start with the <em>classic</em> \"Hello World\" example, which walks you through the basics of using the ArrayFire library. Running this example will print out system and device information, as well as perform some basic matrix operations. This is a good place to get familiar with the basic data container for ArrayFire - the <a href=\"http://www.accelereyes.com/arrayfire/c/classaf_1_1array.htm\" target=\"_blank\">array</a>.\n<pre class=\"lang:default highlight:0 decode:true\">ArrayFire v1.9 (build XXXXXXX) by AccelerEyes (64-bit Linux)\nLicense: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nCUDA toolkit 5.0, driver 304.54\nGPU0 Quadro 6000, 6144 MB, Compute 2.0 (single,double)\nDisplay Device: GPU0 Quadro 6000\nMemory Usage: 5549 MB free (6144 MB total)...</pre>\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2getting_started_2convolve_8cpp-example.htm\" target=\"_blank\"><strong>Convolve</strong></a>\n\nIn this example we show you how to perform a basic image convolution, as well as how to use our timing functions. The output of running this code is simply the time it took to perform each convolution. Here we do it three different ways:\n<pre class=\"lang:default decode:true\">// Wrapper functions for timeit()\nstatic void full() { full_out = convolve(img, kernel); }\nstatic void dsep() { dsep_out = convolve(dx, spread, img); }\nstatic void hsep() { hsep_out = convolve(5, h_dx, 5, h_spread, img); }</pre>\nThe first method simply convolves signal (img) with the filter (kernel). The second method allows you to just supply the two dimensions of the filter independently, and the third method allows you to use native data pointers (what we call a host) instead of the device data type.\n<pre class=\"lang:default highlight:0 decode:true\">Convolving a 640 by 480 matrix\nfull 2D convolution: 0.000258857 seconds\nseparable, device pointers: 9.71524e-05 seconds\nseparable, host pointers: 0.000117301 seconds</pre>\nAnd, trying it on a bigger matrix...\n<pre class=\"lang:default highlight:0 decode:true\">Convolving a 6400 by 4800 matrix\nfull 2D convolution: 0.0242132 seconds\nseparable, device pointers: 0.008284 seconds\nseparable, host pointers: 0.0083929 seconds</pre>\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2getting_started_2fft_8cpp-example.htm\" target=\"_blank\"><strong>FFT</strong></a>\n\nWe have a method for performing the Fast Fourier Transform on an ArrayFire array. In this example we show you how to compute and print the result, as well as extract data from device memory. The following code snippet shows you the extraction:\n<pre class=\"lang:default decode:true\">cuComplex *B = A.host();\nfloat real = cuCrealf(*B), imag = cuCimagf(*B);\nprintf(\"B[0] = %g %c %gin\", real, ((imag &lt; 0) ? \'-\' : \'+\'), imag);</pre>\nGenerally, moving data back and forth between the CPU and devices is relatively slow, and eliminating as much of these transfers as possible will give you the best results. This example also shows you the other way to time a function using ArrayFire. Here are some of the results that I get when running the FFT on my machine \"<code>Quadro 6000, 6144 MB, Compute 2.0 (single,double)</code>\":\n<pre class=\"lang:default highlight:0 decode:true\">FFT on a 30x30 matrix: 0.000431 seconds\nFFT on a 9000x9000 matrix: 0.001324 seconds</pre>\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2getting_started_2gfor_8cpp-example.htm\" target=\"_blank\"><strong>GFOR</strong></a>\n\nThis is a great example because you get to see the power of a special ArrayFire feature, the <em>gfor</em>-loop, which optimizes certain cases of for-loop programming. The basic idea of gfor is that you can launch all iterations of a loop in parallel on the GPU. There are a lot of things that can be done with the gfor loop, see the <a href=\"http://www.accelereyes.com/arrayfire/c/page_gfor.htm\">documentation</a> for more details. In this example we see how much faster gfor is than a regular for (even if we are using ArrayFire arrays in the regular for-loop), and we see a few different ways of using a gfor loop. On my machine \"<code>Quadro 6000, 6144 MB, Compute 2.0 (single,double)</code>\" I got the following speed-up on the matrix multiply portion of the example:\n<pre class=\"lang:default highlight:0 decode:true\">Timing matrix multiply...\n for-loop 0.000210663 seconds\n gfor-loop 6.75187e-05 seconds\n speedup 3.1x</pre>\nOne of the main advantages of using ArrayFire is speed. The library was built to take advantage of your system\'s resources.\n\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2getting_started_2integer_8cpp-example.htm\"><strong>Integer</strong></a>\n\nThis example shows off a bunch of the arithmetic that can be done on the elements of a matrix. One of the key things to learn here is that ArrayFire supports a number of basic data types for the elements of the array container. A description of these types can be found <a href=\"http://www.accelereyes.com/arrayfire/c/page_quickref.htm#quickref_types\">here</a>. Many of these operations that shift or pick elements (like <a href=\"http://www.accelereyes.com/arrayfire/c/group__sort__mat.htm#gabafd9194924cfe3ebe4544fdf4f2863e\">sort</a>, or <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm#gac42e13090c7899711891a4f60a288352\">min</a>) can also return an index array containing references to the original positions of the chosen elements. This example shows another great advantage of using ArrayFire - simplicity. Many of the snippets here perform operations in a way that is easy to understand, without a lot of the typical hassle in worrying about the details of data, memory, not to mention GPU interfacing.\n\nHere is a list of functions found in this example: <a href=\"http://www.accelereyes.com/arrayfire/c/group__indexing.htm#ga2829074e96053cb6dfab7ffa1e542c54\">col</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__indexing.htm#ga80c8b0a6536d955a66d0bcc59488e5d8\">row</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__indexing.htm#ga97ba48bddbe5a6f01e8e242cf57583d5\">span</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm#ga0f0e7e912039bef82e3acae70a627a28\">array</a> bit-wise ops (&amp;, |, ^) and logical-ops (&amp;&amp;, ||), <a href=\"http://www.accelereyes.com/arrayfire/c/group__sort__mat.htm#gabafd9194924cfe3ebe4544fdf4f2863e\">sort</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__manip.htm#gaeadf9256b56215a58dc12f14d97312eb\">transpose</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__manip.htm#ga920af856ce0c993a929850149a289d60\">flip</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/namespaceaf.htm#a808f0e19bbc711642067f9507c392da9\">sum</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/namespaceaf.htm#a15c9b1a86d98410e8bf9d2f0ff074cc5\">multiply</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm#gac42e13090c7899711891a4f60a288352\">min</a>, and <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm#ga5a2147389744f4840291f1f059ce2369\">max</a>\n\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2getting_started_2lin_algebra_8cpp-example.htm\"><strong>Linear Algebra</strong></a>\n\nThe example walks you through three of the functions in the linear algebra package - <a href=\"http://www.accelereyes.com/arrayfire/c/group__factor__mat.htm#ga5a97859d6dcdae94c39160d6d6ea9fa0\">LU decomposition</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__linsolve__mat.htm#gab942dfee90538a7f168f514e5dfc443e\">solving</a> the equation AX = B, and <a href=\"http://www.accelereyes.com/arrayfire/c/group__factor__mat.htm#gaf97c09bd475b8e0b415de3e73e8a5589\">Eigen value decomposition</a>. The setup and function calls are simple:\n<pre class=\"lang:default decode:true\">out = lu(in);\narray X = solve(A, B);\nprint(eigen(in));</pre>\nJust as a note, the last function \"eigen\" is part of the <a href=\"http://www.accelereyes.com/products/arrayfire_licensing\">Pro License package</a>, so you won\'t be able to run the example without the license. Here is what the output looks like on my machine \"<code>Quadro 6000, 6144 MB, Compute 2.0 (single,double)</code>\":\n<pre class=\"lang:default highlight:0 decode:true\">-- ArrayFire Eigen value decomposition\n\neigen(in) =\n   1.8201\n   -0.5023\n   0.1251\n\nin =\n   0.3022  0.7513  0.9504\n   0.8077  0.1578  0.4499\n   0.4071  0.5678  0.9829\n\nval =\n   1.8201  0.0000  0.0000\n   0.0000  -0.5023  0.0000\n   0.0000  0.0000  0.1251\n\nvec =\n   -0.6237  -0.5741  -0.3185\n   -0.4717  0.8049  -0.7139\n   -0.6232  -0.1503  0.6237</pre>\n<span style=\"text-decoration: underline;\"><strong>Rainfall</strong></span>\n\nTo wrap it all up, there is an sample problem of measuring data across many sites. The ArrayFire library makes it simple to aggregate, and analyze this data. Of course, here we just use a small number of data points, but you can see how easy it would be to run this kind of powerful analysis on a large data set.\n\n<a href=\"http://www.accelereyes.com/download_arrayfire\">Download</a> the ArrayFire library and give it a try!\n\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\">ArrayFire Examples (Part 1 of 8) – Getting Started</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/06/arrayfire-examples-part-2-of-8-benchmarks/\">ArrayFire Examples (Part 2 of 8) – Benchmarks</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/25/arrayfire-examples-part-3-of-8-financial/\">ArrayFire Examples (Part 3 of 8) – Financial</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/16/arrayfire-examples-part-4-of-8-image-processing\">ArrayFire Examples (Part 4 of 8) - Image Processing</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/05/arrayfire-examples-part-5-of-8-machine-learning/\">ArrayFire Examples (Part 5 of 8) - Machine Learning</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/12/arrayfire-examples-part-6-of-8-multiple-gpus/\">ArrayFire Examples (Part 6 of 8) - Multiple GPU</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/07/03/arrayfire-examples-part-7-of-8-pde/\">ArrayFire Examples (Part 7 of 8) - PDE</a></li>\n</ol>\n&nbsp;','ArrayFire Examples (Part 1 of 8) - Getting Started ','','publish','open','open','','arrayfire-examples-part-1-of-8-getting-started','','','2013-03-04 12:05:07','2013-03-04 16:05:07','',0,'http://blog.accelereyes.com/blog/?p=3471',0,'post','',0),(3507,1,'2013-03-06 18:48:42','2013-03-06 22:48:42','This is the second in a series of posts looking at our current ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\" target=\"_blank\">examples</a>. The code can be compiled and run from <code>arrayfire/examples/</code> when you <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> and install the ArrayFire library. Today we will discuss the examples found in the <code>benchmarks/</code> directory.\n\nIn these examples, my machine has the following configuration:\n<pre class=\"lang:default highlight:0 decode:true\">ArrayFire v1.9 (build XXXXXXX) by AccelerEyes (64-bit Linux)\nLicense: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nCUDA toolkit 5.0, driver 304.54\nGPU0 Quadro 6000, 6144 MB, Compute 2.0 (single,double)\nDisplay Device: GPU0 Quadro 6000\nMemory Usage: 5549 MB free (6144 MB total)...</pre>\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2benchmarks_2blas_8cpp-example.htm\"><strong>Blas</strong></a>\n\nThis example shows a simple bench-marking process using ArrayFire\'s matrix multiply routine. For more information on <em>Blas</em>, click <a href=\"http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms\">here</a>. The data measured in this example is the Giga-Flop (GFLOP <em>Floating Point Operations Per Second</em>). I got the following results using the example code on my machine:\n<pre class=\"lang:default highlight:0 decode:true\">GPU0 Quadro 6000, 6144 MB, Compute 2.0 (single,double)\nDisplay Device: GPU0 Quadro 6000\nMemory Usage: 5543 MB free (6144 MB total)\n128 x 128: 124 Gflops\n256 x 256: 283 Gflops\n384 x 384: 478 Gflops\n512 x 512: 483 Gflops\n640 x 640: 583 Gflops\n768 x 768: 628 Gflops\n896 x 896: 646 Gflops\n1024 x 1024: 647 Gflops\n1152 x 1152: 648 Gflops\n1280 x 1280: 658 Gflops\n1408 x 1408: 659 Gflops\n1536 x 1536: 668 Gflops\n1664 x 1664: 673 Gflops\n1792 x 1792: 674 Gflops\n1920 x 1920: 677 Gflops\n2048 x 2048: 676 Gflops</pre>\nJust for fun, I wrote a small program to perform a simple matrix multiply using the CPU in a triple-for loop (a pretty standard, but non-optimized solution). This basic algorithm has a run-time of O(n^3). Here is what I got measuring the same benchmark using my simple algorithm:\n<pre class=\"lang:default highlight:0 decode:true\">128 x 128: 1 Mflops\n256 x 256: 1 Mflops\n...</pre>\nAs you can see, I got bored fast waiting for my CPU to do what my GPU did in a matter of seconds! I would have ended up spending a long time waiting for this program to finish running on the CPU. Also notice that I measured the CPU computation in terms of Mega-Flops instead of Giga-Flops. Of course, a real linear algebra library would do much better than my simple routine, but using ArrayFire takes the next step beyond smart algorithms, by taking full advantage of the GPU and parallelism.\n\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2benchmarks_2pi_8cpp-example.htm\"><strong>Pi</strong></a>\n\nPi is a fun little example we use to make comparisons between regular programming, and GPU programming. We use a <a href=\"http://en.wikipedia.org/wiki/Monte_Carlo_method\">Monte-Carlo</a> simulation to estimate Pi - the idea is to take a bunch of random points in the Cartesian plane unit-square, and then count the ratio of points that lie within the unit circle to the points in the square. The process of generating millions of random points, then using the Pythagorean theorem to calculate the hypotenuse is fairly simple math, and can be done in a for loop that counts the number of times the resulting hypotenuse has a length of less than 1 (and therefore lies in the unit circle) and compares it to the total number of points generated:\n<pre class=\"lang:default decode:true\">    int count = 0;\n    for (int i = 0; i &lt; samples; ++i) {\n        float x = float(rand()) / RAND_MAX;\n        float y = float(rand()) / RAND_MAX;\n        if (sqrt(x*x + y*y) &lt; 1)\n            count++;\n    }\n    return (4.0 * count / samples);</pre>\nThe ArrayFire version is of course, much simpler:\n<pre class=\"lang:default decode:true\">    array x = randu(samples,f32);\n    array y = randu(samples,f32);\n    return (4.0 * sum&lt;float&gt;(sqrt(x*x + y*y) &lt; 1) / samples);</pre>\nThe speed difference is huge, here are some of the results I get on my machine:\n<pre class=\"lang:default highlight:0 decode:true\">gpu: 0.00635 seconds to estimate pi = 3.1417060\ncpu: 1.89067 seconds to estimate pi = 3.1418986\nspeedup: 297.7433\n\ngpu: 0.00639 seconds to estimate pi = 3.1421003\ncpu: 1.84324 seconds to estimate pi = 3.1417162\nspeedup: 288.457\n\ngpu: 0.00635 seconds to estimate pi = 3.1417060\ncpu: 1.83939 seconds to estimate pi = 3.1420715\nspeedup: 289.6677</pre>\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2benchmarks_2pi_cuda_8cu-example.htm\"><strong>Pi Cuda</strong></a>\n\nThe reason this code example exists is to show you the synthesis between CUDA programming and the ArrayFire library. Of course, we just saw how ArrayFire could calculate Pi just fine all by itself, but in some cases, you will have more complex CUDA routines and need more control. You can still facilitate pieces of your program with the ArrayFire constructs.\n\nFor example, although we are using CUDA vectors instead of ArrayFire arrays, we can still take advantage of the ArrayFire library to <a href=\"http://www.accelereyes.com/arrayfire/c/group__random__ptr.htm#ga30f0770ad54d1439191ce6057c49cc43\">populate</a> these vectors with random numbers:\n<pre class=\"lang:default mark:5-6 decode:true\">float *d_x = NULL, *d_y = NULL;\nunsigned bytes = sizeof(float) * n;\nCUDA(cudaMalloc(&amp;d_x, bytes));\nCUDA(cudaMalloc(&amp;d_y, bytes));\nAF(af_randu_S(d_x, n));\nAF(af_randu_S(d_y, n));</pre>\n... and take the <a href=\"http://www.accelereyes.com/arrayfire/c/group__summul__ptr.htm#gaefb2415d321af39e1bbbd8eeb4cd6e3c\">sum of the elements</a> of a vector:\n<pre class=\"lang:default mark:2 decode:true\">    float h_result;\n    AF(af_sum_vector_S(&amp;h_result, n, d_inside));</pre>\nOne last insight that we can gain from this example is just how much simpler ArrayFire makes GPU programming. Compare this example, to the regular Pi example above, and you can see that ArrayFire abstracts away a lot of initialization/boilerplate coding. There are a lot of lines of code required to set-up devices, allocate memory, manage memory, and handle errors that you don\'t have to worry about when you are using the ArrayFire library.\n\nSo go for it, <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> the ArrayFire library and see how fast your computer can go!\n\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\">ArrayFire Examples (Part 1 of 8) – Getting Started</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/06/arrayfire-examples-part-2-of-8-benchmarks/\">ArrayFire Examples (Part 2 of 8) – Benchmarks</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/25/arrayfire-examples-part-3-of-8-financial/\">ArrayFire Examples (Part 3 of 8) – Financial</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/16/arrayfire-examples-part-4-of-8-image-processing\">ArrayFire Examples (Part 4 of 8) - Image Processing</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/05/arrayfire-examples-part-5-of-8-machine-learning/\">ArrayFire Examples (Part 5 of 8) - Machine Learning</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/12/arrayfire-examples-part-6-of-8-multiple-gpus/\">ArrayFire Examples (Part 6 of 8) - Multiple GPU</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/07/03/arrayfire-examples-part-7-of-8-pde/\">ArrayFire Examples (Part 7 of 8) - PDE</a></li>\n</ol>\n&nbsp;\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/149709769_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\" target=\"_blank\">ArrayFire Examples (Part 1 of 8) - Getting Started</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.tomshardware.com/news/Kepler-Quadro-geforce-gpu-nvidia,21352.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/149939798_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.tomshardware.com/news/Kepler-Quadro-geforce-gpu-nvidia,21352.html\" target=\"_blank\">Kepler in the Workstation: Nvidia Rolls Out New Quadros</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://hemprasad.wordpress.com/2013/03/04/getting-started-with-cuda/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/149542002_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://hemprasad.wordpress.com/2013/03/04/getting-started-with-cuda/\" target=\"_blank\">Getting Started with CUDA</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://openclnews.com/blog/amd_strengthens_opencl_ecosystem_with_new_tools_for_hpc_that_take_advantage\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_9_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://openclnews.com/blog/amd_strengthens_opencl_ecosystem_with_new_tools_for_hpc_that_take_advantage\" target=\"_blank\">AMD strengthens OpenCL ecosystem with new tools for HPC that take advantage of GPU</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://streamcomputing.eu/blog/2013-01-06/x86-workstation-buying-guide-for-opencl-developers-q1-2013/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/138441733_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://streamcomputing.eu/blog/2013-01-06/x86-workstation-buying-guide-for-opencl-developers-q1-2013/\" target=\"_blank\">X86-workstation buying guide for OpenCL developers, Q1 2013</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=5a61e66e-7eda-4e65-9677-5f1dfe15c63c\" /></div>','ArrayFire Examples (Part 2 of 8) - Benchmarks','','publish','open','open','','arrayfire-examples-part-2-of-8-benchmarks','','','2013-03-06 18:48:42','2013-03-06 22:48:42','',0,'http://blog.accelereyes.com/blog/?p=3507',0,'post','',0),(3510,1,'2013-03-25 12:00:54','2013-03-25 16:00:54','This is the third in a series of posts looking at our current ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\" target=\"_blank\">examples</a>. The code can be compiled and run from <code>arrayfire/examples/</code> when you <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> and install the ArrayFire library. Today we will discuss the examples found in the <code>financial/</code> directory.\n\nIn these examples, my machine has the following configuration:\n<pre class=\"lang:default highlight:0 decode:true\">ArrayFire v1.9 (build XXXXXXX) by AccelerEyes (64-bit Linux)\nLicense: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nCUDA toolkit 5.0, driver 304.54\nGPU0 Quadro 6000, 6144 MB, Compute 2.0 (single,double)\nDisplay Device: GPU0 Quadro 6000\nMemory Usage: 5549 MB free (6144 MB total)...</pre>\n<strong><a href=\"http://www.accelereyes.com/arrayfire/c/examples_2financial_2blackscholes_8cpp-example.htm\">Black-Scholes</a></strong>\n\nThere are a number of applications of ArrayFire and GPU programming in the world of finance and markets. Here we have an example of <a href=\"http://en.wikipedia.org/wiki/Black%E2%80%93Scholes\">Black-Scholes</a>, which is a model for computing options prices in the stock market. Understanding how this model works isn\'t necessary to understand this example. In fact, ArrayFire improves the relationship between the scientist/mathematician/analyst who needs to use a particular model, and the programmer who has to write it. Rather than having a whole bunch of nasty GPU code getting in the way and obscuring the algorithm, ArrayFire allows the algorithm to take precedence in your code, and express itself naturally. Take a look at the following snippet of algorithm code:\n<pre class=\"lang:default decode:true\">    // S = Underlying stock price\n    // X = Strike Price\n    // R = Risk free rate of interest\n    // V = Volatility\n    // T = Time to maturity\n\n    array d1 = log(S / X);\n    d1 = d1 + (R + (V*V)*0.5) * T;\n    d1 = d1 / (V*sqrt(T));\n\n    array d2 = d1 - (V*sqrt(T));\n    C = S * cnd(d1) - (X * exp((-R)*T) * cnd(d2));\n    P = X * exp((-R)*T) * cnd(-d2) - (S * cnd(-d1));</pre>\nIn this snippet, it is really easy to see what the mathematics are doing. We don\'t even have to deal with for-loops because of the way ArrayFire naturally works with the array data type.\n\nUsing ArrayFire can simplify many mathematical algorithms and bring the speed of the GPU to the analyst without forcing him or her to waste valuable time with the details of GPU kernel coding.  So go ahead, see which algorithms <em>you</em> can run on the GPU by <a href=\"http://www.accelereyes.com/download_arrayfire\">downloading</a> the ArrayFire library today!\n\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\">ArrayFire Examples (Part 1 of 8) – Getting Started</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/06/arrayfire-examples-part-2-of-8-benchmarks/\">ArrayFire Examples (Part 2 of 8) – Benchmarks</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/25/arrayfire-examples-part-3-of-8-financial/\">ArrayFire Examples (Part 3 of 8) – Financial</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/16/arrayfire-examples-part-4-of-8-image-processing\">ArrayFire Examples (Part 4 of 8) - Image Processing</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/05/arrayfire-examples-part-5-of-8-machine-learning/\">ArrayFire Examples (Part 5 of 8) - Machine Learning</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/12/arrayfire-examples-part-6-of-8-multiple-gpus/\">ArrayFire Examples (Part 6 of 8) - Multiple GPU</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/07/03/arrayfire-examples-part-7-of-8-pde/\">ArrayFire Examples (Part 7 of 8) - PDE</a></li>\n</ol>\n<strong> </strong>','ArrayFire Examples (Part 3 of 8) - Financial','','publish','open','open','','arrayfire-examples-part-3-of-8-financial','','','2013-03-25 12:00:54','2013-03-25 16:00:54','',0,'http://blog.accelereyes.com/blog/?p=3510',0,'post','',0),(3511,1,'2013-04-16 16:35:12','2013-04-16 20:35:12','This is the fourth in a series of posts looking at our current ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\" target=\"_blank\">examples</a>. The code can be compiled and run from <code>arrayfire/examples/</code> when you <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> and install the ArrayFire library. Today we will discuss the examples found in the <code>image_processing/</code> directory.\n\nIn these examples, my machine has the following configuration:\n<pre class=\"lang:default highlight:0 decode:true\">ArrayFire v1.9 (build XXXXXXX) by AccelerEyes (64-bit Windows)\nLicense: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nCUDA toolkit 5.0, driver 306.94\nGPU0 GeForce GT 650M, 2048 MB, Compute 3.0 (single,double)\nDisplay Device: GPU0 GeForce GT 650M\nMemory Usage: 1981 MB free (2048 MB total)...</pre>\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2image_processing_2image_demo_8cpp-example.htm\"><strong>Image Demo</strong></a>\n\nThe purpose of this example is to show how to do some common image manipulations. The method <code>channel_split</code> shows how easily multi-dimensional arrays can be subdivided:\n<pre class=\"lang:default decode:true\">// Split a MxNx3 image into 3 separate channel matrices.\nstatic void channel_split(array&amp; rgb, array&amp; outr, array&amp; outg, array&amp; outb) {\n    outr = rgb(span, span, 0);\n    outg = rgb(span, span, 1);\n    outb = rgb(span, span, 2);\n}</pre>\nThe <a href=\"http://www.accelereyes.com/arrayfire/c/group__colorconv__mat.htm#gaf0073a3ad8cbb75c7f13f707b51c6a81\">colorspace</a> function is useful for moving images between representation spaces. Images can easily be loaded as color images, or converted to grayscale images. Note that when loading images, scaler division is performed to normalize the values between 0 and 1:\n<pre class=\"lang:default decode:true\">array img_rgb  = loadimage(\"logo.jpg\", true) / 255.f; // 3 channel RGB       [0-1]</pre>\nOther useful functions in this example include computing the <a href=\"http://www.accelereyes.com/arrayfire/c/group__hist__mat.htm#ga8e823d2440808b58870c0d9846700616\">histogram</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__hist__mat.htm#gab6860c2f3992d9616896c2220fe54574\">equalization</a>, and calculating thresholds:\n<pre class=\"lang:default decode:true\">    // connected component labeling\n    array B = img_gray &lt; 190; // binary [0 1]</pre>\nThis is just a small sample of what our library can do, check out all of our image processing functions <a href=\"http://www.accelereyes.com/arrayfire/c/group__image__mat.htm\">here</a>.\n\nRunning the example produces the following output:\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/image.png\"><img class=\"alignnone  wp-image-3857\" alt=\"image\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/image-1024x576.png\" width=\"717\" height=\"403\" /></a>\n\n<a href=\"http://www.accelereyes.com/arrayfire/c/examples_2image_processing_2optical_flow_8cpp-example.htm\"><strong>Optical Flow</strong></a>\n\nOptical Flow is the apparent motion of an object due to the difference in motion between the object and its observer. <a href=\"http://en.wikipedia.org/wiki/Horn%E2%80%93Schunck_method\">Horn-Schunck</a> is a mathematical method for calculating optical flow using integration techniques. As usual for these examples, it isn\'t so much about understanding the math, as it is seeing the results of ArrayFire applied to the math. What this example does essentially is convolve images repeatedly for a period of time. Being able to convolve these images on the GPU greatly increases the speed with which we can simulate the integration. Writing the code is simple with ArrayFire, we simply encode the mathematics in a way that is simple to follow:\n<pre class=\"lang:default decode:true\">        array u_ = convolve(u, mean_kernel);\n        array v_ = convolve(v, mean_kernel);\n\n        const float alphasq = 0.1f;\n        array num = Ix * u_ + Iy * v_ + It;\n        array den = alphasq + Ix * Ix + Iy * Iy;\n\n        array tmp = 0.01 * num;\n        u = u_ - (Ix * tmp) / den;\n        v = v_ - (Iy * tmp) / den;</pre>\nThis example is best run on your own computer so you can see the results in action, here is what the final output looks like:\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/image1.png\"><img class=\"alignnone  wp-image-3861\" alt=\"image\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/image1-1024x576.png\" width=\"717\" height=\"403\" /></a>\n\nBeing able to repeat image calculations for a period of time is a technique for solving a number of important image processing problems. The GPU is perfect for these kinds of algorithms, because each operation can be performed to an entire image at once (like a convolution). This allows us to get results that are much more real time.\n\nWhat other image processing applications can you see for GPU processing and ArrayFire? <a href=\"http://www.accelereyes.com/download_arrayfire\">Download</a> the ArrayFire library and find out today!\n\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\">ArrayFire Examples (Part 1 of 8) – Getting Started</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/06/arrayfire-examples-part-2-of-8-benchmarks/\">ArrayFire Examples (Part 2 of 8) – Benchmarks</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/25/arrayfire-examples-part-3-of-8-financial/\">ArrayFire Examples (Part 3 of 8) – Financial</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/16/arrayfire-examples-part-4-of-8-image-processing\">ArrayFire Examples (Part 4 of 8) - Image Processing</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/05/arrayfire-examples-part-5-of-8-machine-learning/\">ArrayFire Examples (Part 5 of 8) - Machine Learning</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/12/arrayfire-examples-part-6-of-8-multiple-gpus/\">ArrayFire Examples (Part 6 of 8) - Multiple GPU</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/07/03/arrayfire-examples-part-7-of-8-pde/\">ArrayFire Examples (Part 7 of 8) - PDE</a></li>\n</ol>','ArrayFire Examples (Part 4 of 8) - Image Processing','','publish','open','open','','arrayfire-examples-part-4-of-8-image-processing','','','2013-04-16 16:35:12','2013-04-16 20:35:12','',0,'http://blog.accelereyes.com/blog/?p=3511',0,'post','',0),(3512,1,'2013-06-05 15:00:05','2013-06-05 19:00:05','This is the fifth in a series of posts looking at our current ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\" target=\"_blank\">examples</a>. The code can be compiled and run from <code>arrayfire/examples/</code> when you <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> and install the ArrayFire library. Today we will discuss the examples found in the <code>machine_learning/</code> directory.\n\nIn these examples, my machine has the following configuration:\n<pre>ArrayFire v1.9 (build XXXXXXX) by AccelerEyes (64-bit Mac OSX)\nLicense: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nCUDA toolkit 5.0, driver 304.54\nGPU0 GeForce GT 560M, 1024 MB, Compute 3.0 (single,double)\nDisplay Device: GPU0 GeForce GT 650M\nMemory Usage: 245 MB free (1024 MB total)...</pre>\n&nbsp;\n\n<strong> 1. K-Means Clustering - <a title=\"kmeans.cpp\" href=\"http://www.accelereyes.com/arrayfire/c/examples_2machine_learning_2kmeans_8cpp-example.htm\">kmeans.cpp</a></strong>\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-12.25.57-PM.png\"><img class=\"aligncenter  wp-image-4251\" alt=\"Screen Shot 2013-05-31 at 12.25.57 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-12.25.57-PM-1024x438.png\" width=\"717\" height=\"307\" /></a></p>\n<p style=\"text-align: center;\">Figure 1</p>\nThis is an example of K-Means Clustering Algorithm. K-Means Clustering Algorithm is a data mining technique that partitions the given data into groups by their similarities. All you need to know from this example is that this algorithm will repeatedly run through many loops to stabilize the clusters. Again, ArrayFire has this beautiful tool called <a href=\"http://www.accelereyes.com/arrayfire/c/page_gfor.htm#gfor_intro\">GFOR</a> loop that handles any matrix array arithmetic and transformation in parallel. This increases the speed of both the cluster stabilization and k-means computation in this example.\n<pre class=\"lang:default decode:true\" title=\"gfor loops\"> 35        gfor(array i, num_uniq) {    // current classification\n 36             array diffs = abs(hist_idx(i) - means_vec);\n 37             array val, idx;\n 38             min(val, idx, diffs);\n 39             hist_counts(hist_idx(i)) = idx;\n 40         }  \n ..\n 57     gfor(array i, k) { // pixel differences from computed means\n 58         vol(span, span, i) = abs(data - means_vec(i));\n 59     }</pre>\nJust to verify the speed improvement in computation with ArrayFire again, I made a simple change in the code to find the elapsed times in FOR loop (left below) and GFOR loop (right below) as following.\n<pre class=\"lang:default decode:true\"> FOR Loop                                               GFOR Loop\n 36  clock_t begin = clock();                           47  clock_t begin = clock();  \n 37  for(int i=0; i&lt;num_uniq; i++){                     48  gfor(array i, num_uniq) {    // current classification\n 38    array diffs = abs(hist_idx(i) - means_vec);      49    array diffs = abs(hist_idx(i) - means_vec);\n 39    array val, idx;                                  50    array val, idx;\n 40    min(val, idx, diffs);                            51    min(val, idx, diffs);\n 41    hist_counts(hist_idx(i)) = idx;                  52    hist_counts(hist_idx(i)) = idx;\n 42  }                                                  53  }   \n 43                                                     54\n 44  clock_t end = clock();                             55  clock_t end = clock();\n 45  double t =  double(end - begin) / CLOCKS_PER_SEC;  56  double t =  double(end - begin) / CLOCKS_PER_SEC;\n 46  printf(\"Elapsed Time: %f secn\", t);               57  printf(\"Elapsed Time: %f secn\", t);</pre>\nIn result, each GFOR loop was approximately 200x faster than each FOR loop as shown below. Since there were a total of twelve loops in this example, ArrayFire has performed almost 2000x faster in time. If there were more loops performed, you can imagine how much time we would save with ArrayFire.\n<pre class=\"lang:r decode:true\">FOR Loop                                    GFOR Loop\nElapsed Time: 0.016808 sec                  Elapsed Time: 0.002231 sec\nElapsed Time: 0.014868 sec                  Elapsed Time: 0.000676 sec\nElapsed Time: 0.053122 sec                  Elapsed Time: 0.000088 sec\nElapsed Time: 0.048089 sec                  Elapsed Time: 0.000074 sec\nElapsed Time: 0.048284 sec                  Elapsed Time: 0.000074 sec\nElapsed Time: 0.033541 sec                  Elapsed Time: 0.000075 sec\nElapsed Time: 0.013796 sec                  Elapsed Time: 0.000068 sec      \nElapsed Time: 0.029183 sec                  Elapsed Time: 0.000068 sec\nElapsed Time: 0.011643 sec                  Elapsed Time: 0.000068 sec\nElapsed Time: 0.011273 sec                  Elapsed Time: 0.000067 sec\nElapsed Time: 0.026709 sec                  Elapsed Time: 0.000068 sec\nElapsed Time: 0.010750 sec                  Elapsed Time: 0.000068 sec</pre>\nThe number of loops in this example was actually arbitrary because stabling the cluster could take longer than expected depending on the situation; thus it was a great example to evaluate the performance of ArrayFire. In the result of my experiment, ArrayFire was again proven to provide big performance benefits within loops.\n\n&nbsp;\n\n<strong>2. Neural Network - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2machine_learning_2neuralnetwork_8cpp-example.htm\">neuralnetwork.cpp</a>\n</strong>\n<p style=\"text-align: center;\"><img class=\"aligncenter  wp-image-4234\" alt=\"Screen Shot 2013-05-31 at 10.58.20 AM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-10.58.20-AM-1024x584.png\" width=\"614\" height=\"350\" /></p>\n<p style=\"text-align: center;\">Figure 2</p>\nThis is an example of Neural Network algorithm. Neural Network algorithm (also known as Artificial Neural Network) is another data mining technique that is inspired by biological neural network system. I won\'t talk about the details of this algorithm, but let\'s first take a look at the three following images.\n<p style=\"text-align: center;\"><img class=\"aligncenter  wp-image-4230\" alt=\"fireice\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-11.30.17-AM-1024x196.png\" width=\"737\" height=\"141\" /></p>\nThese three layers are used as an input for our algorithm. The layers first get joined in a single matrix array by <a href=\"http://www.accelereyes.com/arrayfire/c/group__manip.htm#ga4971f0f3af2fd52c2db2967b721c5547\">JOIN</a> function after flattened into a column vector by <a href=\"http://www.accelereyes.com/arrayfire/c/group__manip.htm#ga6667548d963698db28ff83cea4380154\">FLAT</a> function. The algorithm contains a \"train\" procedure with a given number of iteration time (200 iterations in this example). During this iteration process, the algorithm determines errors for each layer and corrects them to train (or learn) the most optimized weight for each pixel using gradient. As shown Figure 2, the example loads another image to compare with the optimized pixel values after the train procedure has completed. It finally prints out the result of numbers that indicates the difference between the image (in Figure 2) and trained weights.\n<pre class=\"lang:default decode:true\"> 80     array samples = join(0,\n 81                          flat(loadimage(\"images/fire-1.jpg\")).T(),\n 82                          flat(loadimage(\"images/ice-1.jpg\")).T(),\n 83                          flat(loadimage(\"images/fire-2.jpg\")).T());\n 84     samples = join(0,\n 85                    samples,\n 86                    flat(loadimage(\"images/ice-2.jpg\")).T(),\n 87                    flat(loadimage(\"images/fire-3.jpg\")).T(),\n 88                    flat(loadimage(\"images/ice-3.jpg\")).T());\n 89</pre>\nNormally, this algorithm has to be done with the massive number of iteration for each pixel in all three layers. ArrayFire is, again, convenient in this algorithm; instead of having three layers independently, ArrayFire uses <a href=\"http://www.accelereyes.com/arrayfire/c/group__manip.htm#ga4971f0f3af2fd52c2db2967b721c5547\">JOIN</a> function to combine all the layers into one single matrix array. This way, ArrayFire reduces all the matrix iterations and maximizes the efficiency of parallel matrix arithmetics (such as <a href=\"http://www.accelereyes.com/arrayfire/c/group__matmul__mat.htm#ga7491b0767aab0b0f7fe1a67274bdf586\">MATMUL</a>, <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm#gacfc8b9d8b36c97330f23ef72e1bfaa31\">POW</a>, and <a href=\"http://www.accelereyes.com/arrayfire/c/group__manip.htm#gaf7c3f5aad54e191bb3badd69e8ad4014\">TILE</a>). Basically, this example ended up not requiring any matrix iteration by using ArrayFire (but still requires only the iterations for the number of train, which must be done without any trick).\n\n&nbsp;\n\n<strong>3. Principal Component Analysis - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2machine_learning_2pca_8cpp-example.htm\">pca.cpp</a></strong>\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-12.27.40-PM.png\"><img class=\"aligncenter  wp-image-4252\" alt=\"Screen Shot 2013-05-31 at 12.27.40 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-12.27.40-PM-1024x556.png\" width=\"717\" height=\"389\" /></a></p>\n<p style=\"text-align: center;\">Figure 3</p>\n<p style=\"text-align: left;\">This is an example of Principal Component Analysis. Principal Component Analysis is yet another data mining technique for finding unique patterns in high-dimensional data space. This technique is often found in applications for face recognition and image compression. The basic idea is to reduce the high-dimensional data space to a lower dimension in order to have a simpler representation of data set; so, it is easier to handle the data set as well as to plot them in a human readable dimensional space (three-dimension in our example).</p>\n\n<pre class=\"lang:default decode:true\"> 20     // data normalization\n 21     array means = mean(data);\n 22     array stdvs = stdev(data);\n 23     array sdata = (data - tile(means, n, 1)) / tile(stdvs, n, 1);\n 24 \n 25     // decomposition\n 26     array V, D, E;\n 27     eigen(V, D, cov(sdata));\n 28     E = diag(D);\n 29     array val, idx;\n 30     sort(val, idx, -1*E);\n 31     array comps = matmul(sdata, V); // principal components\n ..\n 68         fig(\"sub\",2,1,1); fig(\"title\",\"Input\");\n 69         plot3(data(span,1), data(span,2), data(span,3));\n 70 \n 71         fig(\"sub\",2,1,2); fig(\"title\",\"14D-&gt;3D PCA\");\n 72         plot3(proj(span,1), proj(span,2), proj(span,3));\n 73 \n 74         fig(\"draw\");\n 75     }</pre>\nFor this purpose, this algorithm consists of various matrix transformations such as Covariance (<a href=\"http://www.accelereyes.com/arrayfire/c/group__stats__mat.htm#gafd568a5dba252d6706e76a5bbd390af5\">COV</a>), Standard Deviation (<a href=\"http://www.accelereyes.com/arrayfire/c/group__stats__mat.htm#ga4489167f96d0a302899341ca2af4fa91\">STDEV</a>), Eigenvalues (<a href=\"http://www.accelereyes.com/arrayfire/c/group__factor__mat.htm#gaf97c09bd475b8e0b415de3e73e8a5589\">EIGEN</a>), Means (<a href=\"http://www.accelereyes.com/arrayfire/c/group__stats__mat.htm#ga2173742174ff6ff7c336db645fd59828\">MEAN</a>), Multiplication (<a href=\"http://www.accelereyes.com/arrayfire/c/group__matmul__mat.htm#ga7491b0767aab0b0f7fe1a67274bdf586\">MATMUL</a>), and Sort (<a href=\"http://www.accelereyes.com/arrayfire/c/group__sort__mat.htm#gabafd9194924cfe3ebe4544fdf4f2863e\">SORT</a>). The ArrayFire library already has these functions available for user\'s usage. ArrayFire certainly accelerates the speed of these matrix transformations as we have shown in previous examples. Finally, this example uses <a href=\"http://www.accelereyes.com/arrayfire/c/group__gfx__mat.htm#ga3ead87d1cd240d67389eb843ecda3784\">PLOT3</a> function to plot the final data set in three-dimensional space for visualization as shown in Figure 3.\n\n&nbsp;\n\n<strong>4. Genetic Algorithm - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2machine_learning_2geneticalgorithm_8cpp-example.htm\">geneticalgorithm.cpp</a></strong>\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-12.28.59-PM.png\"><img class=\"aligncenter  wp-image-4254\" alt=\"Screen Shot 2013-05-31 at 12.28.59 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-12.28.59-PM-1024x574.png\" width=\"717\" height=\"402\" /></a></p>\n<p style=\"text-align: center;\">Figure 4</p>\n<p style=\"text-align: left;\">This is an example of Genetic Algorithm. Genetic Algorithm is the last data mining technique in this post. This algorithm is inspired by the concept of neurological development as in learning through repetition over time. Therefore, a good model to describe this algorithm is the brain, which habitually tries and learns to achieve the optimal answer. The algorithm is a powerful tool for many applications, but the steps are simple enough.</p>\n\n<pre class=\"lang:default decode:true\"> 33 array selectFittest() {\n 34     //pick top 50% fittest\n 35     array sorted = sort(samplez);\n 36     array indices = where(samplez &gt;= sorted.row(nsamples / 2));\n 37 \n 38     if (indices.elements() &gt; nsamples / 2) {\n 39         indices = indices.rows(indices.elements() - nsamples / 2, indices.elements() - 1);\n 40     }\n 41 \n 42     return indices;\n 43 }</pre>\nFirst, the algorithm selects only the top 50% fittest data elements (potential candidates close to the answer) from the initial data set. This may require to create a new data structure with unknown size and to check each element under the given condition in order to collect only the wanted data. Normally, the performance can be really slow, because it has to resize the data structure and check with the condition. To accomplish this procedure more efficient and faster, ArrayFire has <a href=\"http://www.accelereyes.com/arrayfire/c/group__sp__help.htm#ga767a83c029df2889ed4dc43afecf4f1e\">WHERE</a> function that collects the elements that satisfy the specific requirements, of course, in a parallel manner, and forms a new matrix array with the collected elements.\n<pre class=\"lang:default decode:true\"> 52     //Divide selection in two\n 53     array parentsx1 = parentsx.rows(0, parentsx.elements() / 2 - 1);\n 54     array parentsx2 = parentsx.rows(parentsx.elements() / 2, parentsx.elements() - 1);\n 55     array parentsy1 = parentsy.rows(0, parentsy.elements() / 2 - 1);\n 56     array parentsy2 = parentsy.rows(parentsy.elements() / 2, parentsy.elements() - 1);    \n .. \n 63     //Create children as the cross between two parents\n 64     array children_x1 = (parentsx1 &amp; uppermask) + (parentsx2 &amp; lowermask);\n 65     array children_y1 = (parentsy1 &amp; uppermask) + (parentsy2 &amp; lowermask);\n 66     \n 67     array children_x2 = (parentsx2 &amp; uppermask) + (parentsx1 &amp; lowermask);\n 68     array children_y2 = (parentsy2 &amp; uppermask) + (parentsy1 &amp; lowermask);</pre>\nAfter the new data set has been created with the fittest elements, secondly, the algorithm divides the elements in two parent groups and uses the crossover points to create children (You don\'t need to know how to calculate the crossover points in this example; all you need to know is that the algorithm uses the crossover points to generate children for the next generation). For this procedure, the algorithm uses many element-wise arithmetic operations. Without ArrayFire library, this must take a long annoying waiting time to finish these same computations repeatedly. But, since the same equations will be applied on every element, we can simply use <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm\">Element-wise arithmetics</a>, already built in ArrayFire library, to apply the maths on all the elements in a parallel manner.\n<pre class=\"lang:default decode:true\"> 70     //Join two new sets\n 71     samplex = join(0, children_x1, children_x2);\n 72     sampley = join(0, children_y1, children_y2);\n ..\n 83     samplex = join(0, samplex, mutantx);\n 84     sampley = join(0, sampley, mutanty);</pre>\nThirdly, the algorithm performs <a href=\"http://www.accelereyes.com/arrayfire/c/group__manip.htm#ga4971f0f3af2fd52c2db2967b721c5547\">JOIN</a> to combine all the children in one single matrix array indicating itself as the current generation. In the meantime, it generates mutant elements by purposely masking random bits; mutants are formed to possibly arrive closer to the answer by random chance (Again, you don\'t need to know much detail about the Mutant either if you are only here for learning ArrayFire). Lastly, it updates current data set with the new generation data set and plot into three-dimensional space for display. With our ArrayFire library, the algorithm is now capable of executing these heavy procedures very quickly in real time.\n\n&nbsp;\n\nMachine Learning is really a technique that requires lots of digging, collecting, organizing, and optimizing the massive data sets. If you ever felt it slow, <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> the ArrayFire library and accelerate your performance today!\n\n&nbsp;\n\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\">ArrayFire Examples (Part 1 of 8) – Getting Started</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/06/arrayfire-examples-part-2-of-8-benchmarks/\">ArrayFire Examples (Part 2 of 8) – Benchmarks</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/25/arrayfire-examples-part-3-of-8-financial/\">ArrayFire Examples (Part 3 of 8) – Financial</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/16/arrayfire-examples-part-4-of-8-image-processing\">ArrayFire Examples (Part 4 of 8) - Image Processing</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/05/arrayfire-examples-part-5-of-8-machine-learning/\">ArrayFire Examples (Part 5 of 8) - Machine Learning</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/12/arrayfire-examples-part-6-of-8-multiple-gpus/\">ArrayFire Examples (Part 6 of 8) - Multiple GPU</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/07/03/arrayfire-examples-part-7-of-8-pde/\">ArrayFire Examples (Part 7 of 8) - PDE</a></li>\n</ol>\n&nbsp;','ArrayFire Examples (Part 5 of 8) - Machine Learning','','publish','open','open','','arrayfire-examples-part-5-of-8-machine-learning','','','2013-06-05 15:00:05','2013-06-05 19:00:05','',0,'http://blog.accelereyes.com/blog/?p=3512',0,'post','',0),(3513,1,'2013-06-12 00:00:12','2013-06-12 04:00:12','This is the sixth in a series of posts looking at our current ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\" target=\"_blank\">examples</a>. The code can be compiled and run from <code>arrayfire/examples/</code> when you <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> and install the ArrayFire library. Today we will discuss the examples found in the <code>multi_gpu/</code> directory.\n\nIn these examples, my machine has the following configuration:\n<pre class=\"lang:default decode:true\">ArrayFire v1.9.1 (build XXXXXXX) by AccelerEyes (64-bit Linux)\nLicense: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nCUDA toolkit 5.0, driver 319.17\nGPU0 Tesla K20c, 5120 MB, Compute 3.5  (current)\nGPU1 Tesla C2075, 6144 MB, Compute 2.0 \nGPU2 Tesla C1060, 4096 MB, Compute 1.3 \nMemory Usage: 4935 MB free (5120 MB total)</pre>\n*The following order represents the speed of GPUs in my machine from fastest to slowest: K20c, C2070, C1060.\n\nArrayFire is capable of <a href=\"http://www.accelereyes.com/arrayfire/c/group__device__mat.htm\">multi-GPU management</a>. This capability becomes useful for benchmarking a multiple GPUs in dynamic executions.\n\nLet\'s take a look at the following examples.\n\n<strong>1. Fast Fourier Transform - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2getting_started_2fft_8cpp-example.htm#a1\">fft.cpp</a></strong>\n\nThis is an example of calculating the elapsed time for analyzing signal of each column in a matrix with random complex-valued floating point for each device in your machine. Basically, it is attempting to calculate the Fast Fourier Transform performance with collected data with your GPUs. Kindly, ArrayFire already contains the Fast Fourier Transform method - so we don\'t really need to know how FFT works.\n<pre class=\"lang:default decode:true\"> 19     try {\n 20         info();\n 21         int total_device = devicecount();</pre>\nAs you have found a several times in previous examples, \"info()\" was also a function in <a href=\"http://www.accelereyes.com/arrayfire/c/group__device__mat.htm\">multi-GPU management</a> and it prints the current diagnosis on your driver, runtime, memory, and devices. You can find the output result from \"info()\" for my device on the top of this page. Since my machine is equipped with three GPUs, \"devicecount()\" will return 3 for \"total_device\".\n<pre class=\"lang:default decode:true\">  7 static void bench()\n  8 {\n  9     for (int i = 0; i &lt; ndevice; ++i) {\n 10         deviceset(i);              // switch to device\n 11         array x = randu(n,n,c32);  // generate random complex input\n 12         array y = fft(x);          // analyze signal of each column\n 13     }\n 14 }</pre>\nAfter defining the number of devices in your machine, it iterates by that number in order to generate a matrix random complex-valued floating point for each device set and to analyze FFT values for the matrices. \"deviceset(...)\" switches among multiple GPUs to use by its index. Once the device is set, you can find the index of a device currently in use by \"deviceget()\". Our example is benchmarking FFT for three cases with first device, first two devices, and then all three devices.\n<pre class=\"lang:default decode:true\">2048x2048 random number gen and complex FFT on 1 devices...  101.1 gflops\n2048x2048 random number gen and complex FFT on 2 devices...  404.7 gflops\n2048x2048 random number gen and complex FFT on 3 devices...  303.4 gflops</pre>\nIf you\'re paying attention, you\'ll realize that the results above are counter-intuitive. Why does running on more GPUs result in less performance? The answer is due to using a mix of different GPUs in the configuration and requiring each of those GPUs to complete the same amount of work before completion.\n\nThe execution configuration of each iteration is as follows: a C1060 for the first benchmark; a C2070 and a K20 for the second benchmark; and a C1060, a C2070, and a K20 for the third benchmark. Because C1060 is the slowest GPU in my machine, the output was 101.1 glfops which was the slowest as expected. For the second output, because K20 is the fastest GPU in my machine, C2070 and K20 hit the best result with 404.7 gflops. The third benchmark took K20 as well; however, since C1060 became a bottleneck for benchmark in this case. it hit the second best result with 303.4 gflops.\n\nOne last thing to know in this example, is <a href=\"https://www.accelereyes.com/arrayfire/c/namespaceaf.htm#a3a6988c736ce7e76987e3c7a4b46ee6d\">TIMEIT</a> function.\n<pre class=\"lang:default decode:true\">24            double time_s = timeit(bench);</pre>\nArrayFire provides <a href=\"https://www.accelereyes.com/arrayfire/c/page_quickref.htm#quickref_timing\">TIMER</a> functions to determine the elapsed time in many cases, but this timer isn\'t sometimes accurate because GPU takes some time for warm-up in the first run with some initialization and loading libraries. <a href=\"https://www.accelereyes.com/arrayfire/c/namespaceaf.htm#a3a6988c736ce7e76987e3c7a4b46ee6d\">TIMEIT</a> solves this problem by generating a few dummy functions to prepare the GPU before performing the actual input function and returns the robust timing result. So this is really useful method for those who frequently benchmark GPU performances.\n\nThus, ArrayFire assists users with more flexibility in device use and also provides an accurate FFT benchmark result.\n\n<strong>2. General Matrix-Vector Product  - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2multi_gpu_2gemv_8cpp-example.htm\">gemv.cpp</a></strong>\n\n<strong></strong>This is an example of General Matrix-Vector Product, known as one of the fundamental operations in the BLAS (Basic Linear Algebra Subprograms). Following is simply what the General Matrix-Vector Product does:\n\n1. Multi-GPU Matrix-Vector Multiply: y = A*x.\n2. The system matrix A is distributed across the available devices.\n3. Each iteration pushes x to the devices, multiplies against the matrix A,\n4. and pulls the result y back to the host.  (In these steps, device refers to the GPU and host refers to CPU)\n<pre class=\"lang:default decode:true\"> 69         float *A = new float[n*n], *X = new float[n], *Y = new float[n];\n 70         ones(A, n*n);\n 71         ones(X, n*1);\n 72 \n 73         // Distribute A partitions across devices\n 74         array *AMatrix = new array[ngpu];\n 75         for (int idx = 0; idx &lt; ngpu; idx++) {\n 76             deviceset(idx);\n 77             AMatrix[idx] = array(n, n/ngpu, A + (n*n/ngpu * idx), afHost);\n 78         }\n 79         delete[] A; // done with A, keep X to push each iteration</pre>\nInitially, Array A contains ones with size of n x n and it is allocated in host memory (CPU). As it declares and initializes float arrays in line 69-71, the arrays are stored in the host memory with ones. Then, AMatrix - created on the device memory (GPU) - stores the data distributed from the host memory.\n\nIn order to do this, it first sets the desired device for current use by \"deviceset(...)\" and performs <a href=\"http://www.accelereyes.com/arrayfire/c/group__construct.htm#gac55f47510934cb8cbd14361dfa077a02\">ARRAY(dim0, dim1, ptr, af_source)</a> function that creates a matrix array onto the device with the data copied from the corresponding host memory.\n<pre class=\"lang:default decode:true\"> 14         // Multiply each piece of A*x\n 15         for (int idx = 0; idx &lt; ngpu; idx++) {\n 16             deviceset(idx);\n 17             YVector[idx] = matmul(AMatrix[idx], array(n/ngpu, X + idx*(n/ngpu), afHost));\n 18         }</pre>\nOnce \"AMatrix\" is set, it temporarily pushes \"X\" data into each device memory, again, using <a href=\"http://www.accelereyes.com/arrayfire/c/group__construct.htm#gac55f47510934cb8cbd14361dfa077a02\">ARRAY(dim0, dim1, ptr, af_source)</a> function - it is to perform \"X\" data with the data on device. Then, each pushed \"X\" data is multiplied to the \"AMatrix\" by using <a href=\"http://www.accelereyes.com/arrayfire/c/group__matmul__mat.htm#ga7491b0767aab0b0f7fe1a67274bdf586\">MATMUL</a> and stored in \"YVector\" array.\n<pre class=\"lang:default decode:true\"> 20         // Copy partial results back to host (implicitly blocks until done)\n 21         for (int idx = 0; idx &lt; ngpu; idx++) {\n 22             deviceset(idx);\n 23             YVector_host[idx] = YVector[idx].host&lt;float&gt;();\n 24         }</pre>\nLastly, it pulls the result from \"YVector\" back to the host memory by assigning it to \"YVector_host\", a float array on the host memory. Finally, it repeats these steps 1000 iterations in this particular example to calculate the performance time with accuracy.\n<pre class=\"lang:default decode:true\"> 81         // do matrix-vector multiply using all GPUs\n 82         af::sync();\n 83         timer::start();\n 84         multi_Sgemv(iterations, ngpu, AMatrix, n, X, n, Y);\n 85         af::sync();</pre>\nOf course, ArrayFire performs all these complicated steps so quickly - within less than 0.01 seconds in average as result below.\n<pre class=\"lang:default decode:true\">size(A)=[21000,21000]  (1683 mb)\nBenchmarking........\nAverage time for 1000 iterations : 0.00997175 seconds</pre>\n&nbsp;\n\nArrayFire provides so much flexibility in device control. If you want to be capable of managing multiple devices, <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> the ArrayFire library and have the flexibility in your GPU programming today!\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\">ArrayFire Examples (Part 1 of 8) – Getting Started</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/06/arrayfire-examples-part-2-of-8-benchmarks/\">ArrayFire Examples (Part 2 of 8) – Benchmarks</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/25/arrayfire-examples-part-3-of-8-financial/\">ArrayFire Examples (Part 3 of 8) – Financial</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/16/arrayfire-examples-part-4-of-8-image-processing\">ArrayFire Examples (Part 4 of 8) - Image Processing</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/05/arrayfire-examples-part-5-of-8-machine-learning/\">ArrayFire Examples (Part 5 of 8) - Machine Learning</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/12/arrayfire-examples-part-6-of-8-multiple-gpus/\">ArrayFire Examples (Part 6 of 8) - Multiple GPU</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/07/03/arrayfire-examples-part-7-of-8-pde/\">ArrayFire Examples (Part 7 of 8) - PDE</a></li>\n</ol>','ArrayFire Examples (Part 6 of 8) - Multiple GPUs','','publish','open','open','','arrayfire-examples-part-6-of-8-multiple-gpus','','','2013-06-12 00:00:12','2013-06-12 04:00:12','',0,'http://blog.accelereyes.com/blog/?p=3513',0,'post','',0),(3514,1,'2013-07-03 12:00:48','2013-07-03 16:00:48','This is the seventh in a series of posts looking at our current ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\" target=\"_blank\">examples</a>. The code can be compiled and run from <code>arrayfire/examples/</code> when you <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> and install the ArrayFire library. Today we will discuss the examples found in the <code>pde/</code> directory.\n\nIn these examples, my machine has the following configuration:\n<pre class=\"lang:default decode:true\">ArrayFire v1.9.1 (build XXXXXXX) by AccelerEyes (64-bit Linux)\nLicense: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nCUDA toolkit 5.0, driver 319.17\nGPU0 Tesla K20c, 5120 MB, Compute 3.5  (current)\nGPU1 Tesla C2075, 6144 MB, Compute 2.0 \nGPU2 Tesla C1060, 4096 MB, Compute 1.3 \nDisplay Device: GPU0 Tesla K20c\nMemory Usage: 5044 MB free (5120 MB total)</pre>\n&nbsp;\n\nThe followings are the examples of formulating Partial Differential Equations, generally used to create a relevant computer model with several variables. In these examples, I don\'t introduce any new functions but focus on the performance of ArrayFire . You can experience the power of ArrayFire in these examples by looking at how it quickly handles the complex formulas and beautifully draws the result in real-time.\n\n<b>1. Shallow Water Equations - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2pde_2swe_8cpp-example.htm\">swe.cpp</a></b>\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-2.40.15-PM.png\"><img class=\"aligncenter  wp-image-4271\" alt=\"Screen Shot 2013-05-31 at 2.40.15 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-2.40.15-PM-1024x578.png\" width=\"645\" height=\"365\" /></a><strong>Figure 1</strong></p>\n<p style=\"text-align: left;\">This is a visualization of the shallow water flow below a pressure. The 2-D image in Figure 1 represents the wave propagation with boundary size of 512 x 512. The 3-D plot on the right in Figure 1 represents the gradient-versus-magnitude graph; it is not necessary to understand what each coordinate and the shape of the plot mean.</p>\n\n<pre class=\"lang:default decode:true\"> 21     unsigned io = (unsigned)floor(Lx / 5.0f),\n 22              jo = (unsigned)floor(Ly / 5.0f),\n 23              k = 20;\n 24 \n 25     array x = tile(array(seq(nx),nx,1), 1,ny);\n 26     array y = tile(array(seq(ny),1,ny), nx,1);\n 27     array etam = 0.01f * exp((-((x - io) * (x - io) + (y - jo) * (y - jo))) / (k * k));\n 28     array eta = etam;\n ..\n 42     while (true) {\n 43     \n 44         // compute\n 45         array up = um + convolve(eta, 2, diff_x_dims, h_diff_kernel);\n 46         array vp = um + convolve(eta, 2, diff_y_dims, h_diff_kernel);\n 47         \n 48         array e = convolve(eta, 2, lap_dims, h_lap_kernel);\n 49         array etap = 2 * eta - etam + (2 * dt * dt) / (dx * dy) * e;\n 50         etam = eta;\n 51         eta = etap;</pre>\n<p style=\"text-align: left;\">Initially, a pressure is added to the shallow water as shown in line 21-28. Once the pressure is added, the flow of the shallow water is repeatedly splashed into many partial waves and destabilized as each wave reflects off the boundary. The Shallow Water Equation uses the zonal velocity, meridional velocity, acceleration due to gravity, force and etc., which makes the display look realistic. Along with these equations, all these physics math must be done fast enough to support the real-time updates in order to depict the waves quickly and smoothly for display.</p>\n\n<pre class=\"lang:default decode:true\">  iterations per second: 2984   (progress 5%)\n  iterations per second: 3348   (progress 10%)\n  ...\n  iterations per second: 3340   (progress 90%)\n  iterations per second: 3339   (progress 95%)</pre>\nWith our ArrayFire libraries, this example gets quick updates for every iteration, which occurs approximately 3300 iterations per second. ArrayFire also provides a expansion capability for drawing multiple objects in parallel manner.\n\n&nbsp;\n\n&nbsp;\n<p style=\"text-align: left;\"><strong>2. Finite-Difference Time-Domain Simulation of Electromagnetic Field - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2pde_2fdtd_8cpp-example.htm\">fdtd.cpp</a></strong></p>\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-2.58.57-PM.png\"><img class=\"aligncenter  wp-image-4272\" alt=\"Screen Shot 2013-05-31 at 2.58.57 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/05/Screen-Shot-2013-05-31-at-2.58.57-PM-1024x578.png\" width=\"645\" height=\"365\" /></a></p>\n<p style=\"text-align: center;\"></p>\n<p style=\"text-align: left;\">Finite-Difference Time-Domain is a numerical analysis technique to solve the electrodynamics problems. This is a cool visual demonstration of ArrayFire that contains various computations. It is not necessary to understand the details of this technique, but you may realize that the algorithm in the example is used to find a solution for very complicated problems, mostly handling differential equations.</p>\n\n<pre class=\"lang:default decode:true\">348         if (!console) {\n349             // continually draw the current field\n350             fig(\"color\",\"heat\");\n351             fig(\"sub\",2,2,2);   image(ey);\n352             fig(\"sub\",2,2,4);   plot2(ey);\n353             fig(\"sub\",2,1,1);   surface(ey);\n354         }</pre>\n<p style=\"text-align: left;\">The image above includes three graphs in different dimensional perspectives. First, the <a href=\"http://www.accelereyes.com/arrayfire/c/group__gfx__mat.htm#ga2119d648f97cb0ce5d843b127d96f73c\">SURFACE</a> function - used for graph on the left - provides a three dimensional display with full 360 degree rotating camera view. The color layer changes by the height of the graph; the larger each value is the brighter its color appears to be, which provides a better vision for our determination. The perspective of <a href=\"http://www.accelereyes.com/arrayfire/c/group__gfx__mat.htm#ga637619207e3626e058daa07eb9d2aed4\">IMAGE</a> (top right) is visualized as if we are observing it from the top of the first graph. It\'s likely that the set of X and Y coordinates from the <a href=\"http://www.accelereyes.com/arrayfire/c/group__gfx__mat.htm#ga2119d648f97cb0ce5d843b127d96f73c\">SURFACE</a> graph without Z coordinate values; however, we can still relatively determine the height of each value by its different coloring. The graph on the bottom right is the side view of the first graph. As drawn, the graph displays with separating the overlapped graphics as much as possible by using filled and lined surface. Also, notice that the X-axis is different from other graphs; this is because <a href=\"http://www.accelereyes.com/arrayfire/c/group__gfx__mat.htm#gac70681e6d537de580863f86f977e5b45\">PLOT2</a> takes the matrix data in a different way. So, there must be some adjustment needs for matrices to display one representation from different graphical views.</p>\n\n<pre class=\"lang:default decode:true\">Finite-difference time-domain simulation of electromagnetic field\n  iterations per second: 1643   (progress 7%)\n  iterations per second: 1635   (progress 10%)\n  iterations per second: 1627   (progress 13%)\n  iterations per second: 1625   (progress 17%)\n  ...\n  iterations per second: 1619   (progress 90%)\n  iterations per second: 1616   (progress 93%)\n  iterations per second: 1614   (progress 97%)</pre>\nAs you can see, the code is 400 lines and contains many computations. But the result still came out to be approximately 1620 iterations per second on my machine. This is a decent performance speed not only because it calculates the massive amount of values in matrices but also it runs them with smooth and fast graphics in real-time updates. If this algorithm had to be done in host (CPU), that could be a disaster for the performance in computation and display. Even if this could be done in device (GPU), without any library like ArrayFire, that could be another disaster for the efficiency in writing code. Thus, as users require writing a larger-scale program in GPU, ArrayFire is a more powerful tool to bring the best performance and efficiency.\n\n&nbsp;\n\nIf you consider yourself as a hardcore programmer, you may look for a powerful library. <a href=\"http://www.accelereyes.com/download_arrayfire\">Download</a> the ArrayFire library now and experience our useful functions with the best performance in your GPU.\n\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\">ArrayFire Examples (Part 1 of 8) – Getting Started</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/06/arrayfire-examples-part-2-of-8-benchmarks/\">ArrayFire Examples (Part 2 of 8) – Benchmarks</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/25/arrayfire-examples-part-3-of-8-financial/\">ArrayFire Examples (Part 3 of 8) – Financial</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/16/arrayfire-examples-part-4-of-8-image-processing\">ArrayFire Examples (Part 4 of 8) - Image Processing</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/05/arrayfire-examples-part-5-of-8-machine-learning/\">ArrayFire Examples (Part 5 of 8) - Machine Learning</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/12/arrayfire-examples-part-6-of-8-multiple-gpus/\">ArrayFire Examples (Part 6 of 8) - Multiple GPU</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/07/03/arrayfire-examples-part-7-of-8-pde/\">ArrayFire Examples (Part 7 of 8) - PDE</a></li>\n</ol>\n&nbsp;\n\n&nbsp;','ArrayFire Examples (Part 7 of 8) - PDE','','publish','open','open','','arrayfire-examples-part-7-of-8-pde','','','2013-07-03 12:00:48','2013-07-03 16:00:48','',0,'http://blog.accelereyes.com/blog/?p=3514',0,'post','',0),(3515,1,'2013-06-17 16:45:22','2013-06-17 20:45:22','This is the eighth in a series of posts looking at our current ArrayFire <a href=\"http://www.accelereyes.com/arrayfire/c/examples.htm\" target=\"_blank\">examples</a>. The code can be compiled and run from <code>arrayfire/examples/</code> when you <a href=\"http://www.accelereyes.com/download_arrayfire\">download</a> and install the ArrayFire library. Today we will discuss the examples found in the <code>visualization/</code> directory.\n\nIn these examples, my machine has the following configuration:\n<pre class=\"lang:default decode:true\">ArrayFire v1.9.1 (build XXXXXXX) by AccelerEyes (64-bit Mac OSX)\nLicense: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nCUDA toolkit 5.0, driver 304.54\nGPU0 GeForce GT 650M, 1024 MB, Compute 3.0 \nDisplay Device: GPU0 GeForce GT 650M\nMemory Usage: 650 MB free (1024 MB total)</pre>\n&nbsp;\n\nSo far, we have been looking at the excellent examples that shows the benefits of using ArrayFire in various fields of study. We performed some appropriate solutions to the complex mathematical computations introducing the ArrayFire libraries. Most of the time, the power of ArrayFire was introduced as a tool to gain a fast performance on those computations and ability to visually draw the real-time results. That is a fact that has been proven by now. If we have been focusing too much on the performance of those complex mathematical operations, in this example, we will take a closer look at the performance of heavy visualizations with simple algorithms.\n\n&nbsp;\n\n<strong>1. Julia Sets - julia.cpp</strong>\n<p style=\"text-align: center;\"><strong> <a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/06/Screen-Shot-2013-06-17-at-3.13.04-PM.png\"><img class=\"aligncenter  wp-image-4322\" alt=\"Screen Shot 2013-06-17 at 3.13.04 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/06/Screen-Shot-2013-06-17-at-3.13.04-PM-1024x546.png\" width=\"614\" height=\"328\" /></a></strong>Figure 1</p>\n<p style=\"text-align: left;\">This is an example of Julia Sets, one of the most famous fractal transformation defined from iteration of the function. The algorithm is simple enough:</p>\n<p style=\"text-align: left;\">1. Set matrix pt = \"any complex numbers\"\n2. Set C = \"a single complex number\" (Julia Set constant)\n3. Set pt = pt<sup>2</sup> + C\n4. If pt is in Julia Set, mark it.\n5. Repeat 3-4</p>\n\n<pre class=\"lang:default decode:true\"> 18         // Calculate the point in complex plane corresponding to the x and y index\n 19         float multiplier = 1.5; // zoom factor\n 20         array realPart =  multiplier *  (DIM/2.0 - x_index) / (DIM/2.0); // used to calculate the real part of pt\n 21         array complexPart =  multiplier *  (DIM/2.0 - y_index) / (DIM/2.0); // used to calculate the imaginary part of pt\n 22         array pt = complex(realPart,complexPart);// DIM*DIM complex points for each pixel of the image\n 23         cuComplex C= {-0.8,0.156}; // constant</pre>\nThe code contains some fixed setting values for the example - not important for our purpose. It first sets the values in matrix \"pt\" with complex numbers. ArrayFire provides <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm#gaa307466288cb4e1ef38561c70826204c\">COMPLEX</a> function that takes a matrix array with a real numbers as a parameter, and another matrix array with imaginary numbers as a parameter. Then, it produces the matrix array \"pt\" filled with complex numbers.\n\n<a href=\"http://www.accelereyes.com/arrayfire/c/page_quickref.htm\">cuComplex</a> type (complex single-precision), used for a single value \"C\" in line 23, is pretty much what <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm#gaa307466288cb4e1ef38561c70826204c\">COMPLEX</a> function uses to produce a single complex number. <a href=\"http://www.accelereyes.com/arrayfire/c/group__arith.htm#gaa307466288cb4e1ef38561c70826204c\">COMPLEX</a> function performs this <a href=\"http://www.accelereyes.com/arrayfire/c/page_quickref.htm\">cuComplex</a> type initializations for many values within a matrix in parallel manner, which makes things much faster.\n\nOnce the value \"C\" (Julia Set Constant) is set and matrix \"pt\" is filled with values, we can now begin the iteration for \"pt = pt<sup>2</sup> + C\".\n\nIf you want to visualize the actual process, so you can possibly see the flow with your eyes, you can simply add a few lines in the for-loop as the following:\n<pre class=\"lang:default decode:true\"> 25         // Calculate pt(n+1) = pt(n)*pt(n) + C iteratively\n 26         for(int i=0; i&lt;200; i++)\n 27         {\n 28             pt = pt*pt+C;                   \n 29             //holds 0 if point is in Julia Set or 1 if point is outside the Julia Set\n 30             array result = (((real(pt)*real(pt)) + (imag(pt)*imag(pt))) &lt; 1000);\n 31             array img = constant(0, DIM, DIM, 3); // DIM*DIM 3 channel (RGB) image initialized to zero\n 32             img(span, span, 1) = 255 * result; // set the blue component of the image\n 33             image(img);\n 34             usleep(10000);\n 35         }</pre>\nProcessing with more iterations will mark off more points for detail. Also, notice that you can replace the complex number C with an arbitrary number and set an appropriate number for iteration to see different image results. It is also noticeable that the whole process for this cool visualization only took seven lines for initial set-up, one line for the a for-loop to do the actual process, and four lines to display the results in plot. There was no need of an additional for-loop for matrix initialization with complex numbers and another additional for-loop for traversing each value within the matrix. With these few lines of code, you can draw \"Juila Sets\" on screen even though it consists of a tremendous number of points for a better accuracy (As you see figure 1, its domain and range is 0 to 1000 for each). ArrayFire library actually made this as simple as the algorithm of Julia Sets.\n\n&nbsp;\n\n<strong>2. Vortex - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2visualization_2vortex_8cpp-example.htm\">vortex.cpp</a></strong>\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/06/Screen-Shot-2013-06-17-at-4.40.29-PM.png\"><img class=\"aligncenter  wp-image-4335\" alt=\"Screen Shot 2013-06-17 at 4.40.29 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/06/Screen-Shot-2013-06-17-at-4.40.29-PM-1024x574.png\" width=\"614\" height=\"344\" /></a></p>\n<p style=\"text-align: center;\">Figure 2</p>\n<p style=\"text-align: left;\">This is an example of drawing a Vortex in three dimensional space. You might only discover that the green points are blinking within a boundary of a vortex; however, the algorithm contains more than what it looks. It only seems like the points are just blinking; that is because there are too many iterations occurring per second with the speed comes from using the device and ArrayFire libraries. If we add \"usleep(10000);\" in the end of the while loop, you will be able to visualize the movement of points with your eyes.</p>\n<p style=\"text-align: left;\">First, the following line simply adds new height to every point passed very bottom of the vortex (Z&lt;0). This visualizes as if it creates many new green points on the top of this vortex, but also remove them when they get to the bottom.</p>\n\n<pre class=\"lang:default decode:true\"> 35         // Remove old points and add new points\n 36         Z = array(Z &lt; zero) + Z * array(Z &gt;= zero);</pre>\n<p style=\"text-align: left;\">After the new points are created, the following lines make them flow through the hollow vortex in tornadoes form with some math operations to X and Y.</p>\n\n<pre class=\"lang:default decode:true\"> 38         // Update the X and Y points\n 39         array TEMP = T + 2 * af::Pi * revolutions * .00025 * (iter++);\n 40         X = xAx * Z * cos(TEMP) + 0.5;\n 41         Y = yAx * Z * sin(TEMP) + 0.5;</pre>\nTo make them flow down to the bottom, each Z value also gets subtracted by 0.0025 before X and Y values are updated.\n<pre class=\"lang:default decode:true\"> 17     float zD = -0.0025f;\n ..\n 33     Z = Z + zD;</pre>\nThe number of points in figure 2 are actually the number of elements formed by the matrix X, Y, and Z. Each matrix contains such many values and each value in those matrices get updated in a parallel manner using ArrayFire libraries - which lead to approximately 1500 iterations per second. This is one of the best example that visually proves that ArrayFire libraries help users to play with a tremendous number of elements and still maintains the decent performance of drawing them.\n\n&nbsp;\n\n<strong> 3. blip - <a href=\"http://www.accelereyes.com/arrayfire/c/examples_2visualization_2blip_8cpp-example.htm\">blip.cpp</a></strong>\n<p style=\"text-align: left;\">This is the last example, blip, a sinusoidal function that oscillates the surface, showing in four different perspective views. This example is also to show off the graphics performance with ArrayFire. Oscillating three dimensional form is a complex movement for graphics since every point has to be relocated for each update, meaning the process must be more precise and complex to make the smooth motion. This also contains only few lines of mathematical operations, but within very wide domain and range. I will probably repeat the same things I mentioned in the example above. Perhaps, it might be better to just visualize this example with a clip in case of those missing to see it. Also, notice that the performance will be better than the quality shown in this clip, depending on your device capacity.</p>\n<object width=\"650\" height=\"400\" classid=\"clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b\" codebase=\"http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0\"><param name=\"src\" value=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/06/blip.m4v\" /><embed width=\"650\" height=\"400\" type=\"video/quicktime\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/06/blip.m4v\" /></object>\n\n&nbsp;\n\nMany of you probably need the GPU programming experience to perform graphics, maybe a simple picture, or maybe heavy three-dimensional motions with your experiment data. However, you may have no experience with the existing GPU programming platforms. ArrayFire can make you to have the GPU programming skill with its easy libraries. If you know C, C++, or Fortran, you are ready to go. <a href=\"http://www.accelereyes.com/download_arrayfire\">Download</a> the ArrayFire library and visualize what you need today!\n\n&nbsp;\n\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/04/arrayfire-examples-part-1-of-8-getting-started/\">ArrayFire Examples (Part 1 of 8) – Getting Started</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/06/arrayfire-examples-part-2-of-8-benchmarks/\">ArrayFire Examples (Part 2 of 8) – Benchmarks</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/25/arrayfire-examples-part-3-of-8-financial/\">ArrayFire Examples (Part 3 of 8) – Financial</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/16/arrayfire-examples-part-4-of-8-image-processing\">ArrayFire Examples (Part 4 of 8) - Image Processing</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/05/arrayfire-examples-part-5-of-8-machine-learning/\">ArrayFire Examples (Part 5 of 8) - Machine Learning</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/06/12/arrayfire-examples-part-6-of-8-multiple-gpus/\">ArrayFire Examples (Part 6 of 8) - Multiple GPU</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/07/03/arrayfire-examples-part-7-of-8-pde/\">ArrayFire Examples (Part 7 of 8) - PDE</a></li>\n</ol>\n&nbsp;','ArrayFire Examples (Part 8 of 8) - Visualization','','draft','open','open','','','','','2013-06-17 16:45:22','2013-06-17 20:45:22','',0,'http://blog.accelereyes.com/blog/?p=3515',0,'post','',0),(3605,4,'2013-03-05 12:55:13','2013-03-05 16:55:13','The <a href=\"http://www.gputechconf.com/page/home.html\">2013 GPU Technology Conference</a> is just two weeks away. We\'re super excited.\n\nWe\'re spending a lot of time preparing for our tutorial on <a href=\"http://registration.gputechconf.com/quicklink/Gsm68g\">CUDA Accelerated Image Processing Libraries</a>. We think it will be well worth your while to attend. This is an 80-minute share all about CUDA image processing from James Malcolm, an AccelerEyes co-founder and lead engineer. You will walk away from the tutorial much better prepared to build fast computer vision and image processing codes.\n\nThe session abstract is as follows:\n<blockquote>Image processing has consistently proven to benefit greatly from GPU acceleration. A number of libraries available from NVIDIA and AccelerEyes make image processing development efficient and lead to big speedups. Using these libraries can often significantly shorten the development time of a GPU project while leading to high-performance, high-quality software. In conjunction with the CUDA 5.0 release, NVIDIA and AccelerEyes introduced enhancements to their libraries to improve performance and take advantage of new features available in the Kepler-series GPUs. In this tutorial, we will provide an overview of the image processing libraries in the CUDA SDK as well as those provided with ArrayFire. The audience will not only learn about the strengths of the individual libraries, but also learn about the decision making process to select the best suited library for their project.</blockquote>\nYou can <a href=\"http://registration.gputechconf.com/quicklink/Gsm68g\">register for the session here</a>. We encourage registering in advance because these tutorial sessions fill up fast!\n\nSee you in San Jose!\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-02-06/nvidia_announces_new_report_outlining_12x_cuda_performance_gains_over_cpu-only_libraries.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/143351767_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-02-06/nvidia_announces_new_report_outlining_12x_cuda_performance_gains_over_cpu-only_libraries.html\" target=\"_blank\">NVIDIA Report: 12x CUDA Performance Gains Over CPU-Only</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/01/21/how-much-speedup-can-you-get-with-cuda-or-opencl/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/139661938_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/01/21/how-much-speedup-can-you-get-with-cuda-or-opencl/\" target=\"_blank\">How much speedup can you get with CUDA or OpenCL?</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=83fa63b7-48ea-42c4-9757-647de0f2569d\" /></div>','GTC 2013 Tutorial - CUDA Accelerated Image Processing Libraries','','publish','open','open','','gtc-2013-tutorial-cuda-accelerated-image-processing-libraries','','','2013-03-05 12:55:13','2013-03-05 16:55:13','',0,'http://blog.accelereyes.com/blog/?p=3605',0,'post','',0),(3624,4,'2013-03-07 23:30:17','2013-03-08 03:30:17','Over the years at AccelerEyes, it has been surprising to me how many people miss a big picture understanding of the trends affecting the computing industry. To help, I\'m going to post a few articles with high-level explanations. I\'m going to do so in a hand-wavy manner. I look forward in advance to the lively comments on my mistakes. But, in general, I think these posts will be a fairly accurate view of the important trends.\n\nToday, I\'ll start by talking about CPU processing trends.\n\nLet\'s start with something we all know:  <a title=\"Central processing unit\" href=\"http://en.wikipedia.org/wiki/Central_processing_unit\" target=\"_blank\" rel=\"wikipedia\">CPUs</a> are central processing units and are the main processor in the computer. You probably had to label the CPU on a diagram at some point in grade school, along with the hard drive, keyboard, mouse, monitor, and floppy drive.\n\nUp until 10 years ago or so, CPUs improved in speed mainly by increasing in the frequency of their clocks. You probably remember CPUs improving from MHz speeds to 1 GHz to ... to 3 GHz. You rarely hear of CPUs running above 4 GHz. There\'s an important reason for this. If the frequency gets too high, the chip can actually melt from the excessive power/heat. Today you typically see CPUs running at 2 to 3 GHz, which is where they landed over 10 years ago.\n\nThere are ways to make CPUs run faster. But that requires keeping them cool so they don\'t melt. Even at 2-3 GHz your computer needs a lot of fans and heat conducting metal apparatuses (called heat sinks) to whisk away the heat from the chip. That\'s why your computer make noises; it\'s the fans keeping your CPU cool. But fans only work up to 2-3 GHz. If you want to go above that, you need liquid cooled solutions. However, short of really hardcore computer geeks and gamers, no one really wants to put liquid in their computer.\n\nSo, in order to keep improving speed over the last 10 years, CPU manufacturers had to find other ways to improve things. They found improvements in adding more CPU cores (each of which is a full CPU) onto the same CPU chip. One of the cores could do one thing (like play a movie) which the other core did something else (like run Microsoft Excel). Since those tasks were split up between different CPU cores, each core did not have to work as hard to get the tasks done and you could effective get a faster experience without raising the clock frequency.\n\nThis is where <a title=\"Parallel computing\" href=\"http://en.wikipedia.org/wiki/Parallel_computing\" target=\"_blank\" rel=\"wikipedia\">parallel computing</a> first entered the technology scene in a big way. On CPUs, this is called \"<a title=\"Task parallelism\" href=\"http://en.wikipedia.org/wiki/Task_parallelism\" target=\"_blank\" rel=\"wikipedia\">Task Parallelism</a>.\" In order for programs to actually use all the CPU resources, the software had to be re-written and re-compiled with special consideration for the fact that the processor architecture had changed.\n\nSo for the last 10 years, we\'ve gone from single core, to dual core, to quad core. But again, you don\'t see many CPUs with more than 4 actual cores. That\'s because with 4 cores on one chip, the size of the chip grows and the power/heat starts to rise again. So again, CPUs have hit again hit some physical barriers. And this time CPUs are having a much harder time figuring out how to deliver substantial performance improvements. Mainly CPUs are relying on making transistors smaller, so that the power per core requirements go down, so that more cores can be added.\n\nLuckily, for most people, regular dual or quad core CPUs are good enough for the tasks that need to be done. If your computer is slow, it likely is not due to the CPU anymore. It is much more likely to be your hard drive (upgrading to an <a title=\"Solid-state drive\" href=\"http://en.wikipedia.org/wiki/Solid-state_drive\" target=\"_blank\" rel=\"wikipedia\">SSD</a> is the best way to speed up your computer these days).\n\nHowever, for scientists, engineers, and financial analysts (i.e. for people that run big simulations), CPUs are still slow. AccelerEyes was founded in 2007 on the cusp of a transformative computing event when the high-end computing professionals realized CPUs were no longer going to improve as fast as is needed for their applications.\n\nThe answer to this problem was found in using other processors to supplement the CPU in getting the computing work done. It started with leveraging the GPU (graphics processing unit) on the video card as a companion to the CPU in computational tasks.\n\nIn my next post, I\'ll talk more about how <a title=\"Graphics processing unit\" href=\"http://en.wikipedia.org/wiki/Graphics_processing_unit\" target=\"_blank\" rel=\"wikipedia\">GPUs</a> have made a permanent home in the world of computing and how heterogeneous computing is the name of the computing game for the next decade.\n\nWhat parallelism does your application use?\n\n<em>Notes:</em>\n<ul>\n	<li><em><span style=\"line-height: 13px;\">CPUs have also improved greatly over the years in architecture, caches, prediction, and more. But those improvements have not been sufficient to stem the tide of heterogeneous computing.</span></em></li>\n	<li><em>CPUs also have ways to offload computations to data-parallel sections of their same chip (using SSE/AVX instructions). Those options are also not significant enough to alter the macro-level trends.</em></li>\n</ul>\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/07/cpu-processing-trends-for-dummies/\">CPU Processing Trends for Dummies</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\">Heterogeneous Computing Trends for Dummies</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/08/parallel-software-development-trends-for-dummies\">Parallel Software Development Trends for Dummies</a></li>\n</ol>\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.networkworld.com/news/2013/030513-why-moore39s-law-not-mobility-267394.html?source=nww_rss\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_118_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.networkworld.com/news/2013/030513-why-moore39s-law-not-mobility-267394.html?source=nww_rss\" target=\"_blank\">Why Moore\'s Law, not mobility, is killing the PC</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.makeuseof.com/tag/what-is-the-difference-between-an-apu-a-cpu-and-a-gpu-makeuseof-explains/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/145443929_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.makeuseof.com/tag/what-is-the-difference-between-an-apu-a-cpu-and-a-gpu-makeuseof-explains/\" target=\"_blank\">What Is the Difference Between An APU, A CPU And A GPU? [MakeUseOf Explains]</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://whitehat0.wordpress.com/2013/03/05/intel-vs-amd-which-processor-is-best/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/149932088_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://whitehat0.wordpress.com/2013/03/05/intel-vs-amd-which-processor-is-best/\" target=\"_blank\">Intel vs AMD: Which Processor is Best</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://streamcomputing.eu/blog/2012-11-28/the-opencl-power-offloading-to-the-cpu-avx-sse/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/138441744_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://streamcomputing.eu/blog/2012-11-28/the-opencl-power-offloading-to-the-cpu-avx-sse/\" target=\"_blank\">The OpenCL power: offloading to the CPU (AVX+SSE)</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=ce8bbf3a-8cae-4441-97b1-5e6f8b7299cf\" /></div>','CPU Processing Trends for Dummies','','publish','open','open','','cpu-processing-trends-for-dummies','','','2013-03-07 23:30:17','2013-03-08 03:30:17','',0,'http://blog.accelereyes.com/blog/?p=3624',0,'post','',0),(3662,1,'2013-03-16 01:01:22','2013-03-16 05:01:22','<a href=\"http://en.wikipedia.org/wiki/Fractal\">Fractals</a> are known as a “self similar images”, that is these images are exactly similar to a part of itself. The <a href=\"http://en.wikipedia.org/wiki/Julia_set\">Julia set</a> is one such fractal, discovered by French mathematician Gaston Maurice Julia. They form a variety of very beautiful patterns.\n\nA popular Julia set quadratic polynomial function f<sub>C</sub>, is shown below:\n\nf<sub>C</sub>: Z<sub>n+1</sub> = Z<sub>n</sub><sup>2</sup>+ C\n\nIt is a set of complex points Z on the complex plane for which the iterative series does not tend to infinity, where C is a constant complex number. Different values of C produce different Julia sets. Some examples of Julia set are shown below (image source: Wikipedia):\n\n<b><img class=\"alignnone\" alt=\"\" src=\"https://lh4.googleusercontent.com/zCyyzDZRe0T0famg_RXiauZS97WI7n-KpK35yQO-DuC5S4BjanEhmC16LaqPo5AWYjftlnEoWjT8DQLJfWMz9JVkg1sRJrnBdWEtmU7KTNEvSTprYU_JSfWw\" width=\"453px;\" height=\"196px;\" /></b>\n\nLet us now see how the Julia set can be calculated and rendered easily using ArrayFire. You can download the full code from <a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/juliaSet.zip\">here</a>.\n\nThe Julia set images can be created by mapping each point in a image to a point on the complex plane. The above equation is then applied to each of these points iteratively to determine whether they fall inside or outside the Julia Set:\n<pre class=\"lang:default decode:true\">array offset = seq(DIM*DIM); // holds sequential numbers 0,1,2,...,DIM\narray x_index = (abs)(offset/DIM); // x index of each pixel\narray y_index = (abs)(offset%DIM); // y index of each pixel\n\n// Calculate the point in complex plane corresponding to the x and y index\nfloat multiplier = 1.5; // zoom factor\narray realPart =  multiplier * (DIM/2.0 - x_index) / (DIM/2.0); // calculate the real part of pt\narray complexPart =  multiplier * (DIM/2.0 - y_index) / (DIM/2.0); // calculate the imag part of pt\narray pt = complex(realPart,complexPart); // DIM*DIM complex points for each pixel of the image\n\ncuComplex C = {0.285,0.01}; // constant\n\n// Calculate pt(n+1) = pt(n)*pt(n) + C iteratively\nfor(int i=0; i&lt;50; i++){\n	pt = pt*pt+ C;\n}\n\n//\'result\' holds 0 if point is in Julia Set or 1 if point is outside the Julia Set \narray result = (((real(pt)*real(pt)) + (imag(pt)*imag(pt))) &lt; 1000);</pre>\nThe next part consists of rendering the image onto the screen. This can be done in 3 simple steps:\n\n1. Create an ArrayFire array “img” representing the image to be rendered:\n<pre class=\"lang:default decode:true\">array img(DIM, DIM, 3); // DIM*DIM 3 channel (RGB) image</pre>\n2.  For each point in the image, set the point to some color if the point is in the Julia set, else set it to a different one. Here all the Julia set points are being set to blue and the rest (background) are set to black:\n<pre class=\"lang:default decode:true\">array img = constant(0, DIM, DIM, 3); // DIM*DIM 3 channel (RGB) image initialized to zero\nimg(span, span, 1) = 255 * result; // set the blue component of the image</pre>\n3. In the last step, render the image on the screen:\n<pre class=\"lang:default decode:true\">image(img); // renders the image on screen.</pre>\nThat’s it! Run the program to see the beautiful Julia set fractal on screen.\n\nHere is an example of a Julia set created with C=0.285+0.01i with 50 iterations\n\n<b id=\"internal-source-marker_0.02422779379412532\"><img alt=\"\" src=\"https://lh4.googleusercontent.com/Cqw3lf_RUMP8hz-Vav5q9jmrzB9DkTTk96FE6nRaNWfa8-IBihbcfEhjiiffIGON0rfDCsYsFjTxFNuX9vjJkCedF2o_udXcheYUA1cR8y_Rnm1azRhcxXMV\" width=\"678px;\" height=\"652px;\" /></b>\n\nAnother Julia set (in green) with C=-0.8+0.156i with 200 iterations.\n\n<b id=\"internal-source-marker_0.7519505347590894\"><b id=\"internal-source-marker_0.02422779379412532\"><img alt=\"\" src=\"https://lh4.googleusercontent.com/Sw4Nd9eAQqJwo3MTDARIVkeUd-3d4HuZYJVpGbpYWfyiSa2zwO-tsevjh9ZcuOUp2wmW9A5Fz55dmQBhmbvzwvQKCtHv7MHFJaFJbZC3TsQ5mgxre1tLqSul\" width=\"677px;\" height=\"651px;\" /></b></b>\n\n&nbsp;\n\n&nbsp;\n\n&nbsp;\n\n&nbsp;','Julia Set using ArrayFire','','draft','open','open','','rendering-the-julia-set-using-arrayfire-2','','','2013-03-16 01:01:22','2013-03-16 05:01:22','',0,'http://blog.accelereyes.com/blog/?p=3662',0,'post','',0),(3702,1,'2013-03-15 17:18:04','2013-03-15 21:18:04','<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/GTC-banner1.jpg\"><img class=\"alignnone size-full wp-image-3704\" alt=\"GTC banner\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/GTC-banner1.jpg\" width=\"670\" height=\"190\" /></a>\n\nGTC is quickly approaching and AccelerEyes is giddy with excitement!\n\nThis year we are taking things to the next level as a Silver Sponsor at GTC 2013. Meaning, you\'ll be seeing a lot more of us throughout the conference!\n\n<strong>Schedule a Meeting with Us</strong>\n\nDo you want to meet with us personally? Schedule a time to sit down with AccelerEyes engineers and account representatives using our <a href=\"http://meetme.so/accelereyes\">online scheduler</a>.\n\n<b>Visit our Booth</b>\n\nIf  you\'re attending GTC, be sure to come visit us at <strong>booth #204</strong> to see some great demos or to chat with anyone in our Software Shop for CUDA &amp; OpenCL. Come see how ArrayFire complements other GPU development efforts, including raw CUDA/OpenCL development, OpenACC, and other GPU libraries.\n\n<strong>Register for CUDA Accelerated Image Processing Libraries</strong>\n\nWe would also like to extend a special invitation to register for our Tutorial: <a href=\"https://registration.gputechconf.com/form/session-listing&amp;doSearch=true&amp;additional_parameter_selector=Speaker+Name&amp;day_selector=Monday&amp;level_selector=none&amp;queryInput=malcolm&amp;topic_selector=none&amp;type_selector=Tutorial\"><strong>S3559 - CUDA Accelerated Image Processing Libraries</strong></a> by our own very James Malcolm, Co-Founder and VP of Engineering. In this tutorial, James will provide an overview of the image processing libraries in the CUDA SDK as well as those provided with ArrayFire. This will be a great opportunity to not only learn about the strengths of the individual libraries, but also learn about the decision making process to select the best suited library for your projects. The tutorial date and time are, <strong>Day: </strong>Monday, 03/18, <strong>Time: </strong>13:00 - 14:20, <strong>Location: </strong>Room 210A<em id=\"__mceDel\">.</em>\n\n<strong>Get a GTC 2013 10% Discount</strong>\n\nWe have 10% discount coupons available for GTC registrations. If you\'re interested, please contact <strong>sales@accelereyes.com</strong> for more information.\n\n<em id=\"__mceDel\">We look forward to seeing everyone at GTC!</em>\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blogs.nvidia.com/2013/02/how-to-check-out-the-worlds-top-accelerated-computing-innovations-all-in-one-place/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/143845166_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blogs.nvidia.com/2013/02/how-to-check-out-the-worlds-top-accelerated-computing-innovations-all-in-one-place/\" target=\"_blank\">How to Check Out the World\'s Top Accelerated Computing Innovations, All in One Place</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blogs.nvidia.com/2013/03/auto-at-gtc-2013/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/151844226_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blogs.nvidia.com/2013/03/auto-at-gtc-2013/\" target=\"_blank\">Get Up to Speed on Auto Technology\'s Future at GTC Conference Next Week</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/03/14/interview-nvidias-andy-walsh-previews-next-weeks-gpu-technology-conference/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152238300_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/03/14/interview-nvidias-andy-walsh-previews-next-weeks-gpu-technology-conference/\" target=\"_blank\">Interview: Nvidia\'s Andy Walsh Previews Next Week\'s GPU Technology Conference</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-15/microway_to_show_updated_gpu_systems_at_gtc_2013.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152560285_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-15/microway_to_show_updated_gpu_systems_at_gtc_2013.html\" target=\"_blank\">Microway to Show Updated GPU Systems at GTC 2013</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-02-06/nvidia_announces_new_report_outlining_12x_cuda_performance_gains_over_cpu-only_libraries.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/143351767_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-02-06/nvidia_announces_new_report_outlining_12x_cuda_performance_gains_over_cpu-only_libraries.html\" target=\"_blank\">NVIDIA Report: 12x CUDA Performance Gains Over CPU-Only</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=405c5009-70b7-4de0-b294-772ae963d186\" /></div>','Giddy for GTC - We\'re Taking it to the Next Level','','publish','open','open','','giddy-for-gtc-were-taking-it-to-the-next-level','','','2013-03-15 17:18:04','2013-03-15 21:18:04','',0,'http://blog.accelereyes.com/blog/?p=3702',0,'post','',0),(3741,4,'2013-03-17 14:21:53','2013-03-17 18:21:53','Ten days ago, I posted an article on <a href=\"http://blog.accelereyes.com/blog/2013/03/07/cpu-processing-trends-for-dummies/\">CPU Processing Trends for Dummies</a>. Today, I continue that series with an article describing the latest major trend in computing, namely <a class=\"zem_slink\" title=\"Heterogeneous computing\" href=\"http://en.wikipedia.org/wiki/Heterogeneous_computing\" target=\"_blank\" rel=\"wikipedia\">Heterogeneous Computing</a>.\n\n<strong>The Point</strong>\n\nThe point of these articles is to paint the high-level picture for trends in computer processing. I hope this bigger picture will help summarize things for those that do not breathe computer processors and technical software on a daily basis.\n\nOver the last 20 years, big gains in computer processing have been defined by increases in CPU clock speeds, then by increases in the number of CPU cores. The next 10+ years will be defined by heterogeneous computing.\n\n<strong>Heterogeneous Computing</strong>\n\nSo let\'s start with a definition:  Heterogeneous computing is the coordination of 2 or more different processors, of different architecture types, to perform a computational task. \"Architecture type\" is defined below.\n\nIn practice, that means that you actually have more than one processor in your computer. You have the CPU that you already know about (of x86 architecture type), but you also have another processor (of a different architecture type). We\'ll call that other processor an \"accelerator,\" because it accelerates computations by assisting the CPU to get stuff done.\n\nStop and be amazed. Did you realize that your computer actually already has an accelerator in it? Yes it does. You may even have several accelerators already in your computer. Some of those may even be more powerful in terms of ability to do processing than your CPU. However, it is very likely that you are not using those accelerators. They are probably just sitting there unused, like an expensive gym membership in March.\n\nOK, let me explain that in more detail.\n\n<strong>The Rise of GPU Computing</strong>\n\nIn your computer, you have a GPU (graphics processing unit), which is an accelerator to the CPU. You probably know of the GPU (which typically resides on a video card) as the thing that drives your computer monitor. You plug your monitor into your video card/GPU.\n\nInnovations in GPUs over the last 20 years have been primarily driven by the demand for more awesome video games. Video games have advanced tremendously, going from Mario Brothers (which simply had some pre-computed pixel patters that are the same every time you play it) to the games today which are extraordinarily complex in how they perform physics calculations of wind-blowing, water-flowing, trees-swaying, and all sorts of other physical phenomenon. In games, GPUs can actually do all those physics calculations on-the-fly to determine the color of pixels to be sent to the monitor. It still blows my mind that there is <a href=\"http://www.speedtree.com/\" target=\"_blank\">a company</a> purely dedicated to creating physical models for trees in video games (i.e. those physics calculations are extremely complex and the GPU has to be a beast of a processor to handle them).\n\nAnyway, in order to support all of those physics calculations, GPUs have advanced from merely displaying to the monitor to actually having incredible capabilities to do math computations. The processing capability of the GPU is not limited to video games. In fact, any software program can use the GPU to do computations. You can do math on GPUs. You can do financial calculations on GPUs. You can do genomic sequencing on GPUs. Radiologists can find tumors in MRI scans using GPUs. Here are <a href=\"http://accelereyes.com/examples\" target=\"_blank\">some examples</a> of things our users have done with GPUs.\n\nIn terms of sheer capacity to crunch numbers, GPUs can crunch more numbers per minute than CPUs. They have thousands of cores for number crunching. They are more powerful. They also use less energy per computation than CPUs. Note that a GPU core is not nearly as capable as a CPU core in terms of the kinds of things they can do, but there are many more of them available.\n\nGPUs are also ubiquitous. Every computer, smartphone, and tablet has GPUs in them. It is fitting that this article is published today, on the eve of NVIDIA\'s <a href=\"http://www.gputechconf.com/page/home.html\">GPU Technology Conference</a>.\n\n<strong>Software for Heterogeneous Computing</strong>\n\nSo it is really cool that these computational powerhouse accelerators are in all of our computers.\n\nWhat is not so cool is that most software is incapable of actually running on those accelerators. In order to use accelerators, software must be re-written.\n\nThe process for re-writing software involves an understanding of parallelism. I will write a future post in this series to address parallelism for dummies. The take home message is that software written for parallel computing runs circles around other software, because it is able to use the multiple cores of the CPU as well as the many cores of accelerators, like GPUs.\n\n<strong>The Next Decade: A Tidal Wave of Heterogeneous Computing</strong>\n\nThe rise and success of GPU computing over the last 5 years, with NVIDIA as the hardware-vendor leader, solidified the validity of accelerators and has provoked a tidal wave of oncoming heterogeneous computing systems. As followers to NVIDIA, here is a list of other companies and their accelerators pushing heterogeneous computing as the primary path to computational performance increases over the coming decade:\n<ul>\n	<li><span style=\"line-height: 13px;\">Intel Xeon Phi - released this year as a 60+ core accelerator (they prefer the term \"co-processor\"). It has a new processor architecture with a ring of older x86 CPUs.</span></li>\n	<li>Intel integrated graphics - this is Intel\'s GPU. It is not as capable as NVIDIA or AMD\'s GPUs, but comes on the same chip as all Intel\'s CPUs and is probably the most ubiquitous GPU today for that reason.</li>\n	<li>AMD FirePro and Radeon - these are the only other first-rate GPUs for desktops and servers.</li>\n	<li>AMD APUs - this is AMD\'s merger of Radeon technology onto the same chip as the AMD CPU (i.e. APU = CPU + GPU). The GPU AMD is putting on APUs today is not as powerful as the full Radeon GPU, but it can still be used as an accelerator.</li>\n	<li>Altera FPGAs - these used to be restricted to very niche markets, but with the tidal wave towards heterogeneous computing, Altera\'s FPGAs and FPGAs from other vendors will be considered as a viable option for many more applications.</li>\n</ul>\nIn addition to those, all smartphones and tablets have CPUs and GPUs. All these heterogeneous computing concepts apply equally well to getting more performance out of mobile apps. I will discuss mobile heterogeneous computing in a later post in this series.\n\nWith all of these major companies pushing accelerators, heterogeneous computing is easily the biggest trend in computing for the coming decade.\n\nWhat indications of heterogeneous computing trends have you noticed?\n\n<em>Notes:</em>\n<ul>\n	<li><em><span style=\"line-height: 13px;\">Architecture type refers to the blueprint used to create the processor. Software that will run on one architecture will not run on another architecture without modification, either of the code itself or with the way it was compiled to run. AMD and Intel use the same blueprint, called \"x86\", so software compiled for AMD will generally run on Intel and vice versa. Heterogeneous computing involves many different processors of different architecture types. Developing software for all those different types is complicated and will be described in a future post in this series.</span></em></li>\n	<li><em>When I have described this to people in the past, they often get over excited about accelerators and ask, \"When will accelerators overtake CPUs and when will we no longer need CPUs?\" That question misses the point. If your computer were an army, CPUs would be the generals - highly capable and extremely efficient at command and control. Accelerators would be the foot soldiers, massive numbers of production units but not as capable at decision-making.</em></li>\n</ul>\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/07/cpu-processing-trends-for-dummies/\">CPU Processing Trends for Dummies</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\">Heterogeneous Computing Trends for Dummies</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/08/parallel-software-development-trends-for-dummies\">Parallel Software Development Trends for Dummies</a></li>\n</ol>\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/07/cpu-processing-trends-for-dummies/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/150700635_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/07/cpu-processing-trends-for-dummies/\" target=\"_blank\">CPU Processing Trends for Dummies</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://queue.acm.org/detail.cfm?id=2443836\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/147644516_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://queue.acm.org/detail.cfm?id=2443836\" target=\"_blank\">FPGA Programming for the Masses</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://news.techeye.net/chips/amd-sends-developers-new-apus\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/149892439_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://news.techeye.net/chips/amd-sends-developers-new-apus\" target=\"_blank\">AMD sends developers new APUs</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://gpgpu.org/2013/03/12/accelerating-computer-vision-algorithms-using-opencl-on-the-mobile-gpu\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_123_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://gpgpu.org/2013/03/12/accelerating-computer-vision-algorithms-using-opencl-on-the-mobile-gpu\" target=\"_blank\">Accelerating Computer Vision Algorithms Using OpenCL on The Mobile GPU</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/03/14/video-programming-models-and-their-designs-for-exascale-systems-part-ii/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_107_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/03/14/video-programming-models-and-their-designs-for-exascale-systems-part-ii/\" target=\"_blank\">Video: Programming Models and their Designs for Exascale Systems (Part II)</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=3457e11a-7cfb-423f-a550-2c7edd147759\" /></div>','Heterogeneous Computing Trends for Dummies','','publish','open','open','','heterogeneous-computing-trends-for-dummies','','','2013-03-17 14:21:53','2013-03-17 18:21:53','',0,'http://blog.accelereyes.com/blog/?p=3741',0,'post','',0),(3761,4,'2013-03-18 22:43:47','2013-03-19 02:43:47','AccelerEyes is out in force at GTC. We ended up with 10 of our engineers and sales staff here onsite. I collected feedback from the team to learn what people enjoyed the most from today\'s activities.\n\nHere are 7 of the highlights we\'ve collected from our team on the first day of GTC 2013:\n<ul>\n	<li>Will Ramey of NVIDIA kicked off GTC with a tutorial on the CUDA ecosystem. He talked about the three different approaches to getting GPU acceleration:  1) Libraries, 2) Compiler Directives, and 3) Programming Languages. He talked about how libraries, if you can find one for your application (<a href=\"http://accelereyes.com/arrayfire\">hint, hint</a>),  are the best of the 3 options, because you get great performance and you don\'t have to write low-level code yourself.</li>\n	<li>James Malcolm of AccelerEyes gave an excellent tutorial on CUDA Image Processing with ArrayFire and NPP. Half-way into the presentation, someone pulled the fire alarm and the 100+ crowd evacuated the building. To our surprise, the room filled back up to capacity once we were allowed back in the building!</li>\n	<li>Ina Yosun Chang made an awesome <a href=\"https://twitter.com/Yosun/status/313748678647095296\">comment on Twitter</a> about the fire alarm, \"And... ArrayFire is so hot it\'s burning down the San Jose Convention Center.\"</li>\n	<li>The GTC Poster Session - A hive of GPU energy accelerated by 8 free drink coupons for attendees!</li>\n	<li>Creative Consultants showed us a preview of their 18 megapixel stereo virtual reality system, named <a href=\"http://www.computefaster.com/vr-grotto/\">VR Grotto</a>. Super cool and definitely a must see for GTC attendees in the exhibit hall.</li>\n	<li>Cliff Woolley of NVIDIA gave a tutorial driving home the <a href=\"https://developer.nvidia.com/content/assess-parallelize-optimize-deploy\">APOD cycle</a> for systematic optimization: Assess, Parallelize, Optimize, Deploy.</li>\n	<li>29 tutorials - A massive amount of learning today. It felt like a university campus walking around with all these note takers and people trying to get real acceleration work done.</li>\n</ul>\nBonus Highlight:  Dinner with Strangers - GTC attendees meet new people over dinner. Great fun and an excellent way to learn what\'s really going on in GPU computing.\n\nDon\'t discount Monday\'s at GTC. It was awesome!\n\nWe look forward to the keynote tomorrow, to exhibitions, and to 3 more days of GPU energy.\n\nWhat highlights did you enjoy the first day at GTC 2013?\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-18/nvidia_ceo_to_kick_off_fourth_annual_gtc.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153231696_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-18/nvidia_ceo_to_kick_off_fourth_annual_gtc.html\" target=\"_blank\">NVIDIA CEO to Kick Off Fourth Annual GTC</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/03/14/interview-nvidias-andy-walsh-previews-next-weeks-gpu-technology-conference/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152238300_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/03/14/interview-nvidias-andy-walsh-previews-next-weeks-gpu-technology-conference/\" target=\"_blank\">Interview: Nvidia\'s Andy Walsh Previews Next Week\'s GPU Technology Conference</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/03/15/gtcapp/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152589711_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/03/15/gtcapp/\" target=\"_blank\">New GTC App Helps You Navigate the GPU Technology Conference</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-15/microway_to_show_updated_gpu_systems_at_gtc_2013.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152560285_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-15/microway_to_show_updated_gpu_systems_at_gtc_2013.html\" target=\"_blank\">Microway to Show Updated GPU Systems at GTC 2013</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-18/super_micro_exhibits_gpu_platforms_at_gtc_2013.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153231694_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-18/super_micro_exhibits_gpu_platforms_at_gtc_2013.html\" target=\"_blank\">Super Micro Exhibits GPU Platforms at GTC 2013</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/15/giddy-for-gtc-were-taking-it-to-the-next-level/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152648778_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/15/giddy-for-gtc-were-taking-it-to-the-next-level/\" target=\"_blank\">Giddy for GTC - We\'re Taking it to the Next Level</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=6358503b-4dde-40e8-bad0-9f7959f2bb6f\" /></div>','7 Highlights of GTC 2013 - Day 1 of 4','','publish','open','open','','7-highlights-of-gtc-2013-day-1-of-4','','','2013-03-18 22:43:47','2013-03-19 02:43:47','',0,'http://blog.accelereyes.com/blog/?p=3761',0,'post','',0),(3771,1,'2013-03-19 19:16:54','2013-03-19 23:16:54','The general consensus is that you can ease yourself into GPU programming using three approaches:\n<ol>\n	<li>Use libraries (like ArrayFire) and get quick turnaround times in your acceleration projects.</li>\n	<li>Use compiler directives (like OpenACC) that highlight what part of the code can be run in parallel and let the compiler figure out how to best run the code on the GPU and finally,</li>\n	<li>The do-it-yourself approach by redesigning your program to run on GPUs using CUDA or OpenCL.</li>\n</ol>\nIn this blog, I will illustrate approach#3 using a C++ application for exploring the Mandelbrot set as a test case. This is a canonical problem that many people do to show enormous speedups.\n\nThe original code is given below. We\'ll call this the CPU version because it is designed to run on the CPU.\n<pre class=\"lang:default decode:true\" title=\"Mandelbrot.cpp\">/*\n\nCalculating which points in the specified window of the complex plane\nlie inside the Mandelbrot set\n\nCPU version\n\n*/\n\n#include &lt;iostream&gt;\n#include &lt;complex&gt;\n#include &lt;cmath&gt;\n#include &lt;cstdlib&gt;\n\n// -----------------------------\n// declare some global variables\n\nconst int MAX_ITER = 200;    // maximum number of iterations\n\nconst int NX = 1000;  // number of points along X inside the window\nconst int NY = 1000;  // number of points along Y inside the window\n\n// -------------------------------------------------------\n// define a class for complex numbers and their operations\n\nclass dcmplx\n{\npublic:\n    double re;   // real component\n    double im;   // imaginary component\n\n// function to calculate the magnitude or absolute value of the complex number\n\ndouble magnitude()\n{\n    return pow((re*re + im*im),0.5);\n}\n\n};\n\n// ----------------------------------------------------------------------------------\n// function to check all points inside the specified window for membership in the set\n\nvoid Mandelbrot(double xmin, double xmax, double ymin, double ymax, int *color)\n{\n    double dx = (xmax - xmin)/NX; // grid spacing along X\n    double dy = (ymax - ymin)/NY; // grid spacing along Y\n\n    for(int i=0;i&lt;NX;i++)\n    {\n        for(int j=0;j&lt;NY;j++)\n        {\n            double x = xmin + (double) i*dx;   // actual x coordinate (real component)\n            double y = ymin + (double) j*dy;   // actual y coordinate (imaginary component)\n\n            dcmplx c;\n            c.re = x;\n            c.im = y;\n\n            dcmplx z;\n            z.re = 0.0;\n            z.im = 0.0;\n\n            // ---------------\n            // z &lt;---- z*z + c\n\n            int iter = 0;\n\n            while(iter&lt;MAX_ITER)\n            {\n                iter++;\n                dcmplx temp = z;\n                z.re = temp.re*temp.re - temp.im*temp.im  +  c.re;\n                z.im = 2.0*temp.re*temp.im                +  c.im;\n\n                if (z.magnitude() &gt; 2.0) break;\n            }\n\n            // the 2D array \"dev_color\" stores how many iterations were required for divergence\n            // for points outside the Mandelbrot set, this is typically a small number\n            // points inside the set do not diverge and thus iter is a large number for such points\n\n            color[i+j*NX] = iter;\n\n            // GRAPHICS: the value of iter can be used to pick a suitable \"color\" when drawing the set\n        }\n    }\n}\n\n// ------------\n// main program\n\nint main(int argc, char* argv[])\n{\n    // allocate memory for a 2D array\n    int *color = new int[NX*NY];\n\n    // fill the 2D array with zeroes\n    for(int i=0;i&lt;NX;i++)\n    {\n        for(int j=0;j&lt;NY;j++)\n        {\n            color[i+j*NX] = 0;\n        }\n    }\n\n    // initialize parameters on the host\n    double xmin = -2, xmax = 1, ymin = -1.5, ymax = 1.5;\n\n    // check each pixel for membership and fill the 2D array accordingly\n    Mandelbrot(xmin,xmax,ymin,ymax,color);\n\n    return 0;\n}</pre>\n<strong>The CUDA approach</strong>\n\nIt is obvious that the CPU version is going to check each point in the 2D window for membership one after the other, in a serial fashion. However, all these calculations can be carried out in parallel because they are completely independent (embarrassingly parallel problem). With a modern GPU, one can launch thousands of parallel calculations simultaneously and, in theory, vastly reduce execution time compared to a single CPU.\n\nThe modified code using CUDA is provided below. Note how the loops inside the Mandelbrot function have been eliminated and this function (kernel) is launched on a GPU grid using the triple chevron notation in the main program. We also need to allocate space on the GPU for storing the 2D color array and copy this to the CPU once the GPU finishes filling it in.\n<pre class=\"lang:c++ decode:true\" title=\"GPU_Mandelbrot.cpp\">/*\n\nCalculating which points in the specified window of the complex plane\nlie inside the Mandelbrot set\n\nGPU version\n\n*/\n\n#include &lt;iostream&gt;\n#include &lt;complex&gt;\n#include &lt;cmath&gt;\n#include &lt;cstdlib&gt;\n\n// -----------------------------\n// declare some global variables\n\nconst int MAX_ITER = 200;    // maximum number of iterations\n\nconst int NX = 1000;  // number of points along X inside the window\nconst int NY = 1000;  // number of points along Y inside the window\n\n// -------------------------------------------------------\n// define a class for complex numbers and their operations\n\nclass dcmplx\n{\npublic:\n    double re;   // real component\n    double im;   // imaginary component\n\n// function to calculate the magnitude or absolute value of the complex number\n// this function is called from and executes on the device (GPU) \n\n__device__\ndouble magnitude()\n{\n    return pow((re*re + im*im),0.5);\n}\n\n};\n\n// ----------------------------------------------------------------------------------\n// function to check all points inside the specified window for membership in the set\n// this function is called from the host (CPU) but executes on the device (GPU)\n\n__global__\nvoid Mandelbrot(double xmin, double xmax, double ymin, double ymax, <strong>int *dev_color</strong>)\n{\n    double dx = (xmax - xmin)/NX; // grid spacing along X\n    double dy = (ymax - ymin)/NY; // grid spacing along Y\n\n    int i = blockIdx.x;\n    int j = blockIdx.y;\n\n    double x = xmin + (double) i*dx;   // actual x coordinate (real component)\n    double y = ymin + (double) j*dy;   // actual y coordinate (imaginary component)\n\n    dcmplx c;\n    c.re = x;\n    c.im = y;\n\n    dcmplx z;\n    z.re = 0.0;\n    z.im = 0.0;\n\n    // ---------------\n    // z &lt;---- z*z + c\n\n    int iter = 0;\n\n    while(iter&lt;MAX_ITER)\n    {\n        iter++;\n        dcmplx temp = z;\n        z.re = temp.re*temp.re - temp.im*temp.im  +  c.re;\n        z.im = 2.0*temp.re*temp.im                +  c.im;\n\n        if (z.magnitude() &gt; 2.0) break;\n    }\n\n    // the 2D array \"dev_color\" stores how many iterations were required for divergence\n    // for points outside the Mandelbrot set, this is typically a small number\n    // points inside the set do not diverge and thus iter is a large number for such points\n\n    dev_color[i+j*NX] = iter;\n\n    // GRAPHICS: the value of iter can be used to pick a suitable \"color\" when drawing the set\n}\n\n// ---------------------------------------\n// main program executes on the host (CPU)\n\nint main(int argc, char* argv[])\n{\n    // allocate memory for a 2D array on the host (CPU)\n    int *color = new int[NX*NY];\n\n    // fill the 2D array with zeroes\n    for(int i=0;i&lt;NX;i++)\n    {\n        for(int j=0;j&lt;NY;j++)\n        {\n            color[i+j*NX] = 0;\n        }\n    }\n\n    // allocate memory on the device (GPU)\n    int *dev_color;\n    cudaMalloc((void **) &amp;dev_color, NX*NY*sizeof(int));\n\n    // initialize parameters on the host\n    double xmin = -2, xmax = 1, ymin = -1.5, ymax = 1.5;\n\n    // check each pixel for membership and fill the 2D array accordingly\n    // this kernel is executed in parallel using NX*NY blocks on the GPU\n\n    dim3 grid(NX,NY);\n\n    Mandelbrot&lt;&lt;&lt;grid,1&gt;&gt;&gt;(xmin,xmax,ymin,ymax,dev_color);\n\n    // copy the 2D array from device (GPU) to host (CPU)\n    cudaMemcpy(color, dev_color, NX*NY*sizeof(int), cudaMemcpyDeviceToHost);\n\n    return 0;\n}</pre>\n<strong>SPEED UP</strong>\n\nThis is a tricky beast to define, but let us look at some of the results from running the CPU code and the GPU code. If we only focus on the kernel we ran on the GPU and compare it to the same function running on the CPU, <strong>the GPU version is ~400X faster!</strong>\n\n<a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/Slide1.png\"><img class=\"alignnone size-medium wp-image-3834\" alt=\"Slide1\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/Slide1-300x225.png\" width=\"300\" height=\"225\" /></a>\n\nBut, as seen in the picture above, the GPU version also has a significant amount of overhead in allocating memory on the device using \"cudaMalloc\" and in transferring data back to the CPU using \"cudaMemcpy\". You should keep this in mind while considering how to redesign your C/C++ code. The rule of thumb is to minimize data transfers to/from the CPU to realize the full potential of GPU acceleration.\n\n<strong>CONCLUSIONS</strong>\n\nYou can see that porting an existing C++ code to CUDA is not so difficult. But it does involve rewriting portions of the code and moving data to and from the CPU memory to the GPU memory. In addition, there are several options for deploying the kernel (in this case, the Mandelbrot function that runs on the GPU is called a kernel) and making optimal use of the hardware is critical for achieving the maximum performance possible.\n\nA lot of this guesswork can be eliminated by using ArrayFire. This library can be used in conjunction with your existing C/C++/Fortran 90/Python code and the learning curve is much easier compared to writing your own CUDA/OpenCL code. In Part 2 of this blog, I will outline how to use ArrayFire in the original C++ code and make full use of GPU acceleration without writing a single line of CUDA code.','Mandelbrot Set - Porting a CPU code to the GPU - Part 1 of 2','','pending','open','open','','mandelbrot-set-cpu-vs-gpu','','','2013-03-19 19:16:54','2013-03-19 23:16:54','',0,'http://blog.accelereyes.com/blog/?p=3771',0,'post','',0),(3807,4,'2013-03-20 02:24:16','2013-03-20 06:24:16','Day 2 at GTC was high energy. The after parties are still thumping. It was a hive of GPU activity.\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/accelereyes_software_shop_cuda_and_opencl.jpg\"><img class=\"aligncenter  wp-image-3809\" alt=\"accelereyes_software_shop_cuda_and_opencl\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/accelereyes_software_shop_cuda_and_opencl-1024x536.jpg\" width=\"717\" height=\"375\" /></a></p>\nHere are 7 of the highlights we\'ve collected from our team on the second day of GTC 2013:\n<ul>\n	<li>Jen-Hsun Huang of NVIDIA gave an awesome keynote. He covered 5 topics:\n<ul>\n	<li>Computer graphics - Awesome life-like renderings of human faces (<a href=\"https://twitter.com/accelereyes/status/314050691381460994\">here</a> and <a href=\"https://twitter.com/accelereyes/status/314051655152857088\">here</a>)</li>\n	<li>GPU computing update - 1.6 million CUDA downloads so far, tons of interesting GPU-accelerated applications (including matchmaking website fish.com, a diamond cutting company, Shazam, Cortexica, and others), roadmap update (see the next highlight)</li>\n	<li>Tegra roadmap update - (see the 3rd highlight)</li>\n	<li>Remote graphics update - using GPUs to render things remotely and pipe them to the monitors of user\'s thin clients</li>\n	<li>NVIDIA GRID VCA product announcement - NVIDIA will sell their own 4U system with GPUs for visual computing applications</li>\n</ul>\n</li>\n	<li>Tesla Roadmap - <a href=\"https://twitter.com/accelereyes/status/314062179500441600\">it was unveiled</a>. Maxwell architecture is next with unified memory. Volta will come afterward with stacked DRAM.</li>\n	<li>Tegra Roadmap - <a href=\"https://twitter.com/accelereyes/status/314064527119495169\">it was unveiled</a>. CUDA will be supported on the next Tegra release, codenamed \"Logan,\" and will have a Kepler GPU. Starting immediately, a dev system (Logan\'s twin sister), called \"Kayla,\" will be available to help people start developing applications for Logan. Parker comes after Logan and will have a Denver CPU and a Maxwell GPU.</li>\n	<li>Exhibits - Awesome conversations. Great food. Tons of people using ArrayFire!</li>\n	<li>Igor Podladtchiko of Spectraseis.com gave an awesome talk on \"Memory Bound Wave Propagation at Hardware Limit.\" He discussed his approach to optimizing some wave propagation kernels, implementing a number of three-dimensional differential equations modeling wave propagation in solids. He was clear and helpful in style and content, and we thoroughly enjoyed the talk.</li>\n	<li>Neil Trevett of NVIDIA and Khronos gave a great talk on \"Khronos Open API Standards - The Foundation for Mobile Innovation.\" Most people would think a standards talk would be quite boring, but our team walked away impressed.</li>\n	<li>Yuan Lin of NVIDIA gave a nice talk on \"Building Accelerated DSLs and GPU Compilers with libNVVM.\" We love anything to do with high-productivity performance from GPUs!</li>\n</ul>\nAnother awesome day. We look forward to more tomorrow, followed by relaxation in the NVIDIA casino with fake money.\n\nWhat highlights did you enjoy the second day at GTC 2013?\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/18/7-highlights-of-gtc-2013-day-1-of-4/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153347976_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/18/7-highlights-of-gtc-2013-day-1-of-4/\" target=\"_blank\">7 Highlights of GTC 2013 - Day 1 of 4</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://go.theregister.com/feed/www.theregister.co.uk/2013/03/19/nvidia_tegra_logan_and_parker/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153567526_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://go.theregister.com/feed/www.theregister.co.uk/2013/03/19/nvidia_tegra_logan_and_parker/\" target=\"_blank\">Nvidia reveals two future Tegra mobile ARM processors</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.slashgear.com/nvidia-tegra-logan-detailed-with-game-changing-cuda-integration-19274630/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153511784_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.slashgear.com/nvidia-tegra-logan-detailed-with-game-changing-cuda-integration-19274630/\" target=\"_blank\">NVIDIA Tegra \"Logan\" detailed with game-changing CUDA integration</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.anandtech.com/show/6845/nvidia-updates-tegra-roadmap-details-at-gtc-logan-and-parker-detailed\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153510837_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.anandtech.com/show/6845/nvidia-updates-tegra-roadmap-details-at-gtc-logan-and-parker-detailed\" target=\"_blank\">NVIDIA Updates Tegra Roadmap Details at GTC - Logan and Parker Detailed</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://phandroid.com/2013/03/19/nvidia-logan-parker-roadmap/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153513152_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://phandroid.com/2013/03/19/nvidia-logan-parker-roadmap/\" target=\"_blank\">NVIDIA details Tegra roadmap, introduces Logan and Parker mobile platforms</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.slashgear.com/nvidia-tegra-parker-blasts-forth-aside-mini-arm-computer-kayla-19274633/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153511775_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.slashgear.com/nvidia-tegra-parker-blasts-forth-aside-mini-arm-computer-kayla-19274633/\" target=\"_blank\">NVIDIA Tegra \"Parker\" blasts forth aside mini ARM computer \"Kayla\"</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.slashgear.com/nvidia-ceo-races-toward-gpu-computing-tipping-point-at-gtc-2013-19274623/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153511787_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.slashgear.com/nvidia-ceo-races-toward-gpu-computing-tipping-point-at-gtc-2013-19274623/\" target=\"_blank\">NVIDIA CEO races toward GPU Computing \"tipping point\" at GTC 2013</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=f63bd86a-7c98-4ae5-9fcc-fc4cd0f81fe5\" /></div>','7 Highlights of GTC 2013 - Day 2 of 4','','publish','open','open','','7-highlights-of-gtc-2013-day-2-of-4','','','2013-03-20 02:24:16','2013-03-20 06:24:16','',0,'http://blog.accelereyes.com/blog/?p=3807',0,'post','',0),(3842,4,'2013-03-21 03:18:39','2013-03-21 07:18:39','Day 3 at GTC was awesome. It was super hard to narrow down our list to just 7 highlights. For instance, the <a href=\"https://twitter.com/alpfann/status/314516174195011584/photo/1\">stress ball pyramid</a> in our booth does not count. Neither does the massive ArrayFire poster in front of the keynote hall.\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/photo.jpg\"><img class=\"aligncenter  wp-image-3848\" alt=\"photo\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/photo-1024x419.jpg\" width=\"717\" height=\"293\" /></a></p>\nHere are 7 of the highlights we\'ve collected from our team on the third day of GTC 2013:\n<ul>\n	<li>Professor Erez Lieberman Aiden of Baylor and Rice Universities gave a great keynote on \"Parallel Processing of the Genomes, by the Genomes and for the Genomes.\" He discussed how folding of genes and interactions between multiple folded genes can impact genetic expressions. It\'s not just about the composition of the gene, but also how the gene folds. It turns out that Professor Aiden saw us pitch our company shortly after our founding back in 2007. We\'ve both come a long way with GPUs since those days!</li>\n	<li>Awesome exhibit floor demos:\n<ul>\n	<li><a href=\"http://www.computefaster.com/\">CreativeC</a> was showing ArrayFire in a 3 node, 3 GPUs/node environment; we\'ll post a video soon about that demo</li>\n	<li><a href=\"http://vrx.ca/\">VRX</a> demoed the world\'s most advanced racing simulator, <a href=\"http://www.slashgear.com/vxr-racing-sim-possibly-more-realistic-than-actually-driving-195809/\">possibly more realistic than actually driving</a></li>\n	<li><a href=\"http://www.oculusvr.com\">Oculus VR</a> demoed a virtual reality headset with a great sense of presence in the game</li>\n	<li><a href=\"http://www.zillians.com/running-cuda-on-raspberry-pi/\">Zillian Labs</a> showed a virtual GPU environment running CUDA on a Raspberry Pi, which seamlessly offloaded the computations to a remotely attached GPU; they have a special libcudart to make that happen</li>\n</ul>\n</li>\n	<li>Brian Cabral of NVIDIA gave a great talk on \"Tegra 4 Computational Photography Architecture and Always-on HDR.\" Chimera looks like a great package for making computational photography easier. We have several photographers in AccelerEyes; so you will see some related functions in ArrayFire soon!</li>\n	<li>Kevin Tubbs of Dell gave a great talk on \"Accelerating Shallow Water Flow and Mass Transport Using Lattice Boltzmann Methods on GPUs,\" using AccelerEyes libraries. There is a <a href=\"https://www.accelereyes.com/arrayfire/c/examples_2pde_2swe_8cpp-example.htm\">related example in ArrayFire</a>.</li>\n	<li>Several of our engineers walked away impressed by a discussion with Kronos group members. Open standards are valuable to helping many of our customers and make a big impact on moving the industry forward.</li>\n	<li>Great meetings - the day was full of customer meetings at various tables throughout the venue. Wonderful to meet in-person with all these cutting edge scientists, engineers, and financial analysts.</li>\n	<li>Casino Night Party - while almost all of us quickly lost the free, fake casino money, one of our team members raked in the winnings at the poker table and walked away with a $100 prize! Some of the rest of us drowned our sorrows in free booze.</li>\n</ul>\nAnother excellent day. We look forward to the finale tomorrow.\n\nWhat highlights did you enjoy the third day at GTC 2013?\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=6d2b2724-46db-4b75-8554-304e235663c3\" /></div>','7 Highlights of GTC 2013 - Day 3 of 4','','publish','open','open','','7-highlights-of-gtc-2013-day-3-of-4','','','2013-03-21 03:18:39','2013-03-21 07:18:39','',0,'http://blog.accelereyes.com/blog/?p=3842',0,'post','',0),(3876,4,'2013-03-21 22:00:13','2013-03-22 02:00:13','Day 4 at GTC is always a little less hyped than the first 3 days, but it is when some of the best sessions are found.\n\nHere are 7 of the highlights we\'ve collected from our team on the last day of GTC 2013:\n\nPaulius Micikevicius of NVIDIA gave a great talk entitled, \"Performance Optimization: Programming Guidelines and GPU Architecture Details Behind Them.\" It was so great, we have 2 highlights from this talk.\n<ul>\n	<li>The first Paulius highlight is the information about how instruction level parallelism is essential to fully take advantage of Kepler GPUs. Paulius gave a clear presentation on these difficult concepts.</li>\n	<li>The second Paulius highlight is the thorough treatment of memory hierarchy for Kepler. It is very detailed and Paulius did an excellent job at communicating good information on how to best use the Kepler memory hierarchy. These are things that are hard to learn from the internet and documentation.</li>\n</ul>\nLars Nyland and Stephen Jones of NVIDIA gave an excellent entitled, \"Understanding and Using Atomic Memory Operations.\" It was so great, we have 2 highlights from this talk.\n<ul>\n	<li>The first Nyland/Jones highlight is the understanding gained about using atomic memory operations. Atomic operations are not as bad as they look. Great information was conveyed about when and why to use them.</li>\n	<li>The second Nyland/Jones highlight was the explanation of how to use skip lists used for sorting. A great tip for CUDA programming.</li>\n</ul>\nThe remaining 3 highlights include:\n<ul>\n	<li>Daniel Egloff and Xiang Zheng of QuantAlea GmbH gave a nice talk on \"Dynamic CUDA with F# - New Dimensions for GPU Computing on .NET.\" It was an interesting financial application talk and the use of NVVM was intriguing.</li>\n	<li>Meeting GPU conference regulars. Thursday is a great day to connect with the regular buddies that attend all these shows along with us. It\'s always nice to connect.</li>\n	<li>Reflecting on the show with a closing dinner limited to AccelerEyes employees only. It was a great to enjoy time with just our team in a new city, at a new restaurant, with a lot to reflect upon and stories to tell about the show.</li>\n</ul>\nDay 4 was a great finale to GTC. We\'ve signed up as a sponsor again for next year!\n\nWhat highlights did you enjoy the last day at GTC 2013?\n<div></div>\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/18/7-highlights-of-gtc-2013-day-1-of-4/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153347976_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/18/7-highlights-of-gtc-2013-day-1-of-4/\" target=\"_blank\">7 Highlights of GTC 2013 - Day 1 of 4</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/20/7-highlights-of-gtc-2013-day-2-of-4/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153670138_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/20/7-highlights-of-gtc-2013-day-2-of-4/\" target=\"_blank\">7 Highlights of GTC 2013 - Day 2 of 4</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/21/7-highlights-of-gtc-2013-day-3-of-4/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153934357_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/21/7-highlights-of-gtc-2013-day-3-of-4/\" target=\"_blank\">7 Highlights of GTC 2013 - Day 3 of 4</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/03/21/rob-farber-on-the-far-reaching-hpc-implications-from-gtc-2013/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_14_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/03/21/rob-farber-on-the-far-reaching-hpc-implications-from-gtc-2013/\" target=\"_blank\">Rob Farber on the Far-reaching HPC Implications from GTC 2013</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blogs.nvidia.com/2013/03/nvidia-ceo-updates-nvidias-roadmap/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153909691_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blogs.nvidia.com/2013/03/nvidia-ceo-updates-nvidias-roadmap/\" target=\"_blank\">NVIDIA CEO Updates NVIDIA\'s Roadmap</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://insidehpc.com/2013/03/21/gtc-2013-arm-gpu-gpuriffic-says-barcelona-scc/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/noimg_85_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://insidehpc.com/2013/03/21/gtc-2013-arm-gpu-gpuriffic-says-barcelona-scc/\" target=\"_blank\">GTC 2013: ARM + GPU = GPU\'riffic, says Barcelona SCC</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=087ef3f8-bce8-4b98-bfb0-75dfd0a0d72e\" /></div>','7 Highlights of GTC 2013 - Day 4 of 4','','publish','open','open','','7-highlights-of-gtc-2013-day-4-of-4','','','2013-03-21 22:00:13','2013-03-22 02:00:13','',0,'http://blog.accelereyes.com/blog/?p=3876',0,'post','',0),(3899,1,'2013-06-24 15:16:43','0000-00-00 00:00:00','Laplace\'s equation is one of the simplest possible partial differential equations to solve numerically. It applies to various physical processes like electric potentials and temperature fields. In this blog, I will highlight a simple numerical scheme to solve this equation referred to as Jacobi iteration. Starting with a simple CPU based C++ code, I will highlight how easy it is to port this code to the GPU using CUDA.\n\nWe\'ll focus on a particular example from heat transfer, where the goal is to solve for the steady-state temperature field T(x,y) and the solution domain is a square of size L in the X-Y plane. The boundary conditions are as follows:\n<ul>\n	<li>Left edge: x = 0, T(0, y) = 1</li>\n	<li>Right edge: x = L, T(L, y) = 0</li>\n	<li>Bottom edge: y = 0, T(x,0) = 0</li>\n	<li>Top edge: y = L, T(x,L) = 0</li>\n</ul>\nWithout going into too many details, the core algorithm for solving the temperature field inside the domain boils down to this simple equation:\n\nT(i,j) = 0.25 * [T(i-1,j) + T(i+1,j) + T(i,j-1) + T(i,j+1)]       -------   (1)\n\nHere, it is assumed that the square domain is represented using a computational grid of N x N points, equally spaced along X and Y. Equation (1) essentially states that the temperature value at any node point equals the arithmetic average of the 4 neighboring temperature values. The value at the boundary node points are known from the boundary conditions and the objective is to iteratively find the interior T(i,j) values using Eq.(1).\n\n<strong>The CPU approach</strong>\n\nWe define two 2D arrays, T(1:N,1:N) and T_new(1:N,1:N) and essentially loop over all interior node points in the domain, updating T_new(i,j) at each interior node point using values from T(i,j) from the previous iteration. The core Jacobi function from the CPU code is copied below for reference.\n<pre class=\"lang:default decode:true\">void Jacobi(float* T, float* T_new)\n{\n    const int MAX_ITER = 1000;\n    int iter = 0;\n\n    while(iter &lt; MAX_ITER)\n    {\n        for(int i=1; i&lt;NX-1; i++)\n        {\n            for(int j=1; j&lt;NY-1; j++)\n            {\n                float T_E = T[(i+1) + NX*j];\n                float T_W = T[(i-1) + NX*j];\n                float T_N = T[i + NX*(j+1)];\n                float T_S = T[i + NX*(j-1)];\n                T_new[i+NX*j] = 0.25*(T_E + T_W + T_N + T_S);\n            }\n        }\n\n        for(int i=1; i&lt;NX-1; i++)\n        {\n            for(int j=1; j&lt;NY-1; j++)\n            {\n                float T_E = T_new[(i+1) + NX*j];\n                float T_W = T_new[(i-1) + NX*j];\n                float T_N = T_new[i + NX*(j+1)];\n                float T_S = T_new[i + NX*(j-1)];\n                T[i+NX*j] = 0.25*(T_E + T_W + T_N + T_S);\n            }\n        }\n        iter+=2;\n    }\n}</pre>\nIn this implementation, we update T_new(i,j) using values from T(i,j) and then update T(i,j) using values from T_new(i,j). This essentially completes two Jacobi iterations. We keep going until a set number of maximum iterations is reached (1,000 in the above code snippet). The CPU implementation is slow mainly because we update points in a sequential fashion, one after the other. But this was pretty much the best you could hope for before parallel computing.\n\n<strong>The GPU approach: CUDA</strong>\n\nNotice that each update of T_new(i,j) in the above code is independent of every other update. So what if we could update all node points in parallel at the same time? This is exactly what we do using GPUs. The entire CUDA code for solving this problem is copied below for reference.\n<pre class=\"lang:default decode:true\">/*\n\nSolution of the Laplace equation for heat conduction in a square plate\n\n*/\n\n#include &lt;iostream&gt;\n\n// global variables\n\nconst int NX = 256;      // mesh size (number of node points along X)\nconst int NY = 256;      // mesh size (number of node points along Y)\n\nconst int MAX_ITER=1000;  // number of Jacobi iterations\n\n// device function to update the array T_new based on the values in array T_old\n// note that all locations are updated simultaneously on the GPU \n__global__ void Laplace(float *T_old, float *T_new)\n{\n    // compute the \"i\" and \"j\" location of the node point\n    // handled by this thread\n\n    int i = blockIdx.x * blockDim.x + threadIdx.x ;\n    int j = blockIdx.y * blockDim.y + threadIdx.y ;\n\n    // get the natural index values of node (i,j) and its neighboring nodes\n                                //                         N \n    int P = i + j*NX;           // node (i,j)              |\n    int N = i + (j+1)*NX;       // node (i,j+1)            |\n    int S = i + (j-1)*NX;       // node (i,j-1)     W ---- P ---- E\n    int E = (i+1) + j*NX;       // node (i+1,j)            |\n    int W = (i-1) + j*NX;       // node (i-1,j)            |\n                                //                         S \n\n    // only update \"interior\" node points\n    if(i&gt;0 &amp;&amp; i&lt;NX-1 &amp;&amp; j&gt;0 &amp;&amp; j&lt;NY-1) {\n        T_new[P] = 0.25*( T_old[E] + T_old[W] + T_old[N] + T_old[S] );\n    }\n}\n\n// initialization\n\nvoid Initialize(float *TEMPERATURE)\n{\n    for(int i=0;i&lt;NX;i++) {\n        for(int j=0;j&lt;NY;j++) {\n            int index = i + j*NX;\n            TEMPERATURE[index]=0.0;\n        }\n    }\n\n    // set left wall to 1\n\n    for(int j=0;j&lt;NY;j++) {\n        int index = j*NX;\n        TEMPERATURE[index]=1.0;\n    }\n}\n\nint main(int argc,char **argv)\n{\n    float *T;          // pointer to host (CPU) memory\n    float *_T1, *_T2;  // pointers to device (GPU) memory\n\n    // allocate a \"pre-computation\" T array on the host\n    float *T = new float [NX*NY];\n\n    // initialize array on the host\n    Initialize(T);\n\n    // allocate storage space on the GPU\n    cudaMalloc((void **)&amp;_T1,NX*NY*sizeof(float));\n    cudaMalloc((void **)&amp;_T2,NX*NY*sizeof(float));\n\n    // copy (initialized) host arrays to the GPU memory from CPU memory\n    cudaMemcpy(_T1,T,NX*NY*sizeof(float),cudaMemcpyHostToDevice);\n    cudaMemcpy(_T2,T,NX*NY*sizeof(float),cudaMemcpyHostToDevice);\n\n    // assign a 2D distribution of CUDA \"threads\" within each CUDA \"block\"    \n    int ThreadsPerBlock=16;\n    dim3 dimBlock( ThreadsPerBlock, ThreadsPerBlock );\n\n    // calculate number of blocks along X and Y in a 2D CUDA \"grid\"\n    dim3 dimGrid( ceil(float(NX)/float(dimBlock.x)), ceil(float(NY)/float(dimBlock.y)), 1 );\n\n    // begin Jacobi iteration\n    int k = 0;\n    while(k&lt;MAX_ITER) {\n        Laplace&lt;&lt;&lt;dimGrid, dimBlock&gt;&gt;&gt;(_T1,_T2);   // update T1 using data stored in T2\n        Laplace&lt;&lt;&lt;dimGrid, dimBlock&gt;&gt;&gt;(_T2,_T1);   // update T2 using data stored in T1\n        k+=2;\n    }\n\n    // copy final array to the CPU from the GPU \n    cudaMemcpy(T,_T2,NX*NY*sizeof(float),cudaMemcpyDeviceToHost);\n    cudaThreadSynchronize();\n/*\n    // print the results to screen\n    for (int j=NY-1;j&gt;=0;j--) {\n        for (int i=0;i&lt;NX;i++) {\n            int index = i + j*NX;\n            std::cout &lt;&lt; T[index] &lt;&lt; \" \";\n        }\n        std::cout &lt;&lt; std::endl;\n    }\n*/\n    // release memory on the host \n    delete T;\n\n    // release memory on the device \n    cudaFree(_T1);\n    cudaFree(_T2);\n\n    return 0;\n}</pre>\nNotice that the basic instruction for updating the node point using the average of its neighbors is identical in the GPU code. However, the loop over i and j has disappeared in the kernel (function running on the GPU). The key point to understand is that this kernel is executed in parallel using several threads on the GPU using the triple chevron notation &lt;&lt;&lt;   &gt;&gt;&gt;.\n\nEach thread figures out which node point it is updating and updates the value in the appropriate memory location. When all threads are done updating their node point, we move on to the next iteration. Obviously, the GPU approach is faster than the CPU approach, but there is also some time spent in allocating resources on the GPU and in copying data from the CPU to the GPU. Thus, the speed up in the actual execution of the Jacobi iteration may not become apparent until the mesh size is large.\n\n<strong>The GPU approach: ArrayFire</strong>\n\nNow that you have a feel of how to write a simple CUDA kernel for implementing Jacobi iteration, the final step in our journey will be to implement the GPU version of this code using the ArrayFire library. At the core of the code to follow is a ArrayFire function called convolution. This essentially alters an array (1D, 2D or 3D) using a pre-defined \"convolution kernel\". In this particular example, we have a 3 x 3 kernel which tells the code how to calculate the new value at a certain location using neighboring values. If we are only concerned with averaging neighbors along the vertical and horizontal directions, this kernel can be visualized as follows:\n<pre class=\"lang:default decode:true\">0      1/4      0\n\n1/4     0      1/4\n\n0      1/4      0</pre>\nDuring the convolution operation, this kernel is used to update the value at the central location, using the weights for the neighboring points as provided above. This is just another way of implementing Eq.(1) above.\n\nThe ArrayFire code itself is much simpler than the CUDA version copied above. The complete code for implementing Jacobi iteration is provided below.\n<pre class=\"lang:default decode:true\">#include &lt;stdio.h&gt;\n#include &lt;arrayfire.h&gt;\nusing namespace af;\n\nconst int N = 4096;\n\nint main(int argc, char** argv)\n{\n    array T = constant(0,N,N);\n    T(seq(1,end-1),0) = 1;\n\n//  print(T);\n\n    float fval[]={0,0.25,0,0.25,0,0.25,0,0.25,0};\n    array f(3,3,fval);\n\n    int iter=0;\n    while(iter&lt;1000) {\n        T= convolve(T, f);\n        T(seq(1,end-1),0) = 1;\n        T(seq(1,end-1),end) = 0;\n        T(0,seq(1,end-1)) = 0;\n        T(end,seq(1,end-1)) = 0;\n        iter+=1;\n    }\n\n//  print(T);\n\n    return 0;\n}</pre>\n&nbsp;\n\n<strong>RESULTS</strong>\n\nIn the figure below, a comparison of the run-time between the CPU and the GPU is attached. For the largest grid shown below, we obtained a speed up of 143X for the CUDA version compared to the CPU code.\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/Screen-Shot-2013-03-26-at-5.46.18-PM.png\"><img class=\"aligncenter  wp-image-3942\" alt=\"Screen Shot 2013-03-26 at 5.46.18 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/Screen-Shot-2013-03-26-at-5.46.18-PM-1024x781.png\" width=\"614\" height=\"469\" /></a></p>\nIt will be apparent that the GPU version using CUDA is way faster than the CPU version for mesh sizes larger than 256 x 256. In reality, as mentioned above, the actual Jacobi iteration (or convolution) part is <em>always</em> faster than the CPU version (for both raw CUDA and ArrayFire). It will also be seen that the raw CUDA version is a little faster (~2X) than the ArrayFire version. This is mainly because the convolution operation in ArrayFire accounts for all neighbors of the point and the point itself (9 values) while the raw CUDA version skips these additional calculations (which sum to zero).\n\nBut the simplicity of the ArrayFire version is a big win for those new to GPU computing and those who wish to get the benefits of GPU computing without writing their own CUDA kernels.\n\nTo conclude, this example illustrated how a simple partial differential equation (PDE) can be solved on the GPU provided we can execute it as a \"single instruction on multiple data\" (SIMD) algorithm. The basic idea of creating a workspace (array) on the GPU and updating elements of this array in parallel can be applied even to more complex PDEs and algorithms, provided they can be written in a SIMD fashion. The only limitation in this approach is the amount of memory available on the GPU.\n\n&nbsp;','2D Heat Conduction - Solving Laplace\'s Equation on the CPU and the GPU','','pending','open','open','','','','','2013-06-24 15:16:43','0000-00-00 00:00:00','',0,'http://blog.accelereyes.com/blog/?p=3899',0,'post','',0),(3920,1,'2013-03-25 16:25:48','0000-00-00 00:00:00','Over the last couple of decades, the lattice Boltzmann method (LBM) has grown into a potent alternative methodology for computational fluid dynamics (CFD). As such, CFD has been traditionally developed using the Navier-Stokes equations as a starting point. But there are several advantages to using the LBM, chiefly the extreme simplicity of the approach (easy coding) and the inherently parallel nature of the computations (scales easily to large machines). The LBM is akin to an explicit numerical scheme, in that the variable at the new time level can be calculated based on the (local) values of the variable at the previous time level.\n\nUnlike regular CFD, where the primary dependent variables are the velocity components, the density and the pressure, the LBM works with particle velocity distribution functions, or PDFs. A simplified way of understanding the LBM is to imagine that there are a set of discrete points in space (lattice points) and there is a set of finite directions at each lattice point along which fluid particles can move or \"stream\". During each time step, particles \"stream\" or hop from one lattice point to another along these finite directions and then \"collide\" with each other, conserving mass and momentum. This collision event leads to a new distribution of particles, which then streams again to neighboring lattice points. For more information about the LBM, you can refer to several excellent review articles available on the internet.\n\nA simple application of the LBM is to solve for two-dimensional flow inside a square cavity. In this problem, the square cavity is completely filled with a constant viscosity fluid. The three side walls of the cavity are fixed and the top wall suddenly starts moving to the right with a constant velocity, dragging the adjacent fluid along with it and causing a re-circulating flow to develop inside the cavity. In this blog, we will provide a canonical LBM implementation of this problem (for low Reynolds numbers) and provide detailed CPU and GPU versions of the code so interested users can see for themselves how easy it is to migrate from the C++ (CPU version)  to the CUDA (GPU version) and the amazing speed-up than can result from doing so.\n\n<strong>The CPU approach</strong>\n\nA simple LBM code that can be implemented on the CPU is copied below. This 2D implementation uses the D2Q9 model, which means we have a 2 dimensional model with 9 discrete velocity directions.\n<pre class=\"lang:default decode:true\">/*\n\nSimulation of flow inside a 2D square cavity\nusing the lattice Boltzmann method (LBM)\n\nWritten by:       Abhijit Joshi (abhijit@accelereyes.com)\n\nLast modified on: Saturday, March 23 @ 6:41 pm\n\nBuild instructions: g++ cpu_lbm.cpp -o lbmCPU.x\n\nRun instructions: ./lbmCPU.x\n\n*/\n\n#include&lt;iostream&gt;\n\n// problem parameters\nconst int N = 512;            // number of node points along X and Y (cavity length in lattice units)\nconst int TIME_STEPS = 1000;  // number of time steps for which the simulation is run\n\nconst int NDIR = 9;           // number of discrete velocity directions used in the D2Q9 model\n\nconst double DENSITY = 2.7;          // fluid density in lattice units\nconst double LID_VELOCITY = 0.05;    // lid velocity in lattice units\nconst double REYNOLDS_NUMBER = 100;  // Re = \n\nint main(int argc, char *argv[])\n{\n    // the base vectors and associated weight coefficients\n    double *ex = new double[NDIR];\n    double *ey = new double[NDIR];\n    double *alpha = new double[NDIR];\n\n    ex[0] =  0.0;   ey[0] =  0.0;   alpha[0] = 4.0 /  9.0;\n    ex[1] =  1.0;   ey[1] =  0.0;   alpha[1] = 1.0 /  9.0;\n    ex[2] =  0.0;   ey[2] =  1.0;   alpha[2] = 1.0 /  9.0;\n    ex[3] = -1.0;   ey[3] =  0.0;   alpha[3] = 1.0 /  9.0;\n    ex[4] =  0.0;   ey[4] = -1.0;   alpha[4] = 1.0 /  9.0;\n    ex[5] =  1.0;   ey[5] =  1.0;   alpha[5] = 1.0 / 36.0;\n    ex[6] = -1.0;   ey[6] =  1.0;   alpha[6] = 1.0 / 36.0;\n    ex[7] = -1.0;   ey[7] = -1.0;   alpha[7] = 1.0 / 36.0;\n    ex[8] =  1.0;   ey[8] = -1.0;   alpha[8] = 1.0 / 36.0;\n\n    // anti-vector direction for each base vector direction\n    // (useful for implementing the bounce-back scheme)\n    int *ant = new int[NDIR];\n\n    ant[0] = 0;      //      6        2        5\n    ant[1] = 3;      //               ^       \n    ant[2] = 4;      //               |\n    ant[3] = 1;      //               |  \n    ant[4] = 2;      //      3 &lt;----- 0 -----&gt; 1\n    ant[5] = 7;      //               |\n    ant[6] = 8;      //               |\n    ant[7] = 5;      //               v\n    ant[8] = 6;      //      7        4        8\n\n    // distribution functions\n    double *f = new double[N*N*NDIR];\n    double *feq = new double[N*N*NDIR];\n    double *f_new = new double[N*N*NDIR];\n\n    // density\n    double *rh = new double[N*N];\n\n    // velocity components \n    double *ux = new double[N*N];\n    double *uy = new double[N*N];\n\n    // initialize density and velocity fields inside the cavity\n    for(int i=0;i&lt;N;i++) {\n        for(int j=0;j&lt;N;j++) {\n            rh[i+N*j] = DENSITY;\n            ux[i+N*j] = 0;\n            uy[i+N*j] = 0;\n        }\n    }\n    for(int i=0;i&lt;N;i++) ux[i+N*(N-1)] = LID_VELOCITY;\n\n    // assign initial values for distribution functions\n    for(int i=0;i&lt;N;i++) {\n        for(int j=0;j&lt;N;j++) {\n            int ixy = i+N*j;\n            for(int dir=0;dir&lt;NDIR;dir++) {\n                int index = i+j*N+dir*N*N;\n                double edotu = ex[dir]*ux[ixy] + ey[dir]*uy[ixy];\n                double udotu = ux[ixy]*ux[ixy] + uy[ixy]*uy[ixy];\n                feq[index] = rh[ixy] * alpha[dir] * (1 + 3*edotu + 4.5*edotu*edotu - 1.5*udotu);\n                f[index] = feq[index];\n                f_new[index] = feq[index];\n            }\n        }\n    }\n\n    // calculate fluid viscosity based on the Reynolds number\n    double kinematicViscosity = LID_VELOCITY * (double)N / REYNOLDS_NUMBER;\n\n    // calculate relaxation time tau\n    double tau =  0.5 + 3.0 * kinematicViscosity;\n\n    // time integration\n    int time=0;\n    while(time&lt;TIME_STEPS) {\n\n        time++;\n\n        // collision\n        for(int i=1;i&lt;N-1;i++) {\n            for(int j=1;j&lt;N-1;j++) {\n                int ixy = i+N*j;\n                for(int dir=0;dir&lt;NDIR;dir++) {\n                    int index = i+j*N+dir*N*N;\n                    double edotu = ex[dir]*ux[ixy] + ey[dir]*uy[ixy];\n                    double udotu = ux[ixy]*ux[ixy] + uy[ixy]*uy[ixy];\n                    feq[index] = rh[ixy] * alpha[dir] * (1 + 3*edotu + 4.5*edotu*edotu - 1.5*udotu);\n                }\n            }\n        }\n\n        // streaming from interior node points\n        for(int i=1;i&lt;N-1;i++) {\n            for(int j=1;j&lt;N-1;j++) {\n                for(int dir=0;dir&lt;NDIR;dir++) {\n\n                    int index = i+j*N+dir*N*N;   // (i,j,dir)\n                    int index_new = (i+ex[dir]) + (j+ey[dir])*N + dir*N*N;\n                    int index_ant = i + j*N + ant[dir]*N*N;\n\n                    // post-collision distribution at (i,j) along \"dir\"\n                    double f_plus = f[index] - (f[index] - feq[index])/tau;\n\n                    if((i+ex[dir]==0) || (i+ex[dir]==N-1) || (j+ey[dir]==0) || (j+ey[dir]==N-1)) {\n                        // bounce back\n                        int ixy = i+ex[dir] + N*(j+ey[dir]);\n                        double ubdote = ux[ixy]*ex[dir] + uy[ixy]*ey[dir];\n                        f_new[index_ant] = f_plus - 6.0 * DENSITY * alpha[dir] * ubdote;\n                    }\n                    else {\n                        // stream to neighbor\n                        f_new[index_new] = f_plus;\n                    }\n                }\n            }\n        }\n\n        // push f_new into f\n        for(int index=0;index&lt;N*N*NDIR;index++) f[index] = f_new[index];\n\n        // update density at interior nodes\n        for(int i=1;i&lt;N-1;i++) {\n            for(int j=1;j&lt;N-1;j++) {\n                double rho=0;\n                for(int dir=0;dir&lt;NDIR;dir++) {\n                    int index = i+j*N+dir*N*N;\n                    rho+=f_new[index];\n                }\n                rh[i+N*j] = rho;\n            }\n        }\n\n        // update velocity at interior nodes\n        for(int i=1;i&lt;N-1;i++) {\n            for(int j=1;j&lt;N-1;j++) {\n                double velx=0;\n                double vely=0;\n                for(int dir=0;dir&lt;NDIR;dir++) {\n                    int index = i+j*N+dir*N*N;\n                    velx+=f_new[index]*ex[dir];\n                    vely+=f_new[index]*ey[dir];\n                }\n                ux[i+N*j] = velx/rh[i+N*j];\n                uy[i+N*j] = vely/rh[i+N*j];\n            }\n        }\n\n    } // while loop ends\n\n/*\n    // centerline velocity profile\n    for(int i=1;i&lt;N-1;i++) {\n        std::cout &lt;&lt; 0.5 + (double)(i-1) &lt;&lt; \"  \" &lt;&lt; uy[i + N*(N/2)] &lt;&lt; std::endl;\n    }\n*/\n    return 0;</pre>\nLike the Laplace equation discussed in a related blog, the CPU version sweeps through each lattice point in a sequential manner and finds the new distribution functions after streaming and collision at that lattice point. However, all these updates are completely independent of each other and thus, they can be performed in parallel.\n\n<strong>The GPU approach</strong>\n\nThe basic idea behind this particular GPU implementation is very simple. We allocate and initialize all the relevant arrays directly on the GPU. Once this is done (we will assume that we have enough memory to accomplish this task), the actual updating of the PDFs because of streaming and collision is performed in parallel using thousands of threads that each work on independent lattice points. The complete CUDA code for implementing this idea is provided below for reference. As we said, this is just a demonstration of how to port the CPU based C++ code to the GPU and we do not wish to imply that this is the best and most efficient implementation of the LBM on the GPU. But a code is worth a thousand words and here is the code:\n<pre class=\"lang:default decode:true\">  \nSimulation of flow inside a 2D square cavity\nusing the lattice Boltzmann method (LBM)\n\nWritten by:       Abhijit Joshi (abhijit@accelereyes.com)\n\nLast modified on: Sunday, March 24 @ 9:00 am\n\nBuild instructions: nvcc -arch=sm_13 gpu_lbm.cu -o lbmGPU.x\n\nRun instructions: ./lbmGPU.x\n\n*/\n\n#include&lt;iostream&gt;\n\n// problem parameters\nconst int N = 512;            // number of node points along X and Y (cavity length in lattice units)\nconst int TIME_STEPS = 1000;  // number of time steps for which the simulation is run\n\nconst int NDIR = 9;           // number of discrete velocity directions used in the D2Q9 model\n\nconst double DENSITY = 2.7;          // fluid density in lattice units\nconst double LID_VELOCITY = 0.05;    // lid velocity in lattice units\nconst double REYNOLDS_NUMBER = 100;  // Re = \n\n__global__ void initialize(double *_ex, double *_ey, double *_alpha, int *_ant, double *_rh, double *_ux, double *_uy, double *_f, double *_feq, double *_f_new)\n{\n    // these could be initialized directly inside the GPU kernel and moved out of the CPU part...\n    _ex[0] =  0.0;   _ey[0] =  0.0;   _alpha[0] = 4.0 /  9.0;\n    _ex[1] =  1.0;   _ey[1] =  0.0;   _alpha[1] = 1.0 /  9.0;\n    _ex[2] =  0.0;   _ey[2] =  1.0;   _alpha[2] = 1.0 /  9.0;\n    _ex[3] = -1.0;   _ey[3] =  0.0;   _alpha[3] = 1.0 /  9.0;\n    _ex[4] =  0.0;   _ey[4] = -1.0;   _alpha[4] = 1.0 /  9.0;\n    _ex[5] =  1.0;   _ey[5] =  1.0;   _alpha[5] = 1.0 / 36.0;\n    _ex[6] = -1.0;   _ey[6] =  1.0;   _alpha[6] = 1.0 / 36.0;\n    _ex[7] = -1.0;   _ey[7] = -1.0;   _alpha[7] = 1.0 / 36.0;\n    _ex[8] =  1.0;   _ey[8] = -1.0;   _alpha[8] = 1.0 / 36.0;\n\n    // these could be initialized directly inside the GPU kernel and moved out of the CPU part...\n    _ant[0] = 0;      //      6        2        5\n    _ant[1] = 3;      //               ^       \n    _ant[2] = 4;      //               |\n    _ant[3] = 1;      //               |  \n    _ant[4] = 2;      //      3 &lt;----- 0 -----&gt; 1\n    _ant[5] = 7;      //               |\n    _ant[6] = 8;      //               |\n    _ant[7] = 5;      //               v\n    _ant[8] = 6;      //      7        4        8\n\n    // compute the \"i\" and \"j\" location and the \"dir\"\n    // handled by this thread\n\n    int i = blockIdx.x * blockDim.x + threadIdx.x ;\n    int j = blockIdx.y * blockDim.y + threadIdx.y ;\n\n    // initialize density and velocity fields inside the cavity\n    _rh[i+N*j] = DENSITY;\n    _ux[i+N*j] = 0;\n    _uy[i+N*j] = 0;\n\n    if(j==N-1) _ux[i+N*(N-1)] = LID_VELOCITY;\n\n    // assign initial values for distribution functions\n    int ixy = i+N*j;\n    for(int dir=0;dir&lt;NDIR;dir++) {\n        int index = i+j*N+dir*N*N;\n        double edotu = _ex[dir]*_ux[ixy] + _ey[dir]*_uy[ixy];\n        double udotu = _ux[ixy]*_ux[ixy] + _uy[ixy]*_uy[ixy];\n        _feq[index] = _rh[ixy] * _alpha[dir] * (1 + 3*edotu + 4.5*edotu*edotu - 1.5*udotu);\n        _f[index] = _feq[index];\n        _f_new[index] = _feq[index];\n    }\n}\n\n__global__ void timeIntegration(double *_ex, double *_ey, double *_alpha, int *_ant, double *_rh, double *_ux, double *_uy, double *_f, double *_feq, double *_f_new)\n{\n    // calculate fluid viscosity based on the Reynolds number\n    double kinematicViscosity = LID_VELOCITY * (double)N / REYNOLDS_NUMBER;\n\n    // calculate relaxation time tau\n    double tau =  0.5 + 3.0 * kinematicViscosity;\n\n    // compute the \"i\" and \"j\" location and the \"dir\"\n    // handled by this thread\n\n    int i = blockIdx.x * blockDim.x + threadIdx.x ;\n    int j = blockIdx.y * blockDim.y + threadIdx.y ;\n\n    {\n        // collision\n        if((i&gt;0) &amp;&amp; (i&lt;N-1) &amp;&amp; (j&gt;0) &amp;&amp; (j&lt;N-1)) {\n                int ixy = i+N*j;\n                for(int dir=0;dir&lt;NDIR;dir++) {\n                    int index = i+j*N+dir*N*N;\n                    double edotu = _ex[dir]*_ux[ixy] + _ey[dir]*_uy[ixy];\n                    double udotu = _ux[ixy]*_ux[ixy] + _uy[ixy]*_uy[ixy];\n                    _feq[index] = _rh[ixy] * _alpha[dir] * (1 + 3*edotu + 4.5*edotu*edotu - 1.5*udotu);\n                }\n        }\n\n        // streaming from interior node points\n        if((i&gt;0) &amp;&amp; (i&lt;N-1) &amp;&amp; (j&gt;0) &amp;&amp; (j&lt;N-1)) {\n                for(int dir=0;dir&lt;NDIR;dir++) {\n\n                    int index = i+j*N+dir*N*N;   // (i,j,dir)\n                    int index_new = (i+_ex[dir]) + (j+_ey[dir])*N + dir*N*N;\n                    int index_ant = i + j*N + _ant[dir]*N*N;\n\n                    // post-collision distribution at (i,j) along \"dir\"\n                    double f_plus = _f[index] - (_f[index] - _feq[index])/tau;\n\n                    if((i+_ex[dir]==0) || (i+_ex[dir]==N-1) || (j+_ey[dir]==0) || (j+_ey[dir]==N-1)) {\n                        // bounce back\n                        int ixy = i+_ex[dir] + N*(j+_ey[dir]);\n                        double ubdote = _ux[ixy]*_ex[dir] + _uy[ixy]*_ey[dir];\n                        _f_new[index_ant] = f_plus - 6.0 * DENSITY * _alpha[dir] * ubdote;\n                    }\n                    else {\n                        // stream to neighbor\n                        _f_new[index_new] = f_plus;\n                    }\n                }\n        }\n\n        // push f_new into f\n        if((i&gt;0) &amp;&amp; (i&lt;N-1) &amp;&amp; (j&gt;0) &amp;&amp; (j&lt;N-1)) {\n                for(int dir=0;dir&lt;NDIR;dir++) {\n                    int index = i+j*N+dir*N*N;   // (i,j,dir)\n                    _f[index] = _f_new[index];\n                }\n        }\n\n        // update density at interior nodes\n        if((i&gt;0) &amp;&amp; (i&lt;N-1) &amp;&amp; (j&gt;0) &amp;&amp; (j&lt;N-1)) {\n                double rho=0;\n                for(int dir=0;dir&lt;NDIR;dir++) {\n                    int index = i+j*N+dir*N*N;\n                    rho+=_f_new[index];\n                }\n                _rh[i+N*j] = rho;\n        }\n\n        // update velocity at interior nodes\n        if((i&gt;0) &amp;&amp; (i&lt;N-1) &amp;&amp; (j&gt;0) &amp;&amp; (j&lt;N-1)) {\n                double velx=0;\n                double vely=0;\n                for(int dir=0;dir&lt;NDIR;dir++) {\n                    int index = i+j*N+dir*N*N;\n                    velx+=_f_new[index]*_ex[dir];\n                    vely+=_f_new[index]*_ey[dir];\n                }\n                _ux[i+N*j] = velx/_rh[i+N*j];\n                _uy[i+N*j] = vely/_rh[i+N*j];\n        }\n    }\n\n}\n\nint main(int argc, char *argv[])\n{\n    // the base vectors and associated weight coefficients (GPU)\n    double *_ex, *_ey, *_alpha;  // pointers to device (GPU) memory\n    cudaMalloc((void **)&amp;_ex,NDIR*sizeof(double));\n    cudaMalloc((void **)&amp;_ey,NDIR*sizeof(double));\n    cudaMalloc((void **)&amp;_alpha,NDIR*sizeof(double));\n\n    // ant vector (GPU)\n    int *_ant;  // gpu memory\n    cudaMalloc((void **)&amp;_ant,NDIR*sizeof(int));\n\n    // allocate memory on the GPU\n    double *_f, *_feq, *_f_new;\n    cudaMalloc((void **)&amp;_f,N*N*NDIR*sizeof(double));\n    cudaMalloc((void **)&amp;_feq,N*N*NDIR*sizeof(double));\n    cudaMalloc((void **)&amp;_f_new,N*N*NDIR*sizeof(double));\n\n    double *_rh, *_ux, *_uy;\n    cudaMalloc((void **)&amp;_rh,N*N*sizeof(double));\n    cudaMalloc((void **)&amp;_ux,N*N*sizeof(double));\n    cudaMalloc((void **)&amp;_uy,N*N*sizeof(double));\n\n    // assign a 3D distribution of CUDA \"threads\" within each CUDA \"block\"    \n    int threadsAlongX=16, threadsAlongY=16;\n    dim3 dimBlock(threadsAlongX, threadsAlongY, 1);\n\n    // calculate number of blocks along X and Y in a 2D CUDA \"grid\"\n    dim3 dimGrid( ceil(float(N)/float(dimBlock.x)), ceil(float(N)/float(dimBlock.y)), 1 );\n\n    initialize&lt;&lt;&lt;dimGrid,dimBlock&gt;&gt;&gt;(_ex, _ey, _alpha, _ant, _rh, _ux, _uy, _f, _feq, _f_new);\n\n    // time integration\n    int time=0;\n    while(time&lt;TIME_STEPS) {\n\n        time++;\n\n        timeIntegration&lt;&lt;&lt;dimGrid,dimBlock &gt;&gt;&gt;(_ex, _ey, _alpha, _ant, _rh, _ux, _uy, _f, _feq, _f_new);\n\n    }\n\n/*\n    double *uy = new double [N*N];\n    cudaMemcpy(uy,_uy,N*N*sizeof(double),cudaMemcpyDeviceToHost);\n    // centerline velocity profiles\n    for(int i=1;i&lt;N-1;i++) {\n        std::cout &lt;&lt; 0.5 + (double)(i-1) &lt;&lt; \"  \" &lt;&lt; uy[i + N*(N/2)] &lt;&lt; std::endl;\n    }\n*/\n    return 0;\n}</pre>\nThe initial part of the code starts off on the CPU and allocates space to store the PDF arrays on the GPU using cudaMalloc. After this, the main portion of the algorithm runs completely on the GPU. The only instance where we would be required to move data from the GPU to the CPU is when we want to write it to output files for post-processing purposes. This is not done in this example for clarity and conciseness.\n\n<strong>RESULTS</strong>\n\nWe ran this problem using both the CPU version and the GPU version for a range of grid sizes, starting from a 128 x 128 lattice and going up to a 512 x 512 lattice. The results for total simulation time are summarized in the graph below. It can be observed that the GPU version completely outperforms the CPU version, even for the 128 x 128 grid.\n<p style=\"text-align: center;\"><a href=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/Screen-Shot-2013-03-25-at-2.11.49-PM.png\"><img class=\"aligncenter  wp-image-3921\" alt=\"Screen Shot 2013-03-25 at 2.11.49 PM\" src=\"http://blog.accelereyes.com/blog/wp-content/uploads/2013/03/Screen-Shot-2013-03-25-at-2.11.49-PM-1024x767.png\" width=\"614\" height=\"460\" /></a></p>\n<p style=\"text-align: center;\"></p>','Lattice Boltzmann Method - Moving from CPU to GPU','','pending','open','open','','','','','2013-03-25 16:25:48','0000-00-00 00:00:00','',0,'http://blog.accelereyes.com/blog/?p=3920',0,'post','',0),(3945,1,'2013-04-03 14:36:41','2013-04-03 18:36:41','<p dir=\"ltr\"><em>Here\'s an account of life at AccelerEyes from Vish, the first full-time employee at the company. Over the past 3 months, our company has doubled in size and Vish recently wrote the following to the new employees. We share here on the blog too to give a peek into our culture. If you are a great GPU programmer, you might be interested in <a href=\"http://accelereyes.com/careers\">joining our team too</a>.</em></p>\n<p dir=\"ltr\">---</p>\n<p dir=\"ltr\">Hello Everyone,</p>\n<p dir=\"ltr\">When I joined in early 2009, AccelerEyes was barely occupying a full cubicle. \"Could this be a company?\", was my first thought. And yet, here we are, growing in size, reputation, and revenue!</p>\n<p dir=\"ltr\">I will always cherish those early days for the complete uncertainty as to the future - both mine and the company\'s. We were just beginning to take shape, and I guess we all felt that the only way to move was forward. And I am glad that we - and I - have only been moving forward for the four awesome years I have been here.</p>\n<p dir=\"ltr\">The past four years have raced by at breakneck pace. I have dived into so many technologies, got a chance to speak to so many customers, fiddled around with so many systems, and learned more than I ever did in all my professional life. Its fair to say that AccelerEyes made me what I am today.</p>\n<p dir=\"ltr\">I\'d like to say that I have tried my best to give back to AccelerEyes as good as I got. And yet, I can tell you that 4 years is <i>barely enough to scratch the surface</i> on what you can accomplish at AccelerEyes.</p>\n<p dir=\"ltr\">In fact, I sincerely hope that among all of you new hires, we see someone that\'s willing to take up the mantle of creating fully automated, hands-off systems that (for once) do not mysteriously fail (Windows 32-bit, I hope you are listening).</p>\n<p dir=\"ltr\">I\'d like to share some wisdom I have learned - about AccelerEyes, startup life, <i>life</i> in general, to all our new hires:</p>\n\n<ul>\n	<li>Dive in. With all your heart. Ignore the naysayers (of which you will find plenty)</li>\n	<li>Get out of your comfort zone, for that\'s how you\'ll learn!</li>\n	<li>Don\'t be afraid to say, \"I don\'t know.\"</li>\n	<li>But don\'t ask for help as a first resort, but find the solution on your own as far as possible. And if you can\'t, know when to ask for help.</li>\n	<li>\"Done is better than perfect\" (some of the time).</li>\n	<li>Never do something manually if you can automate it.</li>\n	<li>Get accomplished at at least one of vim or emacs.</li>\n	<li>Always keep our customers at the top of your priority list.</li>\n	<li>And lastly, have a blast!</li>\n</ul>\n<p dir=\"ltr\">At AccelerEyes, I have opportunities to build real products and processes. I have opportunities to grow as an engineer and a person. And I have wonderful chances to make my mark on what will hopefully become a world leading company.</p>\n<p dir=\"ltr\">Sincerely,</p>\n<p dir=\"ltr\">Vish</p>\n\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=4f9f65ec-3d6f-4894-9177-862380e27350\" /></div>','Life at AccelerEyes','','publish','open','open','','life-at-accelereyes','','','2013-04-03 14:36:41','2013-04-03 18:36:41','',0,'http://blog.accelereyes.com/blog/?p=3945',0,'post','',0),(3970,4,'2013-04-08 18:53:49','2013-04-08 22:53:49','Last month, I posted two articles describing computing trends and why heterogeneous computing will be a significant force in computing for the next decade. Today, I continue that series with an article describing the biggest challenge to continued increases in computing performance - parallel software development.\n\n<strong>Biggest Challenge</strong>\n\nAs I <a href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\">described previously</a>, in order to use an accelerator, software changes must be made. Regular x86-based compilers cannot compile code to run on accelerators without these needed changes. The amount of software change required varies depending upon the availability of and reliance upon software tools that increase performance and productivity.\n\nThere are four possible approaches to take advantage of accelerators in heterogeneous computing environments:  do-it-yourself, use compilers, use libraries, or use accelerated applications (if you\'re lucky).\n\n<strong>Do-it-Yourself</strong>\n\nThe do-it-yourself approach is defined by taking an inordinate amount of software development time to write code that leverages all the parallel attributes of your heterogeneous computer. Hardware vendors such as AMD, Intel, and NVIDIA provide access to low-level tools that enable developing parallel code to run on their heterogeneous hardware.\n\nNVIDIA is the leader with the CUDA platform. CUDA is the first highly adopted platform enabling high-performance general-purpose GPU code. Developers of CUDA code write GPU kernels, manage different levels of GPU memory, make tradeoffs for data transfers between the host and the device, and optimize many other aspects of the parallel system.\n\nOpenCL is the industry\'s open standard for similarly writing data-parallel code in heterogeneous computers. AMD and Intel both promote OpenCL as a primary approach towards programming their parallel computing hardware offerings. OpenCL requires a similar level of low-level understanding and competence to write efficient parallel software.\n\nBoth CUDA and OpenCL are primarily targeted at leveraging data-parallelism of devices, and additional considerations must be made to use the multiple cores available on the CPUs in the system. For instance, OpenMP and MPI enable the use of multiple CPU cores and compute nodes in a heterogeneous system.\n\nThe do-it-yourself approach is very costly in terms of developer muscle and expertise. The do-it-yourself approach does not adapt well to ongoing hardware updates. For instance, a parallel computing algorithm tuned for NVIDIA\'s Fermi GPUs may not be the best algorithm choice for Kepler GPUs. These difficulties are what prompted AMD to say that <a href=\"http://www.theinquirer.net/inquirer/news/2257035/amd-thinks-most-programmers-will-not-use-cuda-or-opencl\">most programmers will not use CUDA or OpenCL</a>. We agree. Most programmers will be smarter and will use the more productive approaches described below.\n\nThe best attribute of the do-it-yourself approach is that it\'s always available in case other more productive approaches fail.\n\n<strong>Use Compilers</strong>\n\nSerious research attempts have been made by compiler developers to offload the brunt of parallel software development from manpower to compiler power. Unfortunately, these research attempts have not been very successful and the task of automatically finding the parallelism in a code is an unsolved research problem.\n\nThere are some use cases where simple, straightforward loops can be unrolled by compilers and executed efficiently on parallel hardware without much human intervention. But those are not commonplace.\n\nCompilers can also get smarter as software developers introduce compiler-targeted directives (or software changes) that give the compilers hints about which things should be parallelized. However, many people have noticed that by the time you add sufficient compiler hints to the code to get good performance, you often would have been better off simply going the do-it-yourself approach in the first place.\n\nCompilers will continue to improve, but for many decades theoretical researchers have tried to solve the problem of automatic parallelism detection from code and have failed. In fact, it has been proven that it is impossible to automatically detect parallelism in many instances.\n\nThe best attribute of compilers is that they work on simple arithmetic in loops; so if you have a very simple use case with simple operations, compilers are worth consideration.\n\n<strong>Use Libraries</strong>\n\nLibraries benefit from the great performance of the do-it-yourself approach, as well as the easy-of-use of the compiler approach. Software libraries are written by parallel computing experts who are focused on optimizing the last bit of advantage out of one narrow function at a time.\n\nToday, heterogeneous software libraries are built on top of the CUDA or OpenCL platform and selection of the appropriate library depends upon the choice of platform. There are more CUDA libraries available today than OpenCL libraries, largely because NVIDIA has done a marvelous job at building a parallel computing ecosystem. However, with the recent emergence of Intel Xeon Phi and the growth of OpenCL\'s utility in mobile computing, OpenCL libraries are becoming more and more prevalent than before.\n\nUse of libraries requires a trust upon the library\'s developers. Common qualifying questions regarding libraries include:  Is the library fast? Is the library stable? Is the library fully supported? Will the library be updated quickly as new hardware updates occur? Is there a community built around the library?\n\nLibraries that have strong responses to those questions have great benefits for software developers. Libraries that do not can be a waste of time, and developers would do well to not waste their time pushing on broken software.\n\nThe best attribute of libraries is the ability to leverage expertly written parallel software while avoiding the time-sink of the do-it-yourself approach.\n\n<strong>Use Accelerated Applications</strong>\n\nAs heterogeneous computing becomes more prevalent, many popular applications are becoming accelerator-enabled already. For instance, Adobe has products that are CUDA and OpenCL-accelerated for faster video transcoding. We are <a href=\"http://blog.accelereyes.com/blog/2012/12/12/exciting-updates-from-accelereyes/\">working with MathWorks</a> on parallel tools. Ansys has GPU-accelerated products. And there are many more.\n\nUsers of those products do not have to do heavy-lifting to get faster code. They simply get to benefit from the work done by the application developers, often with simple checkboxes or designations that indicate a preference towards accelerated computing.\n\n<strong>The Next Decade: Challenges for Parallel Software</strong>\n\nThe next decade will be defined by how the industry responds to the challenges of developing parallel software for heterogeneous computers, from high-performance computers down to mobile devices. Poor choices will lead to outcomes like that of the <a href=\"http://www.hpcwire.com/hpcwire/2013-04-04/revelations_on_roadrunner_s_retirement.html\">Roadrunner supercomputer</a> (and IBM cell processor) which is being decommissioned after only a few years of use (see note below). Writing software that leverages the best parallel computing hardware, adapts well to the rapid pace of hardware updates, and minimizes developer muscle is the industry\'s goal.\n\nWhat challenges have you noticed about developing parallel software? How do you think the next decade of software development will be defined?\n\n<em>Notes:</em>\n<ul>\n	<li><i>The IBM Cell processor was very popular when we started AccelerEyes in 2007. I\'m glad we never bet on that technology and stuck with GPUs, or we would have wasted a lot of precious resources. Some other library companies were not so lucky and were hurt by the downfall of the Cell processor.</i></li>\n</ul>\n---\n\n<strong>Posts in this series:</strong>\n<ol>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/07/cpu-processing-trends-for-dummies/\">CPU Processing Trends for Dummies</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\">Heterogeneous Computing Trends for Dummies</a></li>\n	<li><a href=\"http://blog.accelereyes.com/blog/2013/04/08/parallel-software-development-trends-for-dummies\">Parallel Software Development Trends for Dummies</a></li>\n</ol>\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-04-08/heterogeneous_computing_in_firing_range.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/158287269_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-04-08/heterogeneous_computing_in_firing_range.html\" target=\"_blank\">Heterogeneous Computing in Firing Range</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://gpuscience.com/articles/comparison-of-openmp-opencl-parallel-processing-technologies/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/145705511_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://gpuscience.com/articles/comparison-of-openmp-opencl-parallel-processing-technologies/\" target=\"_blank\">Comparison of OpenMP &amp; OpenCL Parallel Processing Technologies</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-26/setting_up_cuda_in_the_cloud.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/155318749_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-03-26/setting_up_cuda_in_the_cloud.html\" target=\"_blank\">Setting Up CUDA in the Cloud</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blogs.nvidia.com/2013/03/geforce-gtx-titan-cuda/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152150184_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blogs.nvidia.com/2013/03/geforce-gtx-titan-cuda/\" target=\"_blank\">GeForce GTX TITAN: Why Best Gaming GPU is also Ultimate CUDA Development GPU</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://devgurus.amd.com/thread/159457\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152264878_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://devgurus.amd.com/thread/159457\" target=\"_blank\">OpenCL 8 GPU DGEMM (5.1 TFlop/s double precision). Programming infrastructure for heterogeneous computing and its applications</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/07/cpu-processing-trends-for-dummies/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/150700635_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/07/cpu-processing-trends-for-dummies/\" target=\"_blank\">CPU Processing Trends for Dummies</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153015464_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\" target=\"_blank\">Heterogeneous Computing Trends for Dummies</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=bc3c3273-19b1-448c-afef-c9698c4f8204\" /></div>','Parallel Software Development Trends for Dummies','','publish','open','open','','parallel-software-development-trends-for-dummies','','','2013-04-08 18:53:49','2013-04-08 22:53:49','',0,'http://blog.accelereyes.com/blog/?p=3970',0,'post','',0),(3988,6,'2013-04-10 11:00:58','2013-04-10 15:00:58','<a href=\"http://www.computefaster.com/\">CreativeC</a> makes awesome compute + visualization systems. We got to see the demo in live action at the <a href=\"http://www.gputechconf.com/page/home.html\">GPU Technology Conference</a> last month.\n\nTim Thomas was kind enough to let us film the demo showing how ArrayFire can be used to drive a multi-node, 9 GPU system in a physics application. Checkout the video below.\n\n<iframe width=\"640\" height=\"360\" src=\"http://www.youtube.com/embed/64T69R-_8oQ\" frameborder=\"0\" allowfullscreen=\"\"></iframe>\n\nIf you are interested in high-throughput compute coupled with high-pixel visualizations, we recommend you talk with the folks at CreativeC. They are always pushing the envelope on what can be done with GPU computing and GPU visualizations.\n\nAlso, if you have cool demos showing ArrayFire in action, let us know. We\'d love to film your work and make it available on this blog!\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blogs.nvidia.com/2013/03/a-demo-thats-truly-a-head-of-its-time/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153909706_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blogs.nvidia.com/2013/03/a-demo-thats-truly-a-head-of-its-time/\" target=\"_blank\">A Demo That\'s Truly \'A Head\' of Its Time</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.prweb.com/releases/prweb2013/3/prweb10522631.htm\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/152200277_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.prweb.com/releases/prweb2013/3/prweb10522631.htm\" target=\"_blank\">Zillians Brings CUDA to Raspberry Pi, Creating the Most Flexible and Powerful Computing Platform with Minimal Cost.</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-04-08/heterogeneous_computing_in_firing_range.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/158287269_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-04-08/heterogeneous_computing_in_firing_range.html\" target=\"_blank\">Heterogeneous Computing in Firing Range</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/21/7-highlights-of-gtc-2013-day-3-of-4/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153934357_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/21/7-highlights-of-gtc-2013-day-3-of-4/\" target=\"_blank\">7 Highlights of GTC 2013 - Day 3 of 4</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/20/7-highlights-of-gtc-2013-day-2-of-4/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153670138_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/20/7-highlights-of-gtc-2013-day-2-of-4/\" target=\"_blank\">7 Highlights of GTC 2013 - Day 2 of 4</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=145c29e4-0b14-4570-b061-f0201e8049fb\" /></div>','ArrayFire + Scorpii Demo by CreativeC','','publish','open','open','','arrayfire-scorpii-demo-by-creativec','','','2013-04-10 11:00:58','2013-04-10 15:00:58','',0,'http://blog.accelereyes.com/blog/?p=3988',0,'post','',0),(4010,4,'2013-04-23 16:55:23','2013-04-23 20:55:23','Graham Singer over at Techspot posted a series of articles a few weeks ago covering the history of the modern GPU. It is well-written and in-depth.\n\nFor GPU affectionados, this is a nice read. There are 4 parts to the series:\n<ol>\n	<li><a href=\"http://www.techspot.com/article/650-history-of-the-gpu/\">Part 1: (1976 - 1995) The Early Days of 3D Consumer Graphics</a></li>\n	<li><a href=\"http://www.techspot.com/article/653-history-of-the-gpu-part-2/\">Part 2: (1995 - 1999) 3Dfx Voodoo: The Game-changer</a></li>\n	<li><a href=\"http://www.techspot.com/article/657-history-of-the-gpu-part-3/\">Part 3: (2000 - 2006) The Nvidia vs. ATI Era Begins</a></li>\n	<li><a href=\"http://www.techspot.com/article/659-history-of-the-gpu-part-4/\">Part 4: (2006 - 2013) The Modern GPU: Stream processing units a.k.a. GPGPU</a></li>\n</ol>\nEnjoy!\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=10afddf9-4f83-444c-9fb1-aac79b04c61e\" /></div>','History of the Modern GPU Series','','publish','open','open','','history-of-the-modern-gpu-series','','','2013-04-23 16:55:23','2013-04-23 20:55:23','',0,'http://blog.accelereyes.com/blog/?p=4010',0,'post','',0),(4015,4,'2013-05-01 15:48:39','2013-05-01 19:48:39','<a href=\"http://www.hpcwire.com/hpcwire/2013-05-01/idc_posits_processor_possibilities.html\">HPCwire posted a nice article</a> today with trends from IDC on computer processing. These trends fall inline and corroborate <a href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\" target=\"_blank\">things we\'ve been saying</a> here on this blog. Accelerators (including GPUs and co-processors) are taking off. Are you getting left behind? If you\'re reading this blog, you\'re probably at the bleeding edge, but nonetheless here are some interesting excerpts from HPCwire\'s market report (<a href=\"http://www.hpcwire.com/hpcwire/2013-05-01/idc_posits_processor_possibilities.html\">go read the whole thing</a>):\n<ul>\n	<li>\"While they expected to see a jump in coprocessor and accelerator uptake, they were wholly unprepared for the overwhelming positive response to GPUs and new entrants into the market, most notably Intel’s shiny new Phi.\"</li>\n	<li>\"Conway said that while accelerator and coprocessor adoption growth was anticipated, they had no idea that it would have been over double what it was from the short time since their last survey. [18 months apart]\"</li>\n	<li>\"The point is, says Conway, \'Heterogeneity is very much on the rise. We are moving past the experimental phase, people are doing real work now.\'\"</li>\n	<li>\"Of Phi in particular he notes that things are moving along,  \'but it’s still not clear how easy the new generation will be to program—the real thing here is that it’s going to take time to grow the software ecosystem.\'\"</li>\n	<li>\"Accelerator use is in the early stages but results point to continued penetration of the market.\"</li>\n</ul>\nExcellent trends for everyone investing in accelerators today and bodes well for the future. If you\'re not yet biting down hard onto heterogeneous computing, take another look!\n<h6 class=\"zemanta-related-title\" style=\"font-size: 1em;\">Related articles</h6>\n<ul class=\"zemanta-article-ul zemanta-article-ul-image\" style=\"margin: 0; padding: 0; overflow: hidden;\">\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/153015464_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/03/17/heterogeneous-computing-trends-for-dummies/\" target=\"_blank\">Heterogeneous Computing Trends for Dummies</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://blog.accelereyes.com/blog/2013/04/08/parallel-software-development-trends-for-dummies/\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/158419255_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://blog.accelereyes.com/blog/2013/04/08/parallel-software-development-trends-for-dummies/\" target=\"_blank\">Parallel Software Development Trends for Dummies</a></li>\n	<li class=\"zemanta-article-ul-li-image zemanta-article-ul-li\" style=\"padding: 0; background: none; list-style: none; display: block; float: left; vertical-align: top; text-align: left; width: 84px; font-size: 11px; margin: 2px 10px 10px 2px;\"><a style=\"box-shadow: 0px 0px 4px #999; padding: 2px; display: block; border-radius: 2px; text-decoration: none;\" href=\"http://www.hpcwire.com/hpcwire/2013-04-08/heterogeneous_computing_in_firing_range.html\" target=\"_blank\"><img style=\"padding: 0; margin: 0; border: 0; display: block; width: 80px; max-width: 100%;\" alt=\"\" src=\"http://i.zemanta.com/158287269_80_80.jpg\" /></a><a style=\"display: block; overflow: hidden; text-decoration: none; line-height: 12pt; height: 80px; padding: 5px 2px 0 2px;\" href=\"http://www.hpcwire.com/hpcwire/2013-04-08/heterogeneous_computing_in_firing_range.html\" target=\"_blank\">Heterogeneous Computing in Firing Range</a></li>\n</ul>\n<div class=\"zemanta-pixie\" style=\"margin-top: 10px; height: 15px;\"><img class=\"zemanta-pixie-img\" style=\"border: none; float: right;\" alt=\"\" src=\"http://img.zemanta.com/pixy.gif?x-id=86b3bf29-67b3-43c0-ba2d-4784fe838c11\" /></div>','Are You Getting Left Behind?','','publish','open','open','','are-you-getting-left-behind','','','2013-05-01 15:48:39','2013-05-01 19:48:39','',0,'http://blog.accelereyes.com/blog/?p=4015',0,'post','',0),