'Suggest a launch configuration with reasonable occupancy.
:param func: kernel for which occupancy is calculated
:param b2d_func: function that calculates how much per-block dynamic shared memory \'func\' uses based on the block size.
:param memsize: per-block dynamic shared memory usage intended, in bytes
:param blocksizelimit: maximum block size the kernel is designed to handle'

def get_max_potential_block_size(self, func, b2d_func, memsize, blocksizelimit, flags=None):

    gridsize = c_int()
    blocksize = c_int()
    b2d_cb = cu_occupancy_b2d_size(b2d_func)
    if (not flags):
        driver.cuOccupancyMaxPotentialBlockSize(byref(gridsize), byref(blocksize), func.handle, b2d_cb, memsize, blocksizelimit)
    else:
        driver.cuOccupancyMaxPotentialBlockSizeWithFlags(byref(gridsize), byref(blocksize), func.handle, b2d_cb, memsize, blocksizelimit, flags)
    return (gridsize.value, blocksize.value)
