o
    Meƻ                     @   s.  d dl Z d dlZd dlZd dlZd dlmZ d dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlmZ d dlmZ d dlZd dlZg ZG dd deZG dd deZG dd	 d	eZG d
d deZG dd deZG dd deZG dd deZdddZG dd deZG dd deZdS )    N)datetime)corec                   @      e Zd ZdS )ExecuteErrorN__name__
__module____qualname__ r
   r
   QD:\Projects\ConvertPro\env\Lib\site-packages\paddle/distributed/fleet/utils/fs.pyr   %       r   c                   @   r   )FSFileExistsErrorNr   r
   r
   r
   r   r   )   r   r   c                   @   r   )FSFileNotExistsErrorNr   r
   r
   r
   r   r   -   r   r   c                   @   r   )	FSTimeOutNr   r
   r
   r
   r   r   1   r   r   c                   @   r   )FSShellCmdAbortedNr   r
   r
   r
   r   r   5   r   r   c                   @   s   e Zd Zejdd Zejdd Zejdd Zejdd Zejd	d
 Z	ejdd Z
ejdd Zejdd Zejdd Zejdd Zejd"ddZejdd Zejdd Zejd#ddZejd$d d!ZdS )%FSc                 C      t NNotImplementedErrorselffs_pathr
   r
   r   ls_dir;      z	FS.ls_dirc                 C   r   r   r   r   r
   r
   r   is_file?   r   z
FS.is_filec                 C   r   r   r   r   r
   r
   r   is_dirC   r   z	FS.is_dirc                 C   r   r   r   r   r
   r
   r   is_existG   r   zFS.is_existc                 C   r   r   r   )r   
local_pathr   r
   r
   r   uploadK   r   z	FS.uploadc                 C   r   r   r   )r   r   r   r
   r
   r   downloadO   r   zFS.downloadc                 C   r   r   r   r   r
   r
   r   mkdirsS   r   z	FS.mkdirsc                 C   r   r   r   r   r
   r
   r   deleteW   r   z	FS.deletec                 C   r   r   r   r   r
   r
   r   need_upload_download[   r   zFS.need_upload_downloadc                 C   r   r   r   r   fs_src_pathfs_dst_pathr
   r
   r   rename_   r   z	FS.renameFc                 C   r   r   r   r   r&   r'   	overwritetest_existsr
   r
   r   mvc   r   zFS.mvc                 C   r   r   r   )r   	local_dirdest_dirr
   r
   r   
upload_dirg   r   zFS.upload_dirc                 C   r   r   r   r   r
   r
   r   	list_dirsk   r   zFS.list_dirsTc                 C   r   r   r   r   r   exist_okr
   r
   r   toucho   r   zFS.touchNc                 C   r   r   r   r   r
   r
   r   cats   r   zFS.catFFTr   )r   r   r	   abcabstractmethodr   r   r   r   r   r    r!   r"   r$   r(   r,   r/   r0   r3   r4   r
   r
   r
   r   r   9   s>    











r   c                   @   s|   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd ZdddZd ddZdd ZdS )!LocalFSz
    A tool of local file system.

    Examples:
        .. code-block:: python

            from paddle.distributed.fleet.utils import LocalFS

            client = LocalFS()
            subdirs, files = client.ls_dir("./")
    c                 C   s\   |  |s	g g fS g }g }t|D ]}tj|d | r$|| q|| q||fS )a5  	
        List directorys and files under `fs_path` .

        Args:
            fs_path(str): The local file path.

        Returns:
            Tuple: Return a 2-tuple, the first is a list of all its subdirectories, 
            and the second is a list of all its subfiles, e.g. ([subdirname1, subdirname1, ...], [filename1, filename2, ...]).

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                subdirs, files = client.ls_dir("./")
        /)r   oslistdirpathisdirappend)r   r   dirsfilesfr
   r
   r   r      s   
zLocalFS.ls_dirc                 C   s.   t j|rJ d|t d| dS )af  
        Create a local directory.

        Args:
            fs_path(str): The local directory path.

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                client.mkdirs("test_mkdirs")
                client.delete("test_mkdirs")
        z{} is already a filemkdir -p {}N)r;   r=   isfileformatsystemr   r
   r
   r   r!      s   zLocalFS.mkdirsc                 C   s   t || dS )a  
        Rename the file.

        Args:
            fs_src_path(str): The actual name of the file or directory
            fs_dst_path(str): The new name of the file or directory.

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                client.touch("test_rename_src")
                print(client.is_exists("test_rename_src")) # True
                client.rename("test_rename_src", "test_rename_dst")
                print(client.is_exists("test_rename_src")) # False
                print(client.is_exists("test_rename_dst")) # True
                client.delete("test_rename_dst")
        N)r;   r(   r%   r
   r
   r   r(      s   zLocalFS.renamec                 C      t | d S r   )shutilrmtreer   r
   r
   r   _rmr      zLocalFS._rmrc                 C   rG   r   )r;   remover   r
   r
   r   _rm   rK   zLocalFS._rmc                 C   s.   |  |sdS tj|r| |S | |S )a  
        Delete the local file path, whether it's a file or directory.

        Args:
            fs_path(str): The local file path.

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                client.mkdirs("test_localFS_mkdirs")
                client.delete("test_localFS_mkdirs")
        N)r   r;   r=   rD   rM   rJ   r   r
   r
   r   r"      s
   


zLocalFS.deletec                 C      dS )NFr
   r#   r
   r
   r   r$         zLocalFS.need_upload_downloadc                 C      t j|S )a  
        Whether the local file path is a file.

        Args:
            fs_path(str): The local file path.

        Returns:
            Bool: Return true if the path exists and it's a file, otherwise return false.

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                client.touch("test_is_file")
                print(client.is_file("test_is_file")) # True
                client.delete("test_is_file")
        )r;   r=   rD   r   r
   r
   r   r         zLocalFS.is_filec                 C   rP   )a   
        Whether the local file path is a directory.

        Args:
            fs_path(str): The local file path.

        Returns:
            Bool: Return true if the path exists and it's a directory, otherwise return false.

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                client.mkdirs("test_is_dir")
                print(client.is_dir("test_is_file")) # True
                client.delete("test_is_dir")
        r;   r=   r>   r   r
   r
   r   r     rQ   zLocalFS.is_dirc                 C   rP   )a  
        Whether the local file path exists.

        Args:
            fs_path(str): The local file path.

        Returns:
            Bool: Wheter it's a file or directory, return true if the path exists, 
            otherwise return false.

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                ret = local_fs.is_exist("test_is_exist")
        )r;   r=   existsr   r
   r
   r   r     s   zLocalFS.is_existTc                 C   s*   |  |r|r	dS ttd| dS )a  
        Create a local file.

        Args:
            fs_path(str): The local file path.
            exist_ok(bool): When `fs_path` exists, if `exist_ok` is set false,
            program will throw an Exception. Default is true.

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                client.touch("test_touch")
                client.delete("test_touch")
        Nztouch {})r   r   r;   rF   rE   r1   r
   r
   r   r3   2  s
   
zLocalFS.touchFc                 C   s@   |  |st|r|  |r| | |  |rt| ||S )a  
        Move a local file or directory from `src_path` to `dst_path` .

        Args:
            src_path(str):  Name of the file or directory, that's needed to be moved.
            dst_path(str):  Name of the file or directory to which to move to.
            overwrite(bool): Whether to re-write `dst_path` if that exists. Default is False.

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                client.touch("test_mv_src")
                client.mv("test_mv_src", "test_mv_dst")
                client.delete("test_mv_dst")
        )r   r   r"   r   r(   )r   Zsrc_pathZdst_pathr*   r+   r
   r
   r   r,   K  s   


z
LocalFS.mvc                    s*   |   sg S  fddt D }|S )a  	
        Only list directorys under `fs_path` .

        Args:
            fs_path(str): The local file path.

        Returns:
            List: A list of all its subdirectories, e.g. [subdirname1, subdirname1, ...].

        Examples:
            .. code-block:: python

                from paddle.distributed.fleet.utils import LocalFS

                client = LocalFS()
                subdirs = client.list_dirs("./")
        c                    s$   g | ]}t j d  | r|qS r:   rR   ).0rB   r   r
   r   
<listcomp>~  s
    z%LocalFS.list_dirs.<locals>.<listcomp>)r   r;   r<   )r   r   r@   r
   rV   r   r0   i  s   

zLocalFS.list_dirsNr6   r5   )r   r   r	   __doc__r   r!   r(   rJ   rM   r"   r$   r   r   r   r3   r,   r0   r
   r
   r
   r   r9   x   s     

r9   c                    s    fdd}|S )Nc                    s   t   fdd}|S )Nc               
      s   | d }}|d u rt |jd }n|d }t |jd }t }|}	 z | i |W S  tyW } zt | |krHtd| t | t| W Y d }~nd }~ww t | dkrptd| t |  t }q$)Nr   g     @@Tzargs:{} timeout:{}   z*hadoop operator timeout:args:{} timeout:{})	float	_time_out_sleep_intertimer   r   rE   sleepprint)argskwargsotime_outinterstartZlast_print_timee)rB   max_time_outr
   r   handler  s6   

z2_handle_errors.<locals>.decorator.<locals>.handler)	functoolswraps)rB   rh   rg   )rB   r   	decorator  s   z!_handle_errors.<locals>.decoratorr
   )rg   rl   r
   rk   r   _handle_errors  s   "rm   c                   @   sF  e Zd ZdZ		d@ddZdAdd	Ze d
d Ze dd Zdd Z	dd Z
e dd Zdd Zdd Ze dd ZdBddZdCddZe dd ZdCd d!Ze d"d# Ze d$d% ZdDd'd(Ze d)d* Zd+d, Zd-d. Ze d/d0 ZdEd1d2Ze d3d4 Zd5d6 ZdFd8d9Ze d:d; Zd<d= Zd>d? Z d7S )G
HDFSClienta  
    A tool of HDFS.

    Args:
        hadoop_home(str): Hadoop home. 
        configs(dict): Hadoop config. It is a dictionary and needs to contain the
            keys: "fs.default.name" and "hadoop.job.ugi".

    Examples:

        .. code-block:: text

            from paddle.distributed.fleet.utils import HDFSClient
            hadoop_home = "/home/client/hadoop-client/hadoop/"

            configs = {
                "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                "hadoop.job.ugi": "hello,hello123"
            }

            client = HDFSClient(hadoop_home, configs)
            client.ls_dir("hdfs:/test_hdfs_client")
       c           
      C   s   g | _ d| }| j | d}| j | |r-t|D ]\}}d||f }	| j |	 q|| _|| _d| j | _t	d| _
d S )Nz%s/bin/hadoopfsz-D%s=%s z8\s?responseErrorMsg\s?\:.*, errorCode\:\s?[0-9]+, path\:)Zpre_commandsr?   six	iteritemsr[   r\   join	_base_cmdrecompile
_bd_err_re)
r   Zhadoop_homeZconfigsrc   sleep_interZ
hadoop_bindfskvZconfig_commandr
   r
   r   __init__  s   
zHDFSClient.__init__F   c           	      C   sz   d | j|}d}d }d}t|d D ]}t|dd|\}}t|}|dkr) nt| q|dkr7t|||	 fS )Nz{} -{}r            )
rE   rv   ranger   Zshell_execute_cmdintr]   r^   r   
splitlines)	r   cmdredirect_stderrretry_timesZexe_cmdretoutputZretry_sleep_secondxr
   r
   r   _run_cmd  s   zHDFSClient._run_cmdc                 C       |  |sg S | |\}}|S )a  	
        Only list directorys under `fs_path` .

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            List: A list of all its subdirectories, e.g. [subdirname1, subdirname1, ...].

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                subdirs = client.list_dirs("hdfs:/test_hdfs_client")
        r   _ls_dirr   r   r@   rA   r
   r
   r   r0     s   
zHDFSClient.list_dirsc                 C      |  |s	g g fS | |S )a`  	
        List directorys and files under `fs_path` .

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            Tuple: Return a 2-tuple, the first element is the list of all its subdirectories, 
            and the second one is the list of all its subfiles, e.g. ([subdirname1, subdirname1, ...], [filename1, filename2, ...]).

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                subdirs, files = client.ls_dir("hdfs:/test_hdfs_client")
        r   r   r
   r
   r   r     s   

zHDFSClient.ls_dirc           
      C   s   d |}| |\}}|dkrt|g }g }|D ](}| }t|dkr'qtj|d }	|d d dkr=||	 q||	 q||fS )Nzls {}r         d)	rE   r   r   splitlenr;   r=   basenamer?   )
r   r   r   r   linesr@   rA   linearrpr
   r
   r   r   ,  s   
zHDFSClient._ls_dirc                 C   s*   |D ]}| j |}|d kr|  S qd S r   )ry   match)r   r   lmr
   r
   r   _test_matchB  s   zHDFSClient._test_matchc                 C      |  |sdS | |S )a  
        Whether the remote HDFS path is a directory.

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            Bool: Return true if the path exists and it's a directory, otherwise return false.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                ret = client.is_file("hdfs:/test_hdfs_client")
        Fr   _is_dirr   r
   r
   r   r   J  s   

zHDFSClient.is_dirc                 C   sT   dj |dd}| j|dd\}}|r(| |r&td td| t|dS dS )	Nz
test -d {}Tr   r   r   zraise exception: 
F)rE   r   r   r_   ru   r   )r   r   r   r   r   r
   r
   r   r   i  s   
zHDFSClient._is_dirc                 C      |  |sdS | | S )a  
        Whether the remote HDFS path is a file.

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            Bool: Return true if the path exists and it's a file, otherwise return false.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                ret = client.is_file("hdfs:/test_hdfs_client")
        Fr   r   r
   r
   r   r   w  s   
zHDFSClient.is_filec                 C   s.   d |}| j|ddd\}}|dkrdS dS )a  
        Whether the remote HDFS path exists.

        Args:
            fs_path(str): The hdfs file path.

        Returns:
            Bool: Whether it's is file or directory, return true if the path exists,
            otherwise return false.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                ret = client.is_exist("hdfs:/test_hdfs_client")
        ztest -e {} Tr   )r   r   r   F)rE   r   )r   r   r   r   outr
   r
   r   r     s
   
zHDFSClient.is_existc                 C   sl   | d}| d}tj|}| |d | r$|r$| |d |  | |s.| | | || dS z
        upload dir to hdfs
        Args:
            local_dir(str): local dir
            dest_dir(str): hdfs dest dir
            overwrite(bool): is overwrite
        Returns:
            return code
        r:   N)rstripr;   r=   r   r   r"   r!   _try_uploadr   r-   r.   r*   Zlocal_basenamer
   r
   r   r/     s   




zHDFSClient.upload_dirc                    s    fdd}dd }t  }||std|||}|s%td dS  |r6|r6 |  | g }	t|D ]}
 ||
|}t	j
|||fd}|	| |  q<|	D ]}|  qZdS )	a,  
        Upload the local path to remote HDFS.

        Args:
            local_path(str): The local path.
            fs_path(str): The HDFS path.
            multi_processes(int|1): the upload data process at the same time, default=5
            overwrite(bool|False): will overwrite file on HDFS or not

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                client.upload("test_hdfs_client", "hdfs:/test_hdfs_client")
        c                    s   |D ]}  ||  qd S r   )r   )Zhdfs_path_singledatasdatar#   r
   r   Z__subprocess_upload  s   z.HDFSClient.upload.<locals>.__subprocess_uploadc                 S   sZ   g }t j| s
|S t j| r&t | D ]}t j| |}|| q|S ||  |S )z
            get local files
            Args:
                path(str): local path
            Returns:
                list of local files
            )r;   r=   rS   r>   r<   ru   r?   )r=   Zrlistfiletr
   r
   r   get_local_files  s   
z*HDFSClient.upload.<locals>.get_local_files{} not existsz/there are nothing need to upload, function exitNtargetr`   )r9   r   r   rE   r_   r"   r!   r   _split_filesmultiprocessingProcessr?   re   ru   )r   r   r   multi_processesr*   Z_HDFSClient__subprocess_uploadr   local	all_filesprocsiprocess_datasr   procr
   r#   r   r     s.   





zHDFSClient.uploadc              
   C   s\   d ||}d}z| |\}}|dkrt|W d S  ty- } z| | |d }~ww )Nz	put {} {}r   )rE   r   r   	Exceptionr"   )r   r   r   r   r   _rf   r
   r
   r   r     s   
zHDFSClient._try_uploadc                    s   fdd}  std  r |S  \}} fdd|D }| fdd|D  g }	t|D ]}
||
|}t	j
|||fd}|	| |  q?|	D ]}|  q]dS )	a	  
        Download remote HDFS path to the local.

        Args:
            fs_path(str):  The HDFS path.
            local_path(str): The local path.
            multi_processes(int|1): the download data process at the same time, default=1
            overwrite(bool): is overwrite

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                client.download("hdfs:/test_hdfs_client", "./")
        c                    s   |D ]}  ||  qdS z
            download file from HDFS
            Args:
                local_path(str): the local file path
                datas(str): the hdfs file path list
            N)_try_downloadr   r   r   r#   r
   r   __subprocess_download>  s   z2HDFSClient.download.<locals>.__subprocess_download{} not exitsc                       g | ]} d  | qS rT   r
   rU   r   rV   r
   r   rW   O      z'HDFSClient.download.<locals>.<listcomp>c                    r   rT   r
   r   rV   r
   r   rW   P  r   r   N)r   r   rE   r   r   r   extendr   r   r   r   r?   re   ru   )r   r   r   r   r*   Z _HDFSClient__subprocess_downloadr@   all_filenamesr   r   r   r   r   r   r
   r   r   r   r    $  s&   





zHDFSClient.downloadc              
   C   sb   d ||}d}z| |\}}|dkrt|W d S  ty0 } z
t }|| |d }~ww )Nz	get {} {}r   )rE   r   r   r   r9   r"   )r   r   r   r   r   r   rf   Zlocal_fsr
   r
   r   r   ]  s   
zHDFSClient._try_downloadc                 C   s   |  |rdS d}d|}| j|dd\}}|dkr.|D ]
}d|v r'd} nq|s.t||rI|  |sKd|}| |\}}|dkrMt|dS dS dS )	aQ  
        Create a remote HDFS directory.

        Args:
            fs_path(str): The HDFS directory path.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                client.mkdirs("hdfs:/test_hdfs_client")
        NFz	mkdir {} Tr   r   zNo such file or directoryrC   )r   rE   r   r   )r   r   Zout_hdfsr   r   r   r   r   r
   r
   r   r!   j  s(   


zHDFSClient.mkdirsTc                 C   sX   |r|  |r| | |r&|  |std||  |r&td|| ||S )a?  
        Move a remote HDFS file or directory from `fs_src_path` to `fs_dst_path` .

        Args:
            fs_src_path(str):  Name of the file or directory, that's needed to be moved.
            fs_dst_path(str):  Name of the file or directory to which to move to.
            overwrite(bool): Whether to re-write `fs_dst_path` if that exists. Default is False.
            test_exists(bool): Check the existence of `fs_src_path` and `fs_dst_path` . When `test_exists` is set true, if `fs_src_path` doesn't exist or `fs_dst_path` exists, program will throw an Excetption. 

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                client.mv("hdfs:/test_hdfs_client", "hdfs:/test_hdfs_client2")
        {} is not exists{} exists already)r   r"   r   rE   r   _try_mvr)   r
   r
   r   r,     s   


zHDFSClient.mvc              
   C   sx   d ||}d}z| j|dd\}}|dkrt|W d S  ty; } z| |s5| |r5W Y d }~d S |d }~ww )Nzmv {} {}r   r   r   )rE   r   r   r   r   )r   r&   r'   r   r   r   rf   r
   r
   r   r     s   
zHDFSClient._try_mvc                 C   ,   d |}| |\}}|dkrt|d S )Nzrmr {}r   rE   r   r   r   r   r   r   r   r
   r
   r   rJ     
   
zHDFSClient._rmrc                 C   r   )Nzrm {}r   r   r   r
   r
   r   rM     r   zHDFSClient._rmc                 C   s0   |  |sdS | |}|r| |S | |S )ai  
        Delete a remote HDFS path, whether it's a file or directory.

        Args:
            fs_path(str): The HDFS file path.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                client.delete("hdfs:/test_hdfs_client")
        N)r   r   rJ   rM   )r   r   r   r
   r
   r   r"     s   



zHDFSClient.deletec                 C   s    |  |r|r	dS t| |S )a  
        Create a remote HDFS file.

        Args:
            fs_path(str): The HDFS file path.
            exist_ok(bool): When `fs_path` exists, if `exist_ok` is set false,
            program will throw an Exception. Default is true.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                client.touch("hdfs:/test_hdfs_client")
        N)r   r   _touchzr1   r
   r
   r   r3     s
   

zHDFSClient.touchc                 C   r   )Nz	touchz {}r   r   r   r
   r
   r   r     s
   
zHDFSClient._touchzc                 C   rN   NTr
   r#   r
   r
   r   r$     rO   zHDFSClient.need_upload_downloadNc                 C   s"   |  |r| |}d|S dS )al  
        Cat a remote HDFS file.

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            file content

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                hadoop_home = "/home/client/hadoop-client/hadoop/"
                configs = {
                    "fs.default.name": "hdfs://xxx.hadoop.com:54310",
                    "hadoop.job.ugi": "hello,hello123"
                }

                client = HDFSClient(hadoop_home, configs)
                client.cat("hdfs:/test_hdfs_client")
        r    )r   _try_catru   )r   r   r   r
   r
   r   r4     s   


zHDFSClient.catc                 C   s0   d |}| j|dd\}}|dkrt||S )Nzcat {}r   r   r   r   )r   r   r   r   r   r
   r
   r   r   >  s
   
zHDFSClient._try_catc           
      C      t || }t || }|g| }t|D ]
}||  d7  < qg g| }d}	t|D ]}||	|	||   ||< |	|| 7 }	q+|| S z
        split file list
        Args:
            files(list): file list
            trainer_id(int): trainer mpi rank id
            trainers(int): all trainers num
        Returns:
            fileist(list): file list of current trainer
        r   r   r   r   
r   rA   Z
trainer_idZtrainers	remainder	blocksizeblocksr   Ztrainer_filesbeginr
   r
   r   r   F     


zHDFSClient._split_filesc                 C   s   t |dkrg S g }d}|D ]}||d 7 }qd| d }| |\}}t |dkr3td|  g S |D ] }|d}	t |	dk rCq5|	d }
t|	d }||
|d	 q5|S )
z
        list_files return file path and size
        Args:
            path_list(list): file list
        Returns:
            fileist(list): file list with file path and size
        r   r   rr   zls z) | awk '{if ($8 != "") {print $5" "$8 }}'zlist_files empty, path[%s]   r   )r=   size)r   r   loggerwarningr   r   r?   )r   	path_list	file_listZ
str_concatr=   r   r   r   r   r   	file_path	file_sizer
   r
   r   list_files_info_  s&   
zHDFSClient.list_files_inforo   rp   )Fr   F)r   FFTr6   r   )!r   r   r	   rX   r~   r   rm   r0   r   r   r   r   r   r   r   r/   r   r   r    r   r!   r,   r   rJ   rM   r"   r3   r   r$   r4   r   r   r   r
   r
   r
   r   rn     sV    






!
L

9


+&





rn   c                   @   s   e Zd ZdZ		d.ddZdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zd/ddZd0ddZd0ddZdd Zd1d!d"Zd#d$ Zd2d%d&Zd'd( Zd3d*d+Zd,d- Zd)S )4	AFSClientaE  
    A tool of AFS. Use AfsWrapper.

    Examples:

        .. code-block:: text

            from paddle.distributed.fleet.utils import AFSClient
            client = AFSClient()
            client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
            client.ls_dir("hdfs:/test_hdfs_client")
    ro   rp   c                 C   s   t  | _|| _d S r   )r   Z
AfsWrapper_fsr[   )r   rc   rz   r
   r
   r   r~     s   

zAFSClient.__init__c                 C   s   | j |||| d S r   )r   init)r   Zfs_nameZfs_userZ	fs_passwdZfs_confr
   r
   r   r     s   zAFSClient.initc                 C   r   )a%  	
        Only list directorys under `fs_path` .

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            List: A list of all its subdirectories, e.g. [subdirname1, subdirname1, ...].

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                subdirs = client.list_dirs("hdfs:/test_hdfs_client")
        r   r   r
   r
   r   r0     s   
zAFSClient.list_dirsc                 C   r   )a  	
        List directorys and files under `fs_path` .

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            Tuple: Return a 2-tuple, the first element is the list of all its subdirectories, 
            and the second one is the list of all its subfiles, e.g. ([subdirname1, subdirname1, ...], [filename1, filename2, ...]).

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                subdirs, files = client.ls_dir("hdfs:/test_hdfs_client")
        r   r   r
   r
   r   r     s   

zAFSClient.ls_dirc                 C   s   | j |}|g}||fS r   )r   list)r   r   rA   r@   r
   r
   r   r     s   zAFSClient._ls_dirc                 C   r   )a)  
        Whether the remote HDFS path is a directory.

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            Bool: Return true if the path exists and it's a directory, otherwise return false.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                ret = client.is_file("hdfs:/test_hdfs_client")
        Fr   r   r
   r
   r   r     s   

zAFSClient.is_dirc                 C   s    | j |}t|dkrdS dS )Nr   TF)r   r   r   )r   r   	list_pathr
   r
   r   r     s   zAFSClient._is_dirc                 C   r   )a  
        Whether the remote HDFS path is a file.

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            Bool: Return true if the path exists and it's a file, otherwise return false.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                ret = client.is_file("hdfs:/test_hdfs_client")
        Fr   r   r
   r
   r   r     s   
zAFSClient.is_filec                 C   s   | j |S )a<  
        Whether the remote HDFS path exists.

        Args:
            fs_path(str): The hdfs file path.

        Returns:
            Bool: Whether it's is file or directory, return true if the path exists,
            otherwise return false.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                ret = client.is_exist("hdfs:/test_hdfs_client")
        )r   existr   r
   r
   r   r     s   zAFSClient.is_existFc                 C   sn   | d}| d}tj|}| |d | r$|r$| |d |  | |s.| | | j|| dS r   )	r   r;   r=   r   r   r"   r!   r   r   r   r
   r
   r   r/   "  s   




zAFSClient.upload_dirr   c                 C   s0   t  }||std|| j|| dS )a  
        Upload the local path to remote HDFS.

        Args:
            local_path(str): The local path.
            fs_path(str): The HDFS path.
            multi_processes(int|1): the upload data process at the same time, default=5
            overwrite(bool|False): will overwrite file on HDFS or not

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                client.upload("test_hdfs_client", "hdfs:/test_hdfs_client")
        r   N)r9   r   r   rE   r   r   )r   r   r   r   r*   r   r
   r
   r   r   6  s   
zAFSClient.uploadc                    s   fdd}  std  rj| S  \}} fdd|D }g }	t|D ]}
||
|}t	j
|||fd}|	| |  q4|	D ]}|  qRdS )aa  
        Download remote HDFS path to the local.

        Args:
            fs_path(str):  The HDFS path.
            local_path(str): The local path.
            multi_processes(int|1): the download data process at the same time, default=1
            overwrite(bool): is overwrite

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                client.download("hdfs:/test_hdfs_client", "./")
        c                    s   |D ]	} j | | qdS r   )r   r    r   r#   r
   r   r   f  s   z1AFSClient.download.<locals>.__subprocess_downloadr   c                    s   g | ]} | qS r
   r
   r   rV   r
   r   rW   w  s    z&AFSClient.download.<locals>.<listcomp>r   N)r   r   rE   r   r   r    r   r   r   r   r   r?   re   ru   )r   r   r   r   r*   Z_AFSClient__subprocess_downloadr   r   r   r   r   r   r   r   r
   r   r   r    Q  s$   





zAFSClient.downloadc                 C   s   |  |rdS | j| dS )a  
        Create a remote HDFS directory.

        Args:
            fs_path(str): The HDFS directory path.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                client.mkdirs("hdfs:/test_hdfs_client")
        N)r   r   mkdirr   r
   r
   r   r!     s   
zAFSClient.mkdirsTc                 C   s^   |r|  |r| | |r&|  |std||  |r&td|| j|| dS )a  
        Move a remote HDFS file or directory from `fs_src_path` to `fs_dst_path` .

        Args:
            fs_src_path(str):  Name of the file or directory, that's needed to be moved.
            fs_dst_path(str):  Name of the file or directory to which to move to.
            overwrite(bool): Whether to re-write `fs_dst_path` if that exists. Default is False.
            test_exists(bool): Check the existence of `fs_src_path` and `fs_dst_path` . When `test_exists` is set true, if `fs_src_path` doesn't exist or `fs_dst_path` exists, program will throw an Excetption. 

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                client.mv("hdfs:/test_hdfs_client", "hdfs:/test_hdfs_client2")
        r   r   N)r   r"   r   rE   r   r   r,   r)   r
   r
   r   r,     s   


zAFSClient.mvc                 C   s   |  |sdS | j| dS )a  
        Delete a remote HDFS path, whether it's a file or directory.

        Args:
            fs_path(str): The HDFS file path.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import HDFSClient

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                client.delete("hdfs:/test_hdfs_client")
        N)r   r   rL   r   r
   r
   r   r"     s   
zAFSClient.deletec                 C   s"   |  |r|r	dS t| j|S )a+  
        Create a remote HDFS file.

        Args:
            fs_path(str): The HDFS file path.
            exist_ok(bool): When `fs_path` exists, if `exist_ok` is set false,
            program will throw an Exception. Default is true.

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                client.touch("hdfs:/test_hdfs_client")
        N)r   r   r   Ztouchzr1   r
   r
   r   r3     s
   
zAFSClient.touchc                 C   rN   r   r
   r#   r
   r
   r   r$     rO   zAFSClient.need_upload_downloadNc                 C   s   |  |r| j|S dS )a  
        Cat a remote HDFS file.

        Args:
            fs_path(str): The HDFS file path.

        Returns:
            file content

        Examples:

            .. code-block:: text

                from paddle.distributed.fleet.utils import AFSClient

                client = AFSClient()
                client.init("hdfs://xxx.hadoop.com:54310", "hello", "hello123", "./fs_conf")
                client.cat("hdfs:/test_hdfs_client")
        r   )r   r   r4   r   r
   r
   r   r4     s   
zAFSClient.catc           
      C   r   r   r   r   r
   r
   r   r     r   zAFSClient._split_filesr   r   )r   Fr   r6   r   )r   r   r	   rX   r~   r   r0   r   r   r   r   r   r   r/   r   r    r!   r,   r"   r3   r$   r4   r   r
   r
   r
   r   r     s.    



3
!

r   r   )r;   sys
subprocessr   r   rw   copyerrnor]   loggingrs   r7   Zpaddle.fluidZfluidr   ri   rH   __all__r   r   r   r   r   r   objectr   r9   rm   rn   r   r
   r
   r
   r   <module>   sD   ?  
'     Y