ViennaCL - The Vienna Computing Library 1.3.0
/export/development/ViennaCL/viennacl/generator/traits/result_of.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_GENERATOR_TRAITS_RESULT_OF_HPP
00002 #define VIENNACL_GENERATOR_TRAITS_RESULT_OF_HPP
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2012, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                   ViennaCL - The Vienna Computing Library
00011                             -----------------
00012 
00013    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00014                
00015    (A list of authors and contributors can be found in the PDF manual)
00016 
00017    License:         MIT (X11), see file LICENSE in the base directory
00018 ============================================================================= */
00019 
00026 #include <string>
00027 
00028 #include "viennacl/generator/traits/general_purpose_traits.hpp"
00029 #include "viennacl/generator/forwards.h"
00030 #include "viennacl/generator/meta_tools/utils.hpp"
00031 #include "viennacl/generator/elementwise_modifier.hpp"
00032 #include "viennacl/ocl/local_mem.hpp"
00033 #include "viennacl/ocl/handle.hpp"
00034 #include "viennacl/forwards.h"
00035 #include "CL/cl.h"
00036 
00037 namespace viennacl
00038 {
00039   namespace generator
00040   {
00041     namespace result_of 
00042     {
00043 
00044       class runtime_wrapper
00045       {
00046         protected:
00047                 bool is_temporary_;
00048                 std::string name_;
00049                 int arg_id_;
00050                 
00051         public:
00052                 runtime_wrapper(bool _is_temporary, std::string const & _name, int _arg_id) 
00053                  : is_temporary_(_is_temporary), name_(_name), arg_id_(_arg_id) {}
00054                  
00055                 bool is_temporary() const { return is_temporary_; }
00056                 int arg_id() const { return arg_id_; }
00057                 std::string name() const { return name_; }
00058                 
00059                 virtual void enqueue(unsigned int arg_pos, 
00060                                      viennacl::ocl::kernel & k,
00061                                      std::map<unsigned int, viennacl::any> & runtime_args,
00062                                      std::map<std::string, viennacl::ocl::handle<cl_mem> > & temporaries) = 0;
00063       };
00064 
00065       class shared_memory_wrapper : public runtime_wrapper
00066       {
00067         public:
00068                 shared_memory_wrapper() : runtime_wrapper(true, "shared_memory_ptr", -1 ){ }
00069         
00070                 void enqueue(unsigned int arg_pos,
00071                              viennacl::ocl::kernel & k,
00072                              std::map<unsigned int, viennacl::any> & runtime_args,
00073                              std::map<std::string, viennacl::ocl::handle<cl_mem> > & temporaries)
00074                 {
00075                         unsigned int lmem_size = k.local_work_size();
00076                         k.arg(arg_pos, viennacl::ocl::local_mem(lmem_size*sizeof(float)));
00077                 }
00078         
00079       };
00080 
00081       template <class T, class SIZE_T>
00082       struct vector_runtime_wrapper : public runtime_wrapper 
00083       {
00084         private:
00085           unsigned int size_id_;
00086           
00087           template<typename ScalarType, unsigned int Alignment>
00088           typename SIZE_T::size_type size(viennacl::vector<ScalarType,Alignment> * size_arg) { return size_arg->size(); }
00089 
00090           template<typename ScalarType, class F, unsigned int Alignment>
00091           typename SIZE_T::size_type size(viennacl::matrix<ScalarType,F,Alignment> * size_arg) { return size_arg->size2(); }
00092           
00093           template<typename ScalarType, unsigned int Alignment>
00094           typename SIZE_T::size_type internal_size(viennacl::vector<ScalarType,Alignment> * size_arg) { return size_arg->internal_size(); }
00095 
00096           template<typename ScalarType, class F, unsigned int Alignment>
00097           typename SIZE_T::size_type internal_size(viennacl::matrix<ScalarType,F,Alignment> * size_arg) { return size_arg->internal_size2(); }
00098           
00099     public:
00100           vector_runtime_wrapper(bool _is_temporary, std::string const & _name, int _arg_id, unsigned int _size_id) 
00101             : runtime_wrapper(_is_temporary,_name,_arg_id),size_id_(_size_id) {}
00102             
00103           void enqueue(unsigned int arg_pos,
00104                        viennacl::ocl::kernel & k,
00105                        std::map<unsigned int, viennacl::any> & runtime_args,
00106                        std::map<std::string, 
00107                        viennacl::ocl::handle<cl_mem> > & temporaries)
00108           { 
00109             SIZE_T * size_arg = viennacl::any_cast<SIZE_T * >(runtime_args[size_id_]);
00110             viennacl::ocl::handle<cl_mem> handle = NULL;
00111             if(is_temporary_)
00112             {
00113                     if(temporaries.find(name_)==temporaries.end())
00114                     {
00115                             temporaries.insert(
00116                              std::make_pair(name_,
00117                                             viennacl::ocl::handle<cl_mem>(
00118                                               viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE,
00119                                                                                              size_arg->internal_size()*sizeof(typename T::value_type))
00120                                                                                             )
00121                                            )
00122                                               );
00123                     }
00124                     handle = temporaries[name_];
00125             }
00126             else
00127             {
00128                     T * current_arg = viennacl::any_cast<T * >(runtime_args[arg_id_]);
00129                     handle = current_arg->handle();
00130             }
00131             k.arg(arg_pos, handle );
00132             k.arg(arg_pos+1,cl_uint(size(size_arg)));
00133             k.arg(arg_pos+2,cl_uint(internal_size(size_arg)));
00134           }
00135       };
00136 
00137       template <class T, class SIZE_DESCRIPTOR>
00138       struct vector_expression : public runtime_wrapper
00139       {
00140         typedef T type;
00141         typedef typename SIZE_DESCRIPTOR::ScalarType ScalarType;
00142         static const unsigned int Alignment = SIZE_DESCRIPTOR::Alignment;
00143 
00144         static runtime_wrapper * runtime_descriptor()
00145         {
00146           return new vector_runtime_wrapper<viennacl::vector<ScalarType,Alignment>,
00147                                             typename SIZE_DESCRIPTOR::runtime_type>(viennacl::generator::is_temporary<T>::value,
00148                                                                                     T::name(),
00149                                                                                     T::id,SIZE_DESCRIPTOR::id);
00150         }
00151         
00152         static const std::string size_expression() 
00153         {
00154           return SIZE_DESCRIPTOR::size2_name();
00155         }
00156         
00157         static const std::string internal_size_expression() 
00158         {
00159           return SIZE_DESCRIPTOR::internal_size2_name() + "/" + to_string(Alignment);
00160         }
00161       };
00162 
00163       template <class T, class SIZE1_T, class SIZE2_T>
00164       struct matrix_runtime_wrapper : public runtime_wrapper
00165       {
00166         private:
00167                 unsigned int size1_id_;
00168                 unsigned int size2_id_;
00169         public:
00170           matrix_runtime_wrapper(bool _is_temporary, 
00171                                  std::string const & _name,
00172                                  int _arg_id,
00173                                  unsigned int _size1_id,
00174                                  unsigned int _size2_id) 
00175                                 : runtime_wrapper(_is_temporary,_name,_arg_id), size1_id_(_size1_id), size2_id_(_size2_id) {}
00176                                 
00177           unsigned int n_elements(){ return size1_id_*size2_id_; }
00178           
00179           void enqueue(unsigned int arg_pos,
00180                        viennacl::ocl::kernel & k,
00181                        std::map<unsigned int, viennacl::any> & runtime_args,
00182                        std::map<std::string,
00183                        viennacl::ocl::handle<cl_mem> > & temporaries)
00184           { 
00185                   if (is_temporary_) {}
00186                   
00187                   T * current_arg = any_cast<T * >(runtime_args[arg_id_]);
00188                   SIZE1_T * size1_arg = any_cast<SIZE1_T * >(runtime_args[size1_id_]);
00189                   SIZE2_T * size2_arg = any_cast<SIZE2_T * >(runtime_args[size2_id_]);
00190                   k.arg(arg_pos, current_arg->handle());
00191                   k.arg(arg_pos+1,cl_uint(size1_arg->size1()));
00192                   k.arg(arg_pos+2,cl_uint(size2_arg->size2()));
00193                   k.arg(arg_pos+3,cl_uint(size1_arg->internal_size1()));
00194                   k.arg(arg_pos+4,cl_uint(size2_arg->internal_size2()));
00195           }
00196       };
00197           
00198       template <class T, class SIZE1_DESCRIPTOR, class SIZE2_DESCRIPTOR>
00199       struct matrix_expression 
00200       {
00201         typedef typename SIZE1_DESCRIPTOR::ScalarType ScalarType;
00202         typedef typename SIZE1_DESCRIPTOR::Layout Layout;
00203         static const unsigned int Alignment = SIZE1_DESCRIPTOR::Alignment;
00204         
00205         static runtime_wrapper * runtime_descriptor()
00206         {
00207           return new matrix_runtime_wrapper<viennacl::matrix<ScalarType,Layout,Alignment>,
00208                                             typename SIZE1_DESCRIPTOR::runtime_type,
00209                                             typename SIZE2_DESCRIPTOR::runtime_type>(is_temporary<T>::value,T::name(),
00210                                                                                      T::id,SIZE1_DESCRIPTOR::id,
00211                                                                                      SIZE2_DESCRIPTOR::id);
00212         }
00213         
00214         static const std::string size1_expression() 
00215         {
00216           return SIZE1_DESCRIPTOR::size1_name();
00217         }
00218 
00219         static const std::string size2_expression() 
00220         {
00221           return SIZE2_DESCRIPTOR::size2_name();
00222         }
00223 
00224         static const std::string internal_size1_expression() 
00225         {
00226           return SIZE1_DESCRIPTOR::internal_size1_name() + "/" + to_string(Alignment);
00227         }
00228 
00229         static const std::string internal_size2_expression() 
00230         {
00231           return SIZE2_DESCRIPTOR::internal_size2_name() + "/" + to_string(Alignment);
00232         }
00233 
00234         typedef T type;
00235       };
00236 
00237       template <class T>
00238       struct scalar_size_descriptor
00239       {
00240               static unsigned int size(viennacl::ocl::kernel & k) { return 1; }
00241       };
00242 
00243       template <class LHS, class RHS, bool is_temporary>
00244       struct scalar_size_descriptor<compound_node<LHS,inner_prod_type,RHS,is_temporary> >
00245       {
00246               static unsigned int size(viennacl::ocl::kernel & k)
00247               {
00248                       return k.global_work_size(0)/k.local_work_size(0);
00249               }
00250       };
00251 
00252       template <class T>
00253       struct scalar_runtime_wrapper: public runtime_wrapper
00254       {
00255         typedef typename T::ScalarType ScalarType;
00256         
00257         scalar_runtime_wrapper(bool _is_temporary, std::string const & _name, int _arg_id) : runtime_wrapper(_is_temporary,_name,_arg_id){}
00258         
00259         void enqueue(unsigned int arg_pos,
00260                      viennacl::ocl::kernel & k,
00261                      std::map<unsigned int,
00262                      viennacl::any> & runtime_args, 
00263                      std::map<std::string, 
00264                      viennacl::ocl::handle<cl_mem> > & temporaries)
00265         {
00266                       if(is_temporary_)
00267                       {
00268                               if(temporaries.find(name_)==temporaries.end()) 
00269                               {
00270                                       temporaries.insert(
00271                                          std::make_pair(name_,
00272                                   viennacl::ocl::handle<cl_mem>(
00273                                   viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE,
00274                                                                                  scalar_size_descriptor<T>::size(k)*sizeof(ScalarType))
00275                                                                )
00276                                  )
00277                                );
00278                               }
00279                               k.arg(arg_pos, temporaries[name_]);
00280                       }
00281                       
00282                       if(arg_id_==-2)
00283                               k.arg(arg_pos, temporaries[name_]);
00284                       else
00285                       {
00286                               viennacl::scalar<ScalarType>* current_arg = any_cast<viennacl::scalar<ScalarType> * >(runtime_args[arg_id_]);
00287                               k.arg(arg_pos, current_arg->handle());
00288                       }
00289                 
00290         }
00291       };
00292 
00293       template <unsigned int ID, class ScalarType>
00294       struct scalar_runtime_wrapper<viennacl::generator::cpu_symbolic_scalar<ID, ScalarType> >: public runtime_wrapper
00295       {
00296         scalar_runtime_wrapper(bool _is_temporary, std::string const & _name, int _arg_id) : runtime_wrapper(_is_temporary,_name,_arg_id){ }
00297         
00298         void enqueue(unsigned int arg_pos,
00299                      viennacl::ocl::kernel & k,
00300                      std::map<unsigned int, viennacl::any> & runtime_args,
00301                      std::map<std::string, viennacl::ocl::handle<cl_mem> > & temporaries)
00302         {
00303           ScalarType* current_arg = any_cast<ScalarType * >(runtime_args[arg_id_]);
00304           k.arg(arg_pos, cl_float(*current_arg));
00305         }
00306       };
00307           
00308       template <class T>
00309       struct scalar_expression 
00310       {
00311         typedef typename T::ScalarType ScalarType;
00312         
00313         static runtime_wrapper * runtime_descriptor()
00314         {
00315           return new scalar_runtime_wrapper<T>(is_temporary<T>::value,T::name(),T::id);
00316         }
00317       };
00318 
00319       /*
00320        * Compound Nodes - General case
00321        */
00322       template <class T>
00323       struct expression_type 
00324       {
00325         typedef NullType Result;
00326       };
00327 
00328       template <class LHS, class OP, class RHS, bool is_temporary>
00329       struct expression_type<compound_node<LHS,OP,RHS,is_temporary> > 
00330       {
00331         private:
00332           typedef typename expression_type<LHS>::Result LHS_Result;
00333           typedef typename expression_type<RHS>::Result RHS_Result;
00334           
00335         public:
00336           typedef typename expression_type<compound_node<LHS_Result, OP, RHS_Result,is_temporary> >::Result Result;
00337       };
00338 
00339       /*
00340        * Compound Nodes - usual operators
00341        */
00342       template <class LHS, class LHS_SIZE_DESCRIPTOR ,class OP ,class RHS, class RHS_SIZE_DESCRIPTOR ,bool is_temporary>
00343       struct expression_type<compound_node<vector_expression<LHS,LHS_SIZE_DESCRIPTOR>,
00344                                            OP,
00345                                            vector_expression<RHS,RHS_SIZE_DESCRIPTOR>,
00346                                            is_temporary>
00347                             >
00348       {
00349         private:
00350           typedef compound_node<LHS ,OP, RHS, is_temporary> T;
00351           
00352         public:
00353           typedef vector_expression<T, LHS_SIZE_DESCRIPTOR> Result;
00354       };
00355 
00356 
00357       template <class LHS, class LHS_SIZE1_DESCRIPTOR, class LHS_SIZE2_DESCRIPTOR,
00358                 class OP,
00359                 class RHS, class RHS_SIZE1_DESCRIPTOR, class RHS_SIZE2_DESCRIPTOR,
00360                 bool is_temporary>
00361       struct expression_type<compound_node<matrix_expression<LHS, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR>,
00362                                            OP,
00363                                            matrix_expression<RHS, RHS_SIZE1_DESCRIPTOR, RHS_SIZE2_DESCRIPTOR>,
00364                                            is_temporary> 
00365                              > 
00366       {
00367         private:
00368           typedef compound_node<LHS ,OP, RHS, is_temporary> T;
00369           
00370         public:
00371           typedef matrix_expression<T, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR> Result;
00372       };
00373 
00374       template <class LHS, class OP, class RHS, bool is_temporary>
00375       struct expression_type<compound_node<scalar_expression<LHS>, 
00376                                            OP,
00377                                            scalar_expression<RHS>,
00378                                            is_temporary> 
00379                             > 
00380       {
00381         private:
00382           typedef compound_node<LHS ,OP, RHS, is_temporary> T;
00383           
00384         public:
00385           typedef scalar_expression<T> Result;
00386       };
00387 
00388       /*
00389        * Scalar Operators
00390        */
00391       template <class LHS, class LHS_SIZE_DESCRIPTOR,
00392                 class OP,
00393                 class RHS,
00394                 bool is_temporary>
00395       struct  expression_type<compound_node<vector_expression<LHS,LHS_SIZE_DESCRIPTOR>,
00396                                             OP,
00397                                             scalar_expression<RHS>,
00398                                             is_temporary> > 
00399       {
00400         private:
00401           typedef compound_node<LHS ,OP, RHS, is_temporary> T;
00402         public:
00403           typedef vector_expression<T, LHS_SIZE_DESCRIPTOR> Result;
00404       };
00405 
00406       template <class LHS,
00407                 class OP,
00408                 class RHS, class RHS_SIZE_DESCRIPTOR,
00409                 bool is_temporary>
00410       struct expression_type<compound_node<scalar_expression<LHS>,
00411                                            OP,
00412                                            vector_expression<RHS,RHS_SIZE_DESCRIPTOR>,
00413                                            is_temporary>
00414                             > 
00415       {
00416         private:
00417           typedef compound_node<LHS ,OP, RHS, is_temporary> T;
00418         public:
00419           typedef vector_expression<T, RHS_SIZE_DESCRIPTOR> Result;
00420       };
00421 
00422 
00423       template <class LHS, class LHS_SIZE1_DESCRIPTOR, class LHS_SIZE2_DESCRIPTOR,
00424                 class OP,
00425                 class RHS, bool is_temporary>
00426       struct expression_type<compound_node<matrix_expression<LHS,LHS_SIZE1_DESCRIPTOR,LHS_SIZE2_DESCRIPTOR>,
00427                                            OP,
00428                                            scalar_expression<RHS>,
00429                                            is_temporary>
00430                             > 
00431       {
00432         private:
00433           typedef compound_node<LHS ,OP, RHS, is_temporary> T;
00434         public:
00435           typedef matrix_expression<T, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR> Result;
00436       };
00437 
00438       template <class LHS, 
00439                 class OP,
00440                 class RHS, class RHS_SIZE1_DESCRIPTOR, class RHS_SIZE2_DESCRIPTOR,
00441                 bool is_temporary>
00442       struct expression_type<compound_node<scalar_expression<LHS>,
00443                                            OP,
00444                                            matrix_expression<RHS,RHS_SIZE1_DESCRIPTOR, RHS_SIZE2_DESCRIPTOR>,
00445                                            is_temporary>
00446                             >
00447       {
00448         private:
00449           typedef compound_node<LHS ,OP, RHS, is_temporary> T;
00450         public:
00451           typedef matrix_expression<T, RHS_SIZE1_DESCRIPTOR, RHS_SIZE2_DESCRIPTOR> Result;
00452       };
00453 
00454 
00455       /*
00456        * Compound Nodes - Non Trivial Operators
00457        */
00458 
00459       //Matrix-Vector product
00460       template <class LHS, class LHS_SIZE1_DESCRIPTOR, class LHS_SIZE2_DESCRIPTOR,
00461                 class RHS, class RHS_SIZE_DESCRIPTOR,
00462                 bool is_temporary>
00463       struct expression_type<compound_node<matrix_expression<LHS, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR>,
00464                                            prod_type,
00465                                            vector_expression<RHS,RHS_SIZE_DESCRIPTOR>,
00466                                            is_temporary> 
00467                             >
00468       {
00469         typedef vector_expression<compound_node<LHS,prod_type,RHS,is_temporary>, LHS_SIZE1_DESCRIPTOR > Result;
00470       };
00471 
00472       template <class T>
00473       struct expression_type<inner_prod_impl_t<T> >
00474       {
00475               typedef scalar_expression<T> Result;
00476       };
00477 
00478       //Matrix-Matrix product
00479       template <class LHS, class LHS_SIZE1_DESCRIPTOR, class LHS_SIZE2_DESCRIPTOR,
00480                 class RHS, class RHS_SIZE1_DESCRIPTOR, class RHS_SIZE2_DESCRIPTOR,
00481                 bool is_temporary>
00482       struct expression_type<compound_node<matrix_expression<LHS, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR>,
00483                                            prod_type,
00484                                            matrix_expression<RHS,RHS_SIZE1_DESCRIPTOR,RHS_SIZE2_DESCRIPTOR>,
00485                                            is_temporary> 
00486                             >
00487       {
00488         typedef matrix_expression<compound_node<LHS,prod_type,RHS,is_temporary>, LHS_SIZE1_DESCRIPTOR, RHS_SIZE2_DESCRIPTOR > Result;
00489       };
00490 
00491       //Inner product
00492       template <class LHS, class LHS_SIZE_DESCRIPTOR,
00493                 class RHS, class RHS_SIZE_DESCRIPTOR,
00494                 bool is_temporary>
00495       struct expression_type< compound_node<vector_expression<LHS,LHS_SIZE_DESCRIPTOR>,
00496                                             inner_prod_type,
00497                                             vector_expression<RHS,RHS_SIZE_DESCRIPTOR>,
00498                                             is_temporary>
00499                             >
00500       {
00501         typedef scalar_expression<compound_node<LHS,inner_prod_type,RHS,is_temporary> > Result;
00502       };
00503 
00504 
00505       /*
00506        * Elementwise Modifiers
00507        */
00508       template <class T, std::string (*U)()>
00509       struct expression_type< elementwise_modifier_impl<T,U> > 
00510       {
00511         typedef typename expression_type<T>::Result Result;
00512       };
00513 
00514       template <class T, class SIZE_DESCRIPTOR>
00515       struct expression_type< vector_expression<T,SIZE_DESCRIPTOR> > 
00516       {
00517         typedef typename expression_type<T>::Result Result;
00518       };
00519 
00520       template <class T, class SIZE1_DESCRIPTOR, class SIZE2_DESCRIPTOR>
00521       struct expression_type< matrix_expression<T,SIZE1_DESCRIPTOR,SIZE2_DESCRIPTOR> > 
00522       {
00523         typedef typename expression_type<T>::Result Result;
00524       };
00525 
00526       template <class T>
00527       struct expression_type< scalar_expression<T> > 
00528       {
00529         typedef typename expression_type<T>::Result Result;
00530       };
00531 
00532       /*
00533        * Symbolic Vectors
00534        */
00535 
00536       template <unsigned int ID,typename SCALARTYPE, unsigned int ALIGNMENT>
00537       struct expression_type< symbolic_vector<ID,SCALARTYPE,ALIGNMENT> > 
00538       {
00539         typedef vector_expression<symbolic_vector<ID,SCALARTYPE,ALIGNMENT>,
00540                                   symbolic_vector<ID,SCALARTYPE,ALIGNMENT> > Result;
00541       };
00542 
00543       template <class Ref>
00544       struct  expression_type<tmp_symbolic_vector<Ref> > 
00545       {
00546         typedef vector_expression<tmp_symbolic_vector<Ref>, Ref> Result;
00547       };
00548 
00549       /*
00550        * Symbolic Matrices
00551        */
00552 
00553       template <unsigned int ID,typename SCALARTYPE, class F, unsigned int ALIGNMENT>
00554       struct expression_type<symbolic_matrix<ID,SCALARTYPE,F,ALIGNMENT> > 
00555       {
00556         private:
00557           typedef symbolic_matrix<ID,SCALARTYPE,F,ALIGNMENT> T;
00558         public:
00559           typedef matrix_expression<T, T, T> Result;
00560       };
00561 
00562       template <class Ref>
00563       struct expression_type<tmp_symbolic_matrix<Ref> > 
00564       {
00565         typedef matrix_expression<tmp_symbolic_matrix<Ref>, Ref, Ref > Result;
00566       };
00567 
00568       /*
00569        * Symbolic Scalars
00570        */
00571 
00572       template <unsigned int ID, typename SCALARTYPE>
00573       struct expression_type<cpu_symbolic_scalar<ID, SCALARTYPE> > 
00574       {
00575         typedef scalar_expression<cpu_symbolic_scalar<ID, SCALARTYPE> > Result;
00576       };
00577 
00578       template <unsigned int ID, typename SCALARTYPE>
00579       struct expression_type<gpu_symbolic_scalar<ID, SCALARTYPE> > 
00580       {
00581         typedef scalar_expression< gpu_symbolic_scalar<ID, SCALARTYPE> > Result;
00582       };
00583 
00584 
00585     }
00586   }
00587 }
00588 
00589 #endif
00590 
00591