Пример #1
0
 def objective(trial):
     args = suggest_func(trial)
     max_total_time = optimize_config.max_total_time_per_trial
     try:
         perf = time.repeat(target_func, args, max_duration=max_total_time)
         return perf.gpu_times.mean()
     except Exception as e:
         if isinstance(e, ignore_error):
             return math.inf
         else:
             raise e
Пример #2
0
 def objective(trial):
     args = suggest_func(trial)
     max_total_time = optimize_config.max_total_time_per_trial
     perf = time.repeat(target_func, args, max_duration=max_total_time)
     return perf.gpu_times.mean()
Пример #3
0
def test_invert_vector_field(shape):
    r"""
    Inverts a synthetic, analytically invertible, displacement field
    """
    ndim = len(shape)
    if ndim == 3:
        ns = shape[0]
        nr = shape[1]
        nc = shape[2]

        # Create an arbitrary image-to-space transform

        # Select an arbitrary rotation axis
        axis = np.array([2.0, 0.5, 1.0])
        t = 2.5  # translation factor

        trans = np.array([
            [1, 0, 0, -t * ns],
            [0, 1, 0, -t * nr],
            [0, 0, 1, -t * nc],
            [0, 0, 0, 1],
        ])
        dipy_create_func = vfu.create_harmonic_fields_3d
        dipy_reorient_func = vfu.reorient_vector_field_3d
        dipy_invert_func = vfu.invert_vector_field_fixed_point_3d
    elif ndim == 2:
        nr = shape[0]
        nc = shape[1]
        # Create an arbitrary image-to-space transform
        t = 2.5  # translation factor

        trans = np.array([[1, 0, -t * nr], [0, 1, -t * nc], [0, 0, 1]])
        dipy_create_func = vfu.create_harmonic_fields_2d
        dipy_reorient_func = vfu.reorient_vector_field_2d
        dipy_invert_func = vfu.invert_vector_field_fixed_point_2d

    trans_inv = np.linalg.inv(trans)

    d, _ = dipy_create_func(*shape, 0.2, 8)
    d = np.asarray(d).astype(floating)

    for theta in [-1 * np.pi / 5.0, 0.0, np.pi / 5.0]:  # rotation angle
        for s in [0.5, 1.0, 2.0]:  # scale
            if ndim == 3:
                rot = np.zeros(shape=(4, 4))
                rot[:3, :3] = geometry.rodrigues_axis_rotation(axis, theta)
                rot[3, 3] = 1.0
                scale = np.array([
                    [1 * s, 0, 0, 0],
                    [0, 1 * s, 0, 0],
                    [0, 0, 1 * s, 0],
                    [0, 0, 0, 1],
                ])
            elif ndim == 2:
                ct = np.cos(theta)
                st = np.sin(theta)

                rot = np.array([[ct, -st, 0], [st, ct, 0], [0, 0, 1]])

                scale = np.array([[1 * s, 0, 0], [0, 1 * s, 0], [0, 0, 1]])

            gt_affine = trans_inv.dot(scale.dot(rot.dot(trans)))
            gt_affine_inv = np.linalg.inv(gt_affine)
            dcopy = np.copy(d)

            dcopyd = cupy.asarray(dcopy)
            gt_affined = cupy.asarray(gt_affine)
            gt_affine_invd = cupy.asarray(gt_affine_inv)

            # make sure the field remains invertible after the re-mapping
            dipy_reorient_func(dcopy, gt_affine)

            # TODO: can't do in-place computation unless out= is supplied and
            #       dcopy has the dimensions axis first instead of last
            dcopyd = reorient_vector_field(dcopyd, gt_affined)
            cupy.testing.assert_array_almost_equal(dcopyd, dcopy, decimal=4)

            # Note: the spacings are used just to check convergence, so they
            # don't need to be very accurate. Here we are passing (0.5 * s) to
            # force the algorithm to make more iterations: in ANTS, there is a
            # hard-coded bound on the maximum residual, that's why we cannot
            # force more iteration by changing the parameters.
            # We will investigate this issue with more detail in the future.

            if False:
                from cupyx.time import repeat

                perf = repeat(
                    invert_vector_field_fixed_point,
                    (
                        dcopyd,
                        gt_affine_invd,
                        cupy.asarray([s, s, s]) * 0.5,
                        40,
                        1e-7,
                    ),
                    n_warmup=20,
                    n_repeat=80,
                )
                print(perf)
                perf = repeat(
                    dipy_invert_func,
                    (
                        dcopy,
                        gt_affine_inv,
                        np.asarray([s, s, s]) * 0.5,
                        40,
                        1e-7,
                    ),
                    n_warmup=0,
                    n_repeat=8,
                )
                print(perf)
            # if False:
            #     from pyvolplot import volshow
            #     from matplotlib import pyplot as plt
            #     inv_approx, q, norms, tmp1, tmp2, epsilon, maxlen = vfu.invert_vector_field_fixed_point_3d_debug(
            #         dcopy, gt_affine_inv, np.array([s, s, s]) * 0.5, max_iter=1, tol=1e-7
            #     )
            #     inv_approxd, qd, normsd, tmp1d, tmp2d, epsilond, maxlend = invert_vector_field_fixed_point(
            #         dcopyd, gt_affine_invd, cupy.asarray([s, s, s]) * 0.5, max_iter=1, tol=1e-7
            #     )
            inv_approxd = invert_vector_field_fixed_point(
                dcopyd, gt_affine_invd,
                cupy.asarray([s, s, s]) * 0.5, 40, 1e-7)

            if False:
                inv_approx = dipy_invert_func(dcopy, gt_affine_inv,
                                              np.array([s, s, s]) * 0.5, 40,
                                              1e-7)
                cupy.testing.assert_allclose(inv_approx,
                                             inv_approxd,
                                             rtol=1e-2,
                                             atol=1e-2)

            # TODO: use GPU-based imwarp here once implemented
            mapping = imwarp.DiffeomorphicMap(ndim, shape, gt_affine)
            mapping.forward = dcopy
            mapping.backward = inv_approxd.get()
            residual, stats = mapping.compute_inversion_error()
            assert_almost_equal(stats[1], 0, decimal=3)
            assert_almost_equal(stats[2], 0, decimal=3)