| 209 | |
| 210 | |
| 211 | class BucketConfig: |
| 212 | bucket_config = OrderedDict({}) |
| 213 | flop = FlopEstimatorExact |
| 214 | |
| 215 | @classmethod |
| 216 | def from_class_name(cls, class_name, class_kwargs: dict): |
| 217 | bucket_class = globals().get(class_name) |
| 218 | if not (isinstance(bucket_class, BucketConfig) |
| 219 | or issubclass(bucket_class, BucketConfig)): |
| 220 | raise ValueError(f'wrong class name {class_name}') |
| 221 | return bucket_class(**class_kwargs) |
| 222 | |
| 223 | def __init__(self, ) -> None: |
| 224 | ar_value_arr = np.array(list(self.bucket_config.keys())) |
| 225 | assert np.all(ar_value_arr[:-1] < ar_value_arr[1:]) |
| 226 | self.ar_value_arr = ar_value_arr |
| 227 | for ar, (hwp, prob) in self.bucket_config.items(): |
| 228 | assert isinstance(hwp, np.ndarray) |
| 229 | assert isinstance(prob, np.ndarray) |
| 230 | if hwp.shape[1] == 2: |
| 231 | hwp = np.stack([hwp[:, 0], hwp[:, 1], hwp[:, 0] * hwp[:, 1]], |
| 232 | axis=-1) |
| 233 | else: |
| 234 | assert np.all(hwp[:-1, 2] <= hwp[1:, 2]) |
| 235 | if len(hwp) != len(prob): |
| 236 | raise ValueError( |
| 237 | f'wrong config of aspect ratio: {ar}, size_list: {hwp}, prob_list: {prob}' |
| 238 | ) |
| 239 | prob[:] = prob[:] / prob.sum() |
| 240 | self.bucket_config[ar] = (hwp, prob) |
| 241 | print(f'aspect ratio: {ar}, size list: {self.bucket_config[ar]}') |
| 242 | pass |
| 243 | |
| 244 | def preprocess(self, n_frame: int, height: int, width: int, |
| 245 | rnd_state: np.random.RandomState): |
| 246 | """process original height width, sample a (height, width) in |
| 247 | bucket_config with the closed aspect ratio.""" |
| 248 | ar = height / width |
| 249 | tgt_ar_idx = find_nearest_value(ar, self.ar_value_arr, return_idx=True) |
| 250 | h_w_pixel_list, prob_list = self.bucket_config[ |
| 251 | self.ar_value_arr[tgt_ar_idx]] |
| 252 | if h_w_pixel_list[-1, -1] > height * width: |
| 253 | down_num = np.sum(h_w_pixel_list[:, -1] <= height * width) |
| 254 | h_w_pixel_list = h_w_pixel_list[:down_num] |
| 255 | prob_list = prob_list[:down_num] / prob_list[:down_num].sum() |
| 256 | selected_idx = rnd_state.choice( |
| 257 | len(prob_list), size=None, replace=False, p=prob_list) |
| 258 | h, w = h_w_pixel_list[selected_idx][:2] |
| 259 | return h, w |
| 260 | |
| 261 | def __call__(self, n_frame: int, height: int, width: int, |
| 262 | rnd_state: np.random.RandomState) -> Any: |
| 263 | tgt_h, tgt_w = self.preprocess(n_frame, height, width, rnd_state) |
| 264 | return self.flop(n_frame, tgt_h, tgt_w) |
| 265 | |
| 266 | |
| 267 | class BucketConfigHardCoded1(BucketConfig): |
nothing calls this directly
no outgoing calls
no test coverage detected