ViennaCL - The Vienna Computing Library  1.5.2
viennacl/scheduler/execute_scalar_assign.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_SCHEDULER_EXECUTE_SCALAR_ASSIGN_HPP
00002 #define VIENNACL_SCHEDULER_EXECUTE_SCALAR_ASSIGN_HPP
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2014, 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 "viennacl/forwards.h"
00027 #include "viennacl/scheduler/forwards.h"
00028 #include "viennacl/scheduler/execute_vector_dispatcher.hpp"
00029 
00030 namespace viennacl
00031 {
00032   namespace scheduler
00033   {
00035     inline void execute_scalar_assign_composite(statement const & s, statement_node const & root_node)
00036     {
00037       statement_node const & leaf = s.array()[root_node.rhs.node_index];
00038 
00039       if (leaf.op.type  == OPERATION_BINARY_INNER_PROD_TYPE) // alpha = inner_prod( (x), (y) ) with x, y being either vectors or expressions
00040       {
00041         assert(root_node.lhs.type_family == SCALAR_TYPE_FAMILY && bool("Inner product requires assignment to scalar type!"));
00042 
00043         if (   leaf.lhs.type_family == VECTOR_TYPE_FAMILY
00044             && leaf.rhs.type_family == VECTOR_TYPE_FAMILY)
00045 
00046         {
00047           detail::inner_prod_impl(leaf.lhs, leaf.rhs, root_node.lhs);
00048         }
00049         else if (   leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY  // temporary for (x)
00050                  && leaf.rhs.type_family == VECTOR_TYPE_FAMILY)
00051         {
00052           statement_node new_root_x;
00053 
00054           detail::new_element(new_root_x.lhs, leaf.rhs);
00055 
00056           new_root_x.op.type_family = OPERATION_BINARY_TYPE_FAMILY;
00057           new_root_x.op.type        = OPERATION_BINARY_ASSIGN_TYPE;
00058 
00059           new_root_x.rhs.type_family  = COMPOSITE_OPERATION_FAMILY;
00060           new_root_x.rhs.subtype      = INVALID_SUBTYPE;
00061           new_root_x.rhs.numeric_type = INVALID_NUMERIC_TYPE;
00062           new_root_x.rhs.node_index   = leaf.lhs.node_index;
00063 
00064           // work on subexpression:
00065           // TODO: Catch exception, free temporary, then rethrow
00066           detail::execute_composite(s, new_root_x);
00067 
00068           detail::inner_prod_impl(new_root_x.lhs, leaf.rhs, root_node.lhs);
00069 
00070           detail::delete_element(new_root_x.lhs);
00071         }
00072         else if (   leaf.lhs.type_family == VECTOR_TYPE_FAMILY
00073                  && leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY) // temporary for (y)
00074         {
00075           statement_node new_root_y;
00076 
00077           detail::new_element(new_root_y.lhs, leaf.lhs);
00078 
00079           new_root_y.op.type_family = OPERATION_BINARY_TYPE_FAMILY;
00080           new_root_y.op.type        = OPERATION_BINARY_ASSIGN_TYPE;
00081 
00082           new_root_y.rhs.type_family  = COMPOSITE_OPERATION_FAMILY;
00083           new_root_y.rhs.subtype      = INVALID_SUBTYPE;
00084           new_root_y.rhs.numeric_type = INVALID_NUMERIC_TYPE;
00085           new_root_y.rhs.node_index   = leaf.rhs.node_index;
00086 
00087           // work on subexpression:
00088           // TODO: Catch exception, free temporary, then rethrow
00089           detail::execute_composite(s, new_root_y);
00090 
00091           detail::inner_prod_impl(leaf.lhs, new_root_y.lhs, root_node.lhs);
00092 
00093           detail::delete_element(new_root_y.lhs);
00094         }
00095         else if (   leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY   // temporary for (x)
00096                  && leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY)  // temporary for (y)
00097         {
00098           // extract size information from vectors:
00099           lhs_rhs_element const & temp_node = detail::extract_representative_vector(s, leaf.lhs);
00100 
00101           // temporary for (x)
00102           statement_node new_root_x;
00103           detail::new_element(new_root_x.lhs, temp_node);
00104 
00105           new_root_x.op.type_family = OPERATION_BINARY_TYPE_FAMILY;
00106           new_root_x.op.type        = OPERATION_BINARY_ASSIGN_TYPE;
00107 
00108           new_root_x.rhs.type_family  = COMPOSITE_OPERATION_FAMILY;
00109           new_root_x.rhs.subtype      = INVALID_SUBTYPE;
00110           new_root_x.rhs.numeric_type = INVALID_NUMERIC_TYPE;
00111           new_root_x.rhs.node_index   = leaf.lhs.node_index;
00112 
00113           // work on subexpression:
00114           // TODO: Catch exception, free temporary, then rethrow
00115           detail::execute_composite(s, new_root_x);
00116 
00117           // temporary for (y)
00118           statement_node new_root_y;
00119           detail::new_element(new_root_y.lhs, temp_node);
00120 
00121           new_root_y.op.type_family = OPERATION_BINARY_TYPE_FAMILY;
00122           new_root_y.op.type        = OPERATION_BINARY_ASSIGN_TYPE;
00123 
00124           new_root_y.rhs.type_family  = COMPOSITE_OPERATION_FAMILY;
00125           new_root_y.rhs.subtype      = INVALID_SUBTYPE;
00126           new_root_y.rhs.numeric_type = INVALID_NUMERIC_TYPE;
00127           new_root_y.rhs.node_index   = leaf.rhs.node_index;
00128 
00129           // work on subexpression:
00130           // TODO: Catch exception, free temporary, then rethrow
00131           detail::execute_composite(s, new_root_y);
00132 
00133           // compute inner product:
00134           detail::inner_prod_impl(new_root_x.lhs, new_root_y.lhs, root_node.lhs);
00135 
00136           detail::delete_element(new_root_x.lhs);
00137           detail::delete_element(new_root_y.lhs);
00138         }
00139         else
00140           throw statement_not_supported_exception("Cannot deal with inner product of the provided arguments");
00141       }
00142       else if (   leaf.op.type  == OPERATION_UNARY_NORM_1_TYPE
00143                || leaf.op.type  == OPERATION_UNARY_NORM_2_TYPE
00144                || leaf.op.type  == OPERATION_UNARY_NORM_INF_TYPE)
00145       {
00146         assert(root_node.lhs.type_family == SCALAR_TYPE_FAMILY && bool("Inner product requires assignment to scalar type!"));
00147 
00148         if (leaf.lhs.type_family == VECTOR_TYPE_FAMILY)
00149         {
00150           detail::norm_impl(leaf.lhs, root_node.lhs, leaf.op.type);
00151         }
00152         else if (leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY) //introduce temporary:
00153         {
00154           lhs_rhs_element const & temp_node = detail::extract_representative_vector(s, leaf.lhs);
00155 
00156           statement_node new_root_y;
00157 
00158           detail::new_element(new_root_y.lhs, temp_node);
00159 
00160           new_root_y.op.type_family = OPERATION_BINARY_TYPE_FAMILY;
00161           new_root_y.op.type        = OPERATION_BINARY_ASSIGN_TYPE;
00162 
00163           new_root_y.rhs.type_family  = COMPOSITE_OPERATION_FAMILY;
00164           new_root_y.rhs.subtype      = INVALID_SUBTYPE;
00165           new_root_y.rhs.numeric_type = INVALID_NUMERIC_TYPE;
00166           new_root_y.rhs.node_index   = leaf.lhs.node_index;
00167 
00168           // work on subexpression:
00169           // TODO: Catch exception, free temporary, then rethrow
00170           detail::execute_composite(s, new_root_y);
00171 
00172           detail::norm_impl(new_root_y.lhs, root_node.lhs, leaf.op.type);
00173 
00174           detail::delete_element(new_root_y.lhs);
00175         }
00176         else
00177           throw statement_not_supported_exception("Cannot deal with norm_inf of the provided arguments");
00178       }
00179       else
00180         throw statement_not_supported_exception("Unsupported operation for scalar.");
00181     }
00182 
00183 
00184   }
00185 
00186 } //namespace viennacl
00187 
00188 #endif
00189