Registry

YAHP also supports instantiating concrete sub-classes of abstract fields directly from the YAML or the command line.

Singleton Example

Consider the following script that defines the Hparams:

 1# Copyright 2021 MosaicML. All Rights Reserved.
 2
 3import abc
 4import dataclasses
 5import os
 6from typing import List
 7
 8import yahp as hp
 9
10
11@dataclasses.dataclass
12class Person(hp.Hparams, abc.ABC):
13    name: str = hp.required('name')
14
15
16@dataclasses.dataclass
17class AdultHparams(Person):
18    num_children: int = hp.optional('num_children', default=0)
19
20
21@dataclasses.dataclass
22class ChildHparams(Person):
23    parents: List[str] = hp.required('parents')
24
25
26@dataclasses.dataclass
27class FooHparams(hp.Hparams):
28    hparams_registry = {
29        'owner':
30            {  # key "owner" corresponds to field name "owner" below
31                'adult': AdultHparams,
32                'child': ChildHparams,
33            }
34    }
35    owner: Person = hp.required('owner')
36
37

Suppose registry_foo.yaml contains the following:

owner:
  child:
    name: Bob
    parents:
      - Alice
      - Charlie

Then, the following example will load owner to the child.

1foo_hparams = FooHparams.create(os.path.join(os.path.dirname(__file__), 'registry_foo.yaml'))
2assert type(foo_hparams.owner) is ChildHparams
3
4print(foo_hparams)
5
6

It will print the following:

FooHparams:
    owner:
        child:
            name: Bob
            parents:
            - Alice
            - Charlie

List Example

Suppose we wanted to permit multiple owners. Consider the following Hparams:

 1@dataclasses.dataclass
 2class BarHparams(hp.Hparams):
 3    hparams_registry = {
 4        'owners':
 5            {  # key "owners" corresponds to field name "owners" below
 6                'adult': AdultHparams,
 7                'child': ChildHparams,
 8            }
 9    }
10    owners: List[Person] = hp.required('owners')
11
12

Suppose registry_bar.yaml contains the following:

owners:
  - adult:
      name: Alice
      num_children: 1
  - child:
      name: Bob
      parents:
        - Alice
        - Charlie

Then, the following example will load owners to the adult and the child.

1bar_hparams = BarHparams.create(os.path.join(os.path.dirname(__file__), 'registry_bar.yaml'))
2assert type(bar_hparams.owners[0]) is AdultHparams
3assert type(bar_hparams.owners[1]) is ChildHparams
4
5print(bar_hparams)

It will print the following:

BarHparams:
    owners:
    - adult:
        name: Alice
        num_children: 1
    - child:
        name: Bob
        parents:
        - Alice
        - Charlie