Dave - sounds good, here is what OpenCL matmult looks like, very similar to cuda but slightly different syntax.  OpenCL takes care of the sub-parallelized jobs that are spawned from each multiprocessor on your card, with CUDA you need to define these, hence the __kernel vs __global__ function types.  <br><br>Also, watch your output precision, more than likely your graphics card does not support double precision operations, and CUDA will silently cast all your doubles to floats.  Another issue which will be resolved with time and hardware upgrades!<br><br>Chris<br><br>///////////////////////////////////////////////////////////////////////////////<br>//! Matrix multiplication on the device: C = A * B<br>//! wA is A's width and wB is B's width<br>////////////////////////////////////////////////////////////////////////////////<br>__kernel void<br>matrixMul( __global float* C, <br>                     __global float* A, <br>                     __global float* B, <br>                     int wA, <br>                     int wB){<br>    <br>    // 2D Thread ID<br>    int tx = get_local_id(0);<br>    int ty = get_local_id(1);<br>    <br>    // value stores the element <br>    // that is computed by the thread<br>    float value = 0;<br>    for (int k = 0; k < wA; ++k){<br>      float elementA = A[ty * wA + k];<br>      float elementB = B[k * wB + tx];<br>      value += elementA * elementB;<br>    }<br>    <br>    // Write the matrix to device memory each <br>    // thread writes one element<br>    C[ty * wA + tx] = value;<br>}<br><br><br>----- Original Message -----<br>From: dave fournier <davef@otter-rsch.com><br>Date: Wednesday, September 14, 2011 10:02 am<br>Subject: Re: [ADMB Users] Does CUDA suck?  answer NO!<br>To: CHRIS GRANDIN <cgrandin@shaw.ca><br>Cc: users@admb-project.org<br><br>> On 11-09-14 08:40 AM, CHRIS GRANDIN wrote:<br>> <br>> The main point of that exercise was simply to check the <br>> performance of gpu stuff.<br>> It appears that opencl may be the future, but the interface <br>> sucks big time compared to cuda.<br>> Since my expertise is in the derivative stuff and since <br>> conversion from cuda to opencl is<br>> well understood  (just don't use any c++) in the kernel <br>> code, I decided to implement<br>> a gpu version of the vectorized negative binomial density for <br>> dvar_vectors in cuda as an<br>> example. With luck it will be finished today.<br>> <br>>         Dave<br>> <br>> <br>> <br>> <br>> >Dave, I am wondering why you didn't use OpenCL library like I <br>> did in my matrix mult example at the workshop?  If you do <br>> there is no requirement for a special compiler (nvcc) and extra <br>> makefiles, and the code is already optimized.<br>> ><br>> >Yes, the limiting factor is the bussing of data to/from the GPU <br>> and for addition it outweighs the cost of the addition <br>> operations. Its the same for OpenCL, that's why I did the matrix <br>> mult example..<br>> ><br>> >Also I don't see how you are carrying the derivative <br>> information around, that was my issue thus far, CUDA and OpenCL <br>> don't support C++ classes yet!  Please let me know what you <br>> think of this as this parallelization has been of ongoing <br>> interest to me.<br>> ><br>> >Thanks,<br>> >Chris<br>> ><br>> >----- Original Message -----<br>> >From: dave fournier <davef@otter-rsch.com><br>> >Date: Saturday, September 3, 2011 4:05 pm<br>> >Subject: Re: [ADMB Users] Does CUDA suck?  answer NO!<br>> >To: users@admb-project.org<br>> ><br>> >> First there is an error in the code. It should read<br>> >><br>> >><br>> >> return z;<br>> >><br>> >>  and not<br>> >><br>> >>           <br>> return x+y;<br>> >><br>> >> However I thought that maybe the problem is that  addition<br>> >> is too trivial compared to the<br>> >> overhead of moving things to the GPU and back. I changed the<br>> >> function to pow(x,y)<br>> >> and lo!  the el cheapo GPU is faster (about 6 times faster).<br>> >> So how hard is a vector pow.  All that was necessary was to<br>> >> take the included VecAdd<br>> >> function and modify it to<br>> >><br>> >><br>> >> __global__ void VecPow(const double* A, const double* B, double*<br>> >> C, int N)<br>> >> {<br>> >>     int i = blockDim.x * blockIdx.x + <br>> threadIdx.x;>>     double x=0.0;<br>> >>     if (i < N)<br>> >>     {<br>> >>         C[i] = <br>> pow(A[i],B[i]);>>     }<br>> >> }<br>> >><br>> >> Code is attached. Note I use mypow just to avoid clash with<br>> >> existing admb libs.<br>> >><br>> >> <br>> <br>>