def METHOD_NAME(device_type: dace.dtypes.DeviceType):
    """
    Runs Covariance for the given device
    :return: the SDFG
    """
    # Initialize data (polybench mini size)
    M, N = sizes["mini"]
    float_n, data = init_data(M, N)
    gt_data = np.copy(data)
    if device_type in {dace.dtypes.DeviceType.CPU, dace.dtypes.DeviceType.GPU}:
        # Parse the SDFG and apply auto-opt
        sdfg = covariance_kernel.to_sdfg()
        sdfg = auto_optimize(sdfg, device_type)
        dace_res = sdfg(float_n=float_n, data=data, M=M, N=N)
    elif device_type == dace.dtypes.DeviceType.FPGA:
        # Parse SDFG and apply FPGA friendly optimization
        sdfg = covariance_kernel.to_sdfg(simplify=False)
        sdfg.simplify()
        applied = sdfg.apply_transformations([FPGATransformSDFG])
        assert applied == 1
        sdfg.apply_transformations([InlineSDFG])
        # Use FPGA Expansion for lib nodes, and expand them to enable further optimizations
        # Reduce.default_implementation = "FPGAPartialReduction"
        Gemv.default_implementation = "FPGA_Accumulate"
        sdfg.expand_library_nodes()
        sdfg.apply_transformations([InlineSDFG])
        # Other FPGA auto opt
        fpga_auto_opt.fpga_global_to_local(sdfg)
        fpga_auto_opt.fpga_rr_interleave_containers_to_banks(sdfg)
        # Specialize the SDFG
        sdfg.specialize(dict(N=N, M=M))
        # run program
        dace_res = sdfg(float_n=float_n, data=data)
    # Compute ground truth and validate result
    gt_res = ground_truth(M, N, float_n, gt_data)
    assert np.allclose(gt_res, dace_res)
    return sdfg