this example shows how to compute the determinant of many 4x4 matrices using a determinant function and the transform() algorithm. in OpenCL the float16 type can be used to store a 4x4 matrix and the components are laid out in the following order: M = [ s0 s4 s8 sc ] [ s1 s5 s9 sd ] [ s2 s6 sa se ] [ s3 s7 sb sf ] the input matrices are created using eigen's random matrix and then used again at
| 34 | // the input matrices are created using eigen's random matrix and then |
| 35 | // used again at the end to verify the results of the determinant function. |
| 36 | int main() |
| 37 | { |
| 38 | // get default device and setup context |
| 39 | compute::device gpu = compute::system::default_device(); |
| 40 | compute::context context(gpu); |
| 41 | compute::command_queue queue(context, gpu); |
| 42 | std::cout << "device: " << gpu.name() << std::endl; |
| 43 | |
| 44 | size_t n = 1000; |
| 45 | |
| 46 | // create random 4x4 matrices on the host |
| 47 | std::vector<Eigen::Matrix4f> matrices(n); |
| 48 | for(size_t i = 0; i < n; i++){ |
| 49 | matrices[i] = Eigen::Matrix4f::Random(); |
| 50 | } |
| 51 | |
| 52 | // copy matrices to the device |
| 53 | using compute::float16_; |
| 54 | compute::vector<float16_> input(n, context); |
| 55 | compute::copy( |
| 56 | matrices.begin(), matrices.end(), input.begin(), queue |
| 57 | ); |
| 58 | |
| 59 | // function returning the determinant of a 4x4 matrix. |
| 60 | BOOST_COMPUTE_FUNCTION(float, determinant4x4, (const float16_ m), |
| 61 | { |
| 62 | return m.s0*m.s5*m.sa*m.sf + m.s0*m.s6*m.sb*m.sd + m.s0*m.s7*m.s9*m.se + |
| 63 | m.s1*m.s4*m.sb*m.se + m.s1*m.s6*m.s8*m.sf + m.s1*m.s7*m.sa*m.sc + |
| 64 | m.s2*m.s4*m.s9*m.sf + m.s2*m.s5*m.sb*m.sc + m.s2*m.s7*m.s8*m.sd + |
| 65 | m.s3*m.s4*m.sa*m.sd + m.s3*m.s5*m.s8*m.se + m.s3*m.s6*m.s9*m.sc - |
| 66 | m.s0*m.s5*m.sb*m.se - m.s0*m.s6*m.s9*m.sf - m.s0*m.s7*m.sa*m.sd - |
| 67 | m.s1*m.s4*m.sa*m.sf - m.s1*m.s6*m.sb*m.sc - m.s1*m.s7*m.s8*m.se - |
| 68 | m.s2*m.s4*m.sb*m.sd - m.s2*m.s5*m.s8*m.sf - m.s2*m.s7*m.s9*m.sc - |
| 69 | m.s3*m.s4*m.s9*m.se - m.s3*m.s5*m.sa*m.sc - m.s3*m.s6*m.s8*m.sd; |
| 70 | }); |
| 71 | |
| 72 | // calculate determinants on the gpu |
| 73 | compute::vector<float> determinants(n, context); |
| 74 | compute::transform( |
| 75 | input.begin(), input.end(), determinants.begin(), determinant4x4, queue |
| 76 | ); |
| 77 | |
| 78 | // check determinants |
| 79 | std::vector<float> host_determinants(n); |
| 80 | compute::copy( |
| 81 | determinants.begin(), determinants.end(), host_determinants.begin(), queue |
| 82 | ); |
| 83 | |
| 84 | for(size_t i = 0; i < n; i++){ |
| 85 | float det = matrices[i].determinant(); |
| 86 | |
| 87 | if(std::abs(det - host_determinants[i]) > 1e-6){ |
| 88 | std::cerr << "error: wrong determinant at " << i << " (" |
| 89 | << host_determinants[i] << " != " << det << ")" |
| 90 | << std::endl; |
| 91 | return -1; |
| 92 | } |
| 93 | } |