Ë
    ÄÓ^j“L  ã                   ó¾  — 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m	Z	 d dl
mZmZ d dlmZ d dlZd dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlm Z  d dl!m"Z"m#Z# d dl$m%Z%m&Z&m'Z' d dl(m)Z) d dl*m+Z+m,Z, d dl-m.Z. ddl/m0Z0m1Z1m2Z2 erd dl3m4Z4 g d¢Z5 G d„ de	«      Z6 ede7¬«      	 	 	 	 d2dede+dejp                  dz  de9d e:d!e#dz  d"e fd#„«       Z; ed$¬%«      e0dddddd$d&œded'e<ejz                  z  dz  de+dz  d!e#dz  dejp                  dz  d e:d(e:d"e fd)„«       «       Z>e G d*„ d+«      «       Z? ed$¬%«      dddde6j€                  ddd$d,œded'e<ejz                  z  dz  de+dz  d!e#dz  dejp                  dz  d-e6d.e%dz  d e:d(e:d"ee?z  fd/„«       ZA ed$¬%«      ded"efd0„«       ZB	 	 	 	 	 d3dede+dejp                  dz  de9d e:d!e#dz  d(e:d"e fd1„ZCy)4é    N)ÚFuture)Ú	dataclass)ÚEnum)ÚcastÚTYPE_CHECKING)Ú
deprecated)ÚSTATE_DICT_TYPE)Ú$_ProcessBasedAsyncCheckpointExecutor)Ú#_ThreadBasedAsyncCheckpointExecutor)Ú_storage_setup)ÚDefaultSavePlanner)Ú_dcp_method_logger)ÚMetadata)ÚSavePlanÚSavePlanner)ÚAsyncStagerÚDefaultStagerÚStagingOptions)ÚStateful)ÚStorageWriterÚWriteResult)Ú_get_default_groupé   )Ú_api_bc_checkÚ_DistWrapperÚ_profile)Ú_AsyncCheckpointExecutor)Úsave_state_dictÚsaveÚ
async_saveÚAsyncCheckpointerTypeÚAsyncSaveResponsec                   ó   — e Zd ZdZdZdZy)r!   z!Enum for async checkpointer type.ÚthreadÚprocessN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚTHREADÚPROCESS© ó    úx/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/torch/distributed/checkpoint/state_dict_saver.pyr!   r!   4   s   „ Ù+à€FØ�Gr-   r!   za`save_state_dict` is deprecated and will be removed in future versions.Please use `save` instead.)ÚcategoryFÚ
state_dictÚstorage_writerÚprocess_groupÚcoordinator_rankÚno_distÚplannerÚreturnc           	      ó‚   — |j                  «        t        «       5  t        | |||||«      cddd«       S # 1 sw Y   yxY w)z3This method is deprecated. Please switch to 'save'.N)Úresetr   Ú_save_state_dict)r0   r1   r2   r3   r4   r5   s         r.   r   r   ;   sF   € ð ×ÑÔô 
‹ñ 
ÜØØØØØØó
÷
÷ 
ò 
ús   ›5µ>T©Úlog_exceptions©Úcheckpoint_idr1   r5   r2   r4   Úuse_collectivesr=   r>   c          	      ó~  — t         j                  j                  d«       |xs, t        j                  «        xs t        j
                  «        }|rt        j                  dd¬«       t        «       5  t        t        t        ||d¬«      «      }t        t        | «      |||||¬«      cddd«       S # 1 sw Y   yxY w)	a<  
    Save a distributed model in SPMD style.

    This function is different from ``torch.save()`` as it handles
    ``ShardedTensor`` , and ``DTensor`` by having each rank only save their local shards.

    For each ``Stateful`` object (having both a ``state_dict`` and a ``load_state_dict``),
    save will call ``state_dict`` before serialization.

    .. warning::
        There are no guarantees of Backwards Compatibility across PyTorch versions
        for saved state_dicts.

    .. warning::
        If using the `process_group` argument, make sure that only its ranks
        call `save_state_dict` and that all data in state_dict belong to it.

    .. note::
        When saving checkpoint for FSDP's `ShardingStrategy.HYBRID_SHARD`, only one of
        the shard_group should be calling `save_state_dict` and the corresponding process
        group needs to be passed in.

    .. note::
        If no process group is available, this function assumes the intention is to save the
         state_dict in the local process.

    .. note:
        Rank 0 is assumed to be the coordinator rank.


    Args:
        state_dict (Dict[str, Any]): The state_dict to save.
        checkpoint_id (Union[str, os.PathLike, None]):
            The ID of this checkpoint instance. The meaning of the checkpoint_id
            depends on the storage. It can be a path to a folder or to a file.
            It can also be a key if the storage is a key-value store.
            (Default: ``None``)
        storage_writer (Optional[StorageWriter]):
            Instance of StorageWriter used to perform writes. If this is not
            specified, DCP will automatically infer the writer based on the
            checkpoint_id. If checkpoint_id is also None, an exception will
            be raised. (Default: ``None``)
        planner (Optional[SavePlanner]):
            Instance of SavePlanner. If this is not specified, the default
            planner will be used. (Default: ``None``)
        process_group (Optional[ProcessGroup]):
            ProcessGroup to be used for cross-rank synchronization.
            (Default: ``None``)
        no_dist (bool):
            If ``True``, this function will assume the intent is to load
            a checkpoint on a single rank/process.
            (Default: ``False``)
        use_collectives (bool): If ``False``, this function will assume the intent is to save
            a checkpoint without using cross-rank synchronization.
            (Default: ``True``)
            This configuration is experimental and should be used with caution.
            It will change the format of the saved checkpoint and may not be backward compatible.

    Returns:
        Metadata: Metadata object for the saved checkpoint.

    Example:
        >>> # xdoctest: +SKIP
        >>> my_model = MyModule()

        >>> state_dict = {"model": my_model}

        >>> fs_storage_writer = torch.distributed.checkpoint.FileSystemWriter(
        ...     "/checkpoint/1"
        ... )
        >>> torch.distributed.checkpoint.save(
        >>>     state_dict=state_dict,
        >>>     storage_writer=fs_storage_writer,
        >>> )

    .. note::
        save_state_dict uses collectives to coordinate writes across ranks.
        For NCCL-based process groups, internal tensor representations of
        objects must be moved to the GPU device before communication takes place.
        In this case, the device used is given by ``torch.cuda.current_device()``
        and it is the user's responsibility to ensure that this is set so that
        each rank has an individual GPU, via ``torch.cuda.set_device()``.
    z!torch.distributed.checkpoint.savezptorch.distributed is disabled, unavailable or uninitialized, assuming the intent is to save in a single process.é   ©Ú
stacklevelF)Úreader)r0   r1   r2   r4   r5   r>   N)ÚtorchÚ_CÚ_log_api_usage_onceÚdistÚis_availableÚis_initializedÚwarningsÚwarnr   r   r   r   r9   Ú_stateful_to_state_dict)r0   r=   r1   r5   r2   r4   r>   s          r.   r   r   W   sª   € ô~ 
‡H�H× Ñ Ð!DÔEàÒQœd×/Ñ/Ó1Ð1ÒQ¼4×;NÑ;NÓ;PÐ7P€GÙÜ�‰Ø~Øõ	
ô
 
‹ñ 
ÜÜœ>¨.¸-ÐPUÔVó
ˆô  Ü.¨zÓ:Ø)Ø'ØØØ+ô
÷
÷ 
ò 
ús   Á36B3Â3B<c                   ó2   — e Zd ZU dZed   ed<   ed   ed<   y)r"   a!  This class contains futures for staging and upload completion.
    It is returned by async_save().
    staging_completion is a future that indicates when local copy
    of state_dict is complete.
    upload_completion is a future that indicates when a checkpoint
    completed saving.
    NÚstaging_completionÚupload_completion)r&   r'   r(   r)   r   Ú__annotations__r,   r-   r.   r"   r"   Î   s   … ñð ˜t™Ó$Ø˜d‘|Ô#r-   r"   )r=   r1   r5   r2   Úasync_checkpointer_typeÚasync_stagerr4   r>   rQ   rR   c          
      óh  ‡ ‡‡‡‡— t         j                  j                  d«       t        j                  «       rNt        j
                  «       r:|xs
 t        «       }	t        j                  d«      |	j                  vrt        d«      ‚dŠ‰€.|�t        |t        «      r|Šnt        t        dddd«      «      Š‰Št        ‰ «      Š dŠdˆˆfd„Št        d¬	«      dt         t"           t"        z  fˆˆ fd
„«       }
t%        j&                  «       5 }‰�|j)                  ‰«        |
«       }|t*        j,                  k(  r
t/        «       n	t1        «       }|j3                  |||||||¬«      }‰�$|j5                  ˆfd„«       |j7                  «        ddd«       t        t         «      rh|}t!        «       }|fdt         t"           dt         d   fd„}|j9                  «       s|j5                  |«       n|j;                  d«       t=        |¬«      S t        d¬	«      ˆfd„«       } |«        S # 1 sw Y   ŒžxY w)a  Asynchronous version of ``save``. This code first de-stages the state_dict on to the
    staging storage (defaults to CPU memory), and then calls the `save` in a separate thread.

    .. warning::
        This feature is experimental and subject to change.
        If you provide an ``async_stager``, call ``close()`` after the last
        checkpoint is saved. Internally created default stagers are closed
        automatically.

    Args:
        state_dict (Dict[str, Any]): The state_dict to save.
        checkpoint_id (Union[str, os.PathLike, None]):
            The ID of this checkpoint instance. The meaning of the checkpoint_id
            depends on the storage. It can be a path to a folder or to a file.
            It can also be a key if the storage is a key-value store.
            (Default: ``None``)
        storage_writer (Optional[StorageWriter]):
            Instance of StorageWriter used to perform 'stage' and  'save'. If
            this is not specified, DCP will automatically infer the writer based on the
            checkpoint_id. If checkpoint_id is also None, an exception will
            be raised. (Default: ``None``)
        planner (Optional[SavePlanner]):
            Instance of SavePlanner. If this is not specified, the default
            planner will be used. (Default: ``None``)
        process_group (Optional[ProcessGroup]):
            ProcessGroup to be used for cross-rank synchronization.
            (Default: ``None``)
        async_checkpointer_type (AsyncCheckpointerType):
            whether to do checkpoint in separate thread or process
            (Default: ``AsyncCheckpointerType.THREAD``)
        async_stager (AsyncStager):
            provides staging implementation. If ``storage_writer`` implements
            ``AsyncStager`` and ``async_stager`` is not provided, ``storage_writer``
            will be used for staging. User-provided stagers remain owned by the
            caller and should be closed after the last checkpoint is saved.
        no_dist (bool):
            If ``True``, this function will assume the intent is to save
            a checkpoint on a single rank/process.
            (Default: ``False``)
        use_collectives: If False, Save the checkpoint without rank coordination. (Default: ``True``)
            This configuration is experimental and should be used with caution.
            It will change the format of the saved checkpoint and may not be backward compatible.

    Returns:
        Future: A future holding the resultant Metadata object from `save`.

    Example:
        >>> # xdoctest: +SKIP
        >>> my_model = MyModule()

        >>> state_dict = {"model": my_model}

        >>> fs_storage_writer = torch.distributed.checkpoint.FileSystemWriter(
        ...     "/checkpoint/1"
        ... )
        >>> checkpoint_future = torch.distributed.checkpoint.async_save(
        >>>     state_dict=state_dict,
        >>>     storage_writer=fs_storage_writer,
        >>> )
        >>>
        >>> # ... do some work ...
        >>>
        >>> checkpoint_future.result()

    z'torch.distributed.checkpoint.async_saveÚcpuzfA CPU backend must be enabled for async save; try initializing process group with 'cpu:gloo,cuda:nccl'NFr6   c                  ó6   •— ‰ �‰sdŠ‰ j                  «        y y y )NT)Úclose)Úowned_async_stagerÚowned_async_stager_closeds   €€r.   Úmaybe_close_owned_async_stagerz2async_save.<locals>.maybe_close_owned_async_stagerG  s'   ø€ àÐ)Ñ2KØ(,Ð%Ø×$Ñ$Õ&ð 3LÐ)r-   Tr:   c                  ó&   •— ‰ j                  ‰«      S ©N)Ústage)rR   r0   s   €€r.   Ústage_state_dictz$async_save.<locals>.stage_state_dictM  s   ø€ à×!Ñ! *Ó-Ð-r-   r<   c                 ó   •—  ‰«       S r[   r,   )Ú_rY   s    €r.   ú<lambda>zasync_save.<locals>.<lambda>h  s   ø€ Ñ6TÓ6V€ r-   Úoriginal_staging_futureÚreturn_staging_futurec                 ó–   — 	 | j                  «        |j                  d «       y # t        $ r}|j                  |«       Y d }~y d }~ww xY wr[   )ÚresultÚ
set_resultÚ	ExceptionÚset_exception)ra   rb   Úes      r.   Úcallbackzasync_save.<locals>.callbackp  sB   € ð7Ø'×.Ñ.Ô0Ø%×0Ñ0°Õ6øÜò 7Ø%×3Ñ3°A×6Ñ6ûð7ús   ‚!$ ¤	A­AÁA)rN   rO   c                  ó@   •— ‰ j                   r‰ j                  «        y y r[   )Ú should_synchronize_after_executeÚsynchronize_staging)rR   s   €r.   Úmaybe_synchronize_stagingz-async_save.<locals>.maybe_synchronize_staging…  s   ø€ à×<Ò<Ø×0Ñ0Õ2ð =r-   )r6   N)rD   rE   rF   rG   rH   rI   r   ÚdeviceÚ_device_typesÚAssertionErrorÚ
isinstancer   r   r   rL   r   r   r	   Ú
contextlibÚ	ExitStackri   r!   r+   r
   r   Úexecute_saveÚadd_done_callbackÚpop_allÚdonere   r"   )r0   r=   r1   r5   r2   rQ   rR   r4   r>   Úpgr]   ÚstackÚstaging_future_or_state_dictÚupload_executorÚupload_futureÚstaging_futurerb   ri   rm   rY   rW   rX   s   `     `            @@@r.   r    r    Ü   sA  ü€ ô\ 
‡H�H× Ñ Ð!JÔKä×ÑÔœt×2Ñ2Ô4ØÒ2Ô0Ó2ˆÜ�<‰<˜Ó b×&6Ñ&6Ñ6Ü Øxóð ð .2ÐØÐØÐ%¬*°^Ä[Ô*Qà)‰Lä(ÜØØØØó	óˆLð ".Ðä(¨Ó4€Jà %Ðö'ô  tÔ,ð.œf¤_Ñ5¼ÑGõ .ó -ð.ô 
×	Ñ	Ó	ð  5ØÐ)Ø�N‰NÐ9Ô:á'7Ó'9Ð$ð 'Ô*?×*GÑ*GÒGô 1Ô2ä4Ó6ð 	ð !0× <Ñ <Ø(Ø'Ø)ØØ'ØØ+ð !=ó !
ˆð Ð)Ø×+Ñ+Ó,VÔWà�M‰MŒO÷3ô6 Ð.´Ô7Ø5ˆÜ.4«hÐð 3Hñ	7Ü%+¬OÑ%<ð	7ä#)¨$¡<ó	7ð ×"Ñ"Ô$Ø×,Ñ,¨XÕ6à!×,Ñ,¨TÔ2ô !Ø4Èô
ð 	
ô
 
¨4Ô	0ó	3ó 
1ð	3ñ 	"Ô#ØÐ÷uð ús   ÄB H(È(H1c                 óŠ   — i }| j                  «       D ]-  \  }}d„ }d|› �|_          t        d¬«      |«      |«      ||<   Œ/ |S )z]Creates a shallow copy of `state_dict` where `state_dict` is called for each Stateful object.c                 óF   — t        | t        «      r| j                  «       S | S r[   )rq   r   r0   )Úelems    r.   Ú_elem_to_state_dictz4_stateful_to_state_dict.<locals>._elem_to_state_dict”  s   € Ü(2°4¼Ô(B�4—?‘?Ó$ÐLÈÐLr-   z_stateful_to_state_dict.Tr:   )Úitemsr&   r   )r0   Ústateful_state_dictÚkeyr€   r�   s        r.   rL   rL   Ž  so   € ð ÐØ×%Ñ%Ó'ò 	‰	ˆˆTò	Mð *BÀ#ÀÐ'GÐÔ$ð$
Ð#JÔ#5ÀTÔ#JØó$
à
ó$Ð˜CÒ ð	ð Ðr-   c                 ó`  ‡ ‡‡‡‡‡‡— t         j                  j                  d«       t        || |«      Š‰€
t	        «       Š‰€t        d«      ‚d Ši }t        ‰dd «      x}�||d<   ‰j                  |d<   t        di |¤Žˆˆˆ ˆˆfd„«       }	t        di |¤Žˆˆˆfd„«       }
d Š‰r‰j                  d|	|
«      Šn |	«       } |
|g«      }|d   Št        di |¤Žˆˆˆfd	„«       }t        di |¤Žˆˆfd
„«       }‰r‰j                  d||«      }|S  |«       } ||g«      }‰j                  «        |S )Nz,torch.distributed.checkpoint.save_state_dictúplanner is Noner=   r2   c                  ó\  •— ‰€t        d«      ‚‰j                  «       } dt        j                  ‰j                  «      j
                  vr4t        j                  dd¬«       ‰j	                  ‰‰j                  «       n‰j	                  ‰| ‰j                  ¬«       dt        j                  ‰j                  «      j
                  v r)‰j                  ‰j                  ‰j                  ‰¬«       n‰j                  ‰j                  «       ‰j                  «       }‰j                  |«      }|S )	Nr†   Ústorage_metazªThe function definition for SavePlanner.set_up_planner has been updated to include the storage_meta argument. Please update your implementation to include this parameter.r@   rA   )r0   rˆ   Úis_coordinatorÚkwargs)Úrankr>   )rp   rˆ   ÚinspectÚ	signatureÚset_up_plannerÚ
parametersrJ   rK   r‰   Úset_up_storage_writerr‹   Úcreate_local_planÚprepare_local_plan)rˆ   Ú
local_planÚdistWr5   r0   r1   r>   s     €€€€€r.   Ú
local_stepz$_save_state_dict.<locals>.local_step·  s  ø€ àˆ?Ü Ð!2Ó3Ð3Ø%×2Ñ2Ó4ˆØ¤×!2Ñ!2°7×3IÑ3IÓ!J×!UÑ!UÑUÜ�M‰Mð.ð õ	ð ×"Ñ" :¨u×/CÑ/CÕDà×"Ñ"Ø%Ø)Ø$×3Ñ3ð #ô ð Ü× Ñ  ×!EÑ!EÓF×QÑQñRð ×0Ñ0Ø×$Ñ$Ø—Z‘ZØ /ð 1õ ð ×0Ñ0°×1EÑ1EÔFà×.Ñ.Ó0ˆ
Ø#×6Ñ6°zÓBˆ
ØÐr-   c                 ól   •— ‰€t        d«      ‚‰j                  | «      \  } Š‰j                  | «      } | S )Nr†   )rp   Úcreate_global_planÚprepare_global_plan)Úall_local_plansÚglobal_metadatar5   r1   s    €€€r.   Úglobal_stepz%_save_state_dict.<locals>.global_stepÛ  sA   ø€ ð ˆ?Ü Ð!2Ó3Ð3Ø+2×+EÑ+EÀoÓ+VÑ(ˆ˜Ø(×<Ñ<¸_ÓMˆØÐr-   Úplanr   c                  ó¾   •— ‰€t        d«      ‚‰€t        d«      ‚‰j                  ‰«      } ‰j                  | ‰«      }|j                  «        |j	                  «       S )Nr†   zcentral_plan is None)rp   Úfinish_planÚ
write_dataÚwaitÚvalue)Úfinal_local_planÚ
all_writesÚcentral_planr5   r1   s     €€€r.   rŸ   z$_save_state_dict.<locals>.write_dataí  sc   ø€ àˆ?Ü Ð!2Ó3Ð3ØÐÜ Ð!7Ó8Ð8Ø"×.Ñ.¨|Ó<ÐØ#×.Ñ.Ð/?ÀÓIˆ
à�‰ÔØ×ÑÓ!Ð!r-   c                 óH   •— ‰€t        d«      ‚‰j                  ‰| ¬«       ‰S )Nzglobal_metadata is None)ÚmetadataÚresults)rp   Úfinish)Úall_resultsrš   r1   s    €€r.   Úfinish_checkpointz+_save_state_dict.<locals>.finish_checkpointù  s.   ø€ àÐ"Ü Ð!:Ó;Ð;Ø×Ñ ÀÐÔLØÐr-   Úwriter,   )rD   rE   rF   r   r   rp   ÚgetattrÚgroupr   Úreduce_scatterÚ
all_reduceÚbarrier)r0   r1   r2   r3   r4   r5   r>   Úckpt_kwargsÚckpt_idr•   r›   r“   Úglobal_planrŸ   rª   r¦   Úwrite_resultsr¤   r”   rš   s   ``   ``          @@@r.   r9   r9   Ÿ  sh  þ€ ô 
‡H�H× Ñ Ð!OÔPä˜¨G¨Ð5EÓF€EØ€Ü$Ó&ˆØ€ÜÐ.Ó/Ð/à€Oà€KÜ˜>¨?¸DÓAÐAˆÐNØ'.ˆ�OÑ$Ø',§{¡{ˆ�OÑ$äÑ&˜+Ñ&÷!ó 'ð!ôF Ñ&˜+Ñ&õó 'ðð %)€LÙØ×+Ñ+¨F°JÀÓL‰á)›|ˆ
Ù&1°:°,Ó&?ˆØ" 1‘~ˆäÑ&˜+Ñ&õ	"ó 'ð	"ô Ñ&˜+Ñ&ôó 'ðñ Ø×#Ñ# G¨ZÐ9JÓKˆð €Oñ	 ,6«<ˆÙ$ m _Ó5ˆØ�‰Œà€Or-   )Nr   FN)Nr   FNT)Drr   rŒ   ÚosrJ   Úconcurrent.futuresr   Údataclassesr   Úenumr   Útypingr   r   Útyping_extensionsr   rD   Útorch.distributedÚdistributedrG   Ú#torch.distributed._state_dict_utilsr	   Ú4torch.distributed.checkpoint._async_process_executorr
   Ú3torch.distributed.checkpoint._async_thread_executorr   Ú+torch.distributed.checkpoint._storage_utilsr   Ú,torch.distributed.checkpoint.default_plannerr   Ú#torch.distributed.checkpoint.loggerr   Ú%torch.distributed.checkpoint.metadatar   Ú$torch.distributed.checkpoint.plannerr   r   Ú$torch.distributed.checkpoint.stagingr   r   r   Ú%torch.distributed.checkpoint.statefulr   Ú$torch.distributed.checkpoint.storager   r   Ú"torch.distributed.distributed_c10dr   Úutilsr   r   r   Ú,torch.distributed.checkpoint._async_executorr   Ú__all__r!   ÚFutureWarningÚProcessGroupÚintÚboolr   ÚstrÚPathLiker   r"   r*   r    rL   r9   r,   r-   r.   ú<module>rÒ      s@  ðó Û Û 	Û Ý %Ý !Ý ß &Ý (ã Ý  Ý ?õõõ GÝ KÝ BÝ :ß F÷ñ õ
 ;ß KÝ Aç 8Ñ 8ñ ÝUò€ô˜Dô ñ ð!àôð /3ØØØ"&ñ
Øð
à!ð
ð ×$Ñ$ tÑ+ð
ð ð	
ð
 ð
ð ˜4Ñð
ð ò
óð

ñ.  4Ô(Øð /3Ø+/Ø"&Ø.2ØØ òr
Øðr
ð ˜Ÿ™Ñ$ tÑ+ðr
ð " DÑ(ð	r
ð
 ˜4Ñðr
ð ×$Ñ$ tÑ+ðr
ð ðr
ð ðr
ð òr
ó ó )ðr
ðj ÷
$ð 
$ó ð
$ñ  4Ô(ð /3Ø+/Ø"&Ø.2Ø5J×5QÑ5QØ'+ØØ ònØðnð ˜Ÿ™Ñ$ tÑ+ðnð " DÑ(ð	nð
 ˜4Ñðnð ×$Ñ$ tÑ+ðnð 3ðnð  Ñ$ðnð ðnð ðnð ÐÑònó )ðnñb  4Ô(ð¨ð ¸Oò ó )ðð& /3ØØØ"&Ø ñhØðhà!ðhð ×$Ñ$ tÑ+ðhð ð	hð
 ðhð ˜4Ñðhð ðhð ôhr-   