Permalink
Browse files

Support tiling specializations

  • Loading branch information...
1 parent 32e6671 commit aae2d351eb20a80aaa504f396eb145855084d793 @markflorisson committed Jun 21, 2012
Showing with 63 additions and 17 deletions.
  1. +33 −10 Cython/Compiler/Vector.py
  2. +6 −6 Cython/Utility/Vector.c
  3. +1 −1 Cython/minivect
  4. +23 −0 tests/array_expressions/specializations.pyx
@@ -490,6 +490,16 @@ def run_specializer(self, specializer):
def put_specialization(self, code, specializer):
self.put_specialized_call(code, *self.run_specializer(specializer))
+ def is_c_order_code(self):
+ return "%s & __PYX_ARRAY_C_ORDER" % self.array_layout.result()
+
+ def put_ordered_specializations(self, code, c_specialization, f_specialization):
+ code.putln("if (%s) {" % self.is_c_order_code())
+ self.put_specialization(code, c_specialization)
+ code.putln("} else {")
+ self.put_specialization(code, f_specialization)
+ code.putln("}")
+
def _put_contig_specialization(self, code, if_clause, contig, mixed_contig):
if not mixed_contig:
code.putln("/* Contiguous specialization */")
@@ -507,17 +517,29 @@ def _put_contig_specialization(self, code, if_clause, contig, mixed_contig):
return if_clause
- def _put_strided_specializations(self, code, if_clause):
+ def _put_tiled_specialization(self, code, if_clause, mixed_contig):
+ if not mixed_contig:
+ code.putln("%s (%s & (__PYX_ARRAYS_ARE_MIXED_CONTIG|"
+ "__PYX_ARRAYS_ARE_MIXED_STRIDED)) {" %
+ (if_clause, self.array_layout.result()))
+
+ code.putln("/* Tiled specializations */")
+ self.put_ordered_specializations(code, specializers.CTiledStridedSpecializer,
+ specializers.FTiledStridedSpecializer)
+
+ if not mixed_contig:
+ code.putln("}")
+
+ def _put_strided_specializations(self, code, if_clause, mixed_contig):
+ if mixed_contig:
+ return
+
if if_clause != "if":
code.putln("else {")
code.putln("/* Strided specializations */")
- code.putln("if (%s & __PYX_ARRAY_C_ORDER) {" %
- self.array_layout.result())
- self.put_specialization(code, specializers.StridedSpecializer)
- code.putln("} else {")
- self.put_specialization(code, specializers.StridedFortranSpecializer)
- code.putln("}")
+ self.put_ordered_specializations(code, specializers.StridedSpecializer,
+ specializers.StridedFortranSpecializer)
if if_clause != "if":
code.putln("}")
@@ -530,7 +552,9 @@ def generate_result_code(self, code):
if_clause = "if"
if_clause = self._put_contig_specialization(code, if_clause,
contig, mixed_contig)
- self._put_strided_specializations(code, if_clause)
+ if_clause = self._put_tiled_specialization(code, if_clause,
+ mixed_contig)
+ self._put_strided_specializations(code, if_clause, mixed_contig)
def contig_condition(self, specializer):
if specializer.is_contig_specializer:
@@ -774,10 +798,9 @@ def generate_execution_code(self, code):
self.rhs.generate_evaluation_code(code)
self.final_broadcast.generate_evaluation_code(code)
+ self.final_broadcast.init_broadcast_flag(code)
code.putln("if (!%s) {" % self.overlap())
self.advance_lhs_data_ptr(code)
- code.putln("} else {")
- self.final_broadcast.init_broadcast_flag(code)
code.putln("}")
code.putln("/* Broadcast final RHS and LHS */")
@@ -35,31 +35,31 @@ __pyx_get_arrays_ordering(const {{memviewslice_name}} **ops, const int *ndims,
all_f_contig = 0;
all_c_contig &= contig;
seen_c_contig += all_c_contig;
- seen_c_ish = 1;
+ seen_c_ish++;
} else {
all_c_contig = 0;
all_f_contig &= contig;
seen_f_contig += all_f_contig;
- seen_f_ish = 1;
+ seen_f_ish++;
}
}
if (all_c_contig || all_f_contig) {
return __PYX_ARRAYS_ARE_CONTIG | all_c_contig;
} else if (seen_c_contig + seen_f_contig == nops) {
- return __PYX_ARRAYS_ARE_MIXED_CONTIG;
+ return __PYX_ARRAYS_ARE_MIXED_CONTIG | (seen_c_ish > seen_f_ish);
} else if (seen_c_ish && seen_f_ish) {
- return __PYX_ARRAYS_ARE_MIXED_STRIDED;
+ return __PYX_ARRAYS_ARE_MIXED_STRIDED | (seen_c_ish > seen_f_ish);
} else {
for (i = 0; i < nops; i++) {
int dim = 0;
if (seen_c_ish)
dim = ndims[i] - 1;
if (ops[i]->strides[dim] != itemsizes[i])
- return __PYX_ARRAYS_ARE_STRIDED | seen_c_ish;
+ return __PYX_ARRAYS_ARE_STRIDED | !!seen_c_ish;
}
}
- return __PYX_ARRAYS_ARE_INNER_CONTIG | seen_c_ish;
+ return __PYX_ARRAYS_ARE_INNER_CONTIG | !!seen_c_ish;
}
@@ -70,3 +70,26 @@ def test_contig_ff(_dtype_t[::1, :] m1, _dtype_t[::1, :] m2):
m1[:] = m1 + m2 * m1
return np.asarray(m1)
+@testcase
+def test_tiling(double[:, :] m1, double[:, :] m2):
+ """
+ >>> result = test_tiling(m.copy(), m.copy(order='F'))
+ >>> result
+ array([[ 0., 2., 6., 12., 20., 30., 42., 56.],
+ [ 72., 90., 110., 132., 156., 182., 210., 240.],
+ [ 272., 306., 342., 380., 420., 462., 506., 552.],
+ [ 600., 650., 702., 756., 812., 870., 930., 992.]])
+ >>> np.all(test_tiling(m.copy(order='F'), m.copy()) == result)
+ True
+
+ >>> result = test_tiling(m.copy()[::2], m.copy(order='F')[::2])
+ >>> result
+ array([[ 0., 2., 6., 12., 20., 30., 42., 56.],
+ [ 272., 306., 342., 380., 420., 462., 506., 552.]])
+ >>> np.all(test_tiling(m.copy(order='F')[::2], m.copy()[::2]) == result)
+ True
+ """
+ m1[:] = m1 + m2 * m1
+ return np.asarray(m1)
+
+

0 comments on commit aae2d35

Please sign in to comment.