• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10 
11 #include <iostream>
12 
13 #include <Eigen/Core>
14 #include <Eigen/LU>
15 
16 #include <boost/compute/function.hpp>
17 #include <boost/compute/system.hpp>
18 #include <boost/compute/algorithm/transform.hpp>
19 #include <boost/compute/container/vector.hpp>
20 #include <boost/compute/types/fundamental.hpp>
21 
22 namespace compute = boost::compute;
23 
24 // this example shows how to compute the determinant of many 4x4 matrices
25 // using a determinant function and the transform() algorithm. in OpenCL the
26 // float16 type can be used to store a 4x4 matrix and the components are laid
27 // out in the following order:
28 //
29 // M = [ s0 s4 s8 sc ]
30 //     [ s1 s5 s9 sd ]
31 //     [ s2 s6 sa se ]
32 //     [ s3 s7 sb sf ]
33 //
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.
main()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     }
94 
95     return 0;
96 }
97