# Created by BVH, Jul 2025.

import os
from hydra.core.config_store import ConfigStore
from custom.experiment.template import template_any4d_2b, S3_PRETRAINED_ROOT, S3_OUTPUT_ROOT

#################################################################

job = dict(  # this becomes JobConfig
    project='a4d2',
    group='debug',
    name='fc1',
    prepend_datetime=True,  # becomes {now:%m-%d-%H-%M}_{config.job.name},
    local_root='',  # empty = _DEFAULT_LOCAL_ROOT (/any4d on DGX, /tmp/a4d2 on SM)
    s3_root=S3_OUTPUT_ROOT,  # default from template.py; set '' to disable S3 sync
)

wandb = dict(
    enabled=True,
    entity='tri',
    project='dbg_a4d2',
    num_validation_logs=5,
)

any4d_config = dict(  # this is part of Any4DConfig, which inherits from Predict2Video2WorldModelConfig
    transforms='default',
    dataloader='simple',
    vae='a4d_vae',
    video_entries=[
        # first entry = base / pretrained
        dict(
            # key: (channel_start, channel_end, in_proj_init, out_proj_init)
            # NOTE: there will be T*H*W tokens with this information
            rgb0=(0, 16, 'load', 'load'),  # do not change
            rgb0_input_mask=(16, 17, 'load', None),  # do not change
            rgb0_output_mask=(17, 18, 'zero', None),  # do not change
        ),
    ],
    num_views=1,
    # force_cond_noise_level=True,  # DEBUG
    video_concat_mode='view',
    video_proj_mode='per_view',
    loss_weights=dict(
        rgb0=1.0,
    ),
    load_modals=['rgb', 'language', 'action'],
    task_probs=dict(
        forecast=1.0,
    ),
    track_metrics=dict(
        rgb0=['psnr', 'ssim'],
    ),
    train_visuals_interval=39,
    train_visuals_detail=2,
    val_visuals_detail=2,
)

#################################################################

model = dict(  # this makes up parts of Predict2Video2WorldModelConfig and Predict2ModelManagerConfig
    dit_path=f'{S3_PRETRAINED_ROOT}/nvidia/Cosmos-Predict2-2B-Video2World/model-480p-10fps.pt',
    text_encoder_path=f'{S3_PRETRAINED_ROOT}/google-t5/t5-11b',
    vae_path=f'{S3_PRETRAINED_ROOT}/nvidia/Cosmos-Predict2-2B-Video2World/tokenizer/tokenizer.pth',
    fsdp_shard_size=2,
    ############
    run_validation=True,
    validation_iter=100,  # frequency / interval of validation runs
    max_val_iter=4,  # number of steps per validation run
    max_iter=50000,  # total number of training steps
    grad_accum_iter=1,
    context_parallel_size=1,
    device_monitor=0,
    manual_gc_iter=288,
    ############
    state_t=11,  # for noise level; = latent # frames for now
    tokenizer_chunk_duration=41,  # for VAE; = raw # frames for now
)

checkpoint = dict(
    save_iter=1000,
    early_sanity_check=5,
)

optimizer = dict(
    lr=5.0e-5,
)

scheduler = dict(
    warm_up_steps = [100],
    cycle_lengths = [model['max_iter']],
    f_start=[0.01],
    f_max=[1.0],
    f_min=[0.05],
)

dataset_train = dict(
    config='custom/config/debug/humanoid_tiny_1v.yaml',
    num_workers=4,
    batch_size=4,
)

dataset_val = dict(
    config='custom/config/debug/humanoid_tiny_1v.yaml',
    num_workers=0,  # can crash debugger otherwise
    batch_size=1,
)

metrics = dict(
)

#################################################################

cs = ConfigStore.instance()

this_config = template_any4d_2b(
    job, wandb, any4d_config, model, 
    checkpoint, optimizer, scheduler, metrics,
    dataset_train, dataset_val,
)

# Use the filename (without extension) as the experiment name
experiment_name = 'any4d_' + os.path.splitext(os.path.basename(__file__))[0]

cs.store(
    group='experiment',
    package='_global_',
    name=experiment_name,
    node=this_config,
)

