def median_filter(data, size=3, cval = 0, res_g=None, sub_blocks=None):
    """
        median filter of given size

    Parameters
    ----------
    data: 2 or 3 dimensional ndarray or OCLArray of type float32
        input data
    size: scalar, tuple
        the size of the patch to consider
    cval: scalar, 
        the constant value for out of border access (cf mode = "constant")
    
    res_g: OCLArray
        store result in buffer if given
    sub_blocks:
        perform over subblock tiling (only if data is ndarray)

    Returns
    -------
        filtered image or None (if OCLArray)
    """
    if data.ndim == 2:
        _filt = make_filter(_median_filter_gpu_2d())
    elif data.ndim == 3:
        _filt = make_filter(_median_filter_gpu_3d())
    else:
        raise ValueError("currently only 2 or 3 dimensional data is supported")

    return _filt(data=data, size=size, cval = cval, res_g=res_g, sub_blocks=sub_blocks)