util
Module diagram
classDiagram
class util {
}
class color {
}
class config {
}
class cuda {
}
class file_handler {
}
class function_tree {
}
class memory {
}
class registry {
}
class reproducibility {
}
class string {
}
class system {
}
class test {
}
class timer {
}
class version {
}
system --> reproducibility
util
color
sample_uniform_hue_colors
sample_uniform_hue_colors(num_colors: int, saturation: float = 1.0, brightness: float = 1.0) -> List[List[int]]
Hue space에서 동일한 간격으로 서로 다른 색들을 샘플링합니다.
Parameters:
-
num_colors(int) –number of colors to sample
-
saturation(float, default:1.0) –saturation. Defaults to 1.0.
-
brightness(float, default:1.0) –value. Defaults to 1.0.
Returns:
-
List[List[int]]–List[List[int]]: [num_colors x [R, G, B]]
Source code in SaigeToolkit/util/color.py
config
read_yml
load config dictionary
Parameters:
-
config(str) –file path
Returns:
-
Dict[str, Any]–Dict[str, Any]: result config dict
_load_yml
load config dictionary from *.yml file
Source code in SaigeToolkit/util/config.py
update_import
recursively import and override base config, and there is two conditions of importing:
- if dict has
importkey and its value pointing another config file (*.yml) - if dict value is pointing another config file (*.yml)
Parameters:
-
cfg(Dict[str, Any]) –base config
Returns:
-
Dict[str, Any]–Dict[str, Any]: result config (import conditions updated)
Source code in SaigeToolkit/util/config.py
save_yml
Source code in SaigeToolkit/util/config.py
override_dict
recursively override dictionaries
Source code in SaigeToolkit/util/config.py
convert_keys_string_to_list
keys 입력값이 str인 경우 . 으로 분할해 함수에 전달해줍니다.
Source code in SaigeToolkit/util/config.py
check_key_exists
get_tree_node
tree-like obj에 대해 keys의 값을 순서대로 각 레벨에서 탐색해 최종 노드의 값을 리턴, 최종 노드가 존재하지 않으면 error 발생
Source code in SaigeToolkit/util/config.py
set_tree_node
tree-like obj에 대해 keys의 값을 순서대로 각 레벨에서 탐색해 최종 노드의 값을 수정, 최종 노드가 존재하지 않으면 error 발생
Source code in SaigeToolkit/util/config.py
get_tree_node_with_default
get_tree_node_with_default(obj: Any, keys: List, value: Optional[Any] = None, ignore_type_error: bool = False) -> Any
tree-like obj에 대해 keys의 값을 순서대로 각 레벨에서 탐색해 최종 노드의 값을 리턴, 최종 노드가 존재하지 않으면 value 리턴, ignore_type_error=True 일 경우 최종 value가 더이상 탐색하지 못할 때에도 error 대신 default value를 리턴.
Source code in SaigeToolkit/util/config.py
flatten_tree
tree-like obj를 1 레벨 dictionary로 변환
Source code in SaigeToolkit/util/config.py
cuda
init_cuda_when_available
init cuda when available. if cuda device has error and requires reboot, it will raise CudaDeviceError.
Raises:
-
CudaDeviceError–cuda device error.
Source code in SaigeToolkit/util/cuda.py
file_handler
IMAGE_EXTENSION
module-attribute
ZstdFileHandler
ZstdFileHandler is a utility class for handling the compression and decompression of data using the Zstandard (Zstd) compression algorithm. This class provides static methods to save and load data in a compressed format using Zstd and pickle for serialization.
save_compressed_data
staticmethod
Compresses and saves any Python data object to a file.
This method serializes the given data object using pickle, compresses the serialized data using Zstd, and writes the compressed data to a file.
Parameters:
-
data(Any) –The Python data object to be compressed and saved.
-
file_path(str) –The path of the file where the compressed data will be stored. If the file already exists, it will be overwritten.
Returns:
-
None–None
Raises:
-
FileNotFoundError–If the specified file path is not valid.
-
PicklingError–If the data object cannot be serialized.
-
ZstdError–If compression fails.
Source code in SaigeToolkit/util/file_handler.py
load_compressed_data
staticmethod
Loads and decompresses data from a file.
This method reads compressed data from a file, decompresses it using Zstd, and then deserializes it using pickle to convert it back to the original Python data object.
Parameters:
-
file_path(str) –The path of the file from which the compressed data is to be read. The file must exist and contain valid compressed data.
Returns:
-
Any(Any) –The original Python data object that was compressed and saved in the file.
Raises:
-
FileNotFoundError–If the specified file path does not exist.
-
UnpicklingError–If the decompressed data cannot be deserialized.
-
ZstdError–If decompression fails.
Source code in SaigeToolkit/util/file_handler.py
glob_files
glob_files(root_path: str, extensions: Tuple[str], recursive: bool = True, skip_hidden_directories: bool = True, max_directories: Optional[int] = None, max_files: Optional[int] = None, relative_path: bool = False) -> Tuple[List[str], bool, bool]
glob files with specified extensions
Parameters:
-
root_path(str) –description
-
extensions(Tuple[str]) –description
-
recursive(bool, default:True) –description. Defaults to True.
-
skip_hidden_directories(bool, default:True) –description. Defaults to True.
-
max_directories(Optional[int], default:None) –max number of directories to search. Defaults to None.
-
max_files(Optional[int], default:None) –max file number limit. Defaults to None.
-
relative_path(bool, default:False) –description. Defaults to False.
Returns:
-
Tuple[List[str], bool, bool]–Tuple[List[str], bool, bool]: description
Source code in SaigeToolkit/util/file_handler.py
function_tree
FunctionBase
Bases: Callable
Base node definition for operation graph
Example
sort_functions
sort_functions(functions: List[Type[FunctionBase]], roots: Optional[Type[FunctionBase]] = None) -> List[Type[FunctionBase]]
get sorted output functions with topological sort.
Parameters:
-
functions(List[Type[FunctionBase]]) –desired function classes
-
roots(Optional[Type[FunctionBase]], default:None) –tree root function classes
Returns:
-
List[Type[FunctionBase]]–List[Type[FunctionBase]]: ordered list of all required function classes
Source code in SaigeToolkit/util/function_tree.py
memory
CudaMemoryTracker
특정 구간에서 추가적으로 사용된 최대 GPU 메모리를 측정합니다. 예를 들어 모델을 먼저 GPU에 올린 뒤 __enter__에 진입하면 모델이 점유한 메모리는 제외됩니다. 각 연산의 메모리를 정확하게 트래킹하려면 torch.profiler를 사용하세요.
Example
- Context Manager로 사용하는 경우 with CudaMemoryTracker() as tracker: results = model.inference(batch)
- class로 사용하는 경우 tracker = CudaMemoryTracker() tracker.start() results = model.inference(batch) tracker.end() ...
print(tracker.get_results())
Source code in SaigeToolkit/util/memory.py
__enter__
Source code in SaigeToolkit/util/memory.py
__exit__
Source code in SaigeToolkit/util/memory.py
start
end
get_results
Source code in SaigeToolkit/util/memory.py
get_process_cpu_memory
프로세스가 사용하는 RAM 크기를 바이트 단위로 읽어옵니다.
Parameters:
-
pid(int, default:None) –If None, use current PID.
-
include_virtual(bool, default:False) –to include virtual memory. Defaults to False.
Returns:
-
int(int) –CPU memory in bytes
Note
Use --pid=host flag with Docker.
Source code in SaigeToolkit/util/memory.py
get_process_gpu_memory
프로세스가 사용하는 GPU메모리를 NVML 모듈로부터 바이트 단위로 읽어옵니다.
Parameters:
-
pid(int, default:None) –If None, use current PID.
Returns:
-
int(int) –GPU memory in bytes
Note
Use --pid=host flag with Docker.
Source code in SaigeToolkit/util/memory.py
get_memory_stats
현재 프로세스의 메모리 정보를 MiB 단위로 읽어옵니다. torch_max_allocated gpu mem의 경우 해당 함수 호출 직전까지의 최댓값이며, 해당 함수 호출 시 리셋됩니다.
Returns:
-
Dict[str, int]–Dict[str, int]: description
Source code in SaigeToolkit/util/memory.py
registry
클래스 레지스트리를 가질 수 있도록 하는 추상 클래스를 정의합니다.
Registerable
Bases: ABC
Abstract class for base module classes which have class registry.
Usage
from __future__ import annotations
from typing import Dict
from .SaigeToolkit.SaigeToolkit.util.registry import Registerable
class BaseModule(Registerable):
registry: Dict[str, BaseModule]
class ImplementedModuleA(BaseModule):
pass
class ImplementedModuleB(BaseModule):
pass
print(BaseModule.registry)
# output
# {'ImplementedModuleA': __main__.ImplementedModuleA,
# 'ImplementedModuleB': __main__.ImplementedModuleB}
If you want use arbitrary key for registering,
class BaseModule2(Registerable):
registry: Dict[str, BaseModule2]
class ImplementedModule2A(BaseModule2, key="module_2_a"):
pass
print(BaseModule2.registry)
# output
# {'module_2_a': __main__.ImplementedModule2A}
or, define "init_subclass" again.
__init_subclass__
Source code in SaigeToolkit/util/registry.py
reproducibility
실험 재현성을 위한 유틸리티 함수를 제공합니다.
set_randomness
Source code in SaigeToolkit/util/reproducibility.py
store_config
클래스 메소드 호출 시 파라미터를 self.attr 변수에 dict로 저장하는 데코레이터를 리턴합니다.
Usage
class MyClass: @store_config(attr="_config") def init(self, param1, param2): pass
MyClass 인스턴스 생성 시 self._config에 파라미터가 저장됩니다.
Source code in SaigeToolkit/util/reproducibility.py
get_function_args
Returns the argument received by the parent function as a dictionary.
Returns:
-
Dict(Dict) –keyword arguments dictionary
Example
code: def func(A=1, B=2, C=3): print(get_function_args()) func(C=5)
results: {'A': 1, 'B': 2, 'C': 5}
Note
해당 함수를 호출하기 전에 argument를 수정하는 경우, 수정된 argument가 반환됩니다. Example: code: def func(A=1, B=2, C=3): B = 7 print(get_function_args()) func(C=5)
results:
{'A': 1, 'B': 7, 'C': 5}
Source code in SaigeToolkit/util/reproducibility.py
get_source_git_info
Parse git info
Parameters:
-
git_path(Optional[str], default:None) –git directory path. Defaults to None.
Returns:
-
dict(Dict) –{ "directory": str, "commit": str, "modified files": List[str], "untracked files": List[str], "submodules_info": List[Dict],
-
Dict–}
Source code in SaigeToolkit/util/reproducibility.py
get_source_info
Returns current time (KST) + git info + run command
Parameters:
-
git_path(str, default:None) –git directory path. Defaults to GIT_PATH.
Returns:
-
dict(Dict) –{"time": str, "command": str, **git_info}
Source code in SaigeToolkit/util/reproducibility.py
string
pascal_to_snake
get_time_string
system
get_cpu_name
Get CPU name in string
Returns:
-
str(str) –CPU name (ex: "AMD EPYC 7502 32-Core Processor")
get_torch_device_name
Get device name in string
Parameters:
-
device(Union[device, str, int]) –torch device
Returns:
-
str(str) –device name (ex: "A100-PCIE-40GB", "AMD EPYC 7502 32-Core Processor")
Source code in SaigeToolkit/util/system.py
get_system_info
Source code in SaigeToolkit/util/system.py
get_torch_info
Source code in SaigeToolkit/util/system.py
test
API test에 유용하게 사용할 수 있는 함수들을 정의한 파일입니다.
to_string
Recursively convert object to string.
Source code in SaigeToolkit/util/test.py
get_print_function
Source code in SaigeToolkit/util/test.py
sweep_options
load_numpy_image
Source code in SaigeToolkit/util/test.py
timer
timer_timer
module-attribute
timer_timer = Timer(devices='cpu', print_elapsed=False, is_enabled=True)
cuda_timer
module-attribute
cuda_timer = Timer(devices='cuda', print_elapsed=False, is_enabled=True)
BaseTimer
Bases: ABC
Source code in SaigeToolkit/util/timer.py
_start_record
abstractmethod
_end_record
abstractmethod
_CpuTimer
_CudaTimer
Bases: BaseTimer
Source code in SaigeToolkit/util/timer.py
streams
instance-attribute
_start_record
_end_record
Source code in SaigeToolkit/util/timer.py
Timer
Timer(devices: Union[device, str, list] = 'cuda:0', print_elapsed: bool = False, is_enabled: bool = True)
Bases: ContextDecorator
argument로 받은 device에 따라 _CudaTimer, _CpuTimer 중 하나를 선택해서 시간을 측정합니다. _CpuTimer의 경우 time.perf_counter()으로 시작과 끝 시간을 측정하며 _CudaTimer의 경우 CUDA synchronization을 포함해서 시간을 측정합니다.
_CudaTimer의 경우 CUDA synchronization을 사용하기 때문에, GPU time 측정시 보다 정확하지만, _CpuTimer보다 속도가 느립니다. (1000번 실행시 약 100ms 정도 차이남)
Context Manager로 사용하거나 decorator 형태로 사용할 수 있습니다.
enable, disable 함수를 이용해서 Timer를 켜고 끌수 있으며, is_enable함수를 통해 현재 Timer의 작동여부를 확인할 수 있습니다.
reset 함수를 이용해서 현재까지 측정한 시간을 초기화 할 수 있습니다.
측정 된 시간은 accumulated_time과 time_stack property를 통해 가져올 수 있습니다. Timer를 사용해서 여러번 시간을 측정할 경우 accumulated_time은 측정한 총 시간의 합을 나타내고, time_stack은 List안에 측정된 시간이 각각 들어있습니다.
Example
-
Context Manager로 사용하는 경우 timer = CudaTimer() for batch in dataloader: with timer: results = model.inference(batch) print(f"{timer.accumulated_time} ms")
-
Decorator로 사용하는 경우 @CudaTimer(print_elapsed=True) # 함수 실행시 마다 프린트 def my_function(): ...
my_function_timer = CudaTimer() # 해당 함수 호출시 시간 축적 @my_function_timer def my_function(): ...
print(f"{my_function_timer.accumulated_time} ms")
Source code in SaigeToolkit/util/timer.py
to_device
__enter__
__exit__
Source code in SaigeToolkit/util/timer.py
reset
is_enabled
enable
disable
_build_timer
staticmethod
_build_timer(devices: Union[device, str, list]) -> Union[_CudaTimer, _CpuTimer]
Source code in SaigeToolkit/util/timer.py
InferenceHandlerTimer
IAD/SEG/CLS/DET의 InferenceHandler에서 사용되며, 다른 곳에서 사용하려면 get_time, add_time_to_result를 수정해야합니다. 시간 측정을 원하는 함수를 등록하면 해당 함수가 호출 될 때 시간을 측정해주는 class 입니다. TODO: 범용적으로 사용할 수 있는 부분 분리
Warning 1
instance의 함수를 등록하는 경우 해당 instance의 함수에만 timer가 적용되기 때문에 주의가 필요합니다. ex) inference_handler.postprocess.call_method를 등록했을 때, inference_handler.postprocess 변수가 다른 instance로 변경되는 경우 시간이 측정되지 않습니다.
Warning 2
현재 get_time, add_time_to_result의 경우 아래 api 함수에 매우 specific하게 구현되어 있기 때문에, 코드 변경시 주의가 필요합니다. - API.InferenceHandler.infer_and_postprocess - API.InferenceHandler.step_analysis
Warning 3
빠르게 필요한 기능만 구현하느라 등록한 함수를 제거하는 기능은 아직 추가되어 있지 않습니다. 다만 inference_options를 통해 시간 측정 자체를 끄거나 켤 수 있습니다.
Warning 4
현재는 시간 측정 구간에 cuda synchronize가 필요없어서 overhead를 줄이기 위해 CpuTimer를 사용합니다. 이후에 시간을 측정하는 구간이 늘어난다면 이 부분을 고려한 코드 수정이 필요합니다.
Source code in SaigeToolkit/util/timer.py
register
Source code in SaigeToolkit/util/timer.py
to_device
to_device_all
is_enable
set
reset
add_time_to_result
Source code in SaigeToolkit/util/timer.py
_get_time
현재 등록되어 있는 key 및 특징 - imread_time - ImageLoader class의 call_method 시간을 측정. - 여러 image가 들어오는 경우 각각 측정됨. - step_analysis에서 이전 prediction 결과를 재사용 하는 경우 시간 측정이 안됨. - preprocess_time - PreProcess class의 call_method 시간을 측정. - ImageLoader 시간이 포함되어 있기 때문에 ImageLoader에 들어간 시간을 제외해야함. - 여러 image가 들어오는 경우 한번만 측정됨. (batch 연산 처리) - step_analysis에서 이전 prediction 결과를 재사용 하는 경우 시간 측정이 안됨. - inference_time - infer 함수 시간을 측정. - 여러 image가 들어오는 경우 한번만 측정됨. (batch 연산 처리) - step_analysis에서 이전 prediction 결과를 재사용 하는 경우 시간 측정이 안됨. - post_processing_time - PostProcess의 _apply 시간을 측정. (각 이미지별로 측정하기 위함) - 여러 image가 들어오는 경우 각각 측정됨.
Source code in SaigeToolkit/util/timer.py
_enable
_disable
with_cpu_timer
with_cuda_timer
version
Postfix
Defines pre-release version type. (None > "rc" > "beta" > "alpha")
Usage
Raises:
-
VersionFormatError–postfix must be one of "rc", "beta", "alpha" or None
Source code in SaigeToolkit/util/version.py
__bool__
__str__
__repr__
__eq__
__gt__
Source code in SaigeToolkit/util/version.py
__ge__
__lt__
Version
Version(major: Union[int, str], minor: Union[int, str], patch: Union[int, str], postfix: Optional[str] = None)
Defines Version type: https://semver.org/
Usage
version = Version(0, 0, 0)
print(version)
# 0.0.0
version_rc = Version(0, 0, 0, "rc1")
print(version_rc)
# 0.0.0-rc1
version2 = Version.from_string("0.0.1")
print(version2 > version)
# True
print(Version.from_string("0.0.1") > Version(0, 0, 1, "rc1"))
# True
print(Version.from_string("0.0.1-rc1") > Version(0, 0, 1, "beta2"))
# True
Raises:
-
VersionFormatError–version string format should be f"{self.major}.{self.minor}.{self.patch}-{self.postfix}"