def distributed_task_config(MPI, node_name, node_list_, gpu_list=None,
    default_port=2222):
    """
    create configuration for distributed tensorflow session.
    inputs: 
        MPI             mpi4py.MPI
        node_name       str, the name of the this node
        node_list       [str], the list of nodes of the current mpirun
        gpu_list        [int], the list of GPUs on each node
        default_port    int, the default port for socket communication
    outputs:
        cluster         map, cluster_spec
        job             str, the job name of this task
        task_idx        int, the index of this task
        socket          str, hostname:port socket of this task
        device          str, the device for this task
    """
    node_list = list(set(node_list_))
    node_list.sort()
    node_color = node_list.index(node_name)
    world_idx = MPI.COMM_WORLD.Get_rank()
    node_comm = MPI.COMM_WORLD.Split(node_color, world_idx)
    node_task_idx = node_comm.Get_rank()
    node_numb_task = node_comm.Get_size()
    socket_list = []
    for ii in node_list:
        for jj in range(node_numb_task):
            socket_list.append(ii + ':' + str(default_port + jj))
    ps_map = socket_list[0:1]
    worker_map = socket_list[1:]
    if node_color == 0 and node_task_idx == 0:
        my_job = 'ps'
        my_socket = ps_map[0]
        my_task_idx = ps_map.index(my_socket)
    else:
        my_job = 'worker'
        my_socket = node_name + ':' + str(default_port + node_task_idx)
        assert my_socket in worker_map
        my_task_idx = worker_map.index(my_socket)
    if gpu_list is not None:
        numb_gpu = len(gpu_list)
        gpu_idx = node_numb_task - node_task_idx - 1
        if gpu_idx >= numb_gpu:
            my_device = 'cpu:0'
        else:
            my_device = 'gpu:%d' % gpu_idx
    else:
        my_device = 'cpu:0'
    cluster = {'worker': worker_map, 'ps': ps_map}
    return cluster, my_job, my_task_idx, my_socket, my_device
