ViennaCL - The Vienna Computing Library
1.5.0
|
00001 #ifndef VIENNACL_SCHEDULER_EXECUTE_UTIL_HPP 00002 #define VIENNACL_SCHEDULER_EXECUTE_UTIL_HPP 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2013, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00021 00026 #include <assert.h> 00027 00028 #include "viennacl/forwards.h" 00029 #include "viennacl/scalar.hpp" 00030 #include "viennacl/vector.hpp" 00031 #include "viennacl/matrix.hpp" 00032 #include "viennacl/scheduler/forwards.h" 00033 00034 namespace viennacl 00035 { 00036 namespace scheduler 00037 { 00038 namespace detail 00039 { 00040 // 00041 inline lhs_rhs_element const & extract_representative_vector(statement const & s, lhs_rhs_element const & element) 00042 { 00043 switch (element.type_family) 00044 { 00045 case VECTOR_TYPE_FAMILY: 00046 return element; 00047 case COMPOSITE_OPERATION_FAMILY: 00048 { 00049 statement_node const & leaf = s.array()[element.node_index]; 00050 00051 if (leaf.op.type_family == OPERATION_UNARY_TYPE_FAMILY) 00052 return extract_representative_vector(s, leaf.lhs); 00053 switch (leaf.op.type) 00054 { 00055 case OPERATION_BINARY_ADD_TYPE: 00056 case OPERATION_BINARY_SUB_TYPE: 00057 case OPERATION_BINARY_MULT_TYPE: 00058 case OPERATION_BINARY_DIV_TYPE: 00059 case OPERATION_BINARY_ELEMENT_PROD_TYPE: 00060 case OPERATION_BINARY_ELEMENT_DIV_TYPE: 00061 return extract_representative_vector(s, leaf.lhs); 00062 case OPERATION_BINARY_MAT_VEC_PROD_TYPE: 00063 return extract_representative_vector(s, leaf.rhs); 00064 default: 00065 throw statement_not_supported_exception("Vector leaf encountered an invalid binary operation!"); 00066 } 00067 } 00068 default: 00069 throw statement_not_supported_exception("Vector leaf encountered an invalid node type!"); 00070 } 00071 } 00072 00073 00074 // helper routines for extracting the scalar type 00075 inline float convert_to_float(float f) { return f; } 00076 inline float convert_to_float(double d) { return static_cast<float>(d); } 00077 inline float convert_to_float(lhs_rhs_element const & el) 00078 { 00079 if (el.type_family == SCALAR_TYPE_FAMILY && el.subtype == HOST_SCALAR_TYPE && el.numeric_type == FLOAT_TYPE) 00080 return el.host_float; 00081 if (el.type_family == SCALAR_TYPE_FAMILY && el.subtype == DEVICE_SCALAR_TYPE && el.numeric_type == FLOAT_TYPE) 00082 return *el.scalar_float; 00083 00084 throw statement_not_supported_exception("Cannot convert to float"); 00085 } 00086 00087 // helper routines for extracting the scalar type 00088 inline double convert_to_double(float d) { return static_cast<double>(d); } 00089 inline double convert_to_double(double d) { return d; } 00090 inline double convert_to_double(lhs_rhs_element const & el) 00091 { 00092 if (el.type_family == SCALAR_TYPE_FAMILY && el.subtype == HOST_SCALAR_TYPE && el.numeric_type == DOUBLE_TYPE) 00093 return el.host_double; 00094 if (el.type_family == SCALAR_TYPE_FAMILY && el.subtype == DEVICE_SCALAR_TYPE && el.numeric_type == DOUBLE_TYPE) 00095 return *el.scalar_double; 00096 00097 throw statement_not_supported_exception("Cannot convert to double"); 00098 } 00099 00101 00102 inline void new_element(lhs_rhs_element & new_elem, lhs_rhs_element const & old_element) 00103 { 00104 new_elem.type_family = old_element.type_family; 00105 new_elem.subtype = old_element.subtype; 00106 new_elem.numeric_type = old_element.numeric_type; 00107 if (new_elem.type_family == SCALAR_TYPE_FAMILY) 00108 { 00109 assert(new_elem.subtype == DEVICE_SCALAR_TYPE && bool("Expected a device scalar in root node")); 00110 00111 switch (new_elem.numeric_type) 00112 { 00113 case FLOAT_TYPE: 00114 new_elem.scalar_float = new viennacl::scalar<float>(); 00115 return; 00116 case DOUBLE_TYPE: 00117 new_elem.scalar_double = new viennacl::scalar<double>(); 00118 return; 00119 default: 00120 throw statement_not_supported_exception("Invalid vector type for vector construction"); 00121 } 00122 } 00123 else if (new_elem.type_family == VECTOR_TYPE_FAMILY) 00124 { 00125 assert(new_elem.subtype == DENSE_VECTOR_TYPE && bool("Expected a dense vector in root node")); 00126 00127 switch (new_elem.numeric_type) 00128 { 00129 case FLOAT_TYPE: 00130 new_elem.vector_float = new viennacl::vector<float>((old_element.vector_float)->size()); 00131 return; 00132 case DOUBLE_TYPE: 00133 new_elem.vector_double = new viennacl::vector<double>((old_element.vector_float)->size()); 00134 return; 00135 default: 00136 throw statement_not_supported_exception("Invalid vector type for vector construction"); 00137 } 00138 } 00139 else if (new_elem.type_family == MATRIX_TYPE_FAMILY) 00140 { 00141 assert( (new_elem.subtype == DENSE_COL_MATRIX_TYPE || new_elem.subtype == DENSE_ROW_MATRIX_TYPE) 00142 && bool("Expected a dense matrix in root node")); 00143 00144 if (new_elem.subtype == DENSE_COL_MATRIX_TYPE) 00145 { 00146 switch (new_elem.numeric_type) 00147 { 00148 case FLOAT_TYPE: 00149 new_elem.matrix_col_float = new viennacl::matrix<float, viennacl::column_major>((old_element.matrix_col_float)->size1(), (old_element.matrix_col_float)->size2()); 00150 return; 00151 case DOUBLE_TYPE: 00152 new_elem.matrix_col_double = new viennacl::matrix<double, viennacl::column_major>((old_element.matrix_col_double)->size1(), (old_element.matrix_col_double)->size2()); 00153 return; 00154 default: 00155 throw statement_not_supported_exception("Invalid vector type for vector construction"); 00156 } 00157 } 00158 else if (new_elem.subtype == DENSE_ROW_MATRIX_TYPE) 00159 { 00160 switch (new_elem.numeric_type) 00161 { 00162 case FLOAT_TYPE: 00163 new_elem.matrix_row_float = new viennacl::matrix<float, viennacl::row_major>((old_element.matrix_row_float)->size1(), (old_element.matrix_row_float)->size2()); 00164 return; 00165 case DOUBLE_TYPE: 00166 new_elem.matrix_row_double = new viennacl::matrix<double, viennacl::row_major>((old_element.matrix_row_double)->size1(), (old_element.matrix_row_double)->size2()); 00167 return; 00168 default: 00169 throw statement_not_supported_exception("Invalid vector type for vector construction"); 00170 } 00171 } 00172 else 00173 throw statement_not_supported_exception("Expected a dense matrix in root node when creating a temporary"); 00174 } 00175 else 00176 throw statement_not_supported_exception("Unknown type familty when creating new temporary object"); 00177 } 00178 00179 inline void delete_element(lhs_rhs_element & elem) 00180 { 00181 if (elem.type_family == SCALAR_TYPE_FAMILY) 00182 { 00183 switch (elem.numeric_type) 00184 { 00185 case FLOAT_TYPE: 00186 delete elem.scalar_float; 00187 return; 00188 case DOUBLE_TYPE: 00189 delete elem.scalar_double; 00190 return; 00191 default: 00192 throw statement_not_supported_exception("Invalid vector type for vector destruction"); 00193 } 00194 } 00195 else if (elem.type_family == VECTOR_TYPE_FAMILY) 00196 { 00197 switch (elem.numeric_type) 00198 { 00199 case FLOAT_TYPE: 00200 delete elem.vector_float; 00201 return; 00202 case DOUBLE_TYPE: 00203 delete elem.vector_double; 00204 return; 00205 default: 00206 throw statement_not_supported_exception("Invalid vector type for vector destruction"); 00207 } 00208 } 00209 else if (elem.type_family == MATRIX_TYPE_FAMILY) 00210 { 00211 if (elem.subtype == DENSE_COL_MATRIX_TYPE) 00212 { 00213 switch (elem.numeric_type) 00214 { 00215 case FLOAT_TYPE: 00216 delete elem.matrix_col_float; 00217 return; 00218 case DOUBLE_TYPE: 00219 delete elem.matrix_col_double; 00220 return; 00221 default: 00222 throw statement_not_supported_exception("Invalid vector type for vector destruction"); 00223 } 00224 } 00225 else if (elem.subtype == DENSE_ROW_MATRIX_TYPE) 00226 { 00227 switch (elem.numeric_type) 00228 { 00229 case FLOAT_TYPE: 00230 delete elem.matrix_row_float; 00231 return; 00232 case DOUBLE_TYPE: 00233 delete elem.matrix_row_double; 00234 return; 00235 default: 00236 throw statement_not_supported_exception("Invalid vector type for vector destruction"); 00237 } 00238 } 00239 else 00240 throw statement_not_supported_exception("Expected a dense matrix in root node when deleting temporary"); 00241 } 00242 else 00243 throw statement_not_supported_exception("Unknown type familty when deleting temporary object"); 00244 } 00245 00246 } // namespace detail 00247 00248 00249 } // namespace scheduler 00250 } // namespace viennacl 00251 00252 #endif 00253