From da255bee1bb4955c15304ac7785fe2a81225187a Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 30 Jul 2020 00:18:55 +0100 Subject: [PATCH] compiler: Implement element type coercion for arrays So far, this is not exposed to the user beyond implicit conversions. Note that all the implicit conversions, such as triggered by adding arrays of mismatching types, or dividing integer arrays, are currently emitted in a maximally inefficient way, where a temporary copy is first made for the type conversion. The conversions would more sensibly be implemented during the per-element operations to save on the extra copies, but the current behaviour fell out of the rest of the IR generator structure without extra changes. --- .../compiler/transforms/artiq_ir_generator.py | 18 +++++++++++++++--- artiq/test/lit/integration/array_binops.py | 13 ++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/artiq/compiler/transforms/artiq_ir_generator.py b/artiq/compiler/transforms/artiq_ir_generator.py index 055456e09..9e3ccb6cc 100644 --- a/artiq/compiler/transforms/artiq_ir_generator.py +++ b/artiq/compiler/transforms/artiq_ir_generator.py @@ -1415,9 +1415,21 @@ class ARTIQIRGenerator(algorithm.Visitor): if node.type.find() == value.type: return value else: - return self.append(ir.Coerce(value, node.type, - name="{}.{}".format(_readable_name(value), - node.type.name))) + if builtins.is_array(node.type): + result_elt = node.type.find()["elt"] + shape = self.append(ir.GetAttr(value, "shape")) + result = self._alloate_new_array(result_elt, shape) + func = self._get_array_unaryop("Coerce", + lambda v: ir.Coerce(v, result_elt), + node.type, value.type) + self._invoke_arrayop(func, [result, value]) + return result + else: + return self.append( + ir.Coerce(value, + node.type, + name="{}.{}".format(_readable_name(value), + node.type.name))) def _get_total_array_len(self, shape): lengths = [ diff --git a/artiq/test/lit/integration/array_binops.py b/artiq/test/lit/integration/array_binops.py index 86014cc0c..e60052277 100644 --- a/artiq/test/lit/integration/array_binops.py +++ b/artiq/test/lit/integration/array_binops.py @@ -33,12 +33,15 @@ assert c[0] == 0 assert c[1] == 1 assert c[2] == 0 -# FIXME: Implement array coercion. -# c = b / a -# assert c[0] == 4.0 -# assert c[1] == 2.5 -# assert c[2] == 2.0 +cf = b / a +assert cf[0] == 4.0 +assert cf[1] == 2.5 +assert cf[2] == 2.0 +cf2 = cf + a +assert cf2[0] == 5.0 +assert cf2[1] == 4.5 +assert cf2[2] == 5.0 d = array([[1, 2], [3, 4]]) e = array([[5, 6], [7, 8]])