File indexing completed on 2025-11-03 09:31:28
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 #ifndef boost_numeric_ublas_opencl_misc_hpp_
0011 #define boost_numeric_ublas_opencl_misc_hpp_
0012 
0013 #include <boost/numeric/ublas/opencl/library.hpp>
0014 #include <boost/numeric/ublas/opencl/vector.hpp>
0015 #include <boost/numeric/ublas/opencl/matrix.hpp>
0016 
0017 namespace boost { namespace numeric { namespace ublas { namespace opencl {
0018 
0019 template <typename T>
0020 typename std::enable_if<is_numeric<T>::value, T>::type
0021 a_sum(ublas::vector<T, opencl::storage> const &v, compute::command_queue& queue)
0022 {
0023   compute::vector<T> scratch_buffer(v.size(), queue.get_context());
0024   compute::vector<T> result_buffer(1, queue.get_context());
0025   cl_event event;
0026   if (std::is_same<T, float>::value)
0027     clblasSasum(v.size(),
0028         result_buffer.begin().get_buffer().get(), 
0029         0, 
0030         v.begin().get_buffer().get(), 
0031         0, 
0032         1, 
0033         scratch_buffer.begin().get_buffer().get(),
0034         1, 
0035         &(queue.get()), 
0036         0, 
0037         NULL, 
0038         &event); 
0039   else if (std::is_same<T, double>::value)
0040     clblasDasum(v.size(),
0041         result_buffer.begin().get_buffer().get(), 
0042         0, 
0043         v.begin().get_buffer().get(), 
0044         0, 
0045         1, 
0046         scratch_buffer.begin().get_buffer().get(),
0047         1, 
0048         &(queue.get()), 
0049         0, 
0050         NULL, 
0051         &event); 
0052   else if (std::is_same<T, std::complex<float>>::value)
0053     clblasScasum(v.size(),
0054          result_buffer.begin().get_buffer().get(), 
0055          0, 
0056          v.begin().get_buffer().get(), 
0057          0, 
0058          1, 
0059          scratch_buffer.begin().get_buffer().get(),
0060          1, 
0061          &(queue.get()), 
0062          0, 
0063          NULL, 
0064          &event); 
0065   else if (std::is_same<T, std::complex<double>>::value)
0066     clblasDzasum(v.size(),
0067          result_buffer.begin().get_buffer().get(), 
0068          0, 
0069          v.begin().get_buffer().get(), 
0070          0, 
0071          1, 
0072          scratch_buffer.begin().get_buffer().get(),
0073          1, 
0074          &(queue.get()), 
0075          0, 
0076          NULL, 
0077          &event); 
0078   clWaitForEvents(1, &event);
0079   return result_buffer[0];
0080 }
0081 
0082 template <typename T, typename A>
0083 typename std::enable_if<is_numeric<T>::value, T>::type
0084 a_sum(ublas::vector<T, A> const &v, compute::command_queue& queue)
0085 {
0086   ublas::vector<T, opencl::storage> vdev(v, queue);
0087   return a_sum(vdev, queue);
0088 }
0089 
0090 template <typename T>
0091 typename std::enable_if<std::is_same<T, float>::value |
0092             std::is_same<T, double>::value,
0093             T>::type
0094 norm_1(ublas::vector<T, opencl::storage> const &v, compute::command_queue& queue)
0095 {
0096   return a_sum(v, queue);
0097 }
0098 
0099 template <typename T, typename A>
0100 typename std::enable_if<std::is_same<T, float>::value |
0101             std::is_same<T, double>::value,
0102             T>::type
0103 norm_1(ublas::vector<T, A> const &v, compute::command_queue& queue)
0104 {
0105   ublas::vector<T, opencl::storage> vdev(v, queue);
0106   return norm_1(vdev, queue);
0107 }
0108 
0109 template <typename T>
0110 typename std::enable_if<is_numeric<T>::value, T>::type
0111 norm_2(ublas::vector<T, opencl::storage> const &v, compute::command_queue& queue)
0112 {
0113   compute::vector<T> scratch_buffer(2*v.size(), queue.get_context());
0114   compute::vector<T> result_buffer(1, queue.get_context());
0115   cl_event event;
0116   if (std::is_same<T, float>::value)
0117     clblasSnrm2(v.size(),
0118         result_buffer.begin().get_buffer().get(), 
0119         0, 
0120         v.begin().get_buffer().get(), 
0121         0, 
0122         1, 
0123         scratch_buffer.begin().get_buffer().get(),
0124         1, 
0125         &(queue.get()), 
0126         0, 
0127         NULL, 
0128         &event); 
0129   else if (std::is_same<T, double>::value)
0130     clblasDnrm2(v.size(),
0131         result_buffer.begin().get_buffer().get(), 
0132         0, 
0133         v.begin().get_buffer().get(), 
0134         0, 
0135         1, 
0136         scratch_buffer.begin().get_buffer().get(),
0137         1, 
0138         &(queue.get()), 
0139         0, 
0140         NULL, 
0141         &event); 
0142   else if (std::is_same<T, std::complex<float>>::value)
0143     clblasScnrm2(v.size(),
0144          result_buffer.begin().get_buffer().get(), 
0145          0, 
0146          v.begin().get_buffer().get(), 
0147          0, 
0148          1, 
0149          scratch_buffer.begin().get_buffer().get(),
0150          1, 
0151          &(queue.get()), 
0152          0, 
0153          NULL, 
0154          &event); 
0155   else if (std::is_same<T, std::complex<double>>::value)
0156     clblasDznrm2(v.size(),
0157          result_buffer.begin().get_buffer().get(), 
0158          0, 
0159          v.begin().get_buffer().get(), 
0160          0, 
0161          1, 
0162          scratch_buffer.begin().get_buffer().get(),
0163          1, 
0164          &(queue.get()), 
0165          0, 
0166          NULL, 
0167          &event); 
0168   clWaitForEvents(1, &event);
0169   return result_buffer[0];
0170 }
0171 
0172 template <typename T, typename A>
0173 typename std::enable_if<is_numeric<T>::value, T>::type
0174 norm_2(ublas::vector<T, A> const &v, compute::command_queue& queue)
0175 {
0176   ublas::vector<T, opencl::storage> vdev(v, queue);
0177   return norm_2(vdev, queue);
0178 }
0179 
0180 }}}}
0181 
0182 #endif