Package hedge :: Package backends :: Package jit :: Module lift
[hide private]
[frames] | no frames]

Source Code for Module hedge.backends.jit.lift

  1  """Just-in-time compiling backend.""" 
  2   
  3  from __future__ import division 
  4   
  5  __copyright__ = "Copyright (C) 2008 Andreas Kloeckner" 
  6   
  7  __license__ = """ 
  8  This program is free software: you can redistribute it and/or modify 
  9  it under the terms of the GNU General Public License as published by 
 10  the Free Software Foundation, either version 3 of the License, or 
 11  (at your option) any later version. 
 12   
 13  This program is distributed in the hope that it will be useful, 
 14  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  GNU General Public License for more details. 
 17   
 18  You should have received a copy of the GNU General Public License 
 19  along with this program.  If not, see U{http://www.gnu.org/licenses/}. 
 20  """ 
 21   
 22   
 23   
 24  from pytools import memoize_method 
25 26 27 28 29 -class JitLifter:
30 - def __init__(self, discr):
31 self.discr = discr
32 33 @memoize_method
34 - def make_lift(self, fgroup, with_scale, dtype):
35 discr = self.discr 36 from codepy.cgen import \ 37 FunctionDeclaration, FunctionBody, Typedef, \ 38 Const, Reference, Value, POD, \ 39 Statement, Include, Line, Block, Initializer, Assign, \ 40 For, \ 41 Define 42 43 from pytools import to_uncomplex_dtype 44 45 from codepy.bpl import BoostPythonModule 46 mod = BoostPythonModule() 47 48 S = Statement 49 mod.add_to_preamble([ 50 Include("hedge/face_operators.hpp"), 51 Include("hedge/volume_operators.hpp"), 52 Include("boost/foreach.hpp"), 53 ]) 54 55 mod.add_to_module([ 56 S("namespace ublas = boost::numeric::ublas"), 57 S("using namespace hedge"), 58 S("using namespace pyublas"), 59 Line(), 60 Define("DOFS_PER_EL", fgroup.ldis_loc.node_count()), 61 Define("DOFS_PER_FACE", fgroup.ldis_loc.face_node_count()), 62 Define("FACES_PER_EL", fgroup.ldis_loc.face_count()), 63 Define("FACE_DOFS_PER_EL", "(DOFS_PER_FACE*FACES_PER_EL)"), 64 Define("DIMENSIONS", discr.dimensions), 65 Line(), 66 Typedef(POD(dtype, "value_type")), 67 Typedef(POD(to_uncomplex_dtype(dtype), "uncomplex_type")), 68 ]) 69 70 def if_(cond, result, else_=None): 71 if cond: 72 return [result] 73 else: 74 if else_ is None: 75 return [] 76 else: 77 return [else_]
78 79 fdecl = FunctionDeclaration( 80 Value("void", "lift"), 81 [ 82 Const(Reference(Value("face_group", "fg"))), 83 Value("ublas::matrix<uncomplex_type>", "matrix"), 84 Value("numpy_array<value_type>", "field"), 85 Value("numpy_array<value_type>", "result") 86 ]+if_(with_scale, 87 Const(Reference(Value("numpy_array<double>", 88 "elwise_post_scaling")))) 89 ) 90 91 def make_it(name, is_const=True, tpname="value_type"): 92 if is_const: 93 const = "const_" 94 else: 95 const = "" 96 97 return Initializer( 98 Value("numpy_array<%s>::%siterator" % (tpname, const), name+"_it"), 99 "%s.begin()" % name)
100 101 fbody = Block([ 102 make_it("field"), 103 make_it("result", is_const=False), 104 ]+if_(with_scale, make_it("elwise_post_scaling", tpname="double"))+[ 105 Line(), 106 For("unsigned fg_el_nr = 0", 107 "fg_el_nr < fg.element_count()", 108 "++fg_el_nr", 109 Block([ 110 Initializer( 111 Value("node_number_t", "dest_el_base"), 112 "fg.local_el_to_global_el_base[fg_el_nr]"), 113 Initializer( 114 Value("node_number_t", "src_el_base"), 115 "FACE_DOFS_PER_EL*fg_el_nr"), 116 Line(), 117 For("unsigned i = 0", 118 "i < DOFS_PER_EL", 119 "++i", 120 Block([ 121 Initializer(Value("value_type", "tmp"), 0), 122 Line(), 123 For("unsigned j = 0", 124 "j < FACE_DOFS_PER_EL", 125 "++j", 126 S("tmp += matrix(i, j)*field_it[src_el_base+j]") 127 ), 128 Line(), 129 ]+if_(with_scale, 130 Assign("result_it[dest_el_base+i]", 131 "tmp * value_type(*elwise_post_scaling_it)"), 132 Assign("result_it[dest_el_base+i]", "tmp")) 133 ) 134 ), 135 ]+if_(with_scale, S("elwise_post_scaling_it++")) 136 ) 137 ) 138 ]) 139 140 mod.add_function(FunctionBody(fdecl, fbody)) 141 142 #print "----------------------------------------------------------------" 143 #print FunctionBody(fdecl, fbody) 144 #raw_input() 145 146 return mod.compile(self.discr.toolchain, 147 wait_on_error="jit_wait_on_compile_error" in discr.debug).lift 148
149 - def __call__(self, fgroup, matrix, scaling, field, out):
150 result = self.discr.volume_zeros(dtype=field.dtype) 151 152 from pytools import to_uncomplex_dtype 153 uncomplex_dtype = to_uncomplex_dtype(field.dtype) 154 args = [fgroup, matrix.astype(uncomplex_dtype), field, out] 155 156 if scaling is not None: 157 args.append(scaling) 158 159 self.make_lift(fgroup, 160 with_scale=scaling is not None, 161 dtype=field.dtype)(*args)
162