Пример #1
0
    def test_vectorize_explicit_signature(self):
        def _check_explicit_signature(sig):
            f = vectorize([sig], nopython=True)(mul_usecase)
            # This isn't really right but we can't do better than this,
            # since Numpy's ufuncs don't store the metadata of return types.
            # Related to https://github.com/numpy/numpy/issues/5429
            self.assertPreciseEqual(f(TD(2), 3), TD(6))

        # Test passing the signature in object form (issue #917)
        sig = types.NPTimedelta('s')(types.NPTimedelta('s'), types.int64)
        _check_explicit_signature(sig)
        # Same with the signature in string form
        sig = "NPTimedelta('s')(NPTimedelta('s'), int64)"
        _check_explicit_signature(sig)
Пример #2
0
    def set_output_dt_units(inputs, outputs):
        """
        Sets the output unit of a datetime type based on the input units

        Timedelta is a special dtype that requires the time unit to be
        specified (day, month, etc). Not every operation with timedelta inputs
        leads to an output of timedelta output. However, for those that do,
        the unit of output must be inferred based on the units of the inputs.

        At the moment this function takes care of the case where all
        inputs have the same unit, and therefore the output unit has the same.
        If in the future this should be extended to a case with mixed units,
        the rules should be implemented in `npdatetime_helpers` and called
        from this function to set the correct output unit.
        """
        if all(inp.unit == inputs[0].unit for inp in inputs):
            # Case with operation on same units. Operations on different units
            # not adjusted for now but might need to be added in the future
            unit = inputs[0].unit
            new_outputs = []
            for out in outputs:
                if isinstance(out, types.NPTimedelta) and out.unit == "":
                    new_outputs.append(types.NPTimedelta(unit))
                else:
                    new_outputs.append(out)
        else:
            return outputs
        return new_outputs
Пример #3
0
 def make_specific(outputs, unit):
     new_outputs = []
     for out in outputs:
         if isinstance(out, types.NPTimedelta) and out.unit == "":
             new_outputs.append(types.NPTimedelta(unit))
         else:
             new_outputs.append(out)
     return new_outputs
Пример #4
0
 def test_call_notation(self):
     # Function call signature
     i = types.int32
     d = types.double
     self.assertEqual(i(), typing.signature(i))
     self.assertEqual(i(d), typing.signature(i, d))
     self.assertEqual(i(d, d), typing.signature(i, d, d))
     # Value cast
     self.assertPreciseEqual(i(42.5), 42)
     self.assertPreciseEqual(d(-5), -5.0)
     ty = types.NPDatetime('Y')
     self.assertPreciseEqual(ty('1900'), np.datetime64('1900', 'Y'))
     self.assertPreciseEqual(ty('NaT'), np.datetime64('NaT', 'Y'))
     ty = types.NPTimedelta('s')
     self.assertPreciseEqual(ty(5), np.timedelta64(5, 's'))
     self.assertPreciseEqual(ty('NaT'), np.timedelta64('NaT', 's'))
     ty = types.NPTimedelta('')
     self.assertPreciseEqual(ty(5), np.timedelta64(5))
     self.assertPreciseEqual(ty('NaT'), np.timedelta64('NaT'))
Пример #5
0
 def generic(self, args, kws):
     if len(args) == 1:
         # Guard against unary -
         return
     left, right = args
     if isinstance(left, types.NPDatetime) and isinstance(
             right, types.NPDatetime):
         # All units compatible...
         unit = npdatetime_helpers.get_best_unit(left.unit, right.unit)
         return signature(types.NPTimedelta(unit), left, right)
Пример #6
0
 def test_call_notation(self):
     # Function call signature
     i = types.int32
     d = types.double
     self.assertEqual(i(), typing.signature(i))
     self.assertEqual(i(d), typing.signature(i, d))
     self.assertEqual(i(d, d), typing.signature(i, d, d))
     # Value cast
     self.assertPreciseEqual(i(42.5), 42)
     self.assertPreciseEqual(d(-5), -5.0)
     ty = types.NPDatetime("Y")
     self.assertPreciseEqual(ty("1900"), np.datetime64("1900", "Y"))
     self.assertPreciseEqual(ty("NaT"), np.datetime64("NaT", "Y"))
     ty = types.NPTimedelta("s")
     self.assertPreciseEqual(ty(5), np.timedelta64(5, "s"))
     self.assertPreciseEqual(ty("NaT"), np.timedelta64("NaT", "s"))
     ty = types.NPTimedelta("")
     self.assertPreciseEqual(ty(5), np.timedelta64(5))
     self.assertPreciseEqual(ty("NaT"), np.timedelta64("NaT"))
Пример #7
0
def _from_datetime_dtype(dtype):
    m = re_datetimestr.match(dtype.str)
    if not m:
        raise NotImplementedError(dtype)
    groups = m.groups()
    typecode = groups[0]
    unit = groups[2] or ''
    if typecode == 'm':
        return types.NPTimedelta(unit)
    elif typecode == 'M':
        return types.NPDatetime(unit)
    else:
        raise NotImplementedError(dtype)
Пример #8
0
    def test_jit_explicit_signature(self):
        def _check_explicit_signature(sig):
            f = jit(sig, nopython=True)(add_usecase)
            # Just a sanity check
            args = DT(1, 'ms'), TD(2, 'us')
            expected = add_usecase(*args)
            self.assertPreciseEqual(f(*args), expected)

        # Test passing the signature in object form
        sig = types.NPDatetime('us')(types.NPDatetime('ms'), types.NPTimedelta('us'))
        _check_explicit_signature(sig)
        # Same with the signature in string form
        sig = "NPDatetime('us')(NPDatetime('ms'), NPTimedelta('us'))"
        _check_explicit_signature(sig)
Пример #9
0
    def test_print_values(self):
        """
        Test printing a single argument value.
        """
        pyfunc = print_value

        def check_values(typ, values):
            cr = compile_isolated(pyfunc, (typ,))
            cfunc = cr.entry_point
            for val in values:
                with captured_stdout():
                    cfunc(val)
                    self.assertEqual(sys.stdout.getvalue(), str(val) + '\n')

        # Various scalars
        check_values(types.int32, (1, -234))
        check_values(types.int64, (1, -234,
                                   123456789876543210, -123456789876543210))
        check_values(types.uint64, (1, 234,
                                   123456789876543210, 2**63 + 123))
        check_values(types.boolean, (True, False))
        check_values(types.float64, (1.5, 100.0**10.0, float('nan')))
        check_values(types.complex64, (1+1j,))
        check_values(types.NPTimedelta('ms'), (np.timedelta64(100, 'ms'),))

        cr = compile_isolated(pyfunc, (types.float32,))
        cfunc = cr.entry_point
        with captured_stdout():
            cfunc(1.1)
            # Float32 will lose precision
            got = sys.stdout.getvalue()
            expect = '1.10000002384'
            self.assertTrue(got.startswith(expect))
            self.assertTrue(got.endswith('\n'))

        # NRT-enabled type
        with self.assertNoNRTLeak():
            x = [1, 3, 5, 7]
            with self.assertRefCount(x):
                check_values(types.List(types.int32), (x,))

        # Array will have to use object mode
        arraytype = types.Array(types.int32, 1, 'C')
        cr = compile_isolated(pyfunc, (arraytype,), flags=enable_pyobj_flags)
        cfunc = cr.entry_point
        with captured_stdout():
            cfunc(np.arange(10, dtype=np.int32))
            self.assertEqual(sys.stdout.getvalue(),
                             '[0 1 2 3 4 5 6 7 8 9]\n')
Пример #10
0
 def test_atomic_types(self):
     for unit in ('M', 'ms'):
         ty = types.NPDatetime(unit)
         self.check_pickling(ty)
         ty = types.NPTimedelta(unit)
         self.check_pickling(ty)
    def test_ufunc_find_matching_loop(self):
        f = numpy_support.ufunc_find_matching_loop
        np_add = FakeUFunc(_add_types)
        np_mul = FakeUFunc(_mul_types)
        np_isnan = FakeUFunc(_isnan_types)
        np_sqrt = FakeUFunc(_sqrt_types)

        def check(ufunc, input_types, sigs, output_types=()):
            """
            Check that ufunc_find_matching_loop() finds one of the given
            *sigs* for *ufunc*, *input_types* and optional *output_types*.
            """
            loop = f(ufunc, input_types + output_types)
            self.assertTrue(loop)
            if isinstance(sigs, str):
                sigs = (sigs,)
            self.assertIn(
                loop.ufunc_sig,
                sigs,
                "inputs=%s and outputs=%s should have selected one of %s, got %s"
                % (input_types, output_types, sigs, loop.ufunc_sig),
            )
            self.assertEqual(len(loop.numpy_inputs), len(loop.inputs))
            self.assertEqual(len(loop.numpy_outputs), len(loop.outputs))
            if not output_types:
                # Add explicit outputs and check the result is the same
                loop_explicit = f(ufunc, list(input_types) + loop.outputs)
                self.assertEqual(loop_explicit, loop)
            else:
                self.assertEqual(loop.outputs, list(output_types))
            # Round-tripping inputs and outputs
            loop_rt = f(ufunc, loop.inputs + loop.outputs)
            self.assertEqual(loop_rt, loop)
            return loop

        def check_exact(ufunc, input_types, sigs, output_types=()):
            """
            Like check(), but also ensure no casting of inputs occurred.
            """
            loop = check(ufunc, input_types, sigs, output_types)
            self.assertEqual(loop.inputs, list(input_types))

        def check_no_match(ufunc, input_types):
            loop = f(ufunc, input_types)
            self.assertIs(loop, None)

        # Exact matching for number types
        check_exact(np_add, (types.bool_, types.bool_), "??->?")
        check_exact(np_add, (types.int8, types.int8), "bb->b")
        check_exact(np_add, (types.uint8, types.uint8), "BB->B")
        check_exact(np_add, (types.int64, types.int64), ("ll->l", "qq->q"))
        check_exact(np_add, (types.uint64, types.uint64), ("LL->L", "QQ->Q"))
        check_exact(np_add, (types.float32, types.float32), "ff->f")
        check_exact(np_add, (types.float64, types.float64), "dd->d")
        check_exact(np_add, (types.complex64, types.complex64), "FF->F")
        check_exact(np_add, (types.complex128, types.complex128), "DD->D")

        # Exact matching for datetime64 and timedelta64 types
        check_exact(
            np_add,
            (types.NPTimedelta("s"), types.NPTimedelta("s")),
            "mm->m",
            output_types=(types.NPTimedelta("s"),),
        )
        check_exact(
            np_add,
            (types.NPTimedelta("ms"), types.NPDatetime("s")),
            "mM->M",
            output_types=(types.NPDatetime("ms"),),
        )
        check_exact(
            np_add,
            (types.NPDatetime("s"), types.NPTimedelta("s")),
            "Mm->M",
            output_types=(types.NPDatetime("s"),),
        )

        check_exact(
            np_mul,
            (types.NPTimedelta("s"), types.int64),
            "mq->m",
            output_types=(types.NPTimedelta("s"),),
        )
        check_exact(
            np_mul,
            (types.float64, types.NPTimedelta("s")),
            "dm->m",
            output_types=(types.NPTimedelta("s"),),
        )

        # Mix and match number types, with casting
        check(np_add, (types.bool_, types.int8), "bb->b")
        check(np_add, (types.uint8, types.bool_), "BB->B")
        check(np_add, (types.int16, types.uint16), "ii->i")
        check(np_add, (types.complex64, types.float64), "DD->D")
        check(np_add, (types.float64, types.complex64), "DD->D")
        # Integers, when used together with floating-point numbers,
        # should cast to any real or complex (see #2006)
        int_types = [types.int32, types.uint32, types.int64, types.uint64]
        for intty in int_types:
            check(np_add, (types.float32, intty), "ff->f")
            check(np_add, (types.float64, intty), "dd->d")
            check(np_add, (types.complex64, intty), "FF->F")
            check(np_add, (types.complex128, intty), "DD->D")
        # However, when used alone, they should cast only to
        # floating-point types of sufficient precision
        # (typical use case: np.sqrt(2) should give an accurate enough value)
        for intty in int_types:
            check(np_sqrt, (intty,), "d->d")
            check(np_isnan, (intty,), "d->?")

        # With some timedelta64 arguments as well
        check(
            np_mul,
            (types.NPTimedelta("s"), types.int32),
            "mq->m",
            output_types=(types.NPTimedelta("s"),),
        )
        check(
            np_mul,
            (types.NPTimedelta("s"), types.uint32),
            "mq->m",
            output_types=(types.NPTimedelta("s"),),
        )
        check(
            np_mul,
            (types.NPTimedelta("s"), types.float32),
            "md->m",
            output_types=(types.NPTimedelta("s"),),
        )
        check(
            np_mul,
            (types.float32, types.NPTimedelta("s")),
            "dm->m",
            output_types=(types.NPTimedelta("s"),),
        )

        # No match
        check_no_match(np_add, (types.NPDatetime("s"), types.NPDatetime("s")))
        # No implicit casting from int64 to timedelta64 (Numpy would allow
        # this).
        check_no_match(np_add, (types.NPTimedelta("s"), types.int64))